Merge "Mark location classes as Parcelable appropriately"
diff --git a/Android.bp b/Android.bp
index ea1ed91..1b9210c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -498,7 +498,7 @@
         "telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl",
         "telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl",
         "telephony/java/android/telephony/ims/aidl/IImsServiceControllerListener.aidl",
-	    "telephony/java/android/telephony/ims/aidl/IImsSmsListener.aidl",
+        "telephony/java/android/telephony/ims/aidl/IImsSmsListener.aidl",
         "telephony/java/android/telephony/mbms/IMbmsDownloadSessionCallback.aidl",
         "telephony/java/android/telephony/mbms/IMbmsStreamingSessionCallback.aidl",
         "telephony/java/android/telephony/mbms/IDownloadStateCallback.aidl",
@@ -683,7 +683,8 @@
     // Loaded with System.loadLibrary by android.view.textclassifier
     required: [
         "libtextclassifier",
-        "libmedia2_jni",],
+        "libmedia2_jni",
+    ],
 
     javac_shard_size: 150,
 
@@ -833,7 +834,7 @@
         "  -I . " +
         "  $(in)",
 
-    output_extension = "proto.h",
+    output_extension: "proto.h",
 }
 
 subdirs = [
diff --git a/Android.mk b/Android.mk
index 58e21ff..470714b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -143,7 +143,6 @@
 	bouncycastle \
 	okhttp \
 	ext \
-	icu4j \
 	framework \
 	voip-common \
 
@@ -195,6 +194,7 @@
     -since $(SRC_API_DIR)/25.txt 25 \
     -since $(SRC_API_DIR)/26.txt 26 \
     -since $(SRC_API_DIR)/27.txt 27 \
+    -since ./frameworks/base/api/current.txt P \
     -werror -lerror -hide 111 -hide 113 -hide 125 -hide 126 -hide 127 -hide 128 \
     -overview $(LOCAL_PATH)/core/java/overview.html \
 
diff --git a/apct-tests/perftests/core/Android.mk b/apct-tests/perftests/core/Android.mk
index b7b87dd..6156a0c 100644
--- a/apct-tests/perftests/core/Android.mk
+++ b/apct-tests/perftests/core/Android.mk
@@ -16,6 +16,7 @@
 LOCAL_JAVA_LIBRARIES := android.test.base
 
 LOCAL_PACKAGE_NAME := CorePerfTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_JNI_SHARED_LIBRARIES := libperftestscore_jni
 
diff --git a/apct-tests/perftests/multiuser/Android.mk b/apct-tests/perftests/multiuser/Android.mk
index 2db0dd6..a803369 100644
--- a/apct-tests/perftests/multiuser/Android.mk
+++ b/apct-tests/perftests/multiuser/Android.mk
@@ -24,6 +24,7 @@
     ub-uiautomator
 
 LOCAL_PACKAGE_NAME := MultiUserPerfTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_CERTIFICATE := platform
 
diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/ManualBenchmarkState.java b/apct-tests/perftests/utils/src/android/perftests/utils/ManualBenchmarkState.java
index 2c84db1..40778de 100644
--- a/apct-tests/perftests/utils/src/android/perftests/utils/ManualBenchmarkState.java
+++ b/apct-tests/perftests/utils/src/android/perftests/utils/ManualBenchmarkState.java
@@ -150,6 +150,8 @@
         final Bundle status = new Bundle();
         status.putLong(key + "_median", mStats.getMedian());
         status.putLong(key + "_mean", (long) mStats.getMean());
+        status.putLong(key + "_percentile90", mStats.getPercentile90());
+        status.putLong(key + "_percentile95", mStats.getPercentile95());
         status.putLong(key + "_stddev", (long) mStats.getStandardDeviation());
         instrumentation.sendStatus(Activity.RESULT_OK, status);
     }
diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/Stats.java b/apct-tests/perftests/utils/src/android/perftests/utils/Stats.java
index acc44a8..5e50073 100644
--- a/apct-tests/perftests/utils/src/android/perftests/utils/Stats.java
+++ b/apct-tests/perftests/utils/src/android/perftests/utils/Stats.java
@@ -21,7 +21,7 @@
 import java.util.List;
 
 public class Stats {
-    private long mMedian, mMin, mMax;
+    private long mMedian, mMin, mMax, mPercentile90, mPercentile95;
     private double mMean, mStandardDeviation;
 
     /* Calculate stats in constructor. */
@@ -35,12 +35,14 @@
 
         Collections.sort(values);
 
-        mMedian = size % 2 == 0 ? (values.get(size / 2) + values.get(size / 2 - 1)) / 2 :
-                values.get(size / 2);
-
         mMin = values.get(0);
         mMax = values.get(values.size() - 1);
 
+        mMedian = size % 2 == 0 ? (values.get(size / 2) + values.get(size / 2 - 1)) / 2 :
+                values.get(size / 2);
+        mPercentile90 = getPercentile(values, 90);
+        mPercentile95 = getPercentile(values, 95);
+
         for (int i = 0; i < size; ++i) {
             long result = values.get(i);
             mMean += result;
@@ -73,4 +75,21 @@
     public double getStandardDeviation() {
         return mStandardDeviation;
     }
+
+    public long getPercentile90() {
+        return mPercentile90;
+    }
+
+    public long getPercentile95() {
+        return mPercentile95;
+    }
+
+    private static long getPercentile(List<Long> values, int percentile) {
+        if (percentile < 0 || percentile > 100) {
+            throw new IllegalArgumentException(
+                    "invalid percentile " + percentile + ", should be 0-100");
+        }
+        int idx = (values.size() - 1) * percentile / 100;
+        return values.get(idx);
+    }
 }
diff --git a/api/current.txt b/api/current.txt
index 453eac5..fbf1c22 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1378,6 +1378,7 @@
     field public static final int textEditSidePasteWindowLayout = 16843614; // 0x101035e
     field public static final int textEditSuggestionItemLayout = 16843636; // 0x1010374
     field public static final int textFilterEnabled = 16843007; // 0x10100ff
+    field public static final int textFontWeight = 16844166; // 0x1010586
     field public static final int textIsSelectable = 16843542; // 0x1010316
     field public static final int textOff = 16843045; // 0x1010125
     field public static final int textOn = 16843044; // 0x1010124
@@ -1548,6 +1549,7 @@
     field public static final int windowHideAnimation = 16842935; // 0x10100b7
     field public static final int windowIsFloating = 16842839; // 0x1010057
     field public static final int windowIsTranslucent = 16842840; // 0x1010058
+    field public static final int windowLayoutInDisplayCutoutMode = 16844167; // 0x1010587
     field public static final int windowLightNavigationBar = 16844140; // 0x101056c
     field public static final int windowLightStatusBar = 16844000; // 0x10104e0
     field public static final int windowMinWidthMajor = 16843606; // 0x1010356
@@ -3882,6 +3884,7 @@
     method public android.app.PendingIntent getRunningServiceControlPanel(android.content.ComponentName) throws java.lang.SecurityException;
     method public deprecated java.util.List<android.app.ActivityManager.RunningServiceInfo> getRunningServices(int) throws java.lang.SecurityException;
     method public deprecated java.util.List<android.app.ActivityManager.RunningTaskInfo> getRunningTasks(int) throws java.lang.SecurityException;
+    method public boolean isBackgroundRestricted();
     method public deprecated boolean isInLockTaskMode();
     method public boolean isLowRamDevice();
     method public static boolean isRunningInTestHarness();
@@ -4070,7 +4073,7 @@
     method public android.app.ActivityOptions setAppVerificationBundle(android.os.Bundle);
     method public android.app.ActivityOptions setLaunchBounds(android.graphics.Rect);
     method public android.app.ActivityOptions setLaunchDisplayId(int);
-    method public android.app.ActivityOptions setLockTaskMode(boolean);
+    method public android.app.ActivityOptions setLockTaskEnabled(boolean);
     method public android.os.Bundle toBundle();
     method public void update(android.app.ActivityOptions);
     field public static final java.lang.String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
@@ -5349,18 +5352,18 @@
     ctor public Notification.Action.WearableExtender(android.app.Notification.Action);
     method public android.app.Notification.Action.WearableExtender clone();
     method public android.app.Notification.Action.Builder extend(android.app.Notification.Action.Builder);
-    method public java.lang.CharSequence getCancelLabel();
-    method public java.lang.CharSequence getConfirmLabel();
+    method public deprecated java.lang.CharSequence getCancelLabel();
+    method public deprecated java.lang.CharSequence getConfirmLabel();
     method public boolean getHintDisplayActionInline();
     method public boolean getHintLaunchesActivity();
-    method public java.lang.CharSequence getInProgressLabel();
+    method public deprecated java.lang.CharSequence getInProgressLabel();
     method public boolean isAvailableOffline();
     method public android.app.Notification.Action.WearableExtender setAvailableOffline(boolean);
-    method public android.app.Notification.Action.WearableExtender setCancelLabel(java.lang.CharSequence);
-    method public android.app.Notification.Action.WearableExtender setConfirmLabel(java.lang.CharSequence);
+    method public deprecated android.app.Notification.Action.WearableExtender setCancelLabel(java.lang.CharSequence);
+    method public deprecated android.app.Notification.Action.WearableExtender setConfirmLabel(java.lang.CharSequence);
     method public android.app.Notification.Action.WearableExtender setHintDisplayActionInline(boolean);
     method public android.app.Notification.Action.WearableExtender setHintLaunchesActivity(boolean);
-    method public android.app.Notification.Action.WearableExtender setInProgressLabel(java.lang.CharSequence);
+    method public deprecated android.app.Notification.Action.WearableExtender setInProgressLabel(java.lang.CharSequence);
   }
 
   public static class Notification.BigPictureStyle extends android.app.Notification.Style {
@@ -5583,39 +5586,39 @@
     method public android.graphics.Bitmap getBackground();
     method public java.lang.String getBridgeTag();
     method public int getContentAction();
-    method public int getContentIcon();
-    method public int getContentIconGravity();
+    method public deprecated int getContentIcon();
+    method public deprecated int getContentIconGravity();
     method public boolean getContentIntentAvailableOffline();
-    method public int getCustomContentHeight();
-    method public int getCustomSizePreset();
+    method public deprecated int getCustomContentHeight();
+    method public deprecated int getCustomSizePreset();
     method public java.lang.String getDismissalId();
     method public android.app.PendingIntent getDisplayIntent();
-    method public int getGravity();
+    method public deprecated int getGravity();
     method public boolean getHintAmbientBigPicture();
-    method public boolean getHintAvoidBackgroundClipping();
+    method public deprecated boolean getHintAvoidBackgroundClipping();
     method public boolean getHintContentIntentLaunchesActivity();
-    method public boolean getHintHideIcon();
-    method public int getHintScreenTimeout();
-    method public boolean getHintShowBackgroundOnly();
+    method public deprecated boolean getHintHideIcon();
+    method public deprecated int getHintScreenTimeout();
+    method public deprecated boolean getHintShowBackgroundOnly();
     method public java.util.List<android.app.Notification> getPages();
     method public boolean getStartScrollBottom();
     method public android.app.Notification.WearableExtender setBackground(android.graphics.Bitmap);
     method public android.app.Notification.WearableExtender setBridgeTag(java.lang.String);
     method public android.app.Notification.WearableExtender setContentAction(int);
-    method public android.app.Notification.WearableExtender setContentIcon(int);
-    method public android.app.Notification.WearableExtender setContentIconGravity(int);
+    method public deprecated android.app.Notification.WearableExtender setContentIcon(int);
+    method public deprecated android.app.Notification.WearableExtender setContentIconGravity(int);
     method public android.app.Notification.WearableExtender setContentIntentAvailableOffline(boolean);
-    method public android.app.Notification.WearableExtender setCustomContentHeight(int);
-    method public android.app.Notification.WearableExtender setCustomSizePreset(int);
+    method public deprecated android.app.Notification.WearableExtender setCustomContentHeight(int);
+    method public deprecated android.app.Notification.WearableExtender setCustomSizePreset(int);
     method public android.app.Notification.WearableExtender setDismissalId(java.lang.String);
     method public android.app.Notification.WearableExtender setDisplayIntent(android.app.PendingIntent);
-    method public android.app.Notification.WearableExtender setGravity(int);
+    method public deprecated android.app.Notification.WearableExtender setGravity(int);
     method public android.app.Notification.WearableExtender setHintAmbientBigPicture(boolean);
-    method public android.app.Notification.WearableExtender setHintAvoidBackgroundClipping(boolean);
+    method public deprecated android.app.Notification.WearableExtender setHintAvoidBackgroundClipping(boolean);
     method public android.app.Notification.WearableExtender setHintContentIntentLaunchesActivity(boolean);
-    method public android.app.Notification.WearableExtender setHintHideIcon(boolean);
-    method public android.app.Notification.WearableExtender setHintScreenTimeout(int);
-    method public android.app.Notification.WearableExtender setHintShowBackgroundOnly(boolean);
+    method public deprecated android.app.Notification.WearableExtender setHintHideIcon(boolean);
+    method public deprecated android.app.Notification.WearableExtender setHintScreenTimeout(int);
+    method public deprecated android.app.Notification.WearableExtender setHintShowBackgroundOnly(boolean);
     method public android.app.Notification.WearableExtender setStartScrollBottom(boolean);
     field public static final int SCREEN_TIMEOUT_LONG = -1; // 0xffffffff
     field public static final int SCREEN_TIMEOUT_SHORT = 0; // 0x0
@@ -6595,7 +6598,7 @@
     method public void uninstallCaCert(android.content.ComponentName, byte[]);
     method public boolean updateOverrideApn(android.content.ComponentName, int, android.telephony.data.ApnSetting);
     method public void wipeData(int);
-    method public void wipeDataWithReason(int, java.lang.CharSequence);
+    method public void wipeData(int, java.lang.CharSequence);
     field public static final java.lang.String ACTION_ADD_DEVICE_ADMIN = "android.app.action.ADD_DEVICE_ADMIN";
     field public static final java.lang.String ACTION_APPLICATION_DELEGATION_SCOPES_CHANGED = "android.app.action.APPLICATION_DELEGATION_SCOPES_CHANGED";
     field public static final java.lang.String ACTION_DEVICE_ADMIN_SERVICE = "android.app.action.DEVICE_ADMIN_SERVICE";
@@ -6678,7 +6681,7 @@
     field public static final int LOCK_TASK_FEATURE_KEYGUARD = 32; // 0x20
     field public static final int LOCK_TASK_FEATURE_NONE = 0; // 0x0
     field public static final int LOCK_TASK_FEATURE_NOTIFICATIONS = 2; // 0x2
-    field public static final int LOCK_TASK_FEATURE_RECENTS = 8; // 0x8
+    field public static final int LOCK_TASK_FEATURE_OVERVIEW = 8; // 0x8
     field public static final int LOCK_TASK_FEATURE_SYSTEM_INFO = 1; // 0x1
     field public static final int MAKE_USER_EPHEMERAL = 2; // 0x2
     field public static final java.lang.String MIME_TYPE_PROVISIONING_NFC = "application/com.android.managedprovisioning";
@@ -6702,11 +6705,6 @@
     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 USER_OPERATION_ERROR_CURRENT_USER = 4; // 0x4
-    field public static final int USER_OPERATION_ERROR_MANAGED_PROFILE = 2; // 0x2
-    field public static final int USER_OPERATION_ERROR_MAX_RUNNING_USERS = 3; // 0x3
-    field public static final int USER_OPERATION_ERROR_UNKNOWN = 1; // 0x1
-    field public static final int USER_OPERATION_SUCCESS = 0; // 0x0
     field public static final int WIPE_EUICC = 4; // 0x4
     field public static final int WIPE_EXTERNAL_STORAGE = 1; // 0x1
     field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2
@@ -7267,6 +7265,7 @@
     method public void registerSliceCallback(android.net.Uri, java.util.List<android.app.slice.SliceSpec>, java.util.concurrent.Executor, android.app.slice.SliceManager.SliceCallback);
     method public void unpinSlice(android.net.Uri);
     method public void unregisterSliceCallback(android.net.Uri, android.app.slice.SliceManager.SliceCallback);
+    field public static final java.lang.String SLICE_METADATA_KEY = "android.metadata.SLICE_URI";
   }
 
   public static abstract interface SliceManager.SliceCallback {
@@ -8971,6 +8970,7 @@
 
   public class ClipboardManager extends android.text.ClipboardManager {
     method public void addPrimaryClipChangedListener(android.content.ClipboardManager.OnPrimaryClipChangedListener);
+    method public void clearPrimaryClip();
     method public android.content.ClipData getPrimaryClip();
     method public android.content.ClipDescription getPrimaryClipDescription();
     method public deprecated java.lang.CharSequence getText();
@@ -11389,6 +11389,8 @@
     ctor public PermissionInfo();
     ctor public PermissionInfo(android.content.pm.PermissionInfo);
     method public int describeContents();
+    method public int getProtection();
+    method public int getProtectionFlags();
     method public java.lang.CharSequence loadDescription(android.content.pm.PackageManager);
     field public static final android.os.Parcelable.Creator<android.content.pm.PermissionInfo> CREATOR;
     field public static final int FLAG_COSTS_MONEY = 1; // 0x1
@@ -11405,8 +11407,8 @@
     field public static final int PROTECTION_FLAG_SETUP = 2048; // 0x800
     field public static final deprecated int PROTECTION_FLAG_SYSTEM = 16; // 0x10
     field public static final int PROTECTION_FLAG_VERIFIER = 512; // 0x200
-    field public static final int PROTECTION_MASK_BASE = 15; // 0xf
-    field public static final int PROTECTION_MASK_FLAGS = 65520; // 0xfff0
+    field public static final deprecated int PROTECTION_MASK_BASE = 15; // 0xf
+    field public static final deprecated int PROTECTION_MASK_FLAGS = 65520; // 0xfff0
     field public static final int PROTECTION_NORMAL = 0; // 0x0
     field public static final int PROTECTION_SIGNATURE = 2; // 0x2
     field public static final deprecated int PROTECTION_SIGNATURE_OR_SYSTEM = 3; // 0x3
@@ -11414,7 +11416,7 @@
     field public int flags;
     field public java.lang.String group;
     field public java.lang.CharSequence nonLocalizedDescription;
-    field public int protectionLevel;
+    field public deprecated int protectionLevel;
   }
 
   public final class ProviderInfo extends android.content.pm.ComponentInfo implements android.os.Parcelable {
@@ -13592,7 +13594,7 @@
   }
 
   public class EmbossMaskFilter extends android.graphics.MaskFilter {
-    ctor public EmbossMaskFilter(float[], float, float, float);
+    ctor public deprecated EmbossMaskFilter(float[], float, float, float);
   }
 
   public final class ImageDecoder implements java.lang.AutoCloseable {
@@ -13605,16 +13607,16 @@
     method public static android.graphics.drawable.Drawable decodeDrawable(android.graphics.ImageDecoder.Source, android.graphics.ImageDecoder.OnHeaderDecodedListener) throws java.io.IOException;
     method public static android.graphics.drawable.Drawable decodeDrawable(android.graphics.ImageDecoder.Source) throws java.io.IOException;
     method public android.util.Size getSampledSize(int);
-    method public void setAllocator(int);
-    method public void setAsAlphaMask(boolean);
-    method public void setCrop(android.graphics.Rect);
-    method public void setMutable(boolean);
-    method public void setOnPartialImageListener(android.graphics.ImageDecoder.OnPartialImageListener);
-    method public void setPostProcessor(android.graphics.PostProcessor);
-    method public void setPreferRamOverQuality(boolean);
-    method public void setRequireUnpremultiplied(boolean);
-    method public void setResize(int, int);
-    method public void setResize(int);
+    method public android.graphics.ImageDecoder setAllocator(int);
+    method public android.graphics.ImageDecoder setAsAlphaMask(boolean);
+    method public android.graphics.ImageDecoder setConserveMemory(boolean);
+    method public android.graphics.ImageDecoder setCrop(android.graphics.Rect);
+    method public android.graphics.ImageDecoder setMutable(boolean);
+    method public android.graphics.ImageDecoder setOnPartialImageListener(android.graphics.ImageDecoder.OnPartialImageListener);
+    method public android.graphics.ImageDecoder setPostProcessor(android.graphics.PostProcessor);
+    method public android.graphics.ImageDecoder setRequireUnpremultiplied(boolean);
+    method public android.graphics.ImageDecoder setResize(int, int);
+    method public android.graphics.ImageDecoder setResize(int);
     field public static final int ALLOCATOR_DEFAULT = 0; // 0x0
     field public static final int ALLOCATOR_HARDWARE = 3; // 0x3
     field public static final int ALLOCATOR_SHARED_MEMORY = 2; // 0x2
@@ -14507,7 +14509,9 @@
     ctor public AnimatedImageDrawable();
     method public void clearAnimationCallbacks();
     method public void draw(android.graphics.Canvas);
+    method public int getLoopCount();
     method public int getOpacity();
+    method public final boolean isAutoMirrored();
     method public boolean isRunning();
     method public void registerAnimationCallback(android.graphics.drawable.Animatable2.AnimationCallback);
     method public void setAlpha(int);
@@ -14814,6 +14818,10 @@
     method public static android.graphics.drawable.Icon createWithResource(android.content.Context, int);
     method public static android.graphics.drawable.Icon createWithResource(java.lang.String, int);
     method public int describeContents();
+    method public int getResId();
+    method public java.lang.String getResPackage();
+    method public int getType();
+    method public android.net.Uri getUri();
     method public android.graphics.drawable.Drawable loadDrawable(android.content.Context);
     method public void loadDrawableAsync(android.content.Context, android.os.Message);
     method public void loadDrawableAsync(android.content.Context, android.graphics.drawable.Icon.OnDrawableLoadedListener, android.os.Handler);
@@ -14822,6 +14830,11 @@
     method public android.graphics.drawable.Icon setTintMode(android.graphics.PorterDuff.Mode);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.graphics.drawable.Icon> CREATOR;
+    field public static final int TYPE_ADAPTIVE_BITMAP = 5; // 0x5
+    field public static final int TYPE_BITMAP = 1; // 0x1
+    field public static final int TYPE_DATA = 3; // 0x3
+    field public static final int TYPE_RESOURCE = 2; // 0x2
+    field public static final int TYPE_URI = 4; // 0x4
   }
 
   public static abstract interface Icon.OnDrawableLoadedListener {
@@ -16273,9 +16286,7 @@
     field public static final android.hardware.camera2.CaptureResult.Key<android.hardware.camera2.params.LensShadingMap> STATISTICS_LENS_SHADING_CORRECTION_MAP;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> STATISTICS_LENS_SHADING_MAP_MODE;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> STATISTICS_OIS_DATA_MODE;
-    field public static final android.hardware.camera2.CaptureResult.Key<long[]> STATISTICS_OIS_TIMESTAMPS;
-    field public static final android.hardware.camera2.CaptureResult.Key<float[]> STATISTICS_OIS_X_SHIFTS;
-    field public static final android.hardware.camera2.CaptureResult.Key<float[]> STATISTICS_OIS_Y_SHIFTS;
+    field public static final android.hardware.camera2.CaptureResult.Key<android.hardware.camera2.params.OisSample[]> STATISTICS_OIS_SAMPLES;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> STATISTICS_SCENE_FLICKER;
     field public static final android.hardware.camera2.CaptureResult.Key<android.hardware.camera2.params.TonemapCurve> TONEMAP_CURVE;
     field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Float> TONEMAP_GAMMA;
@@ -16371,6 +16382,13 @@
     field public static final int METERING_WEIGHT_MIN = 0; // 0x0
   }
 
+  public final class OisSample {
+    ctor public OisSample(long, float, float);
+    method public long getTimestamp();
+    method public float getXshift();
+    method public float getYshift();
+  }
+
   public final class OutputConfiguration implements android.os.Parcelable {
     ctor public OutputConfiguration(android.view.Surface);
     ctor public OutputConfiguration(int, android.view.Surface);
@@ -16572,7 +16590,7 @@
     field public static final int FINGERPRINT_ERROR_VENDOR = 8; // 0x8
   }
 
-  public static abstract class FingerprintManager.AuthenticationCallback {
+  public static abstract deprecated class FingerprintManager.AuthenticationCallback {
     ctor public FingerprintManager.AuthenticationCallback();
     method public void onAuthenticationError(int, java.lang.CharSequence);
     method public void onAuthenticationFailed();
@@ -16580,11 +16598,11 @@
     method public void onAuthenticationSucceeded(android.hardware.fingerprint.FingerprintManager.AuthenticationResult);
   }
 
-  public static class FingerprintManager.AuthenticationResult {
+  public static deprecated class FingerprintManager.AuthenticationResult {
     method public android.hardware.fingerprint.FingerprintManager.CryptoObject getCryptoObject();
   }
 
-  public static final class FingerprintManager.CryptoObject {
+  public static final deprecated class FingerprintManager.CryptoObject {
     ctor public FingerprintManager.CryptoObject(java.security.Signature);
     ctor public FingerprintManager.CryptoObject(javax.crypto.Cipher);
     ctor public FingerprintManager.CryptoObject(javax.crypto.Mac);
@@ -21903,6 +21921,7 @@
     field public static final int TYPE_FM_TUNER = 16; // 0x10
     field public static final int TYPE_HDMI = 9; // 0x9
     field public static final int TYPE_HDMI_ARC = 10; // 0xa
+    field public static final int TYPE_HEARING_AID = 23; // 0x17
     field public static final int TYPE_IP = 20; // 0x14
     field public static final int TYPE_LINE_ANALOG = 5; // 0x5
     field public static final int TYPE_LINE_DIGITAL = 6; // 0x6
@@ -22509,8 +22528,8 @@
     method public java.io.FileDescriptor getFileDescriptor();
     method public long getFileDescriptorLength();
     method public long getFileDescriptorOffset();
-    method public long getId();
     method public android.media.Media2DataSource getMedia2DataSource();
+    method public java.lang.String getMediaId();
     method public long getStartPosition();
     method public int getType();
     method public android.net.Uri getUri();
@@ -22534,7 +22553,7 @@
     method public android.media.DataSourceDesc.Builder setDataSource(android.content.Context, android.net.Uri);
     method public android.media.DataSourceDesc.Builder setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>, java.util.List<java.net.HttpCookie>);
     method public android.media.DataSourceDesc.Builder setEndPosition(long);
-    method public android.media.DataSourceDesc.Builder setId(long);
+    method public android.media.DataSourceDesc.Builder setMediaId(java.lang.String);
     method public android.media.DataSourceDesc.Builder setStartPosition(long);
   }
 
@@ -22739,6 +22758,7 @@
     method public abstract void close();
     method public android.graphics.Rect getCropRect();
     method public abstract int getFormat();
+    method public android.hardware.HardwareBuffer getHardwareBuffer();
     method public abstract int getHeight();
     method public abstract android.media.Image.Plane[] getPlanes();
     method public abstract long getTimestamp();
@@ -22831,6 +22851,27 @@
     field public static final int STOP_VIDEO_RECORDING = 3; // 0x3
   }
 
+  public class MediaBrowser2 extends android.media.MediaController2 {
+    ctor public MediaBrowser2(android.content.Context, android.media.SessionToken2, java.util.concurrent.Executor, android.media.MediaBrowser2.BrowserCallback);
+    method public void getChildren(java.lang.String, int, int, android.os.Bundle);
+    method public void getItem(java.lang.String);
+    method public void getLibraryRoot(android.os.Bundle);
+    method public void getSearchResult(java.lang.String, int, int, android.os.Bundle);
+    method public void search(java.lang.String, android.os.Bundle);
+    method public void subscribe(java.lang.String, android.os.Bundle);
+    method public void unsubscribe(java.lang.String);
+  }
+
+  public static class MediaBrowser2.BrowserCallback extends android.media.MediaController2.ControllerCallback {
+    ctor public MediaBrowser2.BrowserCallback();
+    method public void onChildrenChanged(java.lang.String, int, android.os.Bundle);
+    method public void onGetChildrenDone(java.lang.String, int, int, java.util.List<android.media.MediaItem2>, android.os.Bundle);
+    method public void onGetItemDone(java.lang.String, android.media.MediaItem2);
+    method public void onGetLibraryRootDone(android.os.Bundle, java.lang.String, android.os.Bundle);
+    method public void onGetSearchResultDone(java.lang.String, int, int, java.util.List<android.media.MediaItem2>, android.os.Bundle);
+    method public void onSearchResultChanged(java.lang.String, int, android.os.Bundle);
+  }
+
   public final class MediaCas implements java.lang.AutoCloseable {
     ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException;
     method public void close();
@@ -23307,6 +23348,75 @@
     field public static final int REGULAR_CODECS = 0; // 0x0
   }
 
+  public class MediaController2 implements java.lang.AutoCloseable android.media.MediaPlaylistController {
+    ctor public MediaController2(android.content.Context, android.media.SessionToken2, java.util.concurrent.Executor, android.media.MediaController2.ControllerCallback);
+    method public void addPlaylistItem(int, android.media.MediaItem2);
+    method public void adjustVolume(int, int);
+    method public void close();
+    method public void fastForward();
+    method public long getBufferedPosition();
+    method public android.media.MediaItem2 getCurrentPlaylistItem();
+    method public android.media.MediaController2.PlaybackInfo getPlaybackInfo();
+    method public float getPlaybackSpeed();
+    method public int getPlayerState();
+    method public java.util.List<android.media.MediaItem2> getPlaylist();
+    method public android.media.MediaSession2.PlaylistParams getPlaylistParams();
+    method public long getPosition();
+    method public android.app.PendingIntent getSessionActivity();
+    method public android.media.SessionToken2 getSessionToken();
+    method public boolean isConnected();
+    method public void pause();
+    method public void play();
+    method public void playFromMediaId(java.lang.String, android.os.Bundle);
+    method public void playFromSearch(java.lang.String, android.os.Bundle);
+    method public void playFromUri(android.net.Uri, android.os.Bundle);
+    method public void prepare();
+    method public void prepareFromMediaId(java.lang.String, android.os.Bundle);
+    method public void prepareFromSearch(java.lang.String, android.os.Bundle);
+    method public void prepareFromUri(android.net.Uri, android.os.Bundle);
+    method public void removePlaylistItem(android.media.MediaItem2);
+    method public void replacePlaylistItem(int, android.media.MediaItem2);
+    method public void rewind();
+    method public void seekTo(long);
+    method public void sendCustomCommand(android.media.MediaSession2.Command, android.os.Bundle, android.os.ResultReceiver);
+    method public void setPlaybackSpeed(float);
+    method public void setPlaylistParams(android.media.MediaSession2.PlaylistParams);
+    method public void setRating(java.lang.String, android.media.Rating2);
+    method public void setVolumeTo(int, int);
+    method public void skipToNext();
+    method public void skipToPlaylistItem(android.media.MediaItem2);
+    method public void skipToPrevious();
+    method public void stop();
+  }
+
+  public static abstract class MediaController2.ControllerCallback {
+    ctor public MediaController2.ControllerCallback();
+    method public void onAllowedCommandsChanged(android.media.MediaSession2.CommandGroup);
+    method public void onBufferedPositionChanged(long);
+    method public void onConnected(android.media.MediaSession2.CommandGroup);
+    method public void onCurrentPlaylistItemChanged(android.media.MediaItem2);
+    method public void onCustomCommand(android.media.MediaSession2.Command, android.os.Bundle, android.os.ResultReceiver);
+    method public void onCustomLayoutChanged(java.util.List<android.media.MediaSession2.CommandButton>);
+    method public void onDisconnected();
+    method public void onError(int, android.os.Bundle);
+    method public void onPlaybackInfoChanged(android.media.MediaController2.PlaybackInfo);
+    method public void onPlaybackSpeedChanged(float);
+    method public void onPlayerStateChanged(int);
+    method public void onPlaylistChanged(java.util.List<android.media.MediaItem2>);
+    method public void onPlaylistParamsChanged(android.media.MediaSession2.PlaylistParams);
+    method public void onPositionChanged(long, long);
+  }
+
+  public static final class MediaController2.PlaybackInfo {
+    method public android.media.AudioAttributes getAudioAttributes();
+    method public int getControlType();
+    method public int getCurrentVolume();
+    method public int getMaxVolume();
+    method public int getPlaybackType();
+    field public static final int PLAYBACK_TYPE_LOCAL = 1; // 0x1
+    field public static final int PLAYBACK_TYPE_REMOTE = 2; // 0x2
+  }
+
   public final class MediaCrypto {
     ctor public MediaCrypto(java.util.UUID, byte[]) throws android.media.MediaCryptoException;
     method protected void finalize();
@@ -23702,6 +23812,71 @@
     field public static final java.lang.String MIMETYPE_VIDEO_VP9 = "video/x-vnd.on2.vp9";
   }
 
+  public class MediaItem2 {
+    method public static android.media.MediaItem2 fromBundle(android.content.Context, android.os.Bundle);
+    method public android.media.DataSourceDesc getDataSourceDesc();
+    method public int getFlags();
+    method public java.lang.String getMediaId();
+    method public android.media.MediaMetadata2 getMetadata();
+    method public boolean isBrowsable();
+    method public boolean isPlayable();
+    method public void setMetadata(android.media.MediaMetadata2);
+    method public android.os.Bundle toBundle();
+    field public static final int FLAG_BROWSABLE = 1; // 0x1
+    field public static final int FLAG_PLAYABLE = 2; // 0x2
+  }
+
+  public static final class MediaItem2.Builder {
+    ctor public MediaItem2.Builder(android.content.Context, int);
+    method public android.media.MediaItem2 build();
+    method public android.media.MediaItem2.Builder setDataSourceDesc(android.media.DataSourceDesc);
+    method public android.media.MediaItem2.Builder setMediaId(java.lang.String);
+    method public android.media.MediaItem2.Builder setMetadata(android.media.MediaMetadata2);
+  }
+
+  public abstract class MediaLibraryService2 extends android.media.MediaSessionService2 {
+    ctor public MediaLibraryService2();
+    method public abstract android.media.MediaLibraryService2.MediaLibrarySession onCreateSession(java.lang.String);
+    field public static final java.lang.String SERVICE_INTERFACE = "android.media.MediaLibraryService2";
+  }
+
+  public static final class MediaLibraryService2.LibraryRoot {
+    ctor public MediaLibraryService2.LibraryRoot(android.content.Context, java.lang.String, android.os.Bundle);
+    method public android.os.Bundle getExtras();
+    method public java.lang.String getRootId();
+    field public static final java.lang.String EXTRA_OFFLINE = "android.media.extra.OFFLINE";
+    field public static final java.lang.String EXTRA_RECENT = "android.media.extra.RECENT";
+    field public static final java.lang.String EXTRA_SUGGESTED = "android.media.extra.SUGGESTED";
+  }
+
+  public static final class MediaLibraryService2.MediaLibrarySession extends android.media.MediaSession2 {
+    method public void notifyChildrenChanged(android.media.MediaSession2.ControllerInfo, java.lang.String, int, android.os.Bundle);
+    method public void notifyChildrenChanged(java.lang.String, int, android.os.Bundle);
+    method public void notifySearchResultChanged(android.media.MediaSession2.ControllerInfo, java.lang.String, int, android.os.Bundle);
+  }
+
+  public static final class MediaLibraryService2.MediaLibrarySession.Builder {
+    ctor public MediaLibraryService2.MediaLibrarySession.Builder(android.media.MediaLibraryService2, java.util.concurrent.Executor, android.media.MediaLibraryService2.MediaLibrarySession.MediaLibrarySessionCallback);
+    method public android.media.MediaLibraryService2.MediaLibrarySession build();
+    method public android.media.MediaLibraryService2.MediaLibrarySession.Builder setId(java.lang.String);
+    method public android.media.MediaLibraryService2.MediaLibrarySession.Builder setPlayer(android.media.MediaPlayerBase);
+    method public android.media.MediaLibraryService2.MediaLibrarySession.Builder setPlaylistController(android.media.MediaPlaylistController);
+    method public android.media.MediaLibraryService2.MediaLibrarySession.Builder setSessionActivity(android.app.PendingIntent);
+    method public android.media.MediaLibraryService2.MediaLibrarySession.Builder setSessionCallback(java.util.concurrent.Executor, android.media.MediaLibraryService2.MediaLibrarySession.MediaLibrarySessionCallback);
+    method public android.media.MediaLibraryService2.MediaLibrarySession.Builder setVolumeProvider(android.media.VolumeProvider2);
+  }
+
+  public static class MediaLibraryService2.MediaLibrarySession.MediaLibrarySessionCallback extends android.media.MediaSession2.SessionCallback {
+    ctor public MediaLibraryService2.MediaLibrarySession.MediaLibrarySessionCallback(android.content.Context);
+    method public java.util.List<android.media.MediaItem2> onGetChildren(android.media.MediaSession2.ControllerInfo, java.lang.String, int, int, android.os.Bundle);
+    method public android.media.MediaItem2 onGetItem(android.media.MediaSession2.ControllerInfo, java.lang.String);
+    method public android.media.MediaLibraryService2.LibraryRoot onGetLibraryRoot(android.media.MediaSession2.ControllerInfo, android.os.Bundle);
+    method public java.util.List<android.media.MediaItem2> onGetSearchResult(android.media.MediaSession2.ControllerInfo, java.lang.String, int, int, android.os.Bundle);
+    method public void onSearch(android.media.MediaSession2.ControllerInfo, java.lang.String, android.os.Bundle);
+    method public void onSubscribe(android.media.MediaSession2.ControllerInfo, java.lang.String, android.os.Bundle);
+    method public void onUnsubscribe(android.media.MediaSession2.ControllerInfo, java.lang.String);
+  }
+
   public final class MediaMetadata implements android.os.Parcelable {
     method public boolean containsKey(java.lang.String);
     method public int describeContents();
@@ -23757,6 +23932,79 @@
     method public android.media.MediaMetadata.Builder putText(java.lang.String, java.lang.CharSequence);
   }
 
+  public final class MediaMetadata2 {
+    method public boolean containsKey(java.lang.String);
+    method public static android.media.MediaMetadata2 fromBundle(android.content.Context, android.os.Bundle);
+    method public android.graphics.Bitmap getBitmap(java.lang.String);
+    method public android.os.Bundle getExtras();
+    method public float getFloat(java.lang.String);
+    method public long getLong(java.lang.String);
+    method public java.lang.String getMediaId();
+    method public android.media.Rating2 getRating(java.lang.String);
+    method public java.lang.String getString(java.lang.String);
+    method public java.lang.CharSequence getText(java.lang.String);
+    method public java.util.Set<java.lang.String> keySet();
+    method public int size();
+    method public android.os.Bundle toBundle();
+    field public static final long BT_FOLDER_TYPE_ALBUMS = 2L; // 0x2L
+    field public static final long BT_FOLDER_TYPE_ARTISTS = 3L; // 0x3L
+    field public static final long BT_FOLDER_TYPE_GENRES = 4L; // 0x4L
+    field public static final long BT_FOLDER_TYPE_MIXED = 0L; // 0x0L
+    field public static final long BT_FOLDER_TYPE_PLAYLISTS = 5L; // 0x5L
+    field public static final long BT_FOLDER_TYPE_TITLES = 1L; // 0x1L
+    field public static final long BT_FOLDER_TYPE_YEARS = 6L; // 0x6L
+    field public static final java.lang.String METADATA_KEY_ADVERTISEMENT = "android.media.metadata.ADVERTISEMENT";
+    field public static final java.lang.String METADATA_KEY_ALBUM = "android.media.metadata.ALBUM";
+    field public static final java.lang.String METADATA_KEY_ALBUM_ART = "android.media.metadata.ALBUM_ART";
+    field public static final java.lang.String METADATA_KEY_ALBUM_ARTIST = "android.media.metadata.ALBUM_ARTIST";
+    field public static final java.lang.String METADATA_KEY_ALBUM_ART_URI = "android.media.metadata.ALBUM_ART_URI";
+    field public static final java.lang.String METADATA_KEY_ART = "android.media.metadata.ART";
+    field public static final java.lang.String METADATA_KEY_ARTIST = "android.media.metadata.ARTIST";
+    field public static final java.lang.String METADATA_KEY_ART_URI = "android.media.metadata.ART_URI";
+    field public static final java.lang.String METADATA_KEY_AUTHOR = "android.media.metadata.AUTHOR";
+    field public static final java.lang.String METADATA_KEY_BT_FOLDER_TYPE = "android.media.metadata.BT_FOLDER_TYPE";
+    field public static final java.lang.String METADATA_KEY_COMPILATION = "android.media.metadata.COMPILATION";
+    field public static final java.lang.String METADATA_KEY_COMPOSER = "android.media.metadata.COMPOSER";
+    field public static final java.lang.String METADATA_KEY_DATE = "android.media.metadata.DATE";
+    field public static final java.lang.String METADATA_KEY_DISC_NUMBER = "android.media.metadata.DISC_NUMBER";
+    field public static final java.lang.String METADATA_KEY_DISPLAY_DESCRIPTION = "android.media.metadata.DISPLAY_DESCRIPTION";
+    field public static final java.lang.String METADATA_KEY_DISPLAY_ICON = "android.media.metadata.DISPLAY_ICON";
+    field public static final java.lang.String METADATA_KEY_DISPLAY_ICON_URI = "android.media.metadata.DISPLAY_ICON_URI";
+    field public static final java.lang.String METADATA_KEY_DISPLAY_SUBTITLE = "android.media.metadata.DISPLAY_SUBTITLE";
+    field public static final java.lang.String METADATA_KEY_DISPLAY_TITLE = "android.media.metadata.DISPLAY_TITLE";
+    field public static final java.lang.String METADATA_KEY_DOWNLOAD_STATUS = "android.media.metadata.DOWNLOAD_STATUS";
+    field public static final java.lang.String METADATA_KEY_DURATION = "android.media.metadata.DURATION";
+    field public static final java.lang.String METADATA_KEY_EXTRAS = "android.media.metadata.EXTRAS";
+    field public static final java.lang.String METADATA_KEY_GENRE = "android.media.metadata.GENRE";
+    field public static final java.lang.String METADATA_KEY_MEDIA_ID = "android.media.metadata.MEDIA_ID";
+    field public static final java.lang.String METADATA_KEY_MEDIA_URI = "android.media.metadata.MEDIA_URI";
+    field public static final java.lang.String METADATA_KEY_NUM_TRACKS = "android.media.metadata.NUM_TRACKS";
+    field public static final java.lang.String METADATA_KEY_RADIO_CALLSIGN = "android.media.metadata.RADIO_CALLSIGN";
+    field public static final java.lang.String METADATA_KEY_RADIO_FREQUENCY = "android.media.metadata.RADIO_FREQUENCY";
+    field public static final java.lang.String METADATA_KEY_RATING = "android.media.metadata.RATING";
+    field public static final java.lang.String METADATA_KEY_TITLE = "android.media.metadata.TITLE";
+    field public static final java.lang.String METADATA_KEY_TRACK_NUMBER = "android.media.metadata.TRACK_NUMBER";
+    field public static final java.lang.String METADATA_KEY_USER_RATING = "android.media.metadata.USER_RATING";
+    field public static final java.lang.String METADATA_KEY_WRITER = "android.media.metadata.WRITER";
+    field public static final java.lang.String METADATA_KEY_YEAR = "android.media.metadata.YEAR";
+    field public static final long STATUS_DOWNLOADED = 2L; // 0x2L
+    field public static final long STATUS_DOWNLOADING = 1L; // 0x1L
+    field public static final long STATUS_NOT_DOWNLOADED = 0L; // 0x0L
+  }
+
+  public static final class MediaMetadata2.Builder {
+    ctor public MediaMetadata2.Builder(android.content.Context);
+    ctor public MediaMetadata2.Builder(android.content.Context, android.media.MediaMetadata2);
+    method public android.media.MediaMetadata2 build();
+    method public android.media.MediaMetadata2.Builder putBitmap(java.lang.String, android.graphics.Bitmap);
+    method public android.media.MediaMetadata2.Builder putFloat(java.lang.String, float);
+    method public android.media.MediaMetadata2.Builder putLong(java.lang.String, long);
+    method public android.media.MediaMetadata2.Builder putRating(java.lang.String, android.media.Rating2);
+    method public android.media.MediaMetadata2.Builder putString(java.lang.String, java.lang.String);
+    method public android.media.MediaMetadata2.Builder putText(java.lang.String, java.lang.CharSequence);
+    method public android.media.MediaMetadata2.Builder setExtras(android.os.Bundle);
+  }
+
   public abstract deprecated class MediaMetadataEditor {
     method public synchronized void addEditableKey(int);
     method public abstract void apply();
@@ -24064,67 +24312,79 @@
     field public static final int MEDIA_TRACK_TYPE_VIDEO = 1; // 0x1
   }
 
-  public abstract class MediaPlayer2 implements android.media.AudioRouting java.lang.AutoCloseable {
-    method public abstract void addPlaylistItem(int, android.media.DataSourceDesc);
+  public abstract class MediaPlayer2 extends android.media.MediaPlayerBase implements android.media.AudioRouting {
     method public abstract void attachAuxEffect(int);
+    method public abstract void clearDrmEventCallback();
+    method public abstract void clearMediaPlayer2EventCallback();
     method public abstract void clearPendingCommands();
     method public abstract void close();
     method public static final android.media.MediaPlayer2 create();
     method public abstract void deselectTrack(int);
-    method public abstract android.media.DataSourceDesc editPlaylistItem(int, android.media.DataSourceDesc);
     method public abstract int getAudioSessionId();
-    method public abstract android.media.DataSourceDesc getCurrentDataSource();
-    method public abstract int getCurrentPlaylistItemIndex();
-    method public abstract int getCurrentPosition();
+    method public abstract long getBufferedPosition();
+    method public abstract long getCurrentPosition();
     method public abstract android.media.MediaPlayer2.DrmInfo getDrmInfo();
+    method public abstract android.media.MediaDrm.KeyRequest getDrmKeyRequest(byte[], byte[], java.lang.String, int, java.util.Map<java.lang.String, java.lang.String>) throws android.media.MediaPlayer2.NoDrmSchemeException;
     method public abstract java.lang.String getDrmPropertyString(java.lang.String) throws android.media.MediaPlayer2.NoDrmSchemeException;
-    method public abstract int getDuration();
-    method public abstract android.media.MediaDrm.KeyRequest getKeyRequest(byte[], byte[], java.lang.String, int, java.util.Map<java.lang.String, java.lang.String>) throws android.media.MediaPlayer2.NoDrmSchemeException;
-    method public abstract int getLoopingMode();
+    method public abstract long getDuration();
+    method public abstract int getMediaPlayer2State();
     method public abstract android.os.PersistableBundle getMetrics();
     method public abstract android.media.PlaybackParams getPlaybackParams();
-    method public abstract java.util.List<android.media.DataSourceDesc> getPlaylist();
     method public abstract int getSelectedTrack(int);
     method public abstract android.media.SyncParams getSyncParams();
     method public abstract android.media.MediaTimestamp getTimestamp();
     method public abstract java.util.List<android.media.MediaPlayer2.TrackInfo> getTrackInfo();
     method public abstract int getVideoHeight();
     method public abstract int getVideoWidth();
-    method public abstract boolean isPlaying();
-    method public abstract void movePlaylistItem(int, int);
-    method public abstract void pause();
-    method public abstract void play();
-    method public abstract void prepareAsync();
+    method public void notifyWhenCommandLabelReached(java.lang.Object);
     method public abstract void prepareDrm(java.util.UUID) throws android.media.MediaPlayer2.ProvisioningNetworkErrorException, android.media.MediaPlayer2.ProvisioningServerErrorException, android.media.ResourceBusyException, android.media.UnsupportedSchemeException;
-    method public abstract byte[] provideKeyResponse(byte[], byte[]) throws android.media.DeniedByServerException, android.media.MediaPlayer2.NoDrmSchemeException;
-    method public abstract void registerDrmEventCallback(java.util.concurrent.Executor, android.media.MediaPlayer2.DrmEventCallback);
-    method public abstract void registerEventCallback(java.util.concurrent.Executor, android.media.MediaPlayer2.EventCallback);
+    method public abstract byte[] provideDrmKeyResponse(byte[], byte[]) throws android.media.DeniedByServerException, android.media.MediaPlayer2.NoDrmSchemeException;
     method public abstract void releaseDrm() throws android.media.MediaPlayer2.NoDrmSchemeException;
-    method public abstract android.media.DataSourceDesc removePlaylistItem(int);
     method public abstract void reset();
-    method public abstract void restoreKeys(byte[]) throws android.media.MediaPlayer2.NoDrmSchemeException;
+    method public abstract void restoreDrmKeys(byte[]) throws android.media.MediaPlayer2.NoDrmSchemeException;
+    method public void seekTo(long);
     method public abstract void seekTo(long, int);
     method public abstract void selectTrack(int);
-    method public abstract void setAudioAttributes(android.media.AudioAttributes);
     method public abstract void setAudioSessionId(int);
     method public abstract void setAuxEffectSendLevel(float);
-    method public abstract void setCurrentPlaylistItem(int);
-    method public abstract void setDataSource(android.media.DataSourceDesc) throws java.io.IOException;
+    method public abstract void setDrmEventCallback(java.util.concurrent.Executor, android.media.MediaPlayer2.DrmEventCallback);
     method public abstract void setDrmPropertyString(java.lang.String, java.lang.String) throws android.media.MediaPlayer2.NoDrmSchemeException;
-    method public abstract void setLoopingMode(int);
-    method public abstract void setNextPlaylistItem(int);
+    method public abstract void setMediaPlayer2EventCallback(java.util.concurrent.Executor, android.media.MediaPlayer2.MediaPlayer2EventCallback);
     method public abstract void setOnDrmConfigHelper(android.media.MediaPlayer2.OnDrmConfigHelper);
     method public abstract void setPlaybackParams(android.media.PlaybackParams);
-    method public abstract void setPlaylist(java.util.List<android.media.DataSourceDesc>, int) throws java.io.IOException;
     method public abstract void setSurface(android.view.Surface);
     method public abstract void setSyncParams(android.media.SyncParams);
-    method public abstract void setVolume(float, float);
-    method public abstract void unregisterDrmEventCallback(android.media.MediaPlayer2.DrmEventCallback);
-    method public abstract void unregisterEventCallback(android.media.MediaPlayer2.EventCallback);
-    field public static final int LOOPING_MODE_FULL = 1; // 0x1
-    field public static final int LOOPING_MODE_NONE = 0; // 0x0
-    field public static final int LOOPING_MODE_SHUFFLE = 3; // 0x3
-    field public static final int LOOPING_MODE_SINGLE = 2; // 0x2
+    field public static final int MEDIAPLAYER2_STATE_ERROR = 5; // 0x5
+    field public static final int MEDIAPLAYER2_STATE_IDLE = 1; // 0x1
+    field public static final int MEDIAPLAYER2_STATE_PAUSED = 3; // 0x3
+    field public static final int MEDIAPLAYER2_STATE_PLAYING = 4; // 0x4
+    field public static final int MEDIAPLAYER2_STATE_PREPARED = 2; // 0x2
+    field public static final int MEDIA_CALL_ATTACH_AUX_EFFECT = 1; // 0x1
+    field public static final int MEDIA_CALL_DESELECT_TRACK = 2; // 0x2
+    field public static final int MEDIA_CALL_LOOP_CURRENT = 3; // 0x3
+    field public static final int MEDIA_CALL_PAUSE = 4; // 0x4
+    field public static final int MEDIA_CALL_PLAY = 5; // 0x5
+    field public static final int MEDIA_CALL_PREPARE = 6; // 0x6
+    field public static final int MEDIA_CALL_PREPARE_DRM = 7; // 0x7
+    field public static final int MEDIA_CALL_PROVIDE_DRM_KEY_RESPONSE = 8; // 0x8
+    field public static final int MEDIA_CALL_RELEASE_DRM = 12; // 0xc
+    field public static final int MEDIA_CALL_RESTORE_DRM_KEYS = 13; // 0xd
+    field public static final int MEDIA_CALL_SEEK_TO = 14; // 0xe
+    field public static final int MEDIA_CALL_SELECT_TRACK = 15; // 0xf
+    field public static final int MEDIA_CALL_SET_AUDIO_ATTRIBUTES = 16; // 0x10
+    field public static final int MEDIA_CALL_SET_AUDIO_SESSION_ID = 17; // 0x11
+    field public static final int MEDIA_CALL_SET_AUX_EFFECT_SEND_LEVEL = 18; // 0x12
+    field public static final int MEDIA_CALL_SET_DATA_SOURCE = 19; // 0x13
+    field public static final int MEDIA_CALL_SET_DRM_CONFIG_HELPER = 20; // 0x14
+    field public static final int MEDIA_CALL_SET_DRM_PROPERTY_STRING = 21; // 0x15
+    field public static final int MEDIA_CALL_SET_NEXT_DATA_SOURCE = 22; // 0x16
+    field public static final int MEDIA_CALL_SET_NEXT_DATA_SOURCES = 23; // 0x17
+    field public static final int MEDIA_CALL_SET_PLAYBACK_PARAMS = 24; // 0x18
+    field public static final int MEDIA_CALL_SET_PLAYBACK_SPEED = 25; // 0x19
+    field public static final int MEDIA_CALL_SET_PLAYER_VOLUME = 26; // 0x1a
+    field public static final int MEDIA_CALL_SET_SURFACE = 27; // 0x1b
+    field public static final int MEDIA_CALL_SET_SYNC_PARAMS = 28; // 0x1c
+    field public static final int MEDIA_CALL_SKIP_TO_NEXT = 29; // 0x1d
     field public static final int MEDIA_ERROR_IO = -1004; // 0xfffffc14
     field public static final int MEDIA_ERROR_MALFORMED = -1007; // 0xfffffc11
     field public static final int MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 200; // 0xc8
@@ -24136,9 +24396,7 @@
     field public static final int MEDIA_INFO_BAD_INTERLEAVING = 800; // 0x320
     field public static final int MEDIA_INFO_BUFFERING_END = 702; // 0x2be
     field public static final int MEDIA_INFO_BUFFERING_START = 701; // 0x2bd
-    field public static final int MEDIA_INFO_COMPLETE_CALL_PAUSE = 102; // 0x66
-    field public static final int MEDIA_INFO_COMPLETE_CALL_PLAY = 101; // 0x65
-    field public static final int MEDIA_INFO_COMPLETE_CALL_SEEK = 103; // 0x67
+    field public static final int MEDIA_INFO_BUFFERING_UPDATE = 704; // 0x2c0
     field public static final int MEDIA_INFO_METADATA_UPDATE = 802; // 0x322
     field public static final int MEDIA_INFO_NOT_SEEKABLE = 801; // 0x321
     field public static final int MEDIA_INFO_PLAYBACK_COMPLETE = 5; // 0x5
@@ -24164,8 +24422,8 @@
 
   public static abstract class MediaPlayer2.DrmEventCallback {
     ctor public MediaPlayer2.DrmEventCallback();
-    method public void onDrmInfo(android.media.MediaPlayer2, android.media.MediaPlayer2.DrmInfo);
-    method public void onDrmPrepared(android.media.MediaPlayer2, int);
+    method public void onDrmInfo(android.media.MediaPlayer2, android.media.DataSourceDesc, android.media.MediaPlayer2.DrmInfo);
+    method public void onDrmPrepared(android.media.MediaPlayer2, android.media.DataSourceDesc, int);
   }
 
   public static abstract class MediaPlayer2.DrmInfo {
@@ -24174,13 +24432,15 @@
     method public abstract java.util.List<java.util.UUID> getSupportedSchemes();
   }
 
-  public static abstract class MediaPlayer2.EventCallback {
-    ctor public MediaPlayer2.EventCallback();
-    method public void onBufferingUpdate(android.media.MediaPlayer2, long, int);
-    method public void onError(android.media.MediaPlayer2, long, int, int);
-    method public void onInfo(android.media.MediaPlayer2, long, int, int);
-    method public void onTimedMetaDataAvailable(android.media.MediaPlayer2, long, android.media.TimedMetaData);
-    method public void onVideoSizeChanged(android.media.MediaPlayer2, long, int, int);
+  public static abstract class MediaPlayer2.MediaPlayer2EventCallback {
+    ctor public MediaPlayer2.MediaPlayer2EventCallback();
+    method public void onCallComplete(android.media.MediaPlayer2, android.media.DataSourceDesc, int, int);
+    method public void onCommandLabelReached(android.media.MediaPlayer2, java.lang.Object);
+    method public void onError(android.media.MediaPlayer2, android.media.DataSourceDesc, int, int);
+    method public void onInfo(android.media.MediaPlayer2, android.media.DataSourceDesc, int, int);
+    method public void onMediaTimeChanged(android.media.MediaPlayer2, android.media.DataSourceDesc, android.media.MediaTimestamp);
+    method public void onTimedMetaDataAvailable(android.media.MediaPlayer2, android.media.DataSourceDesc, android.media.TimedMetaData);
+    method public void onVideoSizeChanged(android.media.MediaPlayer2, android.media.DataSourceDesc, int, int);
   }
 
   public static final class MediaPlayer2.MetricsConstants {
@@ -24203,7 +24463,7 @@
   }
 
   public static abstract interface MediaPlayer2.OnDrmConfigHelper {
-    method public abstract void onDrmConfig(android.media.MediaPlayer2);
+    method public abstract void onDrmConfig(android.media.MediaPlayer2, android.media.DataSourceDesc);
   }
 
   public static abstract class MediaPlayer2.ProvisioningNetworkErrorException extends android.media.MediaDrmException {
@@ -24227,6 +24487,61 @@
     field public static final int MEDIA_TRACK_TYPE_VIDEO = 1; // 0x1
   }
 
+  public abstract class MediaPlayerBase implements java.lang.AutoCloseable {
+    ctor public MediaPlayerBase();
+    method public abstract android.media.AudioAttributes getAudioAttributes();
+    method public long getBufferedPosition();
+    method public abstract int getBufferingState();
+    method public abstract android.media.DataSourceDesc getCurrentDataSource();
+    method public long getCurrentPosition();
+    method public long getDuration();
+    method public float getMaxPlayerVolume();
+    method public float getPlaybackSpeed();
+    method public abstract int getPlayerState();
+    method public abstract float getPlayerVolume();
+    method public boolean isReversePlaybackSupported();
+    method public abstract void loopCurrent(boolean);
+    method public abstract void pause();
+    method public abstract void play();
+    method public abstract void prepare();
+    method public abstract void registerPlayerEventCallback(java.util.concurrent.Executor, android.media.MediaPlayerBase.PlayerEventCallback);
+    method public abstract void seekTo(long);
+    method public abstract void setAudioAttributes(android.media.AudioAttributes);
+    method public abstract void setDataSource(android.media.DataSourceDesc);
+    method public abstract void setNextDataSource(android.media.DataSourceDesc);
+    method public abstract void setNextDataSources(java.util.List<android.media.DataSourceDesc>);
+    method public abstract void setPlaybackSpeed(float);
+    method public abstract void setPlayerVolume(float);
+    method public abstract void skipToNext();
+    method public abstract void unregisterPlayerEventCallback(android.media.MediaPlayerBase.PlayerEventCallback);
+    field public static final int BUFFERING_STATE_BUFFERING_AND_PLAYABLE = 1; // 0x1
+    field public static final int BUFFERING_STATE_BUFFERING_AND_STARVED = 2; // 0x2
+    field public static final int BUFFERING_STATE_BUFFERING_COMPLETE = 3; // 0x3
+    field public static final int BUFFERING_STATE_UNKNOWN = 0; // 0x0
+    field public static final int PLAYER_STATE_ERROR = 3; // 0x3
+    field public static final int PLAYER_STATE_IDLE = 0; // 0x0
+    field public static final int PLAYER_STATE_PAUSED = 1; // 0x1
+    field public static final int PLAYER_STATE_PLAYING = 2; // 0x2
+    field public static final long UNKNOWN_TIME = -1L; // 0xffffffffffffffffL
+  }
+
+  public static abstract class MediaPlayerBase.PlayerEventCallback {
+    ctor public MediaPlayerBase.PlayerEventCallback();
+    method public void onBufferingStateChanged(android.media.MediaPlayerBase, android.media.DataSourceDesc, int);
+    method public void onCurrentDataSourceChanged(android.media.MediaPlayerBase, android.media.DataSourceDesc);
+    method public void onMediaPrepared(android.media.MediaPlayerBase, android.media.DataSourceDesc);
+    method public void onPlayerStateChanged(android.media.MediaPlayerBase, int);
+  }
+
+  public abstract interface MediaPlaylistController {
+    method public abstract void addPlaylistItem(int, android.media.MediaItem2);
+    method public abstract android.media.MediaItem2 getCurrentPlaylistItem();
+    method public abstract java.util.List<android.media.MediaItem2> getPlaylist();
+    method public abstract void removePlaylistItem(android.media.MediaItem2);
+    method public abstract void replacePlaylistItem(int, android.media.MediaItem2);
+    method public abstract void skipToPlaylistItem(android.media.MediaItem2);
+  }
+
   public class MediaRecorder implements android.media.AudioRouting {
     ctor public MediaRecorder();
     method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
@@ -24503,6 +24818,179 @@
     method public abstract void onScanCompleted(java.lang.String, android.net.Uri);
   }
 
+  public class MediaSession2 implements java.lang.AutoCloseable android.media.MediaPlaylistController {
+    method public void addPlaylistItem(int, android.media.MediaItem2);
+    method public void close();
+    method public void fastForward();
+    method public java.util.List<android.media.MediaSession2.ControllerInfo> getConnectedControllers();
+    method public android.media.MediaItem2 getCurrentPlaylistItem();
+    method public android.media.MediaPlaylistController getMediaPlaylistController();
+    method public float getPlaybackSpeed();
+    method public android.media.MediaPlayerBase getPlayer();
+    method public java.util.List<android.media.MediaItem2> getPlaylist();
+    method public android.media.MediaSession2.PlaylistParams getPlaylistParams();
+    method public android.media.SessionToken2 getToken();
+    method public android.media.VolumeProvider2 getVolumeProvider();
+    method public void notifyError(int, android.os.Bundle);
+    method public void pause();
+    method public void play();
+    method public void prepare();
+    method public void removePlaylistItem(android.media.MediaItem2);
+    method public void replacePlaylistItem(int, android.media.MediaItem2);
+    method public void rewind();
+    method public void seekTo(long);
+    method public void sendCustomCommand(android.media.MediaSession2.Command, android.os.Bundle);
+    method public void sendCustomCommand(android.media.MediaSession2.ControllerInfo, android.media.MediaSession2.Command, android.os.Bundle, android.os.ResultReceiver);
+    method public void setAllowedCommands(android.media.MediaSession2.ControllerInfo, android.media.MediaSession2.CommandGroup);
+    method public void setAudioFocusRequest(android.media.AudioFocusRequest);
+    method public void setCustomLayout(android.media.MediaSession2.ControllerInfo, java.util.List<android.media.MediaSession2.CommandButton>);
+    method public void setPlaybackSpeed(float);
+    method public void setPlaylist(java.util.List<android.media.MediaItem2>);
+    method public void setPlaylistParams(android.media.MediaSession2.PlaylistParams);
+    method public void skipToNext();
+    method public void skipToPlaylistItem(android.media.MediaItem2);
+    method public void skipToPrevious();
+    method public void stop();
+    method public void updatePlayer(android.media.MediaPlayerBase, android.media.MediaPlaylistController, android.media.VolumeProvider2);
+    field public static final int COMMAND_CODE_BROWSER = 22; // 0x16
+    field public static final int COMMAND_CODE_CUSTOM = 0; // 0x0
+    field public static final int COMMAND_CODE_PLAYBACK_FAST_FORWARD = 7; // 0x7
+    field public static final int COMMAND_CODE_PLAYBACK_PAUSE = 2; // 0x2
+    field public static final int COMMAND_CODE_PLAYBACK_PLAY = 1; // 0x1
+    field public static final int COMMAND_CODE_PLAYBACK_PREPARE = 6; // 0x6
+    field public static final int COMMAND_CODE_PLAYBACK_REWIND = 8; // 0x8
+    field public static final int COMMAND_CODE_PLAYBACK_SEEK_TO = 9; // 0x9
+    field public static final int COMMAND_CODE_PLAYBACK_SET_PLAYLIST_PARAMS = 11; // 0xb
+    field public static final int COMMAND_CODE_PLAYBACK_SKIP_NEXT_ITEM = 4; // 0x4
+    field public static final int COMMAND_CODE_PLAYBACK_SKIP_PREV_ITEM = 5; // 0x5
+    field public static final int COMMAND_CODE_PLAYBACK_SKIP_TO_PLAYLIST_ITEM = 10; // 0xa
+    field public static final int COMMAND_CODE_PLAYBACK_STOP = 3; // 0x3
+    field public static final int COMMAND_CODE_PLAYLIST_ADD = 12; // 0xc
+    field public static final int COMMAND_CODE_PLAYLIST_GET = 14; // 0xe
+    field public static final int COMMAND_CODE_PLAYLIST_REMOVE = 13; // 0xd
+    field public static final int COMMAND_CODE_PLAY_FROM_MEDIA_ID = 16; // 0x10
+    field public static final int COMMAND_CODE_PLAY_FROM_SEARCH = 18; // 0x12
+    field public static final int COMMAND_CODE_PLAY_FROM_URI = 17; // 0x11
+    field public static final int COMMAND_CODE_PREPARE_FROM_MEDIA_ID = 19; // 0x13
+    field public static final int COMMAND_CODE_PREPARE_FROM_SEARCH = 21; // 0x15
+    field public static final int COMMAND_CODE_PREPARE_FROM_URI = 20; // 0x14
+    field public static final int COMMAND_CODE_SET_VOLUME = 15; // 0xf
+    field public static final int ERROR_CODE_ACTION_ABORTED = 10; // 0xa
+    field public static final int ERROR_CODE_APP_ERROR = 1; // 0x1
+    field public static final int ERROR_CODE_AUTHENTICATION_EXPIRED = 3; // 0x3
+    field public static final int ERROR_CODE_CONCURRENT_STREAM_LIMIT = 5; // 0x5
+    field public static final int ERROR_CODE_CONTENT_ALREADY_PLAYING = 8; // 0x8
+    field public static final int ERROR_CODE_END_OF_QUEUE = 11; // 0xb
+    field public static final int ERROR_CODE_NOT_AVAILABLE_IN_REGION = 7; // 0x7
+    field public static final int ERROR_CODE_NOT_SUPPORTED = 2; // 0x2
+    field public static final int ERROR_CODE_PARENTAL_CONTROL_RESTRICTED = 6; // 0x6
+    field public static final int ERROR_CODE_PREMIUM_ACCOUNT_REQUIRED = 4; // 0x4
+    field public static final int ERROR_CODE_SETUP_REQUIRED = 12; // 0xc
+    field public static final int ERROR_CODE_SKIP_LIMIT_REACHED = 9; // 0x9
+    field public static final int ERROR_CODE_UNKNOWN_ERROR = 0; // 0x0
+  }
+
+  public static final class MediaSession2.Builder {
+    ctor public MediaSession2.Builder(android.content.Context);
+    method public android.media.MediaSession2 build();
+    method public android.media.MediaSession2.Builder setId(java.lang.String);
+    method public android.media.MediaSession2.Builder setPlayer(android.media.MediaPlayerBase);
+    method public android.media.MediaSession2.Builder setPlaylistController(android.media.MediaPlaylistController);
+    method public android.media.MediaSession2.Builder setSessionActivity(android.app.PendingIntent);
+    method public android.media.MediaSession2.Builder setSessionCallback(java.util.concurrent.Executor, android.media.MediaSession2.SessionCallback);
+    method public android.media.MediaSession2.Builder setVolumeProvider(android.media.VolumeProvider2);
+  }
+
+  public static final class MediaSession2.Command {
+    ctor public MediaSession2.Command(android.content.Context, int);
+    ctor public MediaSession2.Command(android.content.Context, java.lang.String, android.os.Bundle);
+    method public int getCommandCode();
+    method public java.lang.String getCustomCommand();
+    method public android.os.Bundle getExtras();
+  }
+
+  public static final class MediaSession2.CommandButton {
+    method public android.media.MediaSession2.Command getCommand();
+    method public java.lang.String getDisplayName();
+    method public android.os.Bundle getExtras();
+    method public int getIconResId();
+    method public boolean isEnabled();
+  }
+
+  public static final class MediaSession2.CommandButton.Builder {
+    ctor public MediaSession2.CommandButton.Builder(android.content.Context);
+    method public android.media.MediaSession2.CommandButton build();
+    method public android.media.MediaSession2.CommandButton.Builder setCommand(android.media.MediaSession2.Command);
+    method public android.media.MediaSession2.CommandButton.Builder setDisplayName(java.lang.String);
+    method public android.media.MediaSession2.CommandButton.Builder setEnabled(boolean);
+    method public android.media.MediaSession2.CommandButton.Builder setExtras(android.os.Bundle);
+    method public android.media.MediaSession2.CommandButton.Builder setIconResId(int);
+  }
+
+  public static final class MediaSession2.CommandGroup {
+    ctor public MediaSession2.CommandGroup(android.content.Context);
+    ctor public MediaSession2.CommandGroup(android.content.Context, android.media.MediaSession2.CommandGroup);
+    method public void addAllPredefinedCommands();
+    method public void addCommand(android.media.MediaSession2.Command);
+    method public java.util.List<android.media.MediaSession2.Command> getCommands();
+    method public boolean hasCommand(android.media.MediaSession2.Command);
+    method public boolean hasCommand(int);
+    method public void removeCommand(android.media.MediaSession2.Command);
+  }
+
+  public static final class MediaSession2.ControllerInfo {
+    method public java.lang.String getPackageName();
+    method public int getUid();
+    method public boolean isTrusted();
+  }
+
+  public static final class MediaSession2.PlaylistParams {
+    ctor public MediaSession2.PlaylistParams(android.content.Context, int, int, android.media.MediaMetadata2);
+    method public static android.media.MediaSession2.PlaylistParams fromBundle(android.content.Context, android.os.Bundle);
+    method public android.media.MediaMetadata2 getPlaylistMetadata();
+    method public int getRepeatMode();
+    method public int getShuffleMode();
+    method public android.os.Bundle toBundle();
+    field public static final int REPEAT_MODE_ALL = 2; // 0x2
+    field public static final int REPEAT_MODE_GROUP = 3; // 0x3
+    field public static final int REPEAT_MODE_NONE = 0; // 0x0
+    field public static final int REPEAT_MODE_ONE = 1; // 0x1
+    field public static final int SHUFFLE_MODE_ALL = 1; // 0x1
+    field public static final int SHUFFLE_MODE_GROUP = 2; // 0x2
+    field public static final int SHUFFLE_MODE_NONE = 0; // 0x0
+  }
+
+  public static abstract class MediaSession2.SessionCallback {
+    ctor public MediaSession2.SessionCallback(android.content.Context);
+    method public boolean onCommandRequest(android.media.MediaSession2.ControllerInfo, android.media.MediaSession2.Command);
+    method public android.media.MediaSession2.CommandGroup onConnect(android.media.MediaSession2.ControllerInfo);
+    method public void onCustomCommand(android.media.MediaSession2.ControllerInfo, android.media.MediaSession2.Command, android.os.Bundle, android.os.ResultReceiver);
+    method public void onDisconnected(android.media.MediaSession2.ControllerInfo);
+    method public void onPlayFromMediaId(android.media.MediaSession2.ControllerInfo, java.lang.String, android.os.Bundle);
+    method public void onPlayFromSearch(android.media.MediaSession2.ControllerInfo, java.lang.String, android.os.Bundle);
+    method public void onPlayFromUri(android.media.MediaSession2.ControllerInfo, android.net.Uri, android.os.Bundle);
+    method public void onPrepareFromMediaId(android.media.MediaSession2.ControllerInfo, java.lang.String, android.os.Bundle);
+    method public void onPrepareFromSearch(android.media.MediaSession2.ControllerInfo, java.lang.String, android.os.Bundle);
+    method public void onPrepareFromUri(android.media.MediaSession2.ControllerInfo, android.net.Uri, android.os.Bundle);
+    method public void onSetRating(android.media.MediaSession2.ControllerInfo, java.lang.String, android.media.Rating2);
+  }
+
+  public abstract class MediaSessionService2 extends android.app.Service {
+    ctor public MediaSessionService2();
+    method public final android.media.MediaSession2 getSession();
+    method public android.os.IBinder onBind(android.content.Intent);
+    method public abstract android.media.MediaSession2 onCreateSession(java.lang.String);
+    method public android.media.MediaSessionService2.MediaNotification onUpdateNotification();
+    field public static final java.lang.String SERVICE_INTERFACE = "android.media.MediaSessionService2";
+    field public static final java.lang.String SERVICE_META_DATA = "android.media.session";
+  }
+
+  public static class MediaSessionService2.MediaNotification {
+    ctor public MediaSessionService2.MediaNotification(android.content.Context, int, android.app.Notification);
+    method public android.app.Notification getNotification();
+    method public int getNotificationId();
+  }
+
   public final class MediaSync {
     ctor public MediaSync();
     method public android.view.Surface createInputSurface();
@@ -24570,13 +25058,19 @@
     field public static final int DIRECTIONALITY_OMNI = 1; // 0x1
     field public static final int DIRECTIONALITY_SUPER_CARDIOID = 5; // 0x5
     field public static final int DIRECTIONALITY_UNKNOWN = 0; // 0x0
+    field public static final int GROUP_UNKNOWN = -1; // 0xffffffff
+    field public static final int INDEX_IN_THE_GROUP_UNKNOWN = -1; // 0xffffffff
     field public static final int LOCATION_MAINBODY = 1; // 0x1
     field public static final int LOCATION_MAINBODY_MOVABLE = 2; // 0x2
     field public static final int LOCATION_PERIPHERAL = 3; // 0x3
     field public static final int LOCATION_UNKNOWN = 0; // 0x0
+    field public static final android.media.MicrophoneInfo.Coordinate3F ORIENTATION_UNKNOWN;
+    field public static final android.media.MicrophoneInfo.Coordinate3F POSITION_UNKNOWN;
+    field public static final float SENSITIVITY_UNKNOWN = -3.4028235E38f;
+    field public static final float SPL_UNKNOWN = -3.4028235E38f;
   }
 
-  public class MicrophoneInfo.Coordinate3F {
+  public static final class MicrophoneInfo.Coordinate3F {
     field public final float x;
     field public final float y;
     field public final float z;
@@ -24627,6 +25121,29 @@
     field public static final int RATING_THUMB_UP_DOWN = 2; // 0x2
   }
 
+  public final class Rating2 {
+    method public static android.media.Rating2 fromBundle(android.content.Context, android.os.Bundle);
+    method public float getPercentRating();
+    method public int getRatingStyle();
+    method public float getStarRating();
+    method public boolean hasHeart();
+    method public boolean isRated();
+    method public boolean isThumbUp();
+    method public static android.media.Rating2 newHeartRating(android.content.Context, boolean);
+    method public static android.media.Rating2 newPercentageRating(android.content.Context, float);
+    method public static android.media.Rating2 newStarRating(android.content.Context, int, float);
+    method public static android.media.Rating2 newThumbRating(android.content.Context, boolean);
+    method public static android.media.Rating2 newUnratedRating(android.content.Context, int);
+    method public android.os.Bundle toBundle();
+    field public static final int RATING_3_STARS = 3; // 0x3
+    field public static final int RATING_4_STARS = 4; // 0x4
+    field public static final int RATING_5_STARS = 5; // 0x5
+    field public static final int RATING_HEART = 1; // 0x1
+    field public static final int RATING_NONE = 0; // 0x0
+    field public static final int RATING_PERCENTAGE = 6; // 0x6
+    field public static final int RATING_THUMB_UP_DOWN = 2; // 0x2
+  }
+
   public deprecated class RemoteControlClient {
     ctor public RemoteControlClient(android.app.PendingIntent);
     ctor public RemoteControlClient(android.app.PendingIntent, android.os.Looper);
@@ -24716,10 +25233,14 @@
     method public android.media.AudioAttributes getAudioAttributes();
     method public deprecated int getStreamType();
     method public java.lang.String getTitle(android.content.Context);
+    method public float getVolume();
+    method public boolean isLooping();
     method public boolean isPlaying();
     method public void play();
     method public void setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException;
+    method public void setLooping(boolean);
     method public deprecated void setStreamType(int);
+    method public void setVolume(float);
     method public void stop();
   }
 
@@ -24762,6 +25283,22 @@
     field public static final int URI_COLUMN_INDEX = 2; // 0x2
   }
 
+  public final class SessionToken2 {
+    ctor public SessionToken2(android.content.Context, java.lang.String, java.lang.String);
+    method public static android.media.SessionToken2 fromBundle(android.content.Context, android.os.Bundle);
+    method public java.lang.String getId();
+    method public java.lang.String getPackageName();
+    method public int getType();
+    method public int getUid();
+    method public android.os.Bundle toBundle();
+    field public static final int TYPE_LIBRARY_SERVICE = 2; // 0x2
+    field public static final int TYPE_SESSION = 0; // 0x0
+    field public static final int TYPE_SESSION_SERVICE = 1; // 0x1
+  }
+
+  public static abstract class SessionToken2.TokenType implements java.lang.annotation.Annotation {
+  }
+
   public class SoundPool {
     ctor public deprecated SoundPool(int, int, int);
     method public final void autoPause();
@@ -24965,6 +25502,19 @@
     field public static final int VOLUME_CONTROL_RELATIVE = 1; // 0x1
   }
 
+  public abstract class VolumeProvider2 {
+    ctor public VolumeProvider2(android.content.Context, int, int, int);
+    method public final int getControlType();
+    method public final int getCurrentVolume();
+    method public final int getMaxVolume();
+    method public void onAdjustVolume(int);
+    method public void onSetVolumeTo(int);
+    method public final void setCurrentVolume(int);
+    field public static final int VOLUME_CONTROL_ABSOLUTE = 2; // 0x2
+    field public static final int VOLUME_CONTROL_FIXED = 0; // 0x0
+    field public static final int VOLUME_CONTROL_RELATIVE = 1; // 0x1
+  }
+
   public final class VolumeShaper implements java.lang.AutoCloseable {
     method public void apply(android.media.VolumeShaper.Operation);
     method public void close();
@@ -25046,6 +25596,7 @@
     field public static final java.util.UUID EFFECT_TYPE_AEC;
     field public static final java.util.UUID EFFECT_TYPE_AGC;
     field public static final java.util.UUID EFFECT_TYPE_BASS_BOOST;
+    field public static final java.util.UUID EFFECT_TYPE_DYNAMICS_PROCESSING;
     field public static final java.util.UUID EFFECT_TYPE_ENV_REVERB;
     field public static final java.util.UUID EFFECT_TYPE_EQUALIZER;
     field public static final java.util.UUID EFFECT_TYPE_LOUDNESS_ENHANCER;
@@ -25109,6 +25660,201 @@
     field public short strength;
   }
 
+  public final class DynamicsProcessing extends android.media.audiofx.AudioEffect {
+    ctor public DynamicsProcessing(int);
+    ctor public DynamicsProcessing(int, int, android.media.audiofx.DynamicsProcessing.Config);
+    method public android.media.audiofx.DynamicsProcessing.Channel getChannelByChannelIndex(int);
+    method public int getChannelCount();
+    method public android.media.audiofx.DynamicsProcessing.Config getConfig();
+    method public float getInputGainByChannelIndex(int);
+    method public android.media.audiofx.DynamicsProcessing.Limiter getLimiterByChannelIndex(int);
+    method public android.media.audiofx.DynamicsProcessing.MbcBand getMbcBandByChannelIndex(int, int);
+    method public android.media.audiofx.DynamicsProcessing.Mbc getMbcByChannelIndex(int);
+    method public android.media.audiofx.DynamicsProcessing.EqBand getPostEqBandByChannelIndex(int, int);
+    method public android.media.audiofx.DynamicsProcessing.Eq getPostEqByChannelIndex(int);
+    method public android.media.audiofx.DynamicsProcessing.EqBand getPreEqBandByChannelIndex(int, int);
+    method public android.media.audiofx.DynamicsProcessing.Eq getPreEqByChannelIndex(int);
+    method public void setAllChannelsTo(android.media.audiofx.DynamicsProcessing.Channel);
+    method public void setChannelTo(int, android.media.audiofx.DynamicsProcessing.Channel);
+    method public void setInputGainAllChannelsTo(float);
+    method public void setInputGainbyChannel(int, float);
+    method public void setLimiterAllChannelsTo(android.media.audiofx.DynamicsProcessing.Limiter);
+    method public void setLimiterByChannelIndex(int, android.media.audiofx.DynamicsProcessing.Limiter);
+    method public void setMbcAllChannelsTo(android.media.audiofx.DynamicsProcessing.Mbc);
+    method public void setMbcBandAllChannelsTo(int, android.media.audiofx.DynamicsProcessing.MbcBand);
+    method public void setMbcBandByChannelIndex(int, int, android.media.audiofx.DynamicsProcessing.MbcBand);
+    method public void setMbcByChannelIndex(int, android.media.audiofx.DynamicsProcessing.Mbc);
+    method public void setPostEqAllChannelsTo(android.media.audiofx.DynamicsProcessing.Eq);
+    method public void setPostEqBandAllChannelsTo(int, android.media.audiofx.DynamicsProcessing.EqBand);
+    method public void setPostEqBandByChannelIndex(int, int, android.media.audiofx.DynamicsProcessing.EqBand);
+    method public void setPostEqByChannelIndex(int, android.media.audiofx.DynamicsProcessing.Eq);
+    method public void setPreEqAllChannelsTo(android.media.audiofx.DynamicsProcessing.Eq);
+    method public void setPreEqBandAllChannelsTo(int, android.media.audiofx.DynamicsProcessing.EqBand);
+    method public void setPreEqBandByChannelIndex(int, int, android.media.audiofx.DynamicsProcessing.EqBand);
+    method public void setPreEqByChannelIndex(int, android.media.audiofx.DynamicsProcessing.Eq);
+    field public static final int VARIANT_FAVOR_FREQUENCY_RESOLUTION = 0; // 0x0
+    field public static final int VARIANT_FAVOR_TIME_RESOLUTION = 1; // 0x1
+  }
+
+  public static class DynamicsProcessing.BandBase {
+    ctor public DynamicsProcessing.BandBase(boolean, float);
+    method public float getCutoffFrequency();
+    method public boolean isEnabled();
+    method public void setCutoffFrequency(float);
+    method public void setEnabled(boolean);
+  }
+
+  public static class DynamicsProcessing.BandStage extends android.media.audiofx.DynamicsProcessing.Stage {
+    ctor public DynamicsProcessing.BandStage(boolean, boolean, int);
+    method public int getBandCount();
+  }
+
+  public static final class DynamicsProcessing.Channel {
+    ctor public DynamicsProcessing.Channel(float, boolean, int, boolean, int, boolean, int, boolean);
+    ctor public DynamicsProcessing.Channel(android.media.audiofx.DynamicsProcessing.Channel);
+    method public float getInputGain();
+    method public android.media.audiofx.DynamicsProcessing.Limiter getLimiter();
+    method public android.media.audiofx.DynamicsProcessing.Mbc getMbc();
+    method public android.media.audiofx.DynamicsProcessing.MbcBand getMbcBand(int);
+    method public android.media.audiofx.DynamicsProcessing.Eq getPostEq();
+    method public android.media.audiofx.DynamicsProcessing.EqBand getPostEqBand(int);
+    method public android.media.audiofx.DynamicsProcessing.Eq getPreEq();
+    method public android.media.audiofx.DynamicsProcessing.EqBand getPreEqBand(int);
+    method public void setInputGain(float);
+    method public void setLimiter(android.media.audiofx.DynamicsProcessing.Limiter);
+    method public void setMbc(android.media.audiofx.DynamicsProcessing.Mbc);
+    method public void setMbcBand(int, android.media.audiofx.DynamicsProcessing.MbcBand);
+    method public void setPostEq(android.media.audiofx.DynamicsProcessing.Eq);
+    method public void setPostEqBand(int, android.media.audiofx.DynamicsProcessing.EqBand);
+    method public void setPreEq(android.media.audiofx.DynamicsProcessing.Eq);
+    method public void setPreEqBand(int, android.media.audiofx.DynamicsProcessing.EqBand);
+  }
+
+  public static final class DynamicsProcessing.Config {
+    method public android.media.audiofx.DynamicsProcessing.Channel getChannelByChannelIndex(int);
+    method public float getInputGainByChannelIndex(int);
+    method public android.media.audiofx.DynamicsProcessing.Limiter getLimiterByChannelIndex(int);
+    method public android.media.audiofx.DynamicsProcessing.MbcBand getMbcBandByChannelIndex(int, int);
+    method public int getMbcBandCount();
+    method public android.media.audiofx.DynamicsProcessing.Mbc getMbcByChannelIndex(int);
+    method public android.media.audiofx.DynamicsProcessing.EqBand getPostEqBandByChannelIndex(int, int);
+    method public int getPostEqBandCount();
+    method public android.media.audiofx.DynamicsProcessing.Eq getPostEqByChannelIndex(int);
+    method public android.media.audiofx.DynamicsProcessing.EqBand getPreEqBandByChannelIndex(int, int);
+    method public int getPreEqBandCount();
+    method public android.media.audiofx.DynamicsProcessing.Eq getPreEqByChannelIndex(int);
+    method public float getPreferredFrameDuration();
+    method public int getVariant();
+    method public boolean isLimiterInUse();
+    method public boolean isMbcInUse();
+    method public boolean isPostEqInUse();
+    method public boolean isPreEqInUse();
+    method public void setAllChannelsTo(android.media.audiofx.DynamicsProcessing.Channel);
+    method public void setChannelTo(int, android.media.audiofx.DynamicsProcessing.Channel);
+    method public void setInputGainAllChannelsTo(float);
+    method public void setInputGainByChannelIndex(int, float);
+    method public void setLimiterAllChannelsTo(android.media.audiofx.DynamicsProcessing.Limiter);
+    method public void setLimiterByChannelIndex(int, android.media.audiofx.DynamicsProcessing.Limiter);
+    method public void setMbcAllChannelsTo(android.media.audiofx.DynamicsProcessing.Mbc);
+    method public void setMbcBandAllChannelsTo(int, android.media.audiofx.DynamicsProcessing.MbcBand);
+    method public void setMbcBandByChannelIndex(int, int, android.media.audiofx.DynamicsProcessing.MbcBand);
+    method public void setMbcByChannelIndex(int, android.media.audiofx.DynamicsProcessing.Mbc);
+    method public void setPostEqAllChannelsTo(android.media.audiofx.DynamicsProcessing.Eq);
+    method public void setPostEqBandAllChannelsTo(int, android.media.audiofx.DynamicsProcessing.EqBand);
+    method public void setPostEqBandByChannelIndex(int, int, android.media.audiofx.DynamicsProcessing.EqBand);
+    method public void setPostEqByChannelIndex(int, android.media.audiofx.DynamicsProcessing.Eq);
+    method public void setPreEqAllChannelsTo(android.media.audiofx.DynamicsProcessing.Eq);
+    method public void setPreEqBandAllChannelsTo(int, android.media.audiofx.DynamicsProcessing.EqBand);
+    method public void setPreEqBandByChannelIndex(int, int, android.media.audiofx.DynamicsProcessing.EqBand);
+    method public void setPreEqByChannelIndex(int, android.media.audiofx.DynamicsProcessing.Eq);
+  }
+
+  public static final class DynamicsProcessing.Config.Builder {
+    ctor public DynamicsProcessing.Config.Builder(int, int, boolean, int, boolean, int, boolean, int, boolean);
+    method public android.media.audiofx.DynamicsProcessing.Config build();
+    method public android.media.audiofx.DynamicsProcessing.Config.Builder setAllChannelsTo(android.media.audiofx.DynamicsProcessing.Channel);
+    method public android.media.audiofx.DynamicsProcessing.Config.Builder setChannelTo(int, android.media.audiofx.DynamicsProcessing.Channel);
+    method public android.media.audiofx.DynamicsProcessing.Config.Builder setInputGainAllChannelsTo(float);
+    method public android.media.audiofx.DynamicsProcessing.Config.Builder setInputGainByChannelIndex(int, float);
+    method public android.media.audiofx.DynamicsProcessing.Config.Builder setLimiterAllChannelsTo(android.media.audiofx.DynamicsProcessing.Limiter);
+    method public android.media.audiofx.DynamicsProcessing.Config.Builder setLimiterByChannelIndex(int, android.media.audiofx.DynamicsProcessing.Limiter);
+    method public android.media.audiofx.DynamicsProcessing.Config.Builder setMbcAllChannelsTo(android.media.audiofx.DynamicsProcessing.Mbc);
+    method public android.media.audiofx.DynamicsProcessing.Config.Builder setMbcByChannelIndex(int, android.media.audiofx.DynamicsProcessing.Mbc);
+    method public android.media.audiofx.DynamicsProcessing.Config.Builder setPostEqAllChannelsTo(android.media.audiofx.DynamicsProcessing.Eq);
+    method public android.media.audiofx.DynamicsProcessing.Config.Builder setPostEqByChannelIndex(int, android.media.audiofx.DynamicsProcessing.Eq);
+    method public android.media.audiofx.DynamicsProcessing.Config.Builder setPreEqAllChannelsTo(android.media.audiofx.DynamicsProcessing.Eq);
+    method public android.media.audiofx.DynamicsProcessing.Config.Builder setPreEqByChannelIndex(int, android.media.audiofx.DynamicsProcessing.Eq);
+    method public android.media.audiofx.DynamicsProcessing.Config.Builder setPreferredFrameDuration(float);
+  }
+
+  public static final class DynamicsProcessing.Eq extends android.media.audiofx.DynamicsProcessing.BandStage {
+    ctor public DynamicsProcessing.Eq(boolean, boolean, int);
+    ctor public DynamicsProcessing.Eq(android.media.audiofx.DynamicsProcessing.Eq);
+    method public android.media.audiofx.DynamicsProcessing.EqBand getBand(int);
+    method public void setBand(int, android.media.audiofx.DynamicsProcessing.EqBand);
+  }
+
+  public static final class DynamicsProcessing.EqBand extends android.media.audiofx.DynamicsProcessing.BandBase {
+    ctor public DynamicsProcessing.EqBand(boolean, float, float);
+    ctor public DynamicsProcessing.EqBand(android.media.audiofx.DynamicsProcessing.EqBand);
+    method public float getGain();
+    method public void setGain(float);
+  }
+
+  public static final class DynamicsProcessing.Limiter extends android.media.audiofx.DynamicsProcessing.Stage {
+    ctor public DynamicsProcessing.Limiter(boolean, boolean, int, float, float, float, float, float);
+    ctor public DynamicsProcessing.Limiter(android.media.audiofx.DynamicsProcessing.Limiter);
+    method public float getAttackTime();
+    method public int getLinkGroup();
+    method public float getPostGain();
+    method public float getRatio();
+    method public float getReleaseTime();
+    method public float getThreshold();
+    method public void setAttackTime(float);
+    method public void setLinkGroup(int);
+    method public void setPostGain(float);
+    method public void setRatio(float);
+    method public void setReleaseTime(float);
+    method public void setThreshold(float);
+  }
+
+  public static final class DynamicsProcessing.Mbc extends android.media.audiofx.DynamicsProcessing.BandStage {
+    ctor public DynamicsProcessing.Mbc(boolean, boolean, int);
+    ctor public DynamicsProcessing.Mbc(android.media.audiofx.DynamicsProcessing.Mbc);
+    method public android.media.audiofx.DynamicsProcessing.MbcBand getBand(int);
+    method public void setBand(int, android.media.audiofx.DynamicsProcessing.MbcBand);
+  }
+
+  public static final class DynamicsProcessing.MbcBand extends android.media.audiofx.DynamicsProcessing.BandBase {
+    ctor public DynamicsProcessing.MbcBand(boolean, float, float, float, float, float, float, float, float, float, float);
+    ctor public DynamicsProcessing.MbcBand(android.media.audiofx.DynamicsProcessing.MbcBand);
+    method public float getAttackTime();
+    method public float getExpanderRatio();
+    method public float getKneeWidth();
+    method public float getNoiseGateThreshold();
+    method public float getPostGain();
+    method public float getPreGain();
+    method public float getRatio();
+    method public float getReleaseTime();
+    method public float getThreshold();
+    method public void setAttackTime(float);
+    method public void setExpanderRatio(float);
+    method public void setKneeWidth(float);
+    method public void setNoiseGateThreshold(float);
+    method public void setPostGain(float);
+    method public void setPreGain(float);
+    method public void setRatio(float);
+    method public void setReleaseTime(float);
+    method public void setThreshold(float);
+  }
+
+  public static class DynamicsProcessing.Stage {
+    ctor public DynamicsProcessing.Stage(boolean, boolean);
+    method public boolean isEnabled();
+    method public boolean isInUse();
+    method public void setEnabled(boolean);
+  }
+
   public class EnvironmentalReverb extends android.media.audiofx.AudioEffect {
     ctor public EnvironmentalReverb(int, int) throws java.lang.IllegalArgumentException, java.lang.RuntimeException, java.lang.UnsupportedOperationException;
     method public short getDecayHFRatio() throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.UnsupportedOperationException;
@@ -25711,14 +26457,23 @@
   public final class MediaSessionManager {
     method public void addOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener, android.content.ComponentName);
     method public void addOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener, android.content.ComponentName, android.os.Handler);
+    method public void addOnSessionTokensChangedListener(java.util.concurrent.Executor, android.media.session.MediaSessionManager.OnSessionTokensChangedListener);
+    method public java.util.List<android.media.SessionToken2> getActiveSessionTokens();
     method public java.util.List<android.media.session.MediaController> getActiveSessions(android.content.ComponentName);
+    method public java.util.List<android.media.SessionToken2> getAllSessionTokens();
+    method public java.util.List<android.media.SessionToken2> getSessionServiceTokens();
     method public void removeOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener);
+    method public void removeOnSessionTokensChangedListener(android.media.session.MediaSessionManager.OnSessionTokensChangedListener);
   }
 
   public static abstract interface MediaSessionManager.OnActiveSessionsChangedListener {
     method public abstract void onActiveSessionsChanged(java.util.List<android.media.session.MediaController>);
   }
 
+  public static abstract interface MediaSessionManager.OnSessionTokensChangedListener {
+    method public abstract void onSessionTokensChanged(java.util.List<android.media.SessionToken2>);
+  }
+
   public final class PlaybackState implements android.os.Parcelable {
     method public int describeContents();
     method public long getActions();
@@ -32977,7 +33732,7 @@
     method public android.os.StrictMode.ThreadPolicy.Builder penaltyDialog();
     method public android.os.StrictMode.ThreadPolicy.Builder penaltyDropBox();
     method public android.os.StrictMode.ThreadPolicy.Builder penaltyFlashScreen();
-    method public android.os.StrictMode.ThreadPolicy.Builder penaltyListener(android.os.StrictMode.OnThreadViolationListener, java.util.concurrent.Executor);
+    method public android.os.StrictMode.ThreadPolicy.Builder penaltyListener(java.util.concurrent.Executor, android.os.StrictMode.OnThreadViolationListener);
     method public android.os.StrictMode.ThreadPolicy.Builder penaltyLog();
     method public android.os.StrictMode.ThreadPolicy.Builder permitAll();
     method public android.os.StrictMode.ThreadPolicy.Builder permitCustomSlowCalls();
@@ -33009,7 +33764,7 @@
     method public android.os.StrictMode.VmPolicy.Builder penaltyDeathOnCleartextNetwork();
     method public android.os.StrictMode.VmPolicy.Builder penaltyDeathOnFileUriExposure();
     method public android.os.StrictMode.VmPolicy.Builder penaltyDropBox();
-    method public android.os.StrictMode.VmPolicy.Builder penaltyListener(android.os.StrictMode.OnVmViolationListener, java.util.concurrent.Executor);
+    method public android.os.StrictMode.VmPolicy.Builder penaltyListener(java.util.concurrent.Executor, android.os.StrictMode.OnVmViolationListener);
     method public android.os.StrictMode.VmPolicy.Builder penaltyLog();
     method public android.os.StrictMode.VmPolicy.Builder setClassInstanceLimit(java.lang.Class, int);
   }
@@ -33147,6 +33902,17 @@
     field public static final java.lang.String KEY_RESTRICTIONS_PENDING = "restrictions_pending";
     field public static final int USER_CREATION_FAILED_NOT_PERMITTED = 1; // 0x1
     field public static final int USER_CREATION_FAILED_NO_MORE_USERS = 2; // 0x2
+    field public static final int USER_OPERATION_ERROR_CURRENT_USER = 4; // 0x4
+    field public static final int USER_OPERATION_ERROR_LOW_STORAGE = 5; // 0x5
+    field public static final int USER_OPERATION_ERROR_MANAGED_PROFILE = 2; // 0x2
+    field public static final int USER_OPERATION_ERROR_MAX_RUNNING_USERS = 3; // 0x3
+    field public static final int USER_OPERATION_ERROR_MAX_USERS = 6; // 0x6
+    field public static final int USER_OPERATION_ERROR_UNKNOWN = 1; // 0x1
+    field public static final int USER_OPERATION_SUCCESS = 0; // 0x0
+  }
+
+  public static class UserManager.UserOperationException extends java.lang.RuntimeException {
+    method public int getUserOperationResult();
   }
 
   public abstract class VibrationEffect implements android.os.Parcelable {
@@ -34619,7 +35385,6 @@
     field public static final java.lang.String DURATION = "duration";
     field public static final java.lang.String EXTRA_CALL_TYPE_FILTER = "android.provider.extra.CALL_TYPE_FILTER";
     field public static final java.lang.String FEATURES = "features";
-    field public static final int FEATURES_ASSISTED_DIALING_USED = 16; // 0x10
     field public static final int FEATURES_HD_CALL = 4; // 0x4
     field public static final int FEATURES_PULLED_EXTERNALLY = 2; // 0x2
     field public static final int FEATURES_RTT = 32; // 0x20
@@ -38243,17 +39008,6 @@
     method public byte[] transmit(byte[]) throws java.io.IOException;
   }
 
-  public abstract interface ISecureElementListener implements android.os.IInterface {
-    method public abstract void serviceConnected() throws android.os.RemoteException;
-  }
-
-  public static abstract class ISecureElementListener.Stub extends android.os.Binder implements android.se.omapi.ISecureElementListener {
-    ctor public ISecureElementListener.Stub();
-    method public android.os.IBinder asBinder();
-    method public static android.se.omapi.ISecureElementListener asInterface(android.os.IBinder);
-    method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
-  }
-
   public class Reader {
     method public void closeSessions();
     method public java.lang.String getName();
@@ -38263,13 +39017,19 @@
   }
 
   public class SEService {
-    ctor public SEService(android.content.Context, android.se.omapi.ISecureElementListener);
+    ctor public SEService(android.content.Context, android.se.omapi.SEService.SecureElementListener);
     method public android.se.omapi.Reader[] getReaders();
     method public java.lang.String getVersion();
     method public boolean isConnected();
     method public void shutdown();
   }
 
+  public static abstract class SEService.SecureElementListener extends android.os.Binder {
+    ctor public SEService.SecureElementListener();
+    method public android.os.IBinder asBinder();
+    method public void serviceConnected();
+  }
+
   public class Session {
     method public void close();
     method public void closeChannels();
@@ -38429,7 +39189,6 @@
     method public boolean isRandomizedEncryptionRequired();
     method public boolean isStrongBoxBacked();
     method public boolean isTrustedUserPresenceRequired();
-    method public boolean isUnlockedDeviceRequired();
     method public boolean isUserAuthenticationRequired();
     method public boolean isUserAuthenticationValidWhileOnBody();
     method public boolean isUserConfirmationRequired();
@@ -38457,7 +39216,6 @@
     method public android.security.keystore.KeyGenParameterSpec.Builder setRandomizedEncryptionRequired(boolean);
     method public android.security.keystore.KeyGenParameterSpec.Builder setSignaturePaddings(java.lang.String...);
     method public android.security.keystore.KeyGenParameterSpec.Builder setTrustedUserPresenceRequired(boolean);
-    method public android.security.keystore.KeyGenParameterSpec.Builder setUnlockedDeviceRequired(boolean);
     method public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationRequired(boolean);
     method public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationValidWhileOnBody(boolean);
     method public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationValidityDurationSeconds(int);
@@ -38549,8 +39307,6 @@
     method public boolean isDigestsSpecified();
     method public boolean isInvalidatedByBiometricEnrollment();
     method public boolean isRandomizedEncryptionRequired();
-    method public boolean isTrustedUserPresenceRequired();
-    method public boolean isUnlockedDeviceRequired();
     method public boolean isUserAuthenticationRequired();
     method public boolean isUserAuthenticationValidWhileOnBody();
     method public boolean isUserConfirmationRequired();
@@ -38569,8 +39325,6 @@
     method public android.security.keystore.KeyProtection.Builder setKeyValidityStart(java.util.Date);
     method public android.security.keystore.KeyProtection.Builder setRandomizedEncryptionRequired(boolean);
     method public android.security.keystore.KeyProtection.Builder setSignaturePaddings(java.lang.String...);
-    method public android.security.keystore.KeyProtection.Builder setTrustedUserPresenceRequired(boolean);
-    method public android.security.keystore.KeyProtection.Builder setUnlockedDeviceRequired(boolean);
     method public android.security.keystore.KeyProtection.Builder setUserAuthenticationRequired(boolean);
     method public android.security.keystore.KeyProtection.Builder setUserAuthenticationValidWhileOnBody(boolean);
     method public android.security.keystore.KeyProtection.Builder setUserAuthenticationValidityDurationSeconds(int);
@@ -40623,7 +41377,6 @@
     field public static final int CAPABILITY_SUPPORT_DEFLECT = 16777216; // 0x1000000
     field public static final int CAPABILITY_SUPPORT_HOLD = 2; // 0x2
     field public static final int CAPABILITY_SWAP_CONFERENCE = 8; // 0x8
-    field public static final int PROPERTY_ASSISTED_DIALING_USED = 512; // 0x200
     field public static final int PROPERTY_CONFERENCE = 1; // 0x1
     field public static final int PROPERTY_EMERGENCY_CALLBACK_MODE = 4; // 0x4
     field public static final int PROPERTY_ENTERPRISE_CALL = 32; // 0x20
@@ -40848,7 +41601,6 @@
     field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
     field public static final java.lang.String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS";
     field public static final java.lang.String EXTRA_LAST_FORWARDED_NUMBER = "android.telecom.extra.LAST_FORWARDED_NUMBER";
-    field public static final int PROPERTY_ASSISTED_DIALING_USED = 512; // 0x200
     field public static final int PROPERTY_HAS_CDMA_VOICE_PRIVACY = 32; // 0x20
     field public static final int PROPERTY_IS_EXTERNAL_CALL = 16; // 0x10
     field public static final int PROPERTY_IS_RTT = 256; // 0x100
@@ -41265,14 +42017,12 @@
     field public static final deprecated java.lang.String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
     field public static final java.lang.String ACTION_PHONE_ACCOUNT_REGISTERED = "android.telecom.action.PHONE_ACCOUNT_REGISTERED";
     field public static final java.lang.String ACTION_PHONE_ACCOUNT_UNREGISTERED = "android.telecom.action.PHONE_ACCOUNT_UNREGISTERED";
-    field public static final java.lang.String ACTION_SHOW_ASSISTED_DIALING_SETTINGS = "android.telecom.action.SHOW_ASSISTED_DIALING_SETTINGS";
     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 ';'
-    field public static final java.lang.String EXTRA_ASSISTED_DIALING_TRANSFORMATION_INFO = "android.telecom.extra.ASSISTED_DIALING_TRANSFORMATION_INFO";
     field public static final java.lang.String EXTRA_CALL_BACK_NUMBER = "android.telecom.extra.CALL_BACK_NUMBER";
     field public static final java.lang.String EXTRA_CALL_DISCONNECT_CAUSE = "android.telecom.extra.CALL_DISCONNECT_CAUSE";
     field public static final java.lang.String EXTRA_CALL_DISCONNECT_MESSAGE = "android.telecom.extra.CALL_DISCONNECT_MESSAGE";
@@ -41288,7 +42038,6 @@
     field public static final java.lang.String EXTRA_START_CALL_WITH_RTT = "android.telecom.extra.START_CALL_WITH_RTT";
     field public static final java.lang.String EXTRA_START_CALL_WITH_SPEAKERPHONE = "android.telecom.extra.START_CALL_WITH_SPEAKERPHONE";
     field public static final java.lang.String EXTRA_START_CALL_WITH_VIDEO_STATE = "android.telecom.extra.START_CALL_WITH_VIDEO_STATE";
-    field public static final java.lang.String EXTRA_USE_ASSISTED_DIALING = "android.telecom.extra.USE_ASSISTED_DIALING";
     field public static final java.lang.String GATEWAY_ORIGINAL_ADDRESS = "android.telecom.extra.GATEWAY_ORIGINAL_ADDRESS";
     field public static final java.lang.String GATEWAY_PROVIDER_PACKAGE = "android.telecom.extra.GATEWAY_PROVIDER_PACKAGE";
     field public static final java.lang.String METADATA_INCLUDE_EXTERNAL_CALLS = "android.telecom.INCLUDE_EXTERNAL_CALLS";
@@ -41301,18 +42050,6 @@
     field public static final int PRESENTATION_UNKNOWN = 3; // 0x3
   }
 
-  public final class TransformationInfo implements android.os.Parcelable {
-    ctor public TransformationInfo(java.lang.String, java.lang.String, java.lang.String, java.lang.String, int);
-    method public int describeContents();
-    method public java.lang.String getOriginalNumber();
-    method public java.lang.String getTransformedNumber();
-    method public int getTransformedNumberCountryCallingCode();
-    method public java.lang.String getUserHomeCountryCode();
-    method public java.lang.String getUserRoamingCountryCode();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.telecom.TransformationInfo> CREATOR;
-  }
-
   public class VideoProfile implements android.os.Parcelable {
     ctor public VideoProfile(int);
     ctor public VideoProfile(int, int);
@@ -41479,7 +42216,6 @@
     field public static final java.lang.String KEY_ALLOW_NON_EMERGENCY_CALLS_IN_ECM_BOOL = "allow_non_emergency_calls_in_ecm_bool";
     field public static final java.lang.String KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL = "always_show_emergency_alert_onoff_bool";
     field public static final java.lang.String KEY_APN_EXPAND_BOOL = "apn_expand_bool";
-    field public static final java.lang.String KEY_ASSISTED_DIALING_ENABLED_BOOL = "assisted_dialing_enabled_bool";
     field public static final java.lang.String KEY_AUTO_RETRY_ENABLED_BOOL = "auto_retry_enabled_bool";
     field public static final java.lang.String KEY_CALL_FORWARDING_BLOCKS_WHILE_ROAMING_STRING_ARRAY = "call_forwarding_blocks_while_roaming_string_array";
     field public static final java.lang.String KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL = "carrier_allow_turnoff_ims_bool";
@@ -41818,12 +42554,12 @@
   public class MbmsDownloadSession implements java.lang.AutoCloseable {
     method public int cancelDownload(android.telephony.mbms.DownloadRequest);
     method public void close();
-    method public static android.telephony.MbmsDownloadSession create(android.content.Context, android.telephony.mbms.MbmsDownloadSessionCallback, android.os.Handler);
-    method public static android.telephony.MbmsDownloadSession create(android.content.Context, android.telephony.mbms.MbmsDownloadSessionCallback, int, android.os.Handler);
+    method public static android.telephony.MbmsDownloadSession create(android.content.Context, java.util.concurrent.Executor, android.telephony.mbms.MbmsDownloadSessionCallback);
+    method public static android.telephony.MbmsDownloadSession create(android.content.Context, java.util.concurrent.Executor, int, android.telephony.mbms.MbmsDownloadSessionCallback);
     method public int download(android.telephony.mbms.DownloadRequest);
     method public java.io.File getTempFileRootDirectory();
     method public java.util.List<android.telephony.mbms.DownloadRequest> listPendingDownloads();
-    method public int registerStateCallback(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStateCallback, android.os.Handler);
+    method public int registerStateCallback(android.telephony.mbms.DownloadRequest, java.util.concurrent.Executor, android.telephony.mbms.DownloadStateCallback);
     method public void requestDownloadState(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo);
     method public void requestUpdateFileServices(java.util.List<java.lang.String>);
     method public void resetDownloadKnowledge(android.telephony.mbms.DownloadRequest);
@@ -41851,10 +42587,10 @@
 
   public class MbmsStreamingSession implements java.lang.AutoCloseable {
     method public void close();
-    method public static android.telephony.MbmsStreamingSession create(android.content.Context, android.telephony.mbms.MbmsStreamingSessionCallback, int, android.os.Handler);
-    method public static android.telephony.MbmsStreamingSession create(android.content.Context, android.telephony.mbms.MbmsStreamingSessionCallback, android.os.Handler);
+    method public static android.telephony.MbmsStreamingSession create(android.content.Context, java.util.concurrent.Executor, int, android.telephony.mbms.MbmsStreamingSessionCallback);
+    method public static android.telephony.MbmsStreamingSession create(android.content.Context, java.util.concurrent.Executor, android.telephony.mbms.MbmsStreamingSessionCallback);
     method public void requestUpdateStreamingServices(java.util.List<java.lang.String>);
-    method public android.telephony.mbms.StreamingService startStreaming(android.telephony.mbms.StreamingServiceInfo, android.telephony.mbms.StreamingServiceCallback, android.os.Handler);
+    method public android.telephony.mbms.StreamingService startStreaming(android.telephony.mbms.StreamingServiceInfo, java.util.concurrent.Executor, android.telephony.mbms.StreamingServiceCallback);
   }
 
   public class NeighboringCellInfo implements android.os.Parcelable {
@@ -42727,20 +43463,23 @@
 package android.telephony.mbms {
 
   public final class DownloadRequest implements android.os.Parcelable {
-    method public static android.telephony.mbms.DownloadRequest copy(android.telephony.mbms.DownloadRequest);
     method public int describeContents();
+    method public android.net.Uri getDestinationUri();
     method public java.lang.String getFileServiceId();
     method public static int getMaxAppIntentSize();
     method public static int getMaxDestinationUriSize();
     method public android.net.Uri getSourceUri();
     method public int getSubscriptionId();
+    method public byte[] toByteArray();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.telephony.mbms.DownloadRequest> CREATOR;
   }
 
   public static class DownloadRequest.Builder {
-    ctor public DownloadRequest.Builder(android.net.Uri);
+    ctor public DownloadRequest.Builder(android.net.Uri, android.net.Uri);
     method public android.telephony.mbms.DownloadRequest build();
+    method public static android.telephony.mbms.DownloadRequest.Builder fromDownloadRequest(android.telephony.mbms.DownloadRequest);
+    method public static android.telephony.mbms.DownloadRequest.Builder fromSerializedRequest(byte[]);
     method public android.telephony.mbms.DownloadRequest.Builder setAppIntent(android.content.Intent);
     method public android.telephony.mbms.DownloadRequest.Builder setServiceInfo(android.telephony.mbms.FileServiceInfo);
     method public android.telephony.mbms.DownloadRequest.Builder setSubscriptionId(int);
@@ -42836,10 +43575,10 @@
     method public java.util.Date getSessionStartTime();
   }
 
-  public class StreamingService {
+  public class StreamingService implements java.lang.AutoCloseable {
+    method public void close();
     method public android.telephony.mbms.StreamingServiceInfo getInfo();
     method public android.net.Uri getPlaybackUri();
-    method public void stopStreaming();
     field public static final int BROADCAST_METHOD = 1; // 0x1
     field public static final int REASON_BY_USER_REQUEST = 1; // 0x1
     field public static final int REASON_END_OF_SESSION = 2; // 0x2
@@ -47615,6 +48354,7 @@
     method public void setAlpha(float);
     method public void setAnimation(android.view.animation.Animation);
     method public void setAutofillHints(java.lang.String...);
+    method public void setAutofillId(android.view.autofill.AutofillId);
     method public void setBackground(android.graphics.drawable.Drawable);
     method public void setBackgroundColor(int);
     method public deprecated void setBackgroundDrawable(android.graphics.drawable.Drawable);
@@ -49778,6 +50518,7 @@
     method public android.content.ComponentName getAutofillServiceComponentName();
     method public java.util.List<java.lang.String> getAvailableFieldClassificationAlgorithms();
     method public java.lang.String getDefaultFieldClassificationAlgorithm();
+    method public android.view.autofill.AutofillId getNextAutofillId();
     method public android.service.autofill.UserData getUserData();
     method public java.lang.String getUserDataId();
     method public boolean hasEnabledAutofillServices();
@@ -52601,6 +53342,20 @@
     method public void update();
   }
 
+  public class MediaControlView2 extends android.view.ViewGroup {
+    ctor public MediaControlView2(android.content.Context);
+    ctor public MediaControlView2(android.content.Context, android.util.AttributeSet);
+    ctor public MediaControlView2(android.content.Context, android.util.AttributeSet, int);
+    ctor public MediaControlView2(android.content.Context, android.util.AttributeSet, int, int);
+    method public void requestPlayButtonFocus();
+    method public void setMediaSessionToken(android.media.SessionToken2);
+    method public void setOnFullScreenListener(android.widget.MediaControlView2.OnFullScreenListener);
+  }
+
+  public static abstract interface MediaControlView2.OnFullScreenListener {
+    method public abstract void onFullScreen(android.view.View, boolean);
+  }
+
   public class MediaController extends android.widget.FrameLayout {
     ctor public MediaController(android.content.Context, android.util.AttributeSet);
     ctor public MediaController(android.content.Context, boolean);
@@ -53991,6 +54746,27 @@
     method public void suspend();
   }
 
+  public class VideoView2 extends android.view.ViewGroup {
+    ctor public VideoView2(android.content.Context);
+    ctor public VideoView2(android.content.Context, android.util.AttributeSet);
+    ctor public VideoView2(android.content.Context, android.util.AttributeSet, int);
+    ctor public VideoView2(android.content.Context, android.util.AttributeSet, int, int);
+    method public android.widget.MediaControlView2 getMediaControlView2();
+    method public android.media.SessionToken2 getMediaSessionToken();
+    method public int getViewType();
+    method public boolean isSubtitleEnabled();
+    method public void setAudioAttributes(android.media.AudioAttributes);
+    method public void setAudioFocusRequest(int);
+    method public void setDataSource(android.media.DataSourceDesc);
+    method public void setMediaControlView2(android.widget.MediaControlView2, long);
+    method public void setMediaItem(android.media.MediaItem2);
+    method public void setSpeed(float);
+    method public void setSubtitleEnabled(boolean);
+    method public void setViewType(int);
+    field public static final int VIEW_TYPE_SURFACEVIEW = 1; // 0x1
+    field public static final int VIEW_TYPE_TEXTUREVIEW = 2; // 0x2
+  }
+
   public class ViewAnimator extends android.widget.FrameLayout {
     ctor public ViewAnimator(android.content.Context);
     ctor public ViewAnimator(android.content.Context, android.util.AttributeSet);
diff --git a/api/removed.txt b/api/removed.txt
index 55022f3..79c54fd 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -257,6 +257,14 @@
     ctor public RecoverySystem();
   }
 
+  public static final class StrictMode.ThreadPolicy.Builder {
+    method public android.os.StrictMode.ThreadPolicy.Builder penaltyListener(android.os.StrictMode.OnThreadViolationListener, java.util.concurrent.Executor);
+  }
+
+  public static final class StrictMode.VmPolicy.Builder {
+    method public android.os.StrictMode.VmPolicy.Builder penaltyListener(android.os.StrictMode.OnVmViolationListener, java.util.concurrent.Executor);
+  }
+
   public final class SystemClock {
     method public static java.time.Clock elapsedRealtimeClock();
     method public static java.time.Clock uptimeClock();
diff --git a/api/system-current.txt b/api/system-current.txt
index 78ed570..54c5179 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -10,6 +10,7 @@
     field public static final java.lang.String ACCESS_MTP = "android.permission.ACCESS_MTP";
     field public static final java.lang.String ACCESS_NETWORK_CONDITIONS = "android.permission.ACCESS_NETWORK_CONDITIONS";
     field public static final java.lang.String ACCESS_NOTIFICATIONS = "android.permission.ACCESS_NOTIFICATIONS";
+    field public static final java.lang.String ACCESS_SHORTCUTS = "android.permission.ACCESS_SHORTCUTS";
     field public static final java.lang.String ACCESS_SURFACE_FLINGER = "android.permission.ACCESS_SURFACE_FLINGER";
     field public static final java.lang.String ACCOUNT_MANAGER = "android.permission.ACCOUNT_MANAGER";
     field public static final java.lang.String ACTIVITY_EMBEDDING = "android.permission.ACTIVITY_EMBEDDING";
@@ -124,6 +125,7 @@
     field public static final java.lang.String PERFORM_SIM_ACTIVATION = "android.permission.PERFORM_SIM_ACTIVATION";
     field public static final java.lang.String PROVIDE_RESOLVER_RANKER_SERVICE = "android.permission.PROVIDE_RESOLVER_RANKER_SERVICE";
     field public static final java.lang.String PROVIDE_TRUST_AGENT = "android.permission.PROVIDE_TRUST_AGENT";
+    field public static final java.lang.String QUERY_TIME_ZONE_RULES = "android.permission.QUERY_TIME_ZONE_RULES";
     field public static final java.lang.String READ_CONTENT_RATING_SYSTEMS = "android.permission.READ_CONTENT_RATING_SYSTEMS";
     field public static final java.lang.String READ_DREAM_STATE = "android.permission.READ_DREAM_STATE";
     field public static final java.lang.String READ_FRAME_BUFFER = "android.permission.READ_FRAME_BUFFER";
@@ -179,6 +181,7 @@
     field public static final java.lang.String TETHER_PRIVILEGED = "android.permission.TETHER_PRIVILEGED";
     field public static final java.lang.String TV_INPUT_HARDWARE = "android.permission.TV_INPUT_HARDWARE";
     field public static final java.lang.String TV_VIRTUAL_REMOTE_CONTROLLER = "android.permission.TV_VIRTUAL_REMOTE_CONTROLLER";
+    field public static final java.lang.String UNLIMITED_SHORTCUTS_API_CALLS = "android.permission.UNLIMITED_SHORTCUTS_API_CALLS";
     field public static final java.lang.String UPDATE_APP_OPS_STATS = "android.permission.UPDATE_APP_OPS_STATS";
     field public static final java.lang.String UPDATE_DEVICE_STATS = "android.permission.UPDATE_DEVICE_STATS";
     field public static final java.lang.String UPDATE_LOCK = "android.permission.UPDATE_LOCK";
@@ -201,6 +204,7 @@
     field public static final int isVrOnly = 16844152; // 0x1010578
     field public static final int requiredSystemPropertyName = 16844133; // 0x1010565
     field public static final int requiredSystemPropertyValue = 16844134; // 0x1010566
+    field public static final int userRestriction = 16844165; // 0x1010585
   }
 
   public static final class R.raw {
@@ -467,7 +471,11 @@
     method public android.app.backup.RestoreSession beginRestoreSession();
     method public void cancelBackups();
     method public long getAvailableRestoreToken(java.lang.String);
+    method public android.content.Intent getConfigurationIntent(java.lang.String);
     method public java.lang.String getCurrentTransport();
+    method public android.content.Intent getDataManagementIntent(java.lang.String);
+    method public java.lang.String getDataManagementLabel(java.lang.String);
+    method public java.lang.String getDestinationString(java.lang.String);
     method public boolean isAppEligibleForBackup(java.lang.String);
     method public boolean isBackupEnabled();
     method public boolean isBackupServiceActive(android.os.UserHandle);
@@ -609,6 +617,7 @@
     method public java.lang.String transportDirName();
     field public static final int AGENT_ERROR = -1003; // 0xfffffc15
     field public static final int AGENT_UNKNOWN = -1004; // 0xfffffc14
+    field public static final java.lang.String EXTRA_TRANSPORT_REGISTRATION = "android.app.backup.extra.TRANSPORT_REGISTRATION";
     field public static final int FLAG_INCREMENTAL = 2; // 0x2
     field public static final int FLAG_NON_INCREMENTAL = 4; // 0x4
     field public static final int FLAG_USER_INITIATED = 1; // 0x1
@@ -1085,6 +1094,7 @@
   public class PermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
     field public static final int FLAG_REMOVED = 2; // 0x2
     field public static final int PROTECTION_FLAG_OEM = 16384; // 0x4000
+    field public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 65536; // 0x10000
     field public int requestRes;
   }
 
@@ -2639,8 +2649,10 @@
   }
 
   public class AudioPolicy {
+    method public int attachMixes(java.util.List<android.media.audiopolicy.AudioMix>);
     method public android.media.AudioRecord createAudioRecordSink(android.media.audiopolicy.AudioMix) throws java.lang.IllegalArgumentException;
     method public android.media.AudioTrack createAudioTrackSource(android.media.audiopolicy.AudioMix) throws java.lang.IllegalArgumentException;
+    method public int detachMixes(java.util.List<android.media.audiopolicy.AudioMix>);
     method public int getFocusDuckingBehavior();
     method public int getStatus();
     method public int setFocusDuckingBehavior(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
@@ -4168,7 +4180,10 @@
     method public static boolean putString(android.content.ContentResolver, java.lang.String, java.lang.String, java.lang.String, boolean);
     method public static void resetToDefaults(android.content.ContentResolver, java.lang.String);
     field public static final java.lang.String AUTOFILL_COMPAT_ALLOWED_PACKAGES = "autofill_compat_allowed_packages";
+    field public static final java.lang.String CARRIER_APP_NAMES = "carrier_app_names";
+    field public static final java.lang.String CARRIER_APP_WHITELIST = "carrier_app_whitelist";
     field public static final java.lang.String DEFAULT_SM_DP_PLUS = "default_sm_dp_plus";
+    field public static final java.lang.String EUICC_PROVISIONED = "euicc_provisioned";
     field public static final java.lang.String INSTALL_CARRIER_APP_NOTIFICATION_PERSISTENT = "install_carrier_app_notification_persistent";
     field public static final java.lang.String INSTALL_CARRIER_APP_NOTIFICATION_SLEEP_MILLIS = "install_carrier_app_notification_sleep_millis";
     field public static final java.lang.String OTA_DISABLE_AUTOMATIC_UPDATE = "ota_disable_automatic_update";
@@ -4263,7 +4278,8 @@
     method public int getMaxAttempts();
     method public byte[] getServerParams();
     method public int getSnapshotVersion();
-    method public byte[] getTrustedHardwarePublicKey();
+    method public java.security.cert.CertPath getTrustedHardwareCertPath();
+    method public deprecated byte[] getTrustedHardwarePublicKey();
     method public java.util.List<android.security.keystore.recovery.WrappedApplicationKey> getWrappedApplicationKeys();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.security.keystore.recovery.KeyChainSnapshot> CREATOR;
@@ -4284,21 +4300,26 @@
   }
 
   public class RecoveryController {
+    method public android.security.keystore.recovery.RecoverySession createRecoverySession();
     method public byte[] generateAndStoreKey(java.lang.String, byte[]) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.LockScreenRequiredException;
-    method public java.util.List<java.lang.String> getAliases(java.lang.String) throws android.security.keystore.recovery.InternalRecoveryServiceException;
+    method public deprecated java.security.Key generateKey(java.lang.String, byte[]) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.LockScreenRequiredException;
+    method public java.security.Key generateKey(java.lang.String) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.LockScreenRequiredException;
+    method public deprecated java.util.List<java.lang.String> getAliases(java.lang.String) throws android.security.keystore.recovery.InternalRecoveryServiceException;
+    method public java.util.List<java.lang.String> getAliases() throws android.security.keystore.recovery.InternalRecoveryServiceException;
     method public static android.security.keystore.recovery.RecoveryController getInstance(android.content.Context);
     method public int[] getPendingRecoverySecretTypes() throws android.security.keystore.recovery.InternalRecoveryServiceException;
-    method public android.security.keystore.recovery.KeyChainSnapshot getRecoveryData() throws android.security.keystore.recovery.InternalRecoveryServiceException;
+    method public deprecated android.security.keystore.recovery.KeyChainSnapshot getRecoveryData() throws android.security.keystore.recovery.InternalRecoveryServiceException;
     method public int[] getRecoverySecretTypes() throws android.security.keystore.recovery.InternalRecoveryServiceException;
-    method public int getRecoveryStatus(java.lang.String, java.lang.String) throws android.security.keystore.recovery.InternalRecoveryServiceException;
+    method public deprecated int getRecoveryStatus(java.lang.String, java.lang.String) throws android.security.keystore.recovery.InternalRecoveryServiceException;
+    method public int getRecoveryStatus(java.lang.String) throws android.security.keystore.recovery.InternalRecoveryServiceException;
     method public void initRecoveryService(java.lang.String, byte[]) throws java.security.cert.CertificateException, android.security.keystore.recovery.InternalRecoveryServiceException;
     method public void recoverySecretAvailable(android.security.keystore.recovery.KeyChainProtectionParams) throws android.security.keystore.recovery.InternalRecoveryServiceException;
     method public void removeKey(java.lang.String) throws android.security.keystore.recovery.InternalRecoveryServiceException;
     method public void setRecoverySecretTypes(int[]) throws android.security.keystore.recovery.InternalRecoveryServiceException;
-    method public void setRecoveryStatus(java.lang.String, java.lang.String, int) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.content.pm.PackageManager.NameNotFoundException;
+    method public deprecated void setRecoveryStatus(java.lang.String, java.lang.String, int) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.content.pm.PackageManager.NameNotFoundException;
+    method public void setRecoveryStatus(java.lang.String, int) throws android.security.keystore.recovery.InternalRecoveryServiceException;
     method public void setServerParams(byte[]) throws android.security.keystore.recovery.InternalRecoveryServiceException;
     method public void setSnapshotCreatedPendingIntent(android.app.PendingIntent) throws android.security.keystore.recovery.InternalRecoveryServiceException;
-    field public static final int RECOVERY_STATUS_MISSING_ACCOUNT = 2; // 0x2
     field public static final int RECOVERY_STATUS_PERMANENT_FAILURE = 3; // 0x3
     field public static final int RECOVERY_STATUS_SYNCED = 0; // 0x0
     field public static final int RECOVERY_STATUS_SYNC_IN_PROGRESS = 1; // 0x1
@@ -4307,7 +4328,8 @@
   public class RecoverySession implements java.lang.AutoCloseable {
     method public void close();
     method public java.util.Map<java.lang.String, byte[]> recoverKeys(byte[], java.util.List<android.security.keystore.recovery.WrappedApplicationKey>) throws android.security.keystore.recovery.DecryptionFailedException, android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.SessionExpiredException;
-    method public byte[] start(byte[], byte[], byte[], java.util.List<android.security.keystore.recovery.KeyChainProtectionParams>) throws java.security.cert.CertificateException, android.security.keystore.recovery.InternalRecoveryServiceException;
+    method public deprecated byte[] start(byte[], byte[], byte[], java.util.List<android.security.keystore.recovery.KeyChainProtectionParams>) throws java.security.cert.CertificateException, android.security.keystore.recovery.InternalRecoveryServiceException;
+    method public byte[] start(java.security.cert.CertPath, byte[], byte[], java.util.List<android.security.keystore.recovery.KeyChainProtectionParams>) throws java.security.cert.CertificateException, android.security.keystore.recovery.InternalRecoveryServiceException;
   }
 
   public class SessionExpiredException extends java.security.GeneralSecurityException {
@@ -4316,7 +4338,7 @@
 
   public final class WrappedApplicationKey implements android.os.Parcelable {
     method public int describeContents();
-    method public byte[] getAccount();
+    method public deprecated byte[] getAccount();
     method public java.lang.String getAlias();
     method public byte[] getEncryptedKeyMaterial();
     method public void writeToParcel(android.os.Parcel, int);
@@ -4326,7 +4348,7 @@
   public static class WrappedApplicationKey.Builder {
     ctor public WrappedApplicationKey.Builder();
     method public android.security.keystore.recovery.WrappedApplicationKey build();
-    method public android.security.keystore.recovery.WrappedApplicationKey.Builder setAccount(byte[]);
+    method public deprecated android.security.keystore.recovery.WrappedApplicationKey.Builder setAccount(byte[]);
     method public android.security.keystore.recovery.WrappedApplicationKey.Builder setAlias(java.lang.String);
     method public android.security.keystore.recovery.WrappedApplicationKey.Builder setEncryptedKeyMaterial(byte[]);
   }
@@ -5212,6 +5234,7 @@
     method public int describeContents();
     method public int getCarrierPrivilegeStatus(android.content.pm.PackageInfo);
     method public int getCarrierPrivilegeStatus(android.content.pm.Signature, java.lang.String);
+    method public java.lang.String getCertificateHexString();
     method public java.lang.String getPackageName();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.telephony.UiccAccessRule> CREATOR;
@@ -5973,7 +5996,6 @@
     method public void setUiTtyMode(int, android.os.Message);
     method public int shouldProcessCall(java.lang.String[]);
     field public static final int PROCESS_CALL_CSFB = 1; // 0x1
-    field public static final int PROCESS_CALL_EMERGENCY_CSFB = 2; // 0x2
     field public static final int PROCESS_CALL_IMS = 0; // 0x0
   }
 
@@ -6120,7 +6142,9 @@
     method public final void onSmsReceived(int, java.lang.String, byte[]) throws java.lang.RuntimeException;
     method public final void onSmsStatusReportReceived(int, int, java.lang.String, byte[]) throws java.lang.RuntimeException;
     method public void sendSms(int, int, java.lang.String, java.lang.String, boolean, byte[]);
-    field public static final int DELIVER_STATUS_ERROR = 2; // 0x2
+    field public static final int DELIVER_STATUS_ERROR_GENERIC = 2; // 0x2
+    field public static final int DELIVER_STATUS_ERROR_NO_MEMORY = 3; // 0x3
+    field public static final int DELIVER_STATUS_ERROR_REQUEST_NOT_SUPPORTED = 4; // 0x4
     field public static final int DELIVER_STATUS_OK = 1; // 0x1
     field public static final int SEND_STATUS_ERROR = 2; // 0x2
     field public static final int SEND_STATUS_ERROR_FALLBACK = 4; // 0x4
@@ -6157,12 +6181,7 @@
 
 package android.telephony.mbms {
 
-  public final class DownloadRequest implements android.os.Parcelable {
-    method public byte[] getOpaqueData();
-  }
-
   public static class DownloadRequest.Builder {
-    method public android.telephony.mbms.DownloadRequest.Builder setOpaqueData(byte[]);
     method public android.telephony.mbms.DownloadRequest.Builder setServiceId(java.lang.String);
   }
 
diff --git a/api/test-current.txt b/api/test-current.txt
index 92251f7..bc43692 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -12,6 +12,7 @@
   public class ActivityManager {
     method public void addOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener, int);
     method public int getPackageImportance(java.lang.String);
+    method public long getTotalRam();
     method public int getUidImportance(int);
     method public void removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener);
     method public void removeStacksInWindowingModes(int[]) throws java.lang.SecurityException;
@@ -47,7 +48,10 @@
 
   public class AppOpsManager {
     method public static java.lang.String[] getOpStrs();
+    method public boolean isOperationActive(int, int, java.lang.String);
     method public void setMode(int, int, java.lang.String, int);
+    method public void startWatchingActive(int[], android.app.AppOpsManager.OnOpActiveChangedListener);
+    method public void stopWatchingActive(android.app.AppOpsManager.OnOpActiveChangedListener);
     field public static final java.lang.String OPSTR_ACCEPT_HANDOVER = "android:accept_handover";
     field public static final java.lang.String OPSTR_ACCESS_NOTIFICATIONS = "android:access_notifications";
     field public static final java.lang.String OPSTR_ACTIVATE_VPN = "android:activate_vpn";
@@ -89,6 +93,12 @@
     field public static final java.lang.String OPSTR_WRITE_ICC_SMS = "android:write_icc_sms";
     field public static final java.lang.String OPSTR_WRITE_SMS = "android:write_sms";
     field public static final java.lang.String OPSTR_WRITE_WALLPAPER = "android:write_wallpaper";
+    field public static final int OP_RECORD_AUDIO = 27; // 0x1b
+    field public static final int OP_SYSTEM_ALERT_WINDOW = 24; // 0x18
+  }
+
+  public static abstract interface AppOpsManager.OnOpActiveChangedListener {
+    method public abstract void onOpActiveChanged(int, int, java.lang.String, boolean);
   }
 
   public final class NotificationChannelGroup implements android.os.Parcelable {
@@ -167,6 +177,17 @@
 
 }
 
+package android.app.backup {
+
+  public class BackupManager {
+    method public android.content.Intent getConfigurationIntent(java.lang.String);
+    method public android.content.Intent getDataManagementIntent(java.lang.String);
+    method public java.lang.String getDataManagementLabel(java.lang.String);
+    method public java.lang.String getDestinationString(java.lang.String);
+  }
+
+}
+
 package android.app.usage {
 
   public class StorageStatsManager {
@@ -216,6 +237,7 @@
   }
 
   public class PermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
+    field public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 65536; // 0x10000
     field public static final int PROTECTION_FLAG_VENDOR_PRIVILEGED = 32768; // 0x8000
   }
 
@@ -339,6 +361,7 @@
 
   public final class DisplayManager {
     method public java.util.List<android.hardware.display.BrightnessChangeEvent> getBrightnessEvents();
+    method public android.graphics.Point getStableDisplaySize();
     method public void setBrightnessConfiguration(android.hardware.display.BrightnessConfiguration);
   }
 
@@ -434,6 +457,10 @@
 
 package android.os {
 
+  public static class Build.VERSION {
+    field public static final int RESOURCES_SDK_INT;
+  }
+
   public class IncidentManager {
     method public void reportIncident(android.os.IncidentReportArgs);
     method public void reportIncident(java.lang.String, byte[]);
@@ -720,6 +747,10 @@
     field public static final java.lang.String MBMS_STREAMING_SERVICE_OVERRIDE_METADATA = "mbms-streaming-service-override";
   }
 
+  public class ServiceState implements android.os.Parcelable {
+    method public void setSystemAndNetworkId(int, int);
+  }
+
 }
 
 package android.telephony.mbms {
@@ -1096,6 +1127,11 @@
     method public android.graphics.Bitmap getContent();
     method public static android.graphics.PointF getMagnifierDefaultSize();
     method public android.graphics.Rect getWindowPositionOnScreen();
+    method public void setOnOperationCompleteCallback(android.widget.Magnifier.Callback);
+  }
+
+  public static abstract interface Magnifier.Callback {
+    method public abstract void onOperationComplete();
   }
 
   public class NumberPicker extends android.widget.LinearLayout {
diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
index e87a78e..84a04e5 100644
--- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
+++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
@@ -297,6 +297,10 @@
             super.backupFinished(status);
             System.out.println("Backup finished with result: "
                     + convertBackupStatusToString(status));
+            if (status == BackupManager.ERROR_BACKUP_CANCELLED) {
+                System.out.println("Backups can be cancelled if a backup is already running, check "
+                                + "backup dumpsys");
+            }
         }
     }
 
@@ -318,7 +322,7 @@
             case BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED:
                 return "Size quota exceeded";
             case BackupManager.ERROR_BACKUP_CANCELLED:
-                return "Backup Cancelled";
+                return "Backup cancelled";
             default:
                 return "Unknown error";
         }
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 54785ca..8ffe5bf 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -29,11 +29,11 @@
 #include <signal.h>
 #include <time.h>
 
+#include <cutils/atomic.h>
 #include <cutils/properties.h>
 
 #include <androidfw/AssetManager.h>
 #include <binder/IPCThreadState.h>
-#include <utils/Atomic.h>
 #include <utils/Errors.h>
 #include <utils/Log.h>
 #include <utils/SystemClock.h>
diff --git a/cmds/incident_helper/src/parsers/PageTypeInfoParser.cpp b/cmds/incident_helper/src/parsers/PageTypeInfoParser.cpp
index 45a0e7b..ab4382a 100644
--- a/cmds/incident_helper/src/parsers/PageTypeInfoParser.cpp
+++ b/cmds/incident_helper/src/parsers/PageTypeInfoParser.cpp
@@ -104,7 +104,8 @@
 
                 for (size_t i=0; i<blockHeader.size(); i++) {
                     if (!table.insertField(&proto, blockHeader[i], blockCounts[i+1])) {
-                        return BAD_VALUE;
+                        fprintf(stderr, "Header %s has bad data %s\n", blockHeader[i].c_str(),
+                            blockCounts[i+1].c_str());
                     }
                 }
             } else return BAD_VALUE;
diff --git a/cmds/incidentd/Android.mk b/cmds/incidentd/Android.mk
index d2d24c8..3a47fe1 100644
--- a/cmds/incidentd/Android.mk
+++ b/cmds/incidentd/Android.mk
@@ -15,7 +15,8 @@
 LOCAL_PATH:= $(call my-dir)
 
 # proto files used in incidentd to generate cppstream proto headers.
-PROTO_FILES:= frameworks/base/core/proto/android/util/log.proto
+PROTO_FILES:= frameworks/base/core/proto/android/util/log.proto \
+        frameworks/base/core/proto/android/os/data.proto
 
 # ========= #
 # incidentd #
@@ -25,16 +26,7 @@
 
 LOCAL_MODULE := incidentd
 
-LOCAL_SRC_FILES := \
-        src/PrivacyBuffer.cpp \
-        src/FdBuffer.cpp \
-        src/IncidentService.cpp \
-        src/Privacy.cpp \
-        src/Reporter.cpp \
-        src/Section.cpp \
-        src/incidentd_util.cpp \
-        src/main.cpp \
-        src/report_directory.cpp
+LOCAL_SRC_FILES := $(call all-cpp-files-under, src) \
 
 LOCAL_CFLAGS += \
         -Wall -Werror -Wno-missing-field-initializers -Wno-unused-variable -Wunused-parameter
@@ -110,19 +102,15 @@
 
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
 
-LOCAL_SRC_FILES := \
+LOCAL_SRC_FILES := $(call all-cpp-files-under, tests) \
     src/PrivacyBuffer.cpp \
     src/FdBuffer.cpp \
     src/Privacy.cpp \
     src/Reporter.cpp \
     src/Section.cpp \
+    src/Throttler.cpp \
     src/incidentd_util.cpp \
     src/report_directory.cpp \
-    tests/section_list.cpp \
-    tests/PrivacyBuffer_test.cpp \
-    tests/FdBuffer_test.cpp \
-    tests/Reporter_test.cpp \
-    tests/Section_test.cpp \
 
 LOCAL_STATIC_LIBRARIES := \
     libgmock \
@@ -144,7 +132,7 @@
 LOCAL_MODULE_CLASS := NATIVE_TESTS
 gen_src_dir := $(local-generated-sources-dir)
 # generate cppstream proto for testing
-GEN_PROTO := $(gen_src_dir)/log.proto.timestamp
+GEN_PROTO := $(gen_src_dir)/test.proto.timestamp
 $(GEN_PROTO): $(HOST_OUT_EXECUTABLES)/aprotoc $(HOST_OUT_EXECUTABLES)/protoc-gen-cppstream $(PROTO_FILES)
 $(GEN_PROTO): PRIVATE_GEN_SRC_DIR := $(gen_src_dir)
 $(GEN_PROTO): PRIVATE_CUSTOM_TOOL = \
diff --git a/cmds/incidentd/incidentd.rc b/cmds/incidentd/incidentd.rc
index 1bd1468..6dd8114 100644
--- a/cmds/incidentd/incidentd.rc
+++ b/cmds/incidentd/incidentd.rc
@@ -15,7 +15,7 @@
 service incidentd /system/bin/incidentd
     class main
     user incidentd
-    group incidentd log
+    group incidentd log readproc
 
 on post-fs-data
     # Create directory for incidentd
diff --git a/cmds/incidentd/src/FdBuffer.cpp b/cmds/incidentd/src/FdBuffer.cpp
index 883924c8..64da677 100644
--- a/cmds/incidentd/src/FdBuffer.cpp
+++ b/cmds/incidentd/src/FdBuffer.cpp
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#define DEBUG false
 #include "Log.h"
 
 #include "FdBuffer.h"
@@ -75,6 +76,7 @@
                         return -errno;
                     }
                 } else if (amt == 0) {
+                    VLOG("Reached EOF of fd=%d", fd);
                     break;
                 }
                 mBuffer.wp()->move(amt);
@@ -155,10 +157,10 @@
                 if (!(errno == EAGAIN || errno == EWOULDBLOCK)) {
                     VLOG("Fail to read fd %d: %s", fd, strerror(errno));
                     return -errno;
-                }                   // otherwise just continue
-            } else if (amt == 0) {  // reach EOF so don't have to poll pfds[0].
-                ::close(pfds[0].fd);
-                pfds[0].fd = -1;
+                }  // otherwise just continue
+            } else if (amt == 0) {
+                VLOG("Reached EOF of input file %d", fd);
+                pfds[0].fd = -1;  // reach EOF so don't have to poll pfds[0].
             } else {
                 rpos += amt;
                 cirSize += amt;
@@ -186,6 +188,7 @@
 
         // if buffer is empty and fd is closed, close write fd.
         if (cirSize == 0 && pfds[0].fd == -1 && pfds[1].fd != -1) {
+            VLOG("Close write pipe %d", toFd);
             ::close(pfds[1].fd);
             pfds[1].fd = -1;
         }
@@ -206,6 +209,7 @@
                 return -errno;
             }  // otherwise just continue
         } else if (amt == 0) {
+            VLOG("Reached EOF of fromFd %d", fromFd);
             break;
         } else {
             mBuffer.wp()->move(amt);
diff --git a/cmds/incidentd/src/FdBuffer.h b/cmds/incidentd/src/FdBuffer.h
index 5bfa093..66a3de1 100644
--- a/cmds/incidentd/src/FdBuffer.h
+++ b/cmds/incidentd/src/FdBuffer.h
@@ -26,7 +26,7 @@
 using namespace std;
 
 /**
- * Reads a file into a buffer, and then writes that data to an FdSet.
+ * Reads data from fd into a buffer, fd must be closed explicitly.
  */
 class FdBuffer {
 public:
@@ -83,6 +83,11 @@
      */
     EncodedBuffer::iterator data() const;
 
+    /**
+     * Return the internal buffer, don't call unless you are familiar with EncodedBuffer.
+     */
+    EncodedBuffer* getInternalBuffer() { return &mBuffer; }
+
 private:
     EncodedBuffer mBuffer;
     int64_t mStartTime;
diff --git a/cmds/incidentd/src/IncidentService.cpp b/cmds/incidentd/src/IncidentService.cpp
index 9ae6240..28fb38a 100644
--- a/cmds/incidentd/src/IncidentService.cpp
+++ b/cmds/incidentd/src/IncidentService.cpp
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#define DEBUG false
 #include "Log.h"
 
 #include "IncidentService.h"
@@ -38,9 +39,11 @@
 
 enum { WHAT_RUN_REPORT = 1, WHAT_SEND_BACKLOG_TO_DROPBOX = 2 };
 
-//#define DEFAULT_BACKLOG_DELAY_NS (1000000000LL * 60 * 5)
 #define DEFAULT_BACKLOG_DELAY_NS (1000000000LL)
 
+#define DEFAULT_BYTES_SIZE_LIMIT (20 * 1024 * 1024)        // 20MB
+#define DEFAULT_REFACTORY_PERIOD_MS (24 * 60 * 60 * 1000)  // 1 Day
+
 // ================================================================================
 String16 const DUMP_PERMISSION("android.permission.DUMP");
 String16 const USAGE_STATS_PERMISSION("android.permission.PACKAGE_USAGE_STATS");
@@ -113,8 +116,12 @@
 }
 
 // ================================================================================
-ReportHandler::ReportHandler(const sp<Looper>& handlerLooper, const sp<ReportRequestQueue>& queue)
-    : mBacklogDelay(DEFAULT_BACKLOG_DELAY_NS), mHandlerLooper(handlerLooper), mQueue(queue) {}
+ReportHandler::ReportHandler(const sp<Looper>& handlerLooper, const sp<ReportRequestQueue>& queue,
+                             const sp<Throttler>& throttler)
+    : mBacklogDelay(DEFAULT_BACKLOG_DELAY_NS),
+      mHandlerLooper(handlerLooper),
+      mQueue(queue),
+      mThrottler(throttler) {}
 
 ReportHandler::~ReportHandler() {}
 
@@ -159,10 +166,17 @@
         reporter->batch.add(request);
     }
 
+    if (mThrottler->shouldThrottle()) {
+        ALOGW("RunReport got throttled.");
+        return;
+    }
+
     // Take the report, which might take a while. More requests might queue
     // up while we're doing this, and we'll handle them in their next batch.
     // TODO: We should further rate-limit the reports to no more than N per time-period.
-    Reporter::run_report_status_t reportStatus = reporter->runReport();
+    size_t reportByteSize = 0;
+    Reporter::run_report_status_t reportStatus = reporter->runReport(&reportByteSize);
+    mThrottler->addReportSize(reportByteSize);
     if (reportStatus == Reporter::REPORT_NEEDS_DROPBOX) {
         unique_lock<mutex> lock(mLock);
         schedule_send_backlog_to_dropbox_locked();
@@ -184,8 +198,9 @@
 
 // ================================================================================
 IncidentService::IncidentService(const sp<Looper>& handlerLooper)
-    : mQueue(new ReportRequestQueue()) {
-    mHandler = new ReportHandler(handlerLooper, mQueue);
+    : mQueue(new ReportRequestQueue()),
+      mThrottler(new Throttler(DEFAULT_BYTES_SIZE_LIMIT, DEFAULT_REFACTORY_PERIOD_MS)) {
+    mHandler = new ReportHandler(handlerLooper, mQueue, mThrottler);
 }
 
 IncidentService::~IncidentService() {}
@@ -294,6 +309,10 @@
         if (!args[0].compare(String8("privacy"))) {
             return cmd_privacy(in, out, err, args);
         }
+        if (!args[0].compare(String8("throttler"))) {
+            mThrottler->dump(out);
+            return NO_ERROR;
+        }
     }
     return cmd_help(out);
 }
@@ -302,6 +321,9 @@
     fprintf(out, "usage: adb shell cmd incident privacy print <section_id>\n");
     fprintf(out, "usage: adb shell cmd incident privacy parse <section_id> < proto.txt\n");
     fprintf(out, "    Prints/parses for the section id.\n");
+    fprintf(out, "\n");
+    fprintf(out, "usage: adb shell cmd incident throttler\n");
+    fprintf(out, "    Prints the current throttler state\n");
     return NO_ERROR;
 }
 
diff --git a/cmds/incidentd/src/IncidentService.h b/cmds/incidentd/src/IncidentService.h
index 3c66507..0ab34ed 100644
--- a/cmds/incidentd/src/IncidentService.h
+++ b/cmds/incidentd/src/IncidentService.h
@@ -26,6 +26,8 @@
 #include <deque>
 #include <mutex>
 
+#include "Throttler.h"
+
 using namespace android;
 using namespace android::base;
 using namespace android::binder;
@@ -49,7 +51,8 @@
 // ================================================================================
 class ReportHandler : public MessageHandler {
 public:
-    ReportHandler(const sp<Looper>& handlerLooper, const sp<ReportRequestQueue>& queue);
+    ReportHandler(const sp<Looper>& handlerLooper, const sp<ReportRequestQueue>& queue,
+                  const sp<Throttler>& throttler);
     virtual ~ReportHandler();
 
     virtual void handleMessage(const Message& message);
@@ -70,6 +73,7 @@
     nsecs_t mBacklogDelay;
     sp<Looper> mHandlerLooper;
     sp<ReportRequestQueue> mQueue;
+    sp<Throttler> mThrottler;
 
     /**
      * Runs all of the reports that have been queued.
@@ -109,6 +113,7 @@
 private:
     sp<ReportRequestQueue> mQueue;
     sp<ReportHandler> mHandler;
+    sp<Throttler> mThrottler;
 
     /**
      * Commands print out help.
diff --git a/cmds/incidentd/src/Log.h b/cmds/incidentd/src/Log.h
index 46efbd1..22de46d 100644
--- a/cmds/incidentd/src/Log.h
+++ b/cmds/incidentd/src/Log.h
@@ -23,7 +23,6 @@
 #pragma once
 
 #define LOG_TAG "incidentd"
-#define DEBUG false
 
 #include <log/log.h>
 
diff --git a/cmds/incidentd/src/PrivacyBuffer.cpp b/cmds/incidentd/src/PrivacyBuffer.cpp
index e4128f4..ee57f4d 100644
--- a/cmds/incidentd/src/PrivacyBuffer.cpp
+++ b/cmds/incidentd/src/PrivacyBuffer.cpp
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#define DEBUG false
 #include "Log.h"
 
 #include "PrivacyBuffer.h"
diff --git a/cmds/incidentd/src/Reporter.cpp b/cmds/incidentd/src/Reporter.cpp
index c0b5358..12764f8 100644
--- a/cmds/incidentd/src/Reporter.cpp
+++ b/cmds/incidentd/src/Reporter.cpp
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#define DEBUG false
 #include "Log.h"
 
 #include "Reporter.h"
@@ -118,7 +119,7 @@
 
 Reporter::~Reporter() {}
 
-Reporter::run_report_status_t Reporter::runReport() {
+Reporter::run_report_status_t Reporter::runReport(size_t* reportByteSize) {
     status_t err = NO_ERROR;
     bool needMainFd = false;
     int mainFd = -1;
@@ -185,7 +186,6 @@
             int64_t startTime = uptimeMillis();
             err = (*section)->Execute(&batch);
             int64_t endTime = uptimeMillis();
-
             stats->set_success(err == NO_ERROR);
             stats->set_exec_duration_ms(endTime - startTime);
             if (err != NO_ERROR) {
@@ -193,6 +193,7 @@
                       (*section)->name.string(), id, strerror(-err));
                 goto DONE;
             }
+            (*reportByteSize) += stats->report_size_bytes();
 
             // Notify listener of starting
             for (ReportRequestSet::iterator it = batch.begin(); it != batch.end(); it++) {
diff --git a/cmds/incidentd/src/Reporter.h b/cmds/incidentd/src/Reporter.h
index 0f3f221..ba8965e 100644
--- a/cmds/incidentd/src/Reporter.h
+++ b/cmds/incidentd/src/Reporter.h
@@ -18,8 +18,6 @@
 #ifndef REPORTER_H
 #define REPORTER_H
 
-#include "frameworks/base/libs/incident/proto/android/os/metadata.pb.h"
-
 #include <android/os/IIncidentReportStatusListener.h>
 #include <android/os/IncidentReportArgs.h>
 
@@ -29,6 +27,9 @@
 
 #include <time.h>
 
+#include "Throttler.h"
+#include "frameworks/base/libs/incident/proto/android/os/metadata.pb.h"
+
 using namespace android;
 using namespace android::os;
 using namespace std;
@@ -91,7 +92,7 @@
     virtual ~Reporter();
 
     // Run the report as described in the batch and args parameters.
-    run_report_status_t runReport();
+    run_report_status_t runReport(size_t* reportByteSize);
 
     static run_report_status_t upload_backlog();
 
diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp
index 2e4e980..334d77c 100644
--- a/cmds/incidentd/src/Section.cpp
+++ b/cmds/incidentd/src/Section.cpp
@@ -13,16 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#define DEBUG false
 #include "Log.h"
 
 #include "Section.h"
 
-#include <errno.h>
-#include <sys/prctl.h>
-#include <unistd.h>
 #include <wait.h>
 
-#include <memory>
 #include <mutex>
 
 #include <android-base/file.h>
@@ -36,6 +33,7 @@
 #include "FdBuffer.h"
 #include "Privacy.h"
 #include "PrivacyBuffer.h"
+#include "frameworks/base/core/proto/android/os/data.proto.h"
 #include "frameworks/base/core/proto/android/util/log.proto.h"
 #include "incidentd_util.h"
 
@@ -51,31 +49,11 @@
 const int WAIT_MAX = 5;
 const struct timespec WAIT_INTERVAL_NS = {0, 200 * 1000 * 1000};
 const char INCIDENT_HELPER[] = "/system/bin/incident_helper";
+const char GZIP[] = "/system/bin/gzip";
 
-static pid_t fork_execute_incident_helper(const int id, const char* name, Fpipe& p2cPipe,
-                                          Fpipe& c2pPipe) {
+static pid_t fork_execute_incident_helper(const int id, Fpipe* p2cPipe, Fpipe* c2pPipe) {
     const char* ihArgs[]{INCIDENT_HELPER, "-s", String8::format("%d", id).string(), NULL};
-    // fork used in multithreaded environment, avoid adding unnecessary code in child process
-    pid_t pid = fork();
-    if (pid == 0) {
-        if (TEMP_FAILURE_RETRY(dup2(p2cPipe.readFd(), STDIN_FILENO)) != 0 || !p2cPipe.close() ||
-            TEMP_FAILURE_RETRY(dup2(c2pPipe.writeFd(), STDOUT_FILENO)) != 1 || !c2pPipe.close()) {
-            ALOGW("%s can't setup stdin and stdout for incident helper", name);
-            _exit(EXIT_FAILURE);
-        }
-
-        /* make sure the child dies when incidentd dies */
-        prctl(PR_SET_PDEATHSIG, SIGKILL);
-
-        execv(INCIDENT_HELPER, const_cast<char**>(ihArgs));
-
-        ALOGW("%s failed in incident helper process: %s", name, strerror(errno));
-        _exit(EXIT_FAILURE);  // always exits with failure if any
-    }
-    // close the fds used in incident helper
-    close(p2cPipe.readFd());
-    close(c2pPipe.writeFd());
-    return pid;
+    return fork_execute_cmd(INCIDENT_HELPER, const_cast<char**>(ihArgs), p2cPipe, c2pPipe);
 }
 
 // ================================================================================
@@ -244,7 +222,8 @@
     }
     if (requests->mainFd() >= 0 && !metadataBuf.empty()) {
         write_section_header(requests->mainFd(), id, metadataBuf.size());
-        if (!WriteFully(requests->mainFd(), (uint8_t const*)metadataBuf.data(), metadataBuf.size())) {
+        if (!WriteFully(requests->mainFd(), (uint8_t const*)metadataBuf.data(),
+                        metadataBuf.size())) {
             ALOGW("Failed to write metadata to dropbox fd %d", requests->mainFd());
             return -1;
         }
@@ -252,10 +231,12 @@
     return NO_ERROR;
 }
 // ================================================================================
+static inline bool isSysfs(const char* filename) { return strncmp(filename, "/sys/", 5) == 0; }
+
 FileSection::FileSection(int id, const char* filename, const int64_t timeoutMs)
     : Section(id, timeoutMs), mFilename(filename) {
     name = filename;
-    mIsSysfs = strncmp(filename, "/sys/", 5) == 0;
+    mIsSysfs = isSysfs(filename);
 }
 
 FileSection::~FileSection() {}
@@ -278,7 +259,7 @@
         return -errno;
     }
 
-    pid_t pid = fork_execute_incident_helper(this->id, this->name.string(), p2cPipe, c2pPipe);
+    pid_t pid = fork_execute_incident_helper(this->id, &p2cPipe, &c2pPipe);
     if (pid == -1) {
         ALOGW("FileSection '%s' failed to fork", this->name.string());
         return -errno;
@@ -287,6 +268,8 @@
     // parent process
     status_t readStatus = buffer.readProcessedDataInStream(fd, p2cPipe.writeFd(), c2pPipe.readFd(),
                                                            this->timeoutMs, mIsSysfs);
+    close(fd);  // close the fd anyway.
+
     if (readStatus != NO_ERROR || buffer.timedOut()) {
         ALOGW("FileSection '%s' failed to read data from incident helper: %s, timedout: %s",
               this->name.string(), strerror(-readStatus), buffer.timedOut() ? "true" : "false");
@@ -311,7 +294,99 @@
 
     return NO_ERROR;
 }
+// ================================================================================
+GZipSection::GZipSection(int id, const char* filename, ...) : Section(id) {
+    name = "gzip ";
+    name += filename;
+    va_list args;
+    va_start(args, filename);
+    mFilenames = varargs(filename, args);
+    va_end(args);
+}
 
+GZipSection::~GZipSection() {}
+
+status_t GZipSection::Execute(ReportRequestSet* requests) const {
+    // Reads the files in order, use the first available one.
+    int index = 0;
+    int fd = -1;
+    while (mFilenames[index] != NULL) {
+        fd = open(mFilenames[index], O_RDONLY | O_CLOEXEC);
+        if (fd != -1) {
+            break;
+        }
+        ALOGW("GZipSection failed to open file %s", mFilenames[index]);
+        index++;  // look at the next file.
+    }
+    VLOG("GZipSection is using file %s, fd=%d", mFilenames[index], fd);
+    if (fd == -1) return -1;
+
+    FdBuffer buffer;
+    Fpipe p2cPipe;
+    Fpipe c2pPipe;
+    // initiate pipes to pass data to/from gzip
+    if (!p2cPipe.init() || !c2pPipe.init()) {
+        ALOGW("GZipSection '%s' failed to setup pipes", this->name.string());
+        return -errno;
+    }
+
+    const char* gzipArgs[]{GZIP, NULL};
+    pid_t pid = fork_execute_cmd(GZIP, const_cast<char**>(gzipArgs), &p2cPipe, &c2pPipe);
+    if (pid == -1) {
+        ALOGW("GZipSection '%s' failed to fork", this->name.string());
+        return -errno;
+    }
+    // parent process
+
+    // construct Fdbuffer to output GZippedfileProto, the reason to do this instead of using
+    // ProtoOutputStream is to avoid allocation of another buffer inside ProtoOutputStream.
+    EncodedBuffer* internalBuffer = buffer.getInternalBuffer();
+    internalBuffer->writeHeader((uint32_t)GZippedFileProto::FILENAME, WIRE_TYPE_LENGTH_DELIMITED);
+    String8 usedFile(mFilenames[index]);
+    internalBuffer->writeRawVarint32(usedFile.size());
+    for (size_t i = 0; i < usedFile.size(); i++) {
+        internalBuffer->writeRawByte(mFilenames[index][i]);
+    }
+    internalBuffer->writeHeader((uint32_t)GZippedFileProto::GZIPPED_DATA,
+                                WIRE_TYPE_LENGTH_DELIMITED);
+    size_t editPos = internalBuffer->wp()->pos();
+    internalBuffer->wp()->move(8);  // reserve 8 bytes for the varint of the data size.
+    size_t dataBeginAt = internalBuffer->wp()->pos();
+    VLOG("GZipSection '%s' editPos=%zd, dataBeginAt=%zd", this->name.string(), editPos,
+         dataBeginAt);
+
+    status_t readStatus = buffer.readProcessedDataInStream(
+            fd, p2cPipe.writeFd(), c2pPipe.readFd(), this->timeoutMs, isSysfs(mFilenames[index]));
+    close(fd);  // close the fd anyway.
+
+    if (readStatus != NO_ERROR || buffer.timedOut()) {
+        ALOGW("GZipSection '%s' failed to read data from gzip: %s, timedout: %s",
+              this->name.string(), strerror(-readStatus), buffer.timedOut() ? "true" : "false");
+        kill_child(pid);
+        return readStatus;
+    }
+
+    status_t gzipStatus = wait_child(pid);
+    if (gzipStatus != NO_ERROR) {
+        ALOGW("GZipSection '%s' abnormal child process: %s", this->name.string(),
+              strerror(-gzipStatus));
+        return gzipStatus;
+    }
+    // Revisit the actual size from gzip result and edit the internal buffer accordingly.
+    size_t dataSize = buffer.size() - dataBeginAt;
+    internalBuffer->wp()->rewind()->move(editPos);
+    internalBuffer->writeRawVarint32(dataSize);
+    internalBuffer->copy(dataBeginAt, dataSize);
+    VLOG("GZipSection '%s' wrote %zd bytes in %d ms, dataSize=%zd", this->name.string(),
+         buffer.size(), (int)buffer.durationMs(), dataSize);
+    status_t err = write_report_requests(this->id, buffer, requests);
+    if (err != NO_ERROR) {
+        ALOGW("GZipSection '%s' failed writing: %s", this->name.string(), strerror(-err));
+        return err;
+    }
+
+    return NO_ERROR;
+}
 // ================================================================================
 struct WorkerThreadData : public virtual RefBase {
     const WorkerThreadSection* section;
@@ -455,42 +530,20 @@
 }
 
 // ================================================================================
-void CommandSection::init(const char* command, va_list args) {
-    va_list copied_args;
-    int numOfArgs = 0;
-
-    va_copy(copied_args, args);
-    while (va_arg(copied_args, const char*) != NULL) {
-        numOfArgs++;
-    }
-    va_end(copied_args);
-
-    // allocate extra 1 for command and 1 for NULL terminator
-    mCommand = (const char**)malloc(sizeof(const char*) * (numOfArgs + 2));
-
-    mCommand[0] = command;
-    name = command;
-    for (int i = 0; i < numOfArgs; i++) {
-        const char* arg = va_arg(args, const char*);
-        mCommand[i + 1] = arg;
-        name += " ";
-        name += arg;
-    }
-    mCommand[numOfArgs + 1] = NULL;
-}
-
 CommandSection::CommandSection(int id, const int64_t timeoutMs, const char* command, ...)
     : Section(id, timeoutMs) {
+    name = command;
     va_list args;
     va_start(args, command);
-    init(command, args);
+    mCommand = varargs(command, args);
     va_end(args);
 }
 
 CommandSection::CommandSection(int id, const char* command, ...) : Section(id) {
+    name = command;
     va_list args;
     va_start(args, command);
-    init(command, args);
+    mCommand = varargs(command, args);
     va_end(args);
 }
 
@@ -525,7 +578,7 @@
               strerror(errno));
         _exit(err);  // exit with command error code
     }
-    pid_t ihPid = fork_execute_incident_helper(this->id, this->name.string(), cmdPipe, ihPipe);
+    pid_t ihPid = fork_execute_incident_helper(this->id, &cmdPipe, &ihPipe);
     if (ihPid == -1) {
         ALOGW("CommandSection '%s' failed to fork", this->name.string());
         return -errno;
@@ -542,8 +595,7 @@
     }
 
     // TODO: wait for command here has one trade-off: the failed status of command won't be detected
-    // until
-    //       buffer timeout, but it has advatage on starting the data stream earlier.
+    // until buffer timeout, but it has advatage on starting the data stream earlier.
     status_t cmdStatus = wait_child(cmdPid);
     status_t ihStatus = wait_child(ihPid);
     if (cmdStatus != NO_ERROR || ihStatus != NO_ERROR) {
diff --git a/cmds/incidentd/src/Section.h b/cmds/incidentd/src/Section.h
index d644681..8294be1 100644
--- a/cmds/incidentd/src/Section.h
+++ b/cmds/incidentd/src/Section.h
@@ -84,6 +84,21 @@
 };
 
 /**
+ * Section that reads in a file and gzips the content.
+ */
+class GZipSection : public Section {
+public:
+    GZipSection(int id, const char* filename, ...);
+    virtual ~GZipSection();
+
+    virtual status_t Execute(ReportRequestSet* requests) const;
+
+private:
+    // It looks up the content from multiple files and stops when the first one is available.
+    const char** mFilenames;
+};
+
+/**
  * Base class for sections that call a command that might need a timeout.
  */
 class WorkerThreadSection : public Section {
@@ -111,8 +126,6 @@
 
 private:
     const char** mCommand;
-
-    void init(const char* command, va_list args);
 };
 
 /**
diff --git a/cmds/incidentd/src/Throttler.cpp b/cmds/incidentd/src/Throttler.cpp
new file mode 100644
index 0000000..1abf267
--- /dev/null
+++ b/cmds/incidentd/src/Throttler.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 DEBUG false
+#include "Log.h"
+
+#include "Throttler.h"
+
+#include <utils/SystemClock.h>
+
+Throttler::Throttler(size_t limit, int64_t refractoryPeriodMs)
+    : mSizeLimit(limit),
+      mRefractoryPeriodMs(refractoryPeriodMs),
+      mAccumulatedSize(0),
+      mLastRefractoryMs(android::elapsedRealtime()) {}
+
+Throttler::~Throttler() {}
+
+bool Throttler::shouldThrottle() {
+    int64_t now = android::elapsedRealtime();
+    if (now > mRefractoryPeriodMs + mLastRefractoryMs) {
+        mLastRefractoryMs = now;
+        mAccumulatedSize = 0;
+    }
+    return mAccumulatedSize > mSizeLimit;
+}
+
+void Throttler::addReportSize(size_t reportByteSize) {
+    VLOG("The current request took %d bytes to dropbox", (int)reportByteSize);
+    mAccumulatedSize += reportByteSize;
+}
+
+void Throttler::dump(FILE* out) {
+    fprintf(out, "mSizeLimit=%d\n", (int)mSizeLimit);
+    fprintf(out, "mAccumulatedSize=%d\n", (int)mAccumulatedSize);
+    fprintf(out, "mRefractoryPeriodMs=%d\n", (int)mRefractoryPeriodMs);
+    fprintf(out, "mLastRefractoryMs=%d\n", (int)mLastRefractoryMs);
+}
diff --git a/cmds/incidentd/src/Throttler.h b/cmds/incidentd/src/Throttler.h
new file mode 100644
index 0000000..c56f753
--- /dev/null
+++ b/cmds/incidentd/src/Throttler.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 THROTTLER_H
+#define THROTTLER_H
+
+#include <utils/RefBase.h>
+
+#include <unistd.h>
+/**
+ * This is a size-based throttler which prevents incidentd to take more data.
+ */
+class Throttler : public virtual android::RefBase {
+public:
+    Throttler(size_t limit, int64_t refractoryPeriodMs);
+    ~Throttler();
+
+    /**
+     * Asserts this before starting taking report.
+     */
+    bool shouldThrottle();
+
+    void addReportSize(size_t reportByteSize);
+
+    void dump(FILE* out);
+
+private:
+    const size_t mSizeLimit;
+    const int64_t mRefractoryPeriodMs;
+
+    size_t mAccumulatedSize;
+    int64_t mLastRefractoryMs;
+};
+
+#endif  // THROTTLER_H
diff --git a/cmds/incidentd/src/incidentd_util.cpp b/cmds/incidentd/src/incidentd_util.cpp
index 2415860..c095f2b 100644
--- a/cmds/incidentd/src/incidentd_util.cpp
+++ b/cmds/incidentd/src/incidentd_util.cpp
@@ -13,8 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#define DEBUG false
+#include "Log.h"
+
 #include "incidentd_util.h"
 
+#include <sys/prctl.h>
+
 #include "section_list.h"
 
 const Privacy* get_privacy_of_section(int id) {
@@ -50,4 +55,49 @@
 
 int Fpipe::readFd() const { return mRead.get(); }
 
-int Fpipe::writeFd() const { return mWrite.get(); }
\ No newline at end of file
+int Fpipe::writeFd() const { return mWrite.get(); }
+
+pid_t fork_execute_cmd(const char* cmd, char* const argv[], Fpipe* input, Fpipe* output) {
+    // fork used in multithreaded environment, avoid adding unnecessary code in child process
+    pid_t pid = fork();
+    if (pid == 0) {
+        if (TEMP_FAILURE_RETRY(dup2(input->readFd(), STDIN_FILENO)) < 0 || !input->close() ||
+            TEMP_FAILURE_RETRY(dup2(output->writeFd(), STDOUT_FILENO)) < 0 || !output->close()) {
+            ALOGW("Can't setup stdin and stdout for command %s", cmd);
+            _exit(EXIT_FAILURE);
+        }
+
+        /* make sure the child dies when incidentd dies */
+        prctl(PR_SET_PDEATHSIG, SIGKILL);
+
+        execv(cmd, argv);
+
+        ALOGW("%s failed in the child process: %s", cmd, strerror(errno));
+        _exit(EXIT_FAILURE);  // always exits with failure if any
+    }
+    // close the fds used in child process.
+    close(input->readFd());
+    close(output->writeFd());
+    return pid;
+}
+// ================================================================================
+const char** varargs(const char* first, va_list rest) {
+    va_list copied_rest;
+    int numOfArgs = 1;  // first is already count.
+
+    va_copy(copied_rest, rest);
+    while (va_arg(copied_rest, const char*) != NULL) {
+        numOfArgs++;
+    }
+    va_end(copied_rest);
+
+    // allocate extra 1 for NULL terminator
+    const char** ret = (const char**)malloc(sizeof(const char*) * (numOfArgs + 1));
+    ret[0] = first;
+    for (int i = 1; i < numOfArgs; i++) {
+        const char* arg = va_arg(rest, const char*);
+        ret[i] = arg;
+    }
+    ret[numOfArgs] = NULL;
+    return ret;
+}
diff --git a/cmds/incidentd/src/incidentd_util.h b/cmds/incidentd/src/incidentd_util.h
index 09aa040..db7ec82 100644
--- a/cmds/incidentd/src/incidentd_util.h
+++ b/cmds/incidentd/src/incidentd_util.h
@@ -20,12 +20,20 @@
 
 #include <android-base/unique_fd.h>
 
+#include <stdarg.h>
+
 #include "Privacy.h"
 
 using namespace android::base;
 
+/**
+ * Looks up Privacy of a section in the auto-gen PRIVACY_POLICY_LIST;
+ */
 const Privacy* get_privacy_of_section(int id);
 
+/**
+ * This class wraps android::base::Pipe.
+ */
 class Fpipe {
 public:
     Fpipe();
@@ -41,4 +49,15 @@
     unique_fd mWrite;
 };
 
+/**
+ * Forks and exec a command with two pipes, one connects stdin for input,
+ * one connects stdout for output. It returns the pid of the child.
+ */
+pid_t fork_execute_cmd(const char* cmd, char* const argv[], Fpipe* input, Fpipe* output);
+
+/**
+ * Grabs varargs from stack and stores them in heap with NULL-terminated array.
+ */
+const char** varargs(const char* first, va_list rest);
+
 #endif  // INCIDENTD_UTIL_H
\ No newline at end of file
diff --git a/cmds/incidentd/src/report_directory.cpp b/cmds/incidentd/src/report_directory.cpp
index b71c066..f023ee1 100644
--- a/cmds/incidentd/src/report_directory.cpp
+++ b/cmds/incidentd/src/report_directory.cpp
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#define DEBUG false
 #include "Log.h"
 
 #include "report_directory.h"
diff --git a/cmds/incidentd/testdata/kmsg.txt b/cmds/incidentd/testdata/kmsg.txt
new file mode 100644
index 0000000..a8e3c02
--- /dev/null
+++ b/cmds/incidentd/testdata/kmsg.txt
@@ -0,0 +1,47 @@
+[0] bldr_log_init: bldr_log_base=0x83600000, bldr_log_size=458752
+B -    626409 - [INFO][XBL]: Bypass appsbl verification on DEVELOPMENT device
+B -    729255 - [INFO][XBL]: Bypass appsbl verification on DEVELOPMENT device
+B -    729285 - boot_elf_load_and_verify_image: boot_auth_compute_verify_hash for 9:0
+D -    104829 - APPSBL Image Loaded, Delta - (2498816 Bytes)
+B -    729468 - SBL1, End
+D -    643611 - SBL1, Delta
+S - Flash Throughput, 129000 KB/s  (4729638 Bytes,  36613 us)
+S - DDR Frequency, 1017 MHz
+0x400, 0x400
+B -    482296 - Basic DDR tests done
+B -    544638 - clock_init, Start
+D -       244 - clock_init, Delta
+B -    544913 - HTC RPM DATARAM UPDATE info: Done
+B -    545004 - Image Load, Start
+B -    548359 - boot_elf_load_and_verify_image: boot_auth_compute_verify_hash for 5:0
+D -      3386 - QSEE Dev Config Image Loaded, Delta - (46232 Bytes)
+B -    548725 - Image Load, Start
+B -    550860 - boot_elf_load_and_verify_image: boot_auth_compute_verify_hash for 512:0
+D -      2166 - APDP Image Loaded, Delta - (7696 Bytes)
+B -    550891 - Image Load, Start
+B -    601612 - boot_elf_load_and_verify_image: boot_auth_compute_verify_hash for 7:0
+D -     50782 - QSEE Image Loaded, Delta - (1648640 Bytes)
+B -    601704 - Image Load, Start
+D -       244 - SEC Image Loaded, Delta - (4096 Bytes)
+B -    602344 - 0x1310 = 0x24
+B -    602375 - is_above_vbat_weak = 1, pon_reasons (with usb_in checked) = 0x31
+B -    602466 - sbl1_efs_handle_cookies, Start
+D -        91 - sbl1_efs_handle_cookies, Delta
+B -    602558 - Image Load, Start
+B -    613446 - boot_elf_load_and_verify_image: boot_auth_compute_verify_hash for 21:0
+D -     11010 - QHEE Image Loaded, Delta - (258280 Bytes)
+B -    613568 - Image Load, Start
+B -    624274 - boot_elf_load_and_verify_image: boot_auth_compute_verify_hash for 10:0
+D -     10736 - RPM Image Loaded, Delta - (224104 Bytes)
+B -    624335 - Image Load, Start
+D -         0 - STI Image Loaded, Delta - (0 Bytes)
+B -    624548 - Image Load, Start
+m_driver_init, Delta
+B -    471804 - pm_sbl_chg
+ ******************** [ START SECOND] ******************** 
+^@B -    736605 - [INFO][XBL]: Bypass appsbl verification on DEVELOPMENT device
+B -    839451 - [INFO][XBL]: Bypass appsbl verification on DEVELOPMENT device
+B -    839482 - boot_elf_load_and_verify_image: boot_auth_compute_verify_hash for 9:0
+D -    104828 - APPSBL Image Loaded, Delta - (2498816 Bytes)
+B -    839665 - SBL1, End
+D -    753838 - SBL1, Delta
diff --git a/cmds/incidentd/testdata/kmsg.txt.gz b/cmds/incidentd/testdata/kmsg.txt.gz
new file mode 100644
index 0000000..fba449f
--- /dev/null
+++ b/cmds/incidentd/testdata/kmsg.txt.gz
Binary files differ
diff --git a/cmds/incidentd/tests/FdBuffer_test.cpp b/cmds/incidentd/tests/FdBuffer_test.cpp
index 956c8d3..0e5eec6 100644
--- a/cmds/incidentd/tests/FdBuffer_test.cpp
+++ b/cmds/incidentd/tests/FdBuffer_test.cpp
@@ -11,6 +11,7 @@
 // WITHOUT 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 DEBUG false
 #include "Log.h"
 
 #include "FdBuffer.h"
diff --git a/cmds/incidentd/tests/PrivacyBuffer_test.cpp b/cmds/incidentd/tests/PrivacyBuffer_test.cpp
index 7ea9bbf..c7c69a7 100644
--- a/cmds/incidentd/tests/PrivacyBuffer_test.cpp
+++ b/cmds/incidentd/tests/PrivacyBuffer_test.cpp
@@ -11,6 +11,7 @@
 // WITHOUT 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 DEBUG false
 #include "Log.h"
 
 #include "FdBuffer.h"
diff --git a/cmds/incidentd/tests/Reporter_test.cpp b/cmds/incidentd/tests/Reporter_test.cpp
index bd359ac..955dbac 100644
--- a/cmds/incidentd/tests/Reporter_test.cpp
+++ b/cmds/incidentd/tests/Reporter_test.cpp
@@ -11,6 +11,7 @@
 // WITHOUT 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 DEBUG false
 #include "Log.h"
 
 #include "Reporter.h"
@@ -106,6 +107,7 @@
     ReportRequestSet requests;
     sp<Reporter> reporter;
     sp<TestListener> l;
+    size_t size;
 };
 
 TEST_F(ReporterTest, IncidentReportArgs) {
@@ -125,7 +127,7 @@
 }
 
 TEST_F(ReporterTest, RunReportEmpty) {
-    ASSERT_EQ(Reporter::REPORT_FINISHED, reporter->runReport());
+    ASSERT_EQ(Reporter::REPORT_FINISHED, reporter->runReport(&size));
     EXPECT_EQ(l->startInvoked, 0);
     EXPECT_EQ(l->finishInvoked, 0);
     EXPECT_TRUE(l->startSections.empty());
@@ -147,7 +149,7 @@
     reporter->batch.add(r1);
     reporter->batch.add(r2);
 
-    ASSERT_EQ(Reporter::REPORT_FINISHED, reporter->runReport());
+    ASSERT_EQ(Reporter::REPORT_FINISHED, reporter->runReport(&size));
 
     string result;
     ReadFileToString(tf.path, &result);
@@ -171,7 +173,7 @@
     sp<ReportRequest> r = new ReportRequest(args, l, -1);
     reporter->batch.add(r);
 
-    ASSERT_EQ(Reporter::REPORT_FINISHED, reporter->runReport());
+    ASSERT_EQ(Reporter::REPORT_FINISHED, reporter->runReport(&size));
     vector<string> results = InspectFiles();
     ASSERT_EQ((int)results.size(), 1);
     EXPECT_EQ(results[0],
@@ -188,7 +190,7 @@
     sp<ReportRequest> r = new ReportRequest(args, l, -1);
     reporter->batch.add(r);
 
-    ASSERT_EQ(Reporter::REPORT_FINISHED, reporter->runReport());
+    ASSERT_EQ(Reporter::REPORT_FINISHED, reporter->runReport(&size));
     auto metadata = reporter->batch.metadata();
     EXPECT_EQ(IncidentMetadata_Destination_EXPLICIT, metadata.dest());
     EXPECT_EQ(1, metadata.request_size());
diff --git a/cmds/incidentd/tests/Section_test.cpp b/cmds/incidentd/tests/Section_test.cpp
index a1f4fdc..1528224 100644
--- a/cmds/incidentd/tests/Section_test.cpp
+++ b/cmds/incidentd/tests/Section_test.cpp
@@ -11,6 +11,7 @@
 // WITHOUT 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 DEBUG false
 #include "Log.h"
 
 #include "Section.h"
@@ -38,10 +39,22 @@
 using namespace android::os;
 using namespace std;
 using ::testing::StrEq;
+using ::testing::Test;
 using ::testing::internal::CaptureStdout;
 using ::testing::internal::GetCapturedStdout;
 
 // NOTICE: this test requires /system/bin/incident_helper is installed.
+class SectionTest : public Test {
+public:
+    virtual void SetUp() override { ASSERT_NE(tf.fd, -1); }
+
+protected:
+    TemporaryFile tf;
+    ReportRequestSet requests;
+
+    const std::string kTestPath = GetExecutableDirectory();
+    const std::string kTestDataPath = kTestPath + "/testdata/";
+};
 
 class SimpleListener : public IIncidentReportStatusListener {
 public:
@@ -57,10 +70,8 @@
     virtual IBinder* onAsBinder() override { return nullptr; };
 };
 
-TEST(SectionTest, HeaderSection) {
-    TemporaryFile output2;
+TEST_F(SectionTest, HeaderSection) {
     HeaderSection hs;
-    ReportRequestSet requests;
 
     IncidentReportArgs args1, args2;
     args1.addSection(1);
@@ -76,7 +87,7 @@
     args2.addHeader(head2);
 
     requests.add(new ReportRequest(args1, new SimpleListener(), -1));
-    requests.add(new ReportRequest(args2, new SimpleListener(), output2.fd));
+    requests.add(new ReportRequest(args2, new SimpleListener(), tf.fd));
     requests.setMainFd(STDOUT_FILENO);
 
     string content;
@@ -86,28 +97,25 @@
                                            "\x12\x3"
                                            "axe\n\x05\x12\x03pup"));
 
-    EXPECT_TRUE(ReadFileToString(output2.path, &content));
+    EXPECT_TRUE(ReadFileToString(tf.path, &content));
     EXPECT_THAT(content, StrEq("\n\x05\x12\x03pup"));
 }
 
-TEST(SectionTest, MetadataSection) {
+TEST_F(SectionTest, MetadataSection) {
     MetadataSection ms;
-    ReportRequestSet requests;
 
     requests.setMainFd(STDOUT_FILENO);
     requests.sectionStats(1)->set_success(true);
 
     CaptureStdout();
     ASSERT_EQ(NO_ERROR, ms.Execute(&requests));
-    EXPECT_THAT(GetCapturedStdout(), StrEq("\x12\b\x18\x1\"\x4\b\x1\x10\x1"));
+    EXPECT_THAT(GetCapturedStdout(), StrEq("\x12\b(\x1"
+                                           "2\x4\b\x1\x10\x1"));
 }
 
-TEST(SectionTest, FileSection) {
-    TemporaryFile tf;
+TEST_F(SectionTest, FileSection) {
     FileSection fs(REVERSE_PARSER, tf.path);
-    ReportRequestSet requests;
 
-    ASSERT_TRUE(tf.fd != -1);
     ASSERT_TRUE(WriteStringToFile("iamtestdata", tf.path));
 
     requests.setMainFd(STDOUT_FILENO);
@@ -119,66 +127,79 @@
     EXPECT_THAT(GetCapturedStdout(), StrEq("\xa\vatadtsetmai"));
 }
 
-TEST(SectionTest, FileSectionTimeout) {
-    TemporaryFile tf;
-    // id -1 is timeout parser
+TEST_F(SectionTest, FileSectionTimeout) {
     FileSection fs(TIMEOUT_PARSER, tf.path, QUICK_TIMEOUT_MS);
-    ReportRequestSet requests;
     ASSERT_EQ(NO_ERROR, fs.Execute(&requests));
 }
 
-TEST(SectionTest, CommandSectionConstructor) {
+TEST_F(SectionTest, GZipSection) {
+    const std::string testFile = kTestDataPath + "kmsg.txt";
+    const std::string testGzFile = testFile + ".gz";
+    GZipSection gs(NOOP_PARSER, "/tmp/nonexist", testFile.c_str(), NULL);
+
+    requests.setMainFd(tf.fd);
+    requests.setMainDest(android::os::DEST_LOCAL);
+
+    ASSERT_EQ(NO_ERROR, gs.Execute(&requests));
+    std::string expect, gzFile, actual;
+    ASSERT_TRUE(ReadFileToString(testGzFile, &gzFile));
+    ASSERT_TRUE(ReadFileToString(tf.path, &actual));
+    expect = "\x2\xC6\x6\n\"" + testFile + "\x12\x9F\x6" + gzFile;
+    EXPECT_THAT(actual, StrEq(expect));
+}
+
+TEST_F(SectionTest, GZipSectionNoFileFound) {
+    GZipSection gs(NOOP_PARSER, "/tmp/nonexist1", "/tmp/nonexist2", NULL);
+    requests.setMainFd(STDOUT_FILENO);
+    ASSERT_EQ(-1, gs.Execute(&requests));
+}
+
+TEST_F(SectionTest, CommandSectionConstructor) {
     CommandSection cs1(1, "echo", "\"this is a test\"", "ooo", NULL);
     CommandSection cs2(2, "single_command", NULL);
     CommandSection cs3(1, 3123, "echo", "\"this is a test\"", "ooo", NULL);
     CommandSection cs4(2, 43214, "single_command", NULL);
 
-    EXPECT_THAT(cs1.name.string(), StrEq("echo \"this is a test\" ooo"));
+    EXPECT_THAT(cs1.name.string(), StrEq("echo"));
     EXPECT_THAT(cs2.name.string(), StrEq("single_command"));
     EXPECT_EQ(3123, cs3.timeoutMs);
     EXPECT_EQ(43214, cs4.timeoutMs);
-    EXPECT_THAT(cs3.name.string(), StrEq("echo \"this is a test\" ooo"));
+    EXPECT_THAT(cs3.name.string(), StrEq("echo"));
     EXPECT_THAT(cs4.name.string(), StrEq("single_command"));
 }
 
-TEST(SectionTest, CommandSectionEcho) {
+TEST_F(SectionTest, CommandSectionEcho) {
     CommandSection cs(REVERSE_PARSER, "/system/bin/echo", "about", NULL);
-    ReportRequestSet requests;
     requests.setMainFd(STDOUT_FILENO);
     CaptureStdout();
     ASSERT_EQ(NO_ERROR, cs.Execute(&requests));
     EXPECT_THAT(GetCapturedStdout(), StrEq("\xa\x06\ntuoba"));
 }
 
-TEST(SectionTest, CommandSectionCommandTimeout) {
+TEST_F(SectionTest, CommandSectionCommandTimeout) {
     CommandSection cs(NOOP_PARSER, QUICK_TIMEOUT_MS, "/system/bin/yes", NULL);
-    ReportRequestSet requests;
     ASSERT_EQ(NO_ERROR, cs.Execute(&requests));
 }
 
-TEST(SectionTest, CommandSectionIncidentHelperTimeout) {
+TEST_F(SectionTest, CommandSectionIncidentHelperTimeout) {
     CommandSection cs(TIMEOUT_PARSER, QUICK_TIMEOUT_MS, "/system/bin/echo", "about", NULL);
-    ReportRequestSet requests;
     requests.setMainFd(STDOUT_FILENO);
     ASSERT_EQ(NO_ERROR, cs.Execute(&requests));
 }
 
-TEST(SectionTest, CommandSectionBadCommand) {
+TEST_F(SectionTest, CommandSectionBadCommand) {
     CommandSection cs(NOOP_PARSER, "echoo", "about", NULL);
-    ReportRequestSet requests;
     ASSERT_EQ(NAME_NOT_FOUND, cs.Execute(&requests));
 }
 
-TEST(SectionTest, CommandSectionBadCommandAndTimeout) {
+TEST_F(SectionTest, CommandSectionBadCommandAndTimeout) {
     CommandSection cs(TIMEOUT_PARSER, QUICK_TIMEOUT_MS, "nonexistcommand", "-opt", NULL);
-    ReportRequestSet requests;
     // timeout will return first
     ASSERT_EQ(NO_ERROR, cs.Execute(&requests));
 }
 
-TEST(SectionTest, LogSectionBinary) {
+TEST_F(SectionTest, LogSectionBinary) {
     LogSection ls(1, LOG_ID_EVENTS);
-    ReportRequestSet requests;
     requests.setMainFd(STDOUT_FILENO);
     CaptureStdout();
     ASSERT_EQ(NO_ERROR, ls.Execute(&requests));
@@ -186,9 +207,8 @@
     EXPECT_FALSE(results.empty());
 }
 
-TEST(SectionTest, LogSectionSystem) {
+TEST_F(SectionTest, LogSectionSystem) {
     LogSection ls(1, LOG_ID_SYSTEM);
-    ReportRequestSet requests;
     requests.setMainFd(STDOUT_FILENO);
     CaptureStdout();
     ASSERT_EQ(NO_ERROR, ls.Execute(&requests));
@@ -196,12 +216,9 @@
     EXPECT_FALSE(results.empty());
 }
 
-TEST(SectionTest, TestFilterPiiTaggedFields) {
-    TemporaryFile tf;
+TEST_F(SectionTest, TestFilterPiiTaggedFields) {
     FileSection fs(NOOP_PARSER, tf.path);
-    ReportRequestSet requests;
 
-    ASSERT_TRUE(tf.fd != -1);
     ASSERT_TRUE(WriteStringToFile(VARINT_FIELD_1 + STRING_FIELD_2 + FIX64_FIELD_3, tf.path));
 
     requests.setMainFd(STDOUT_FILENO);
@@ -211,11 +228,9 @@
     EXPECT_THAT(GetCapturedStdout(), StrEq("\x02\r" + STRING_FIELD_2));
 }
 
-TEST(SectionTest, TestBadFdRequest) {
-    TemporaryFile input;
-    FileSection fs(NOOP_PARSER, input.path);
-    ReportRequestSet requests;
-    ASSERT_TRUE(WriteStringToFile(VARINT_FIELD_1 + STRING_FIELD_2 + FIX64_FIELD_3, input.path));
+TEST_F(SectionTest, TestBadFdRequest) {
+    FileSection fs(NOOP_PARSER, tf.path);
+    ASSERT_TRUE(WriteStringToFile(VARINT_FIELD_1 + STRING_FIELD_2 + FIX64_FIELD_3, tf.path));
 
     IncidentReportArgs args;
     args.setAll(true);
@@ -230,11 +245,9 @@
     EXPECT_EQ(badFdRequest->err, -EBADF);
 }
 
-TEST(SectionTest, TestBadRequests) {
-    TemporaryFile input;
-    FileSection fs(NOOP_PARSER, input.path);
-    ReportRequestSet requests;
-    ASSERT_TRUE(WriteStringToFile(VARINT_FIELD_1 + STRING_FIELD_2 + FIX64_FIELD_3, input.path));
+TEST_F(SectionTest, TestBadRequests) {
+    FileSection fs(NOOP_PARSER, tf.path);
+    ASSERT_TRUE(WriteStringToFile(VARINT_FIELD_1 + STRING_FIELD_2 + FIX64_FIELD_3, tf.path));
 
     IncidentReportArgs args;
     args.setAll(true);
@@ -243,16 +256,14 @@
     EXPECT_EQ(fs.Execute(&requests), -EBADF);
 }
 
-TEST(SectionTest, TestMultipleRequests) {
-    TemporaryFile input, output1, output2, output3;
-    FileSection fs(NOOP_PARSER, input.path);
-    ReportRequestSet requests;
+TEST_F(SectionTest, TestMultipleRequests) {
+    TemporaryFile output1, output2, output3;
+    FileSection fs(NOOP_PARSER, tf.path);
 
-    ASSERT_TRUE(input.fd != -1);
     ASSERT_TRUE(output1.fd != -1);
     ASSERT_TRUE(output2.fd != -1);
     ASSERT_TRUE(output3.fd != -1);
-    ASSERT_TRUE(WriteStringToFile(VARINT_FIELD_1 + STRING_FIELD_2 + FIX64_FIELD_3, input.path));
+    ASSERT_TRUE(WriteStringToFile(VARINT_FIELD_1 + STRING_FIELD_2 + FIX64_FIELD_3, tf.path));
 
     IncidentReportArgs args1, args2, args3;
     args1.setAll(true);
@@ -285,17 +296,15 @@
     EXPECT_THAT(content, StrEq(""));
 }
 
-TEST(SectionTest, TestMultipleRequestsBySpec) {
-    TemporaryFile input, output1, output2, output3;
-    FileSection fs(NOOP_PARSER, input.path);
-    ReportRequestSet requests;
+TEST_F(SectionTest, TestMultipleRequestsBySpec) {
+    TemporaryFile output1, output2, output3;
+    FileSection fs(NOOP_PARSER, tf.path);
 
-    ASSERT_TRUE(input.fd != -1);
     ASSERT_TRUE(output1.fd != -1);
     ASSERT_TRUE(output2.fd != -1);
     ASSERT_TRUE(output3.fd != -1);
 
-    ASSERT_TRUE(WriteStringToFile(VARINT_FIELD_1 + STRING_FIELD_2 + FIX64_FIELD_3, input.path));
+    ASSERT_TRUE(WriteStringToFile(VARINT_FIELD_1 + STRING_FIELD_2 + FIX64_FIELD_3, tf.path));
 
     IncidentReportArgs args1, args2, args3;
     args1.setAll(true);
@@ -327,4 +336,4 @@
     c = (char)STRING_FIELD_2.size();
     EXPECT_TRUE(ReadFileToString(output3.path, &content));
     EXPECT_THAT(content, StrEq(string("\x02") + c + STRING_FIELD_2));
-}
\ No newline at end of file
+}
diff --git a/cmds/incidentd/tests/Throttler_test.cpp b/cmds/incidentd/tests/Throttler_test.cpp
new file mode 100644
index 0000000..213dcef
--- /dev/null
+++ b/cmds/incidentd/tests/Throttler_test.cpp
@@ -0,0 +1,37 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT 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 DEBUG false
+#include "Log.h"
+
+#include "Throttler.h"
+
+#include <android-base/test_utils.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+TEST(ThrottlerTest, DataSizeExceeded) {
+    Throttler t(100, 100000);
+    EXPECT_FALSE(t.shouldThrottle());
+    t.addReportSize(200);
+    EXPECT_TRUE(t.shouldThrottle());
+}
+
+TEST(ThrottlerTest, TimeReset) {
+    Throttler t(100, 500);
+    EXPECT_FALSE(t.shouldThrottle());
+    t.addReportSize(200);
+    EXPECT_TRUE(t.shouldThrottle());
+    sleep(1);  // sleep for 1 second to make sure throttler resets
+    EXPECT_FALSE(t.shouldThrottle());
+}
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index a5eae15..b566099 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -21,6 +21,7 @@
     name: "libstats_proto_host",
     srcs: [
         "src/atoms.proto",
+        "src/atom_field_options.proto",
     ],
 
     shared_libs: [
@@ -30,6 +31,9 @@
     proto: {
         type: "full",
         export_proto_headers: true,
+        include_dirs: [
+            "external/protobuf/src",
+        ],
     },
 
     export_shared_lib_headers: [
diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk
index 740fdc0..7f76ab1 100644
--- a/cmds/statsd/Android.mk
+++ b/cmds/statsd/Android.mk
@@ -17,14 +17,15 @@
 statsd_common_src := \
     ../../core/java/android/os/IStatsCompanionService.aidl \
     ../../core/java/android/os/IStatsManager.aidl \
-    src/stats_log.proto \
+    src/stats_log_common.proto \
     src/statsd_config.proto \
-    src/atoms.proto \
     src/FieldValue.cpp \
     src/stats_log_util.cpp \
-    src/anomaly/AnomalyMonitor.cpp \
+    src/anomaly/AlarmMonitor.cpp \
+    src/anomaly/AlarmTracker.cpp \
     src/anomaly/AnomalyTracker.cpp \
     src/anomaly/DurationAnomalyTracker.cpp \
+    src/anomaly/subscriber_util.cpp \
     src/condition/CombinationConditionTracker.cpp \
     src/condition/condition_util.cpp \
     src/condition/SimpleConditionTracker.cpp \
@@ -37,6 +38,7 @@
     src/external/StatsCompanionServicePuller.cpp \
     src/external/SubsystemSleepStatePuller.cpp \
     src/external/ResourceHealthManagerPuller.cpp \
+    src/external/ResourceThermalManagerPuller.cpp \
     src/external/CpuTimePerUidPuller.cpp \
     src/external/CpuTimePerUidFreqPuller.cpp \
     src/external/KernelUidCpuActiveTimeReader.cpp \
@@ -100,6 +102,7 @@
     android.hardware.health@2.0 \
     android.hardware.power@1.0 \
     android.hardware.power@1.1 \
+    android.hardware.thermal@1.0 \
     libmemunreachable
 
 # =========
@@ -168,7 +171,11 @@
 
 LOCAL_SRC_FILES := \
     $(statsd_common_src) \
-    tests/AnomalyMonitor_test.cpp \
+    src/atom_field_options.proto \
+    src/atoms.proto \
+    src/stats_log.proto \
+    tests/AlarmMonitor_test.cpp \
+    tests/anomaly/AlarmTracker_test.cpp \
     tests/anomaly/AnomalyTracker_test.cpp \
     tests/ConfigManager_test.cpp \
     tests/external/puller_util_test.cpp \
@@ -202,9 +209,13 @@
     $(statsd_common_static_libraries) \
     libgmock
 
-LOCAL_SHARED_LIBRARIES := $(statsd_common_shared_libraries)
+LOCAL_PROTOC_OPTIMIZE_TYPE := full
 
-LOCAL_PROTOC_OPTIMIZE_TYPE := lite
+LOCAL_PROTOC_FLAGS := \
+    -Iexternal/protobuf/src
+
+LOCAL_SHARED_LIBRARIES := $(statsd_common_shared_libraries) \
+                        libprotobuf-cpp-full
 
 include $(BUILD_NATIVE_TEST)
 
@@ -217,6 +228,7 @@
 
 LOCAL_SRC_FILES := \
     src/stats_log.proto \
+    src/stats_log_common.proto \
     src/statsd_config.proto \
     src/perfetto/perfetto_config.proto \
     src/atoms.proto
@@ -226,6 +238,9 @@
 LOCAL_STATIC_JAVA_LIBRARIES := \
     platformprotoslite
 
+LOCAL_PROTOC_FLAGS := \
+    -Iexternal/protobuf/src
+
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
 ##############################
@@ -239,7 +254,8 @@
                    benchmark/main.cpp \
                    benchmark/hello_world_benchmark.cpp \
                    benchmark/log_event_benchmark.cpp \
-                   benchmark/stats_write_benchmark.cpp
+                   benchmark/stats_write_benchmark.cpp \
+                   benchmark/filter_value_benchmark.cpp
 
 LOCAL_C_INCLUDES := $(statsd_common_c_includes)
 
@@ -261,8 +277,6 @@
     libgtest_prod \
     libstatslog
 
-LOCAL_PROTOC_OPTIMIZE_TYPE := lite
-
 LOCAL_MODULE_TAGS := eng tests
 
 include $(BUILD_NATIVE_BENCHMARK)
diff --git a/cmds/statsd/benchmark/filter_value_benchmark.cpp b/cmds/statsd/benchmark/filter_value_benchmark.cpp
new file mode 100644
index 0000000..b9ddf36
--- /dev/null
+++ b/cmds/statsd/benchmark/filter_value_benchmark.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <vector>
+#include "benchmark/benchmark.h"
+#include "FieldValue.h"
+#include "HashableDimensionKey.h"
+#include "logd/LogEvent.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+using std::vector;
+
+static void BM_FilterValue(benchmark::State& state) {
+    LogEvent event(1, 100000);
+    event.write(3.2f);
+    event.write("LOCATION");
+    event.write((int64_t)990);
+    event.init();
+
+    FieldMatcher field_matcher;
+    field_matcher.set_field(1);
+    field_matcher.add_child()->set_field(2);
+    field_matcher.add_child()->set_field(3);
+
+    std::vector<Matcher> matchers;
+    translateFieldMatcher(field_matcher, &matchers);
+
+    while (state.KeepRunning()) {
+        vector<HashableDimensionKey> output;
+        filterValues(matchers, event.getValues(), &output);
+    }
+}
+
+BENCHMARK(BM_FilterValue);
+
+}  //  namespace statsd
+}  //  namespace os
+}  //  namespace android
diff --git a/cmds/statsd/src/FieldValue.cpp b/cmds/statsd/src/FieldValue.cpp
index 6894bcf..b541612 100644
--- a/cmds/statsd/src/FieldValue.cpp
+++ b/cmds/statsd/src/FieldValue.cpp
@@ -135,6 +135,8 @@
         case STRING:
             str_value = from.str_value;
             break;
+        default:
+            break;
     }
 }
 
@@ -148,6 +150,8 @@
             return std::to_string(float_value) + "[F]";
         case STRING:
             return str_value + "[S]";
+        default:
+            return "[UNKNOWN]";
     }
 }
 
@@ -163,6 +167,8 @@
             return float_value == that.float_value;
         case STRING:
             return str_value == that.str_value;
+        default:
+            return false;
     }
 }
 
@@ -177,6 +183,8 @@
             return float_value != that.float_value;
         case STRING:
             return str_value != that.str_value;
+        default:
+            return false;
     }
 }
 
diff --git a/cmds/statsd/src/FieldValue.h b/cmds/statsd/src/FieldValue.h
index d17dded..b0e2c43 100644
--- a/cmds/statsd/src/FieldValue.h
+++ b/cmds/statsd/src/FieldValue.h
@@ -31,7 +31,7 @@
 const int32_t kLastBitMask = 0x80;
 const int32_t kClearLastBitDeco = 0x7f;
 
-enum Type { INT, LONG, FLOAT, STRING };
+enum Type { UNKNOWN, INT, LONG, FLOAT, STRING };
 
 int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth);
 
@@ -82,6 +82,8 @@
     int32_t mField;
 
 public:
+    Field() {}
+
     Field(int32_t tag, int32_t pos[], int32_t depth) : mTag(tag) {
         mField = getEncodedField(pos, depth, true);
     }
@@ -215,6 +217,14 @@
     const Field mMatcher;
     const int32_t mMask;
 
+    inline const Field& getMatcher() const {
+        return mMatcher;
+    }
+
+    inline int32_t getMask() const {
+        return mMask;
+    }
+
     bool hasAnyPositionMatcher(int* prefix) const {
         if (mMatcher.getDepth() == 2 && mMatcher.getRawPosAtDepth(2) == 0) {
             (*prefix) = mMatcher.getPrefix(2);
@@ -222,6 +232,10 @@
         }
         return false;
     }
+
+    inline bool operator!=(const Matcher& that) const {
+        return mMatcher != that.getMatcher() || mMask != that.getMask();
+    };
 };
 
 /**
@@ -229,6 +243,8 @@
  *
  */
 struct Value {
+    Value() : type(UNKNOWN) {}
+
     Value(int32_t v) {
         int_value = v;
         type = INT;
@@ -280,15 +296,13 @@
     bool operator!=(const Value& that) const;
 
     bool operator<(const Value& that) const;
-
-private:
-    Value(){};
 };
 
 /**
  * Represents a log item, or a dimension item (They are essentially the same).
  */
 struct FieldValue {
+    FieldValue() {}
     FieldValue(const Field& field, const Value& value) : mField(field), mValue(value) {
     }
     bool operator==(const FieldValue& that) const {
diff --git a/cmds/statsd/src/HashableDimensionKey.cpp b/cmds/statsd/src/HashableDimensionKey.cpp
index d901bd6..cc706313 100644
--- a/cmds/statsd/src/HashableDimensionKey.cpp
+++ b/cmds/statsd/src/HashableDimensionKey.cpp
@@ -16,12 +16,16 @@
 #define DEBUG false  // STOPSHIP if true
 #include "Log.h"
 
+#include <mutex>
+
 #include "HashableDimensionKey.h"
 #include "FieldValue.h"
 
 namespace android {
 namespace os {
 namespace statsd {
+
+using std::string;
 using std::vector;
 
 android::hash_t hashDimension(const HashableDimensionKey& value) {
@@ -44,10 +48,12 @@
                                                              fieldValue.mValue.str_value)));
                 break;
             case FLOAT: {
-                float floatVal = fieldValue.mValue.float_value;
-                hash = android::JenkinsHashMixBytes(hash, (uint8_t*)&floatVal, sizeof(float));
+                hash = android::JenkinsHashMix(hash,
+                                               android::hash_type(fieldValue.mValue.float_value));
                 break;
             }
+            default:
+                break;
         }
     }
     return JenkinsHashWhiten(hash);
@@ -62,26 +68,32 @@
     int prevAnyMatcherPrefix = 0;
     size_t prevPrevFanout = 0;
     size_t prevFanout = 0;
+
     // For each matcher get matched results.
+    vector<FieldValue> matchedResults(2);
     for (const auto& matcher : matcherFields) {
-        vector<FieldValue> matchedResults;
+        size_t num_matches = 0;
         for (const auto& value : values) {
             // TODO: potential optimization here to break early because all fields are naturally
             // sorted.
             if (value.mField.matches(matcher)) {
-                matchedResults.push_back(FieldValue(
-                        Field(value.mField.getTag(), (value.mField.getField() & matcher.mMask)),
-                        value.mValue));
+                if (num_matches >= matchedResults.size()) {
+                    matchedResults.resize(num_matches * 2);
+                }
+                matchedResults[num_matches].mField.setTag(value.mField.getTag());
+                matchedResults[num_matches].mField.setField(value.mField.getField() & matcher.mMask);
+                matchedResults[num_matches].mValue = value.mValue;
+                num_matches++;
             }
         }
 
-        if (matchedResults.size() == 0) {
+        if (num_matches == 0) {
             VLOG("We can't find a dimension value for matcher (%d)%#x.", matcher.mMatcher.getTag(),
                    matcher.mMatcher.getField());
             continue;
         }
 
-        if (matchedResults.size() == 1) {
+        if (num_matches == 1) {
             for (auto& dimension : *output) {
                 dimension.addValue(matchedResults[0]);
             }
@@ -117,23 +129,23 @@
             // First create fanout (fanout size is matchedResults.Size which could be one,
             // which means we do nothing here)
             oldSize = output->size();
-            for (size_t i = 1; i < matchedResults.size(); i++) {
+            for (size_t i = 1; i < num_matches; i++) {
                 output->insert(output->end(), output->begin(), output->begin() + oldSize);
             }
             prevPrevFanout = oldSize;
-            prevFanout = matchedResults.size();
+            prevFanout = num_matches;
         } else {
             // If we should not create fanout, e.g., uid tag from same position should be remain
             // together.
             oldSize = prevPrevFanout;
-            if (prevFanout != matchedResults.size()) {
+            if (prevFanout != num_matches) {
                 // sanity check.
                 ALOGE("2 Any matcher result in different output");
                 return false;
             }
         }
         // now add the matched field value to output
-        for (size_t i = 0; i < matchedResults.size(); i++) {
+        for (size_t i = 0; i < num_matches; i++) {
             for (int j = 0; j < oldSize; j++) {
                 (*output)[i * oldSize + j].addValue(matchedResults[i]);
             }
@@ -154,10 +166,11 @@
     }
 }
 
-void getDimensionForCondition(const LogEvent& event, Metric2Condition links,
+void getDimensionForCondition(const std::vector<FieldValue>& eventValues,
+                              const Metric2Condition& links,
                               vector<HashableDimensionKey>* conditionDimension) {
     // Get the dimension first by using dimension from what.
-    filterValues(links.metricFields, event.getValues(), conditionDimension);
+    filterValues(links.metricFields, eventValues, conditionDimension);
 
     // Then replace the field with the dimension from condition.
     for (auto& dim : *conditionDimension) {
diff --git a/cmds/statsd/src/HashableDimensionKey.h b/cmds/statsd/src/HashableDimensionKey.h
index 89fe317..57bdf68 100644
--- a/cmds/statsd/src/HashableDimensionKey.h
+++ b/cmds/statsd/src/HashableDimensionKey.h
@@ -40,7 +40,7 @@
         mValues = values;
     }
 
-    HashableDimensionKey(){};
+    HashableDimensionKey() {};
 
     HashableDimensionKey(const HashableDimensionKey& that) : mValues(that.getValues()){};
 
@@ -144,7 +144,8 @@
 void filterGaugeValues(const std::vector<Matcher>& matchers, const std::vector<FieldValue>& values,
                        std::vector<FieldValue>* output);
 
-void getDimensionForCondition(const LogEvent& event, Metric2Condition links,
+void getDimensionForCondition(const std::vector<FieldValue>& eventValues,
+                              const Metric2Condition& links,
                               std::vector<HashableDimensionKey>* conditionDimension);
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 87dec5d..9b58a14 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -66,13 +66,16 @@
 #define STATS_DATA_DIR "/data/misc/stats-data"
 
 StatsLogProcessor::StatsLogProcessor(const sp<UidMap>& uidMap,
-                                     const sp<AnomalyMonitor>& anomalyMonitor,
+                                     const sp<AlarmMonitor>& anomalyAlarmMonitor,
+                                     const sp<AlarmMonitor>& periodicAlarmMonitor,
                                      const long timeBaseSec,
                                      const std::function<void(const ConfigKey&)>& sendBroadcast)
     : mUidMap(uidMap),
-      mAnomalyMonitor(anomalyMonitor),
+      mAnomalyAlarmMonitor(anomalyAlarmMonitor),
+      mPeriodicAlarmMonitor(periodicAlarmMonitor),
       mSendBroadcast(sendBroadcast),
-      mTimeBaseSec(timeBaseSec) {
+      mTimeBaseSec(timeBaseSec),
+      mLastLogTimestamp(0) {
     StatsPullerManager statsPullerManager;
     statsPullerManager.SetTimeBaseSec(mTimeBaseSec);
 }
@@ -82,10 +85,19 @@
 
 void StatsLogProcessor::onAnomalyAlarmFired(
         const uint64_t timestampNs,
-        unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>> anomalySet) {
+        unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet) {
     std::lock_guard<std::mutex> lock(mMetricsMutex);
     for (const auto& itr : mMetricsManagers) {
-        itr.second->onAnomalyAlarmFired(timestampNs, anomalySet);
+        itr.second->onAnomalyAlarmFired(timestampNs, alarmSet);
+    }
+}
+void StatsLogProcessor::onPeriodicAlarmFired(
+        const uint64_t timestampNs,
+        unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet) {
+
+    std::lock_guard<std::mutex> lock(mMetricsMutex);
+    for (const auto& itr : mMetricsManagers) {
+        itr.second->onPeriodicAlarmFired(timestampNs, alarmSet);
     }
 }
 
@@ -133,9 +145,12 @@
     }
 }
 
-// TODO: what if statsd service restarts? How do we know what logs are already processed before?
 void StatsLogProcessor::OnLogEvent(LogEvent* event) {
     std::lock_guard<std::mutex> lock(mMetricsMutex);
+    if (event->GetElapsedTimestampNs() < mLastLogTimestamp) {
+        return;
+    }
+    mLastLogTimestamp = event->GetElapsedTimestampNs();
     StatsdStats::getInstance().noteAtomLogged(
         event->GetTagId(), event->GetElapsedTimestampNs() / NS_PER_SEC);
 
@@ -170,7 +185,9 @@
 void StatsLogProcessor::OnConfigUpdated(const ConfigKey& key, const StatsdConfig& config) {
     std::lock_guard<std::mutex> lock(mMetricsMutex);
     VLOG("Updated configuration for key %s", key.ToString().c_str());
-    sp<MetricsManager> newMetricsManager = new MetricsManager(key, config, mTimeBaseSec, mUidMap);
+    sp<MetricsManager> newMetricsManager =
+        new MetricsManager(key, config, mTimeBaseSec, mUidMap,
+                           mAnomalyAlarmMonitor, mPeriodicAlarmMonitor);
     auto it = mMetricsManagers.find(key);
     if (it == mMetricsManagers.end() && mMetricsManagers.size() > StatsdStats::kMaxConfigCount) {
         ALOGE("Can't accept more configs!");
@@ -179,7 +196,6 @@
 
     if (newMetricsManager->isConfigValid()) {
         mUidMap->OnConfigUpdated(key);
-        newMetricsManager->setAnomalyMonitor(mAnomalyMonitor);
         if (newMetricsManager->shouldAddUidMapListener()) {
             // We have to add listener after the MetricsManager is constructed because it's
             // not safe to create wp or sp from this pointer inside its constructor.
@@ -316,7 +332,7 @@
         StatsdStats::kMaxMetricsBytesPerConfig) {  // Too late. We need to start clearing data.
         // TODO(b/70571383): By 12/15/2017 add API to drop data directly
         ProtoOutputStream proto;
-        metricsManager.onDumpReport(time(nullptr) * NS_PER_SEC, &proto);
+        metricsManager.onDumpReport(timestampNs, &proto);
         StatsdStats::getInstance().noteDataDropped(key);
         VLOG("StatsD had to toss out metrics for %s", key.ToString().c_str());
     } else if (totalBytes > .9 * StatsdStats::kMaxMetricsBytesPerConfig) {
@@ -340,7 +356,7 @@
     for (auto& pair : mMetricsManagers) {
         const ConfigKey& key = pair.first;
         vector<uint8_t> data;
-        onDumpReportLocked(key, time(nullptr) * NS_PER_SEC, &data);
+        onDumpReportLocked(key, getElapsedRealtimeNs(), &data);
         // TODO: Add a guardrail to prevent accumulation of file on disk.
         string file_name = StringPrintf("%s/%ld_%d_%lld", STATS_DATA_DIR,
              (long)getWallClockSec(), key.GetUid(), (long long)key.GetId());
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index 1444306..7a6aa1e 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -34,7 +34,8 @@
 
 class StatsLogProcessor : public ConfigListener {
 public:
-    StatsLogProcessor(const sp<UidMap>& uidMap, const sp<AnomalyMonitor>& anomalyMonitor,
+    StatsLogProcessor(const sp<UidMap>& uidMap, const sp<AlarmMonitor>& anomalyAlarmMonitor,
+                      const sp<AlarmMonitor>& subscriberTriggerAlarmMonitor,
                       const long timeBaseSec,
                       const std::function<void(const ConfigKey&)>& sendBroadcast);
     virtual ~StatsLogProcessor();
@@ -48,10 +49,15 @@
 
     void onDumpReport(const ConfigKey& key, const uint64_t dumpTimeNs, vector<uint8_t>* outData);
 
-    /* Tells MetricsManager that the alarms in anomalySet have fired. Modifies anomalySet. */
+    /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies anomaly alarmSet. */
     void onAnomalyAlarmFired(
             const uint64_t timestampNs,
-            unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>> anomalySet);
+            unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet);
+
+    /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies periodic alarmSet. */
+    void onPeriodicAlarmFired(
+            const uint64_t timestampNs,
+            unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet);
 
     /* Flushes data to disk. Data on memory will be gone after written to disk. */
     void WriteDataToDisk();
@@ -76,7 +82,9 @@
 
     StatsPullerManager mStatsPullerManager;
 
-    sp<AnomalyMonitor> mAnomalyMonitor;
+    sp<AlarmMonitor> mAnomalyAlarmMonitor;
+
+    sp<AlarmMonitor> mPeriodicAlarmMonitor;
 
     void onDumpReportLocked(const ConfigKey& key, const uint64_t dumpTimeNs,
                             vector<uint8_t>* outData);
@@ -98,6 +106,8 @@
 
     const long mTimeBaseSec;
 
+    int64_t mLastLogTimestamp;
+
     long mLastPullerCacheClearTimeSec = 0;
 
     FRIEND_TEST(StatsLogProcessorTest, TestRateLimitByteSize);
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 791fb14..ee4f434 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -50,49 +50,73 @@
 constexpr const char* kPermissionDump = "android.permission.DUMP";
 #define STATS_SERVICE_DIR "/data/misc/stats-service"
 
-// ======================================================================
 /**
  * Watches for the death of the stats companion (system process).
  */
 class CompanionDeathRecipient : public IBinder::DeathRecipient {
 public:
-    CompanionDeathRecipient(const sp<AnomalyMonitor>& anomalyMonitor);
+    CompanionDeathRecipient(const sp<AlarmMonitor>& anomalyAlarmMonitor,
+                            const sp<AlarmMonitor>& periodicAlarmMonitor) :
+                                mAnomalyAlarmMonitor(anomalyAlarmMonitor),
+                                mPeriodicAlarmMonitor(periodicAlarmMonitor)  {}
     virtual void binderDied(const wp<IBinder>& who);
 
 private:
-    const sp<AnomalyMonitor> mAnomalyMonitor;
+   sp<AlarmMonitor> mAnomalyAlarmMonitor;
+   sp<AlarmMonitor> mPeriodicAlarmMonitor;
 };
 
-CompanionDeathRecipient::CompanionDeathRecipient(const sp<AnomalyMonitor>& anomalyMonitor)
-    : mAnomalyMonitor(anomalyMonitor) {
-}
-
 void CompanionDeathRecipient::binderDied(const wp<IBinder>& who) {
     ALOGW("statscompanion service died");
-    mAnomalyMonitor->setStatsCompanionService(nullptr);
+    mAnomalyAlarmMonitor->setStatsCompanionService(nullptr);
+    mPeriodicAlarmMonitor->setStatsCompanionService(nullptr);
     SubscriberReporter::getInstance().setStatsCompanionService(nullptr);
 }
 
-// ======================================================================
 StatsService::StatsService(const sp<Looper>& handlerLooper)
-    : mAnomalyMonitor(new AnomalyMonitor(MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS))
-{
+    : mAnomalyAlarmMonitor(new AlarmMonitor(MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
+       [](const sp<IStatsCompanionService>& sc, int64_t timeMillis) {
+           if (sc != nullptr) {
+               sc->setAnomalyAlarm(timeMillis);
+               StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
+           }
+       },
+       [](const sp<IStatsCompanionService>& sc) {
+           if (sc != nullptr) {
+               sc->cancelAnomalyAlarm();
+               StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
+           }
+       })),
+   mPeriodicAlarmMonitor(new AlarmMonitor(MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
+      [](const sp<IStatsCompanionService>& sc, int64_t timeMillis) {
+           if (sc != nullptr) {
+               sc->setAlarmForSubscriberTriggering(timeMillis);
+               StatsdStats::getInstance().noteRegisteredPeriodicAlarmChanged();
+           }
+      },
+      [](const sp<IStatsCompanionService>& sc) {
+           if (sc != nullptr) {
+               sc->cancelAlarmForSubscriberTriggering();
+               StatsdStats::getInstance().noteRegisteredPeriodicAlarmChanged();
+           }
+
+      }))  {
     mUidMap = new UidMap();
     StatsPuller::SetUidMap(mUidMap);
     mConfigManager = new ConfigManager();
-    mProcessor = new StatsLogProcessor(mUidMap, mAnomalyMonitor, getElapsedRealtimeSec(),
-        [this](const ConfigKey& key) {
-            sp<IStatsCompanionService> sc = getStatsCompanionService();
-            auto receiver = mConfigManager->GetConfigReceiver(key);
-            if (sc == nullptr) {
-                VLOG("Could not find StatsCompanionService");
-            } else if (receiver == nullptr) {
-                VLOG("Statscompanion could not find a broadcast receiver for %s",
-                     key.ToString().c_str());
-            } else {
-                sc->sendDataBroadcast(receiver);
-            }
+    mProcessor = new StatsLogProcessor(mUidMap, mAnomalyAlarmMonitor, mPeriodicAlarmMonitor,
+                                       getElapsedRealtimeSec(), [this](const ConfigKey& key) {
+        sp<IStatsCompanionService> sc = getStatsCompanionService();
+        auto receiver = mConfigManager->GetConfigReceiver(key);
+        if (sc == nullptr) {
+            VLOG("Could not find StatsCompanionService");
+        } else if (receiver == nullptr) {
+            VLOG("Statscompanion could not find a broadcast receiver for %s",
+                 key.ToString().c_str());
+        } else {
+            sc->sendDataBroadcast(receiver);
         }
+    }
     );
 
     mConfigManager->AddListener(mProcessor);
@@ -423,6 +447,13 @@
             }
 
             if (args[1] == "update") {
+                char* endp;
+                int64_t configID = strtoll(name.c_str(), &endp, 10);
+                if (endp == name.c_str() || *endp != '\0') {
+                    fprintf(err, "Error parsing config ID.\n");
+                    return UNKNOWN_ERROR;
+                }
+
                 // Read stream into buffer.
                 string buffer;
                 if (!android::base::ReadFdToString(fileno(in), &buffer)) {
@@ -438,7 +469,7 @@
                 }
 
                 // Add / update the config.
-                mConfigManager->UpdateConfig(ConfigKey(uid, StrToInt64(name)), config);
+                mConfigManager->UpdateConfig(ConfigKey(uid, configID), config);
             } else {
                 if (argCount == 2) {
                     cmd_remove_all_configs(out);
@@ -493,7 +524,7 @@
         }
         if (good) {
             vector<uint8_t> data;
-            mProcessor->onDumpReport(ConfigKey(uid, StrToInt64(name)), time(nullptr) * NS_PER_SEC,
+            mProcessor->onDumpReport(ConfigKey(uid, StrToInt64(name)), getElapsedRealtimeNs(),
                                      &data);
             // TODO: print the returned StatsLogReport to file instead of printing to logcat.
             if (proto) {
@@ -615,7 +646,8 @@
 
 status_t StatsService::cmd_clear_puller_cache(FILE* out) {
     IPCThreadState* ipc = IPCThreadState::self();
-    VLOG("StatsService::cmd_clear_puller_cache with Pid %i, Uid %i", ipc->getCallingPid(), ipc->getCallingUid());
+    VLOG("StatsService::cmd_clear_puller_cache with Pid %i, Uid %i",
+            ipc->getCallingPid(), ipc->getCallingUid());
     if (checkCallingPermission(String16(kPermissionDump))) {
         int cleared = mStatsPullerManager.ForceClearPullerCache();
         fprintf(out, "Puller removed %d cached data!\n", cleared);
@@ -659,6 +691,7 @@
                                          "Only system uid can call informOnePackageRemoved");
     }
     mUidMap->removeApp(app, uid);
+    mConfigManager->RemoveConfigs(uid);
     return Status::ok();
 }
 
@@ -669,18 +702,40 @@
         return Status::fromExceptionCode(Status::EX_SECURITY,
                                          "Only system uid can call informAnomalyAlarmFired");
     }
+
     uint64_t currentTimeSec = getElapsedRealtimeSec();
-    std::unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>> anomalySet =
-            mAnomalyMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
-    if (anomalySet.size() > 0) {
+    std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet =
+            mAnomalyAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
+    if (alarmSet.size() > 0) {
         VLOG("Found an anomaly alarm that fired.");
-        mProcessor->onAnomalyAlarmFired(currentTimeSec * NS_PER_SEC, anomalySet);
+        mProcessor->onAnomalyAlarmFired(currentTimeSec * NS_PER_SEC, alarmSet);
     } else {
         VLOG("Cannot find an anomaly alarm that fired. Perhaps it was recently cancelled.");
     }
     return Status::ok();
 }
 
+Status StatsService::informAlarmForSubscriberTriggeringFired() {
+    VLOG("StatsService::informAlarmForSubscriberTriggeringFired was called");
+
+    if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
+        return Status::fromExceptionCode(
+                Status::EX_SECURITY,
+                "Only system uid can call informAlarmForSubscriberTriggeringFired");
+    }
+
+    uint64_t currentTimeSec = time(nullptr);
+    std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet =
+            mPeriodicAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
+    if (alarmSet.size() > 0) {
+        VLOG("Found periodic alarm fired.");
+        mProcessor->onPeriodicAlarmFired(currentTimeSec * NS_PER_SEC, alarmSet);
+    } else {
+        ALOGW("Cannot find an periodic alarm that fired. Perhaps it was recently cancelled.");
+    }
+    return Status::ok();
+}
+
 Status StatsService::informPollAlarmFired() {
     VLOG("StatsService::informPollAlarmFired was called");
 
@@ -765,10 +820,11 @@
                 "statscompanion unavailable despite it contacting statsd!");
     }
     VLOG("StatsService::statsCompanionReady linking to statsCompanion.");
-    IInterface::asBinder(statsCompanion)->linkToDeath(new CompanionDeathRecipient(mAnomalyMonitor));
-    mAnomalyMonitor->setStatsCompanionService(statsCompanion);
+    IInterface::asBinder(statsCompanion)->linkToDeath(
+            new CompanionDeathRecipient(mAnomalyAlarmMonitor, mPeriodicAlarmMonitor));
+    mAnomalyAlarmMonitor->setStatsCompanionService(statsCompanion);
+    mPeriodicAlarmMonitor->setStatsCompanionService(statsCompanion);
     SubscriberReporter::getInstance().setStatsCompanionService(statsCompanion);
-
     return Status::ok();
 }
 
@@ -785,7 +841,7 @@
     VLOG("StatsService::getData with Pid %i, Uid %i", ipc->getCallingPid(), ipc->getCallingUid());
     if (checkCallingPermission(String16(kPermissionDump))) {
         ConfigKey configKey(ipc->getCallingUid(), key);
-        mProcessor->onDumpReport(configKey, time(nullptr) * NS_PER_SEC, output);
+        mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(), output);
         return Status::ok();
     } else {
         return Status::fromExceptionCode(binder::Status::EX_SECURITY);
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index 9690de7..e0a1299 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -18,7 +18,7 @@
 #define STATS_SERVICE_H
 
 #include "StatsLogProcessor.h"
-#include "anomaly/AnomalyMonitor.h"
+#include "anomaly/AlarmMonitor.h"
 #include "config/ConfigManager.h"
 #include "external/StatsPullerManager.h"
 #include "packages/UidMap.h"
@@ -58,6 +58,8 @@
     virtual Status statsCompanionReady();
     virtual Status informAnomalyAlarmFired();
     virtual Status informPollAlarmFired();
+    virtual Status informAlarmForSubscriberTriggeringFired();
+
     virtual Status informAllUidData(const vector<int32_t>& uid, const vector<int64_t>& version,
                                     const vector<String16>& app);
     virtual Status informOnePackage(const String16& app, int32_t uid, int64_t version);
@@ -244,9 +246,14 @@
     sp<StatsLogProcessor> mProcessor;
 
     /**
-     * The anomaly detector.
+     * The alarm monitor for anomaly detection.
      */
-    const sp<AnomalyMonitor> mAnomalyMonitor;
+    const sp<AlarmMonitor> mAnomalyAlarmMonitor;
+
+    /**
+     * The alarm monitor for alarms to directly trigger subscriber.
+     */
+    const sp<AlarmMonitor> mPeriodicAlarmMonitor;
 
     /**
      * Whether this is an eng build.
diff --git a/cmds/statsd/src/anomaly/AnomalyMonitor.cpp b/cmds/statsd/src/anomaly/AlarmMonitor.cpp
similarity index 74%
rename from cmds/statsd/src/anomaly/AnomalyMonitor.cpp
rename to cmds/statsd/src/anomaly/AlarmMonitor.cpp
index ca34dc6..78f0c2b 100644
--- a/cmds/statsd/src/anomaly/AnomalyMonitor.cpp
+++ b/cmds/statsd/src/anomaly/AlarmMonitor.cpp
@@ -17,21 +17,24 @@
 #define DEBUG false
 #include "Log.h"
 
-#include "anomaly/AnomalyMonitor.h"
+#include "anomaly/AlarmMonitor.h"
 #include "guardrail/StatsdStats.h"
 
 namespace android {
 namespace os {
 namespace statsd {
 
-AnomalyMonitor::AnomalyMonitor(uint32_t minDiffToUpdateRegisteredAlarmTimeSec)
-    : mRegisteredAlarmTimeSec(0), mMinUpdateTimeSec(minDiffToUpdateRegisteredAlarmTimeSec) {
-}
+AlarmMonitor::AlarmMonitor(
+        uint32_t minDiffToUpdateRegisteredAlarmTimeSec,
+        const std::function<void(const sp<IStatsCompanionService>&, int64_t)>& updateAlarm,
+        const std::function<void(const sp<IStatsCompanionService>&)>& cancelAlarm)
+    : mRegisteredAlarmTimeSec(0), mMinUpdateTimeSec(minDiffToUpdateRegisteredAlarmTimeSec),
+      mUpdateAlarm(updateAlarm),
+      mCancelAlarm(cancelAlarm) {}
 
-AnomalyMonitor::~AnomalyMonitor() {
-}
+AlarmMonitor::~AlarmMonitor() {}
 
-void AnomalyMonitor::setStatsCompanionService(sp<IStatsCompanionService> statsCompanionService) {
+void AlarmMonitor::setStatsCompanionService(sp<IStatsCompanionService> statsCompanionService) {
     std::lock_guard<std::mutex> lock(mLock);
     sp<IStatsCompanionService> tmpForLock = mStatsCompanionService;
     mStatsCompanionService = statsCompanionService;
@@ -40,13 +43,13 @@
         return;
     }
     VLOG("Creating link to statsCompanionService");
-    const sp<const AnomalyAlarm> top = mPq.top();
+    const sp<const InternalAlarm> top = mPq.top();
     if (top != nullptr) {
         updateRegisteredAlarmTime_l(top->timestampSec);
     }
 }
 
-void AnomalyMonitor::add(sp<const AnomalyAlarm> alarm) {
+void AlarmMonitor::add(sp<const InternalAlarm> alarm) {
     std::lock_guard<std::mutex> lock(mLock);
     if (alarm == nullptr) {
         ALOGW("Asked to add a null alarm.");
@@ -66,7 +69,7 @@
     }
 }
 
-void AnomalyMonitor::remove(sp<const AnomalyAlarm> alarm) {
+void AlarmMonitor::remove(sp<const InternalAlarm> alarm) {
     std::lock_guard<std::mutex> lock(mLock);
     if (alarm == nullptr) {
         ALOGW("Asked to remove a null alarm.");
@@ -89,13 +92,13 @@
 
 // More efficient than repeatedly calling remove(mPq.top()) since it batches the
 // updates to the registered alarm.
-unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>> AnomalyMonitor::popSoonerThan(
+unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> AlarmMonitor::popSoonerThan(
         uint32_t timestampSec) {
     VLOG("Removing alarms with time <= %u", timestampSec);
-    unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>> oldAlarms;
+    unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> oldAlarms;
     std::lock_guard<std::mutex> lock(mLock);
 
-    for (sp<const AnomalyAlarm> t = mPq.top(); t != nullptr && t->timestampSec <= timestampSec;
+    for (sp<const InternalAlarm> t = mPq.top(); t != nullptr && t->timestampSec <= timestampSec;
         t = mPq.top()) {
         oldAlarms.insert(t);
         mPq.pop();  // remove t
@@ -113,25 +116,19 @@
     return oldAlarms;
 }
 
-void AnomalyMonitor::updateRegisteredAlarmTime_l(uint32_t timestampSec) {
+void AlarmMonitor::updateRegisteredAlarmTime_l(uint32_t timestampSec) {
     VLOG("Updating reg alarm time to %u", timestampSec);
     mRegisteredAlarmTimeSec = timestampSec;
-    if (mStatsCompanionService != nullptr) {
-        mStatsCompanionService->setAnomalyAlarm(secToMs(mRegisteredAlarmTimeSec));
-        StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
-    }
+    mUpdateAlarm(mStatsCompanionService, secToMs(mRegisteredAlarmTimeSec));
 }
 
-void AnomalyMonitor::cancelRegisteredAlarmTime_l() {
+void AlarmMonitor::cancelRegisteredAlarmTime_l() {
     VLOG("Cancelling reg alarm.");
     mRegisteredAlarmTimeSec = 0;
-    if (mStatsCompanionService != nullptr) {
-        mStatsCompanionService->cancelAnomalyAlarm();
-        StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
-    }
+    mCancelAlarm(mStatsCompanionService);
 }
 
-int64_t AnomalyMonitor::secToMs(uint32_t timeSec) {
+int64_t AlarmMonitor::secToMs(uint32_t timeSec) {
     return ((int64_t)timeSec) * 1000;
 }
 
diff --git a/cmds/statsd/src/anomaly/AnomalyMonitor.h b/cmds/statsd/src/anomaly/AlarmMonitor.h
similarity index 77%
rename from cmds/statsd/src/anomaly/AnomalyMonitor.h
rename to cmds/statsd/src/anomaly/AlarmMonitor.h
index 7acc7904..3badb1f 100644
--- a/cmds/statsd/src/anomaly/AnomalyMonitor.h
+++ b/cmds/statsd/src/anomaly/AlarmMonitor.h
@@ -41,33 +41,34 @@
  * threshold.
  * Timestamps are in seconds since epoch in a uint32, so will fail in year 2106.
  */
-struct AnomalyAlarm : public RefBase {
-    AnomalyAlarm(uint32_t timestampSec) : timestampSec(timestampSec) {
+struct InternalAlarm : public RefBase {
+    InternalAlarm(uint32_t timestampSec) : timestampSec(timestampSec) {
     }
 
     const uint32_t timestampSec;
 
-    /** AnomalyAlarm a is smaller (higher priority) than b if its timestamp is sooner. */
+    /** InternalAlarm a is smaller (higher priority) than b if its timestamp is sooner. */
     struct SmallerTimestamp {
-        bool operator()(sp<const AnomalyAlarm> a, sp<const AnomalyAlarm> b) const {
+        bool operator()(sp<const InternalAlarm> a, sp<const InternalAlarm> b) const {
             return (a->timestampSec < b->timestampSec);
         }
     };
 };
 
-// TODO: Rename this file to AnomalyAlarmMonitor.
 /**
- * Manages alarms for Anomaly Detection.
+ * Manages internal alarms that may get registered with the AlarmManager.
  */
-class AnomalyMonitor : public RefBase {
+class AlarmMonitor : public RefBase {
 public:
     /**
      * @param minDiffToUpdateRegisteredAlarmTimeSec If the soonest alarm differs
      * from the registered alarm by more than this amount, update the registered
      * alarm.
      */
-    AnomalyMonitor(uint32_t minDiffToUpdateRegisteredAlarmTimeSec);
-    ~AnomalyMonitor();
+    AlarmMonitor(uint32_t minDiffToUpdateRegisteredAlarmTimeSec,
+                 const std::function<void(const sp<IStatsCompanionService>&, int64_t)>& updateAlarm,
+                 const std::function<void(const sp<IStatsCompanionService>&)>& cancelAlarm);
+    ~AlarmMonitor();
 
     /**
      * Tells AnomalyMonitor what IStatsCompanionService to use and, if
@@ -80,20 +81,20 @@
     /**
      * Adds the given alarm (reference) to the queue.
      */
-    void add(sp<const AnomalyAlarm> alarm);
+    void add(sp<const InternalAlarm> alarm);
 
     /**
      * Removes the given alarm (reference) from the queue.
      * Note that alarm comparison is reference-based; if another alarm exists
      * with the same timestampSec, that alarm will still remain in the queue.
      */
-    void remove(sp<const AnomalyAlarm> alarm);
+    void remove(sp<const InternalAlarm> alarm);
 
     /**
      * Returns and removes all alarms whose timestamp <= the given timestampSec.
      * Always updates the registered alarm if return is non-empty.
      */
-    unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>> popSoonerThan(
+    unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> popSoonerThan(
             uint32_t timestampSec);
 
     /**
@@ -119,7 +120,7 @@
     /**
      * Priority queue of alarms, prioritized by soonest alarm.timestampSec.
      */
-    indexed_priority_queue<AnomalyAlarm, AnomalyAlarm::SmallerTimestamp> mPq;
+    indexed_priority_queue<InternalAlarm, InternalAlarm::SmallerTimestamp> mPq;
 
     /**
      * Binder interface for communicating with StatsCompanionService.
@@ -146,6 +147,13 @@
 
     /** Converts uint32 timestamp in seconds to a Java long in msec. */
     int64_t secToMs(uint32_t timeSec);
+
+    // Callback function to update the alarm via StatsCompanionService.
+    std::function<void(const sp<IStatsCompanionService>, int64_t)> mUpdateAlarm;
+
+    // Callback function to cancel the alarm via StatsCompanionService.
+    std::function<void(const sp<IStatsCompanionService>)> mCancelAlarm;
+
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/anomaly/AlarmTracker.cpp b/cmds/statsd/src/anomaly/AlarmTracker.cpp
new file mode 100644
index 0000000..eb28383
--- /dev/null
+++ b/cmds/statsd/src/anomaly/AlarmTracker.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 DEBUG true  // STOPSHIP if true
+#include "Log.h"
+
+#include "anomaly/AlarmTracker.h"
+#include "anomaly/subscriber_util.h"
+#include "HashableDimensionKey.h"
+#include "stats_util.h"
+#include "storage/StorageManager.h"
+
+#include <statslog.h>
+#include <time.h>
+
+namespace android {
+namespace os {
+namespace statsd {
+
+AlarmTracker::AlarmTracker(uint64_t startMillis,
+                           const Alarm& alarm, const ConfigKey& configKey,
+                           const sp<AlarmMonitor>& alarmMonitor)
+    : mAlarmConfig(alarm),
+      mConfigKey(configKey),
+      mAlarmMonitor(alarmMonitor) {
+    VLOG("AlarmTracker() called");
+    mAlarmSec = (startMillis + mAlarmConfig.offset_millis()) / MS_PER_SEC;
+    mInternalAlarm = new InternalAlarm{static_cast<uint32_t>(mAlarmSec)};
+    mAlarmMonitor->add(mInternalAlarm);
+}
+
+AlarmTracker::~AlarmTracker() {
+    VLOG("~AlarmTracker() called");
+    if (mInternalAlarm != nullptr) {
+        mAlarmMonitor->remove(mInternalAlarm);
+    }
+}
+
+void AlarmTracker::addSubscription(const Subscription& subscription) {
+    mSubscriptions.push_back(subscription);
+}
+
+uint64_t AlarmTracker::findNextAlarmSec(uint64_t currentTimeSec) {
+    int periodsForward = (currentTimeSec - mAlarmSec) * MS_PER_SEC / mAlarmConfig.period_millis();
+    return mAlarmSec + (periodsForward + 1) * mAlarmConfig.period_millis() / MS_PER_SEC;
+}
+
+void AlarmTracker::informAlarmsFired(
+        const uint64_t& timestampNs,
+        unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms) {
+    if (firedAlarms.empty() || firedAlarms.find(mInternalAlarm) == firedAlarms.end()) {
+        return;
+    }
+    if (!mSubscriptions.empty()) {
+        triggerSubscribers(mAlarmConfig.id(), DEFAULT_METRIC_DIMENSION_KEY, mConfigKey,
+                           mSubscriptions);
+    }
+    firedAlarms.erase(mInternalAlarm);
+    mAlarmSec = findNextAlarmSec(timestampNs / NS_PER_SEC);
+    mInternalAlarm = new InternalAlarm{static_cast<uint32_t>(mAlarmSec)};
+    mAlarmMonitor->add(mInternalAlarm);
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/anomaly/AlarmTracker.h b/cmds/statsd/src/anomaly/AlarmTracker.h
new file mode 100644
index 0000000..d59dacaa
--- /dev/null
+++ b/cmds/statsd/src/anomaly/AlarmTracker.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <gtest/gtest_prod.h>
+
+#include "AlarmMonitor.h"
+#include "config/ConfigKey.h"
+#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"  // Alarm
+
+#include <android/os/IStatsCompanionService.h>
+#include <stdlib.h>
+#include <utils/RefBase.h>
+
+using android::os::IStatsCompanionService;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+class AlarmTracker : public virtual RefBase {
+public:
+    AlarmTracker(uint64_t startMillis,
+                 const Alarm& alarm, const ConfigKey& configKey,
+                 const sp<AlarmMonitor>& subscriberAlarmMonitor);
+
+    virtual ~AlarmTracker();
+
+    void onAlarmFired();
+
+    void addSubscription(const Subscription& subscription);
+
+    void informAlarmsFired(const uint64_t& timestampNs,
+            unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms);
+
+protected:
+    uint64_t findNextAlarmSec(uint64_t currentTimeMillis);
+
+    // statsd_config.proto Alarm message that defines this tracker.
+    const Alarm mAlarmConfig;
+
+    // A reference to the Alarm's config key.
+    const ConfigKey& mConfigKey;
+
+    // The subscriptions that depend on this alarm.
+    std::vector<Subscription> mSubscriptions;
+
+    // Alarm monitor.
+    sp<AlarmMonitor> mAlarmMonitor;
+
+    // The current expected alarm time in seconds.
+    uint64_t mAlarmSec;
+
+    // The current alarm.
+    sp<const InternalAlarm> mInternalAlarm;
+
+    FRIEND_TEST(AlarmTrackerTest, TestTriggerTimestamp);
+};
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.cpp b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
index 6553a14..642604e 100644
--- a/cmds/statsd/src/anomaly/AnomalyTracker.cpp
+++ b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
@@ -18,6 +18,7 @@
 #include "Log.h"
 
 #include "AnomalyTracker.h"
+#include "subscriber_util.h"
 #include "external/Perfetto.h"
 #include "guardrail/StatsdStats.h"
 #include "subscriber/IncidentdReporter.h"
@@ -192,7 +193,7 @@
 
     if (!mSubscriptions.empty()) {
         if (mAlert.has_id()) {
-            ALOGI("An anomaly (%llu) has occurred! Informing subscribers.", mAlert.id());
+            ALOGI("An anomaly (%lld) has occurred! Informing subscribers.", mAlert.id());
             informSubscribers(key);
         } else {
             ALOGI("An anomaly (with no id) has occurred! Not informing any subscribers.");
@@ -231,32 +232,7 @@
 }
 
 void AnomalyTracker::informSubscribers(const MetricDimensionKey& key) {
-    VLOG("informSubscribers called.");
-    if (mSubscriptions.empty()) {
-        ALOGE("Attempt to call with no subscribers.");
-        return;
-    }
-
-    for (const Subscription& subscription : mSubscriptions) {
-        switch (subscription.subscriber_information_case()) {
-            case Subscription::SubscriberInformationCase::kIncidentdDetails:
-                if (!GenerateIncidentReport(subscription.incidentd_details(), mAlert, mConfigKey)) {
-                    ALOGW("Failed to generate incident report.");
-                }
-                break;
-            case Subscription::SubscriberInformationCase::kPerfettoDetails:
-                if (!CollectPerfettoTraceAndUploadToDropbox(subscription.perfetto_details())) {
-                    ALOGW("Failed to generate prefetto traces.");
-                }
-                break;
-            case Subscription::SubscriberInformationCase::kBroadcastSubscriberDetails:
-                SubscriberReporter::getInstance().alertBroadcastSubscriber(mConfigKey, subscription,
-                                                                           key);
-                break;
-            default:
-                break;
-        }
-    }
+    triggerSubscribers(mAlert.id(), key, mConfigKey, mSubscriptions);
 }
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.h b/cmds/statsd/src/anomaly/AnomalyTracker.h
index 3be959d..e3f493c 100644
--- a/cmds/statsd/src/anomaly/AnomalyTracker.h
+++ b/cmds/statsd/src/anomaly/AnomalyTracker.h
@@ -23,7 +23,7 @@
 #include <gtest/gtest_prod.h>
 #include <utils/RefBase.h>
 
-#include "AnomalyMonitor.h"
+#include "AlarmMonitor.h"
 #include "config/ConfigKey.h"
 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"  // Alert
 #include "stats_util.h"  // HashableDimensionKey and DimToValMap
@@ -64,9 +64,9 @@
     void detectAndDeclareAnomaly(const uint64_t& timestampNs, const int64_t& currBucketNum,
                                  const MetricDimensionKey& key, const int64_t& currentBucketValue);
 
-    // Init the AnomalyMonitor which is shared across anomaly trackers.
-    virtual void setAnomalyMonitor(const sp<AnomalyMonitor>& anomalyMonitor) {
-        return;  // Base AnomalyTracker class has no need for the AnomalyMonitor.
+    // Init the AlarmMonitor which is shared across anomaly trackers.
+    virtual void setAlarmMonitor(const sp<AlarmMonitor>& alarmMonitor) {
+        return; // Base AnomalyTracker class has no need for the AlarmMonitor.
     }
 
     // Helper function to return the sum value of past buckets at given dimension.
@@ -92,11 +92,10 @@
     }
 
     // Declares an anomaly for each alarm in firedAlarms that belongs to this AnomalyTracker,
-    // and removes it from firedAlarms. Does NOT remove the alarm from the AnomalyMonitor.
-    virtual void informAlarmsFired(
-            const uint64_t& timestampNs,
-            unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>>& firedAlarms) {
-        return;  // The base AnomalyTracker class doesn't have alarms.
+    // and removes it from firedAlarms. Does NOT remove the alarm from the AlarmMonitor.
+    virtual void informAlarmsFired(const uint64_t& timestampNs,
+            unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms) {
+        return; // The base AnomalyTracker class doesn't have alarms.
     }
 
 protected:
diff --git a/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp b/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp
index 3ba943c..31d50be 100644
--- a/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp
+++ b/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp
@@ -24,8 +24,9 @@
 namespace os {
 namespace statsd {
 
-DurationAnomalyTracker::DurationAnomalyTracker(const Alert& alert, const ConfigKey& configKey)
-    : AnomalyTracker(alert, configKey) {
+DurationAnomalyTracker::DurationAnomalyTracker(const Alert& alert, const ConfigKey& configKey,
+                                               const sp<AlarmMonitor>& alarmMonitor)
+    : AnomalyTracker(alert, configKey), mAlarmMonitor(alarmMonitor) {
 }
 
 DurationAnomalyTracker::~DurationAnomalyTracker() {
@@ -59,10 +60,10 @@
         VLOG("Setting a delayed anomaly alarm lest it fall in the refractory period");
         timestampSec = getRefractoryPeriodEndsSec(dimensionKey) + 1;
     }
-    sp<const AnomalyAlarm> alarm = new AnomalyAlarm{timestampSec};
+    sp<const InternalAlarm> alarm = new InternalAlarm{timestampSec};
     mAlarms.insert({dimensionKey, alarm});
-    if (mAnomalyMonitor != nullptr) {
-        mAnomalyMonitor->add(alarm);
+    if (mAlarmMonitor != nullptr) {
+        mAlarmMonitor->add(alarm);
     }
 }
 
@@ -70,8 +71,8 @@
     auto itr = mAlarms.find(dimensionKey);
     if (itr != mAlarms.end()) {
         mAlarms.erase(dimensionKey);
-        if (mAnomalyMonitor != nullptr) {
-            mAnomalyMonitor->remove(itr->second);
+        if (mAlarmMonitor != nullptr) {
+            mAlarmMonitor->remove(itr->second);
         }
     }
 }
@@ -86,16 +87,16 @@
     }
 }
 
-void DurationAnomalyTracker::informAlarmsFired(
-        const uint64_t& timestampNs,
-        unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>>& firedAlarms) {
+void DurationAnomalyTracker::informAlarmsFired(const uint64_t& timestampNs,
+        unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms) {
+
     if (firedAlarms.empty() || mAlarms.empty()) return;
     // Find the intersection of firedAlarms and mAlarms.
     // The for loop is inefficient, since it loops over all keys, but that's okay since it is very
-    // seldomly called. The alternative would be having AnomalyAlarms store information about the
+    // seldomly called. The alternative would be having InternalAlarms store information about the
     // DurationAnomalyTracker and key, but that's a lot of data overhead to speed up something that
     // is rarely ever called.
-    unordered_map<MetricDimensionKey, sp<const AnomalyAlarm>> matchedAlarms;
+    unordered_map<MetricDimensionKey, sp<const InternalAlarm>> matchedAlarms;
     for (const auto& kv : mAlarms) {
         if (firedAlarms.count(kv.second) > 0) {
             matchedAlarms.insert({kv.first, kv.second});
diff --git a/cmds/statsd/src/anomaly/DurationAnomalyTracker.h b/cmds/statsd/src/anomaly/DurationAnomalyTracker.h
index 15aef29..51186df 100644
--- a/cmds/statsd/src/anomaly/DurationAnomalyTracker.h
+++ b/cmds/statsd/src/anomaly/DurationAnomalyTracker.h
@@ -16,7 +16,7 @@
 
 #pragma once
 
-#include "AnomalyMonitor.h"
+#include "AlarmMonitor.h"
 #include "AnomalyTracker.h"
 
 namespace android {
@@ -27,7 +27,8 @@
 
 class DurationAnomalyTracker : public virtual AnomalyTracker {
 public:
-    DurationAnomalyTracker(const Alert& alert, const ConfigKey& configKey);
+    DurationAnomalyTracker(const Alert& alert, const ConfigKey& configKey,
+                           const sp<AlarmMonitor>& alarmMonitor);
 
     virtual ~DurationAnomalyTracker();
 
@@ -40,11 +41,6 @@
     // Stop all the alarms owned by this tracker.
     void stopAllAlarms();
 
-    // Init the AnomalyMonitor which is shared across anomaly trackers.
-    void setAnomalyMonitor(const sp<AnomalyMonitor>& anomalyMonitor) override {
-        mAnomalyMonitor = anomalyMonitor;
-    }
-
     // Declares the anomaly when the alarm expired given the current timestamp.
     void declareAnomalyIfAlarmExpired(const MetricDimensionKey& dimensionKey,
                                       const uint64_t& timestampNs);
@@ -53,17 +49,16 @@
     // and removes it from firedAlarms.
     // Note that this will generally be called from a different thread from the other functions;
     // the caller is responsible for thread safety.
-    void informAlarmsFired(
-            const uint64_t& timestampNs,
-            unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>>& firedAlarms) override;
+    void informAlarmsFired(const uint64_t& timestampNs,
+            unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms) override;
 
 protected:
     // The alarms owned by this tracker. The alarm monitor also shares the alarm pointers when they
     // are still active.
-    std::unordered_map<MetricDimensionKey, sp<const AnomalyAlarm>> mAlarms;
+    std::unordered_map<MetricDimensionKey, sp<const InternalAlarm>> mAlarms;
 
     // Anomaly alarm monitor.
-    sp<AnomalyMonitor> mAnomalyMonitor;
+    sp<AlarmMonitor> mAlarmMonitor;
 
     // Resets all bucket data. For use when all the data gets stale.
     void resetStorage() override;
diff --git a/cmds/statsd/src/anomaly/subscriber_util.cpp b/cmds/statsd/src/anomaly/subscriber_util.cpp
new file mode 100644
index 0000000..e796d19
--- /dev/null
+++ b/cmds/statsd/src/anomaly/subscriber_util.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 DEBUG true  // STOPSHIP if true
+#include "Log.h"
+
+#include <android/os/IIncidentManager.h>
+#include <android/os/IncidentReportArgs.h>
+#include <binder/IServiceManager.h>
+
+#include "external/Perfetto.h"
+#include "frameworks/base/libs/incident/proto/android/os/header.pb.h"
+#include "subscriber/IncidentdReporter.h"
+#include "subscriber/SubscriberReporter.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+void triggerSubscribers(const int64_t rule_id,
+                        const MetricDimensionKey& dimensionKey,
+                        const ConfigKey& configKey,
+                        const std::vector<Subscription>& subscriptions) {
+    VLOG("informSubscribers called.");
+    if (subscriptions.empty()) {
+        VLOG("No Subscriptions were associated.");
+        return;
+    }
+
+    for (const Subscription& subscription : subscriptions) {
+        if (subscription.probability_of_informing() < 1
+                && ((float)rand() / RAND_MAX) >= subscription.probability_of_informing()) {
+            // Note that due to float imprecision, 0.0 and 1.0 might not truly mean never/always.
+            // The config writer was advised to use -0.1 and 1.1 for never/always.
+            ALOGI("Fate decided that a subscriber would not be informed.");
+            continue;
+        }
+        switch (subscription.subscriber_information_case()) {
+            case Subscription::SubscriberInformationCase::kIncidentdDetails:
+                if (!GenerateIncidentReport(subscription.incidentd_details(), rule_id, configKey)) {
+                    ALOGW("Failed to generate incident report.");
+                }
+                break;
+            case Subscription::SubscriberInformationCase::kPerfettoDetails:
+                if (!CollectPerfettoTraceAndUploadToDropbox(subscription.perfetto_details())) {
+                    ALOGW("Failed to generate prefetto traces.");
+                }
+                break;
+            case Subscription::SubscriberInformationCase::kBroadcastSubscriberDetails:
+                SubscriberReporter::getInstance().alertBroadcastSubscriber(configKey, subscription,
+                                                                           dimensionKey);
+                break;
+            default:
+                break;
+        }
+    }
+}
+
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/anomaly/subscriber_util.h b/cmds/statsd/src/anomaly/subscriber_util.h
new file mode 100644
index 0000000..dba8981
--- /dev/null
+++ b/cmds/statsd/src/anomaly/subscriber_util.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "config/ConfigKey.h"
+#include "HashableDimensionKey.h"
+#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+void triggerSubscribers(const int64_t rule_id,
+                        const MetricDimensionKey& dimensionKey,
+                        const ConfigKey& configKey,
+                        const std::vector<Subscription>& subscriptions);
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/atom_field_options.proto b/cmds/statsd/src/atom_field_options.proto
new file mode 100644
index 0000000..19d00b7
--- /dev/null
+++ b/cmds/statsd/src/atom_field_options.proto
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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";
+
+package android.os.statsd;
+option java_package = "com.android.os";
+option java_multiple_files = true;
+option java_outer_classname = "AtomFieldOptions";
+
+import "google/protobuf/descriptor.proto";
+
+enum StateField {
+    // Default value for fields that are not primary or exclusive state.
+    STATE_FIELD_UNSET = 0;
+    // Fields that represent the key that the state belongs to.
+    PRIMARY = 1;
+    // The field that represents the state. It's an exclusive state.
+    EXCLUSIVE = 2;
+}
+
+// Used to annotate an atom that reprsents a state change. A state change atom must have exactly ONE
+// exclusive state field, and any number of primary key fields.
+// For example,
+// message UidProcessStateChanged {
+//    optional int32 uid = 1 [(stateFieldOption).option = PRIMARY];
+//    optional android.app.ProcessStateEnum state = 2 [(stateFieldOption).option = EXCLUSIVE];
+//  }
+// Each of this UidProcessStateChanged atom represents a state change for a specific uid.
+// A new state automatically overrides the previous state.
+//
+// If the atom has 2 or more primary fields, it means the combination of the primary fields are
+// the primary key.
+// For example:
+// message ThreadStateChanged {
+//    optional int32 pid = 1  [(stateFieldOption).option = PRIMARY];
+//    optional int32 tid = 2  [(stateFieldOption).option = PRIMARY];
+//    optional int32 state = 3 [(stateFieldOption).option = EXCLUSIVE];
+// }
+//
+// Sometimes, there is no primary key field, when the state is GLOBAL.
+// For example,
+//
+// message ScreenStateChanged {
+//    optional android.view.DisplayStateEnum state = 1 [(stateFieldOption).option = EXCLUSIVE];
+// }
+//
+// Only fields of primary types can be annotated. AttributionNode cannot be primary keys (and they
+// usually are not).
+message StateAtomFieldOption {
+    optional StateField option = 1 [default = STATE_FIELD_UNSET];
+}
+
+extend google.protobuf.FieldOptions {
+    // Flags to decorate an atom that presents a state change.
+    optional StateAtomFieldOption stateFieldOption = 50000;
+}
\ No newline at end of file
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index d9094dd..42ae022 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -21,6 +21,7 @@
 option java_package = "com.android.os";
 option java_outer_classname = "AtomsProto";
 
+import "frameworks/base/cmds/statsd/src/atom_field_options.proto";
 import "frameworks/base/core/proto/android/app/enums.proto";
 import "frameworks/base/core/proto/android/os/enums.proto";
 import "frameworks/base/core/proto/android/server/enums.proto";
@@ -71,7 +72,7 @@
         BatteryLevelChanged battery_level_changed = 30;
         ChargingStateChanged charging_state_changed = 31;
         PluggedStateChanged plugged_state_changed = 32;
-        DeviceTemperatureReported device_temperature_reported = 33;
+        // TODO: 33 is blank, but is available for use.
         DeviceOnStatusChanged device_on_status_changed = 34;
         WakeupAlarmOccurred wakeup_alarm_occurred = 35;
         KernelWakeupReported kernel_wakeup_reported = 36;
@@ -100,11 +101,14 @@
         OverlayStateChanged overlay_state_changed = 59;
         ForegroundServiceStateChanged foreground_service_state_changed = 60;
         CallStateChanged call_state_changed = 61;
+        KeyguardStateChanged keyguard_state_changed = 62;
+        KeyguardBouncerStateChanged keyguard_bouncer_state_changed = 63;
+        KeyguardBouncerPasswordEntered keyguard_bouncer_password_entered = 64;
         // TODO: Reorder the numbering so that the most frequent occur events occur in the first 15.
     }
 
     // Pulled events will start at field 10000.
-    // Next: 10021
+    // Next: 10022
     oneof pulled {
         WifiBytesTransfer wifi_bytes_transfer = 10000;
         WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001;
@@ -127,7 +131,11 @@
         DiskSpace disk_space = 10018;
         RemainingBatteryCapacity remaining_battery_capacity = 10019;
         FullBatteryCapacity full_battery_capacity = 10020;
+        Temperature temperature = 10021;
     }
+
+    // DO NOT USE field numbers above 100,000 in AOSP. Field numbers above
+    // 100,000 are reserved for non-AOSP (e.g. OEMs) to use.
 }
 
 /**
@@ -179,7 +187,7 @@
  */
 message ScreenStateChanged {
     // New screen state, from frameworks/base/core/proto/android/view/enums.proto.
-    optional android.view.DisplayStateEnum state = 1;
+    optional android.view.DisplayStateEnum state = 1 [(stateFieldOption).option = EXCLUSIVE];
 }
 
 /**
@@ -189,10 +197,10 @@
  *   frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
  */
 message UidProcessStateChanged {
-    optional int32 uid = 1; // TODO: should be a string tagged w/ uid annotation
+    optional int32 uid = 1 [(stateFieldOption).option = PRIMARY];
 
     // The state, from frameworks/base/core/proto/android/app/enums.proto.
-    optional android.app.ProcessStateEnum state = 2;
+    optional android.app.ProcessStateEnum state = 2 [(stateFieldOption).option = EXCLUSIVE];
 }
 
 /**
@@ -535,17 +543,6 @@
     optional android.os.BatteryPluggedStateEnum state = 1;
 }
 
-/**
- * Logs the temperature of the device, in tenths of a degree Celsius.
- *
- * Logged from:
- *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message DeviceTemperatureReported {
-    // Temperature in tenths of a degree C.
-    optional int32 temperature = 1;
-}
-
 // TODO: Define this more precisely.
 // TODO: Log the ON state somewhere. It isn't currently logged anywhere.
 /**
@@ -756,14 +753,74 @@
 }
 
 /**
+ * Logs keyguard state. The keyguard is the lock screen.
+ *
+ * Logged from:
+ *   frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+ */
+message KeyguardStateChanged {
+    enum State {
+        UNKNOWN = 0;
+        // The keyguard is hidden when the phone is unlocked.
+        HIDDEN = 1;
+        // The keyguard is shown when the phone is locked (screen turns off).
+        SHOWN= 2;
+        // The keyguard is occluded when something is overlaying the keyguard.
+        // Eg. Opening the camera while on the lock screen.
+        OCCLUDED = 3;
+    }
+    optional State state = 1;
+}
+
+/**
+ * Logs keyguard bouncer state. The bouncer is a part of the keyguard, and
+ * prompts the user to enter a password (pattern, pin, etc).
+ *
+ * Logged from:
+ *   frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+ */
+
+message KeyguardBouncerStateChanged {
+    enum State {
+        UNKNOWN = 0;
+        // Bouncer is hidden, either as a result of successfully entering the
+        // password, screen timing out, or user going back to lock screen.
+        HIDDEN = 1;
+        // This is when the user is being prompted to enter the password.
+        SHOWN = 2;
+    }
+    optional State state = 1;
+}
+
+/**
+ * Logs the result of entering a password into the keyguard bouncer.
+ *
+ * Logged from:
+ *   frameworks/base/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+ */
+message KeyguardBouncerPasswordEntered {
+    enum BouncerResult {
+        UNKNOWN = 0;
+        // The password entered was incorrect.
+        FAILURE = 1;
+        // The password entered was correct.
+        SUCCESS = 2;
+    }
+    optional BouncerResult result = 1;
+}
+
+/**
  * Logs the duration of a davey (jank of >=700ms) when it occurs
  *
  * Logged from:
  *   frameworks/base/libs/hwui/JankTracker.cpp
  */
 message DaveyOccurred {
+    // The UID that logged this atom.
+    optional int32 uid = 1;
+
     // Amount of time it took to render the frame. Should be >=700ms.
-    optional int64 jank_duration_millis = 1;
+    optional int64 jank_duration_millis = 2;
 }
 
 /**
@@ -939,6 +996,11 @@
     // Empty if not set.
     optional string launch_token = 13;
 
+    // The compiler filter used when when the package was optimized.
+    optional string package_optimization_compilation_filter = 14;
+
+    // The reason why the package was optimized.
+    optional string package_optimization_compilation_reason = 15;
 }
 
 message AppStartCancelChanged {
@@ -1502,7 +1564,8 @@
 
 /**
  * Pulls battery coulomb counter, which is the remaining battery charge in uAh.
- * Logged from: frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
+ * Pulled from:
+ *   frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
  */
 message RemainingBatteryCapacity {
     optional int32 charge_uAh = 1;
@@ -1510,9 +1573,26 @@
 
 /**
  * Pulls battery capacity, which is the battery capacity when full in uAh.
- * Logged from: frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
+ * Pulled from:
+ *   frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
  */
 message FullBatteryCapacity {
     optional int32 capacity_uAh = 1;
 }
 
+/**
+ * Pulls the temperature of various parts of the device, in Celsius.
+ *
+ * Pulled from:
+ *   frameworks/base/cmds/statsd/src/external/ResourceThermalManagerPuller.cpp
+ */
+message Temperature {
+    // The type of temperature being reported. Eg. CPU, GPU, SKIN, BATTERY.
+    optional android.os.TemperatureTypeEnum sensor_location = 1;
+
+    // The name of the temperature source. Eg. CPU0
+    optional string sensor_name = 2;
+
+    // Temperature in degrees C.
+    optional float temperature_C = 3;
+}
diff --git a/cmds/statsd/src/external/Perfetto.h b/cmds/statsd/src/external/Perfetto.h
index e2e0253..2a5679c 100644
--- a/cmds/statsd/src/external/Perfetto.h
+++ b/cmds/statsd/src/external/Perfetto.h
@@ -16,6 +16,8 @@
 
 #pragma once
 
+#include <android/os/StatsLogEventWrapper.h>
+
 using android::os::StatsLogEventWrapper;
 
 namespace android {
diff --git a/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp b/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
index 261cb43..3741202 100644
--- a/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
+++ b/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define DEBUG true  // STOPSHIP if true
+#define DEBUG false  // STOPSHIP if true
 #include "Log.h"
 
 #include <android/hardware/health/2.0/IHealth.h>
@@ -47,7 +47,6 @@
 bool getHealthHal() {
     if (gHealthHal == nullptr) {
         gHealthHal = get_health_service();
-
     }
     return gHealthHal != nullptr;
 }
diff --git a/cmds/statsd/src/external/ResourceThermalManagerPuller.cpp b/cmds/statsd/src/external/ResourceThermalManagerPuller.cpp
new file mode 100644
index 0000000..b3acdfc
--- /dev/null
+++ b/cmds/statsd/src/external/ResourceThermalManagerPuller.cpp
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 DEBUG false  // STOPSHIP if true
+#include "Log.h"
+
+#include <android/hardware/thermal/1.0/IThermal.h>
+#include "external/ResourceThermalManagerPuller.h"
+#include "external/StatsPuller.h"
+
+#include "ResourceThermalManagerPuller.h"
+#include "logd/LogEvent.h"
+#include "statslog.h"
+#include "stats_log_util.h"
+
+#include <chrono>
+
+using android::hardware::hidl_death_recipient;
+using android::hardware::hidl_vec;
+using android::hidl::base::V1_0::IBase;
+using android::hardware::thermal::V1_0::IThermal;
+using android::hardware::thermal::V1_0::Temperature;
+using android::hardware::thermal::V1_0::ThermalStatus;
+using android::hardware::thermal::V1_0::ThermalStatusCode;
+using android::hardware::Return;
+using android::hardware::Void;
+
+using std::chrono::duration_cast;
+using std::chrono::nanoseconds;
+using std::chrono::system_clock;
+using std::make_shared;
+using std::shared_ptr;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+bool getThermalHalLocked();
+sp<android::hardware::thermal::V1_0::IThermal> gThermalHal = nullptr;
+std::mutex gThermalHalMutex;
+
+struct ThermalHalDeathRecipient : virtual public hidl_death_recipient {
+      virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override {
+          std::lock_guard<std::mutex> lock(gThermalHalMutex);
+          ALOGE("ThermalHAL just died");
+          gThermalHal = nullptr;
+          getThermalHalLocked();
+      }
+};
+
+sp<ThermalHalDeathRecipient> gThermalHalDeathRecipient = nullptr;
+
+// The caller must be holding gThermalHalMutex.
+bool getThermalHalLocked() {
+    if (gThermalHal == nullptr) {
+            gThermalHal = IThermal::getService();
+            if (gThermalHal == nullptr) {
+                ALOGE("Unable to get Thermal service.");
+            } else {
+                if (gThermalHalDeathRecipient == nullptr) {
+                    gThermalHalDeathRecipient = new ThermalHalDeathRecipient();
+                }
+                hardware::Return<bool> linked = gThermalHal->linkToDeath(
+                    gThermalHalDeathRecipient, 0x451F /* cookie */);
+                if (!linked.isOk()) {
+                    ALOGE("Transaction error in linking to ThermalHAL death: %s",
+                            linked.description().c_str());
+                    gThermalHal = nullptr;
+                } else if (!linked) {
+                    ALOGW("Unable to link to ThermalHal death notifications");
+                    gThermalHal = nullptr;
+                } else {
+                    ALOGD("Link to death notification successful");
+                }
+            }
+    }
+    return gThermalHal != nullptr;
+}
+
+ResourceThermalManagerPuller::ResourceThermalManagerPuller() :
+        StatsPuller(android::util::TEMPERATURE) {
+}
+
+bool ResourceThermalManagerPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) {
+    std::lock_guard<std::mutex> lock(gThermalHalMutex);
+    if (!getThermalHalLocked()) {
+        ALOGE("Thermal Hal not loaded");
+        return false;
+    }
+
+    int64_t wallClockTimestampNs = getWallClockNs();
+    int64_t elapsedTimestampNs = getElapsedRealtimeNs();
+
+    data->clear();
+    bool resultSuccess = true;
+
+    Return<void> ret = gThermalHal->getTemperatures(
+            [&](ThermalStatus status, const hidl_vec<Temperature>& temps) {
+        if (status.code != ThermalStatusCode::SUCCESS) {
+            ALOGE("Failed to get temperatures from ThermalHAL. Status: %d", status.code);
+            resultSuccess = false;
+            return;
+        }
+        if (mTagId == android::util::TEMPERATURE) {
+            for (size_t i = 0; i < temps.size(); ++i) {
+                auto ptr = make_shared<LogEvent>(android::util::TEMPERATURE,
+                        wallClockTimestampNs, elapsedTimestampNs);
+                ptr->write((static_cast<int>(temps[i].type)));
+                ptr->write(temps[i].name);
+                ptr->write(temps[i].currentValue);
+                ptr->init();
+                data->push_back(ptr);
+            }
+        } else {
+            ALOGE("Unsupported tag in ResourceThermalManagerPuller: %d", mTagId);
+        }
+    });
+    if (!ret.isOk()) {
+        ALOGE("getThermalHalLocked() failed: thermal HAL service not available. Description: %s",
+                ret.description().c_str());
+        if (ret.isDeadObject()) {
+            gThermalHal = nullptr;
+        }
+        return false;
+    }
+    return resultSuccess;
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/external/ResourceThermalManagerPuller.h b/cmds/statsd/src/external/ResourceThermalManagerPuller.h
new file mode 100644
index 0000000..13c675a
--- /dev/null
+++ b/cmds/statsd/src/external/ResourceThermalManagerPuller.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/String16.h>
+#include "StatsPuller.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+/**
+ * Reads IThermal.hal
+ */
+class ResourceThermalManagerPuller : public StatsPuller {
+public:
+    ResourceThermalManagerPuller();
+    bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override;
+};
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
\ No newline at end of file
diff --git a/cmds/statsd/src/external/StatsPullerManagerImpl.cpp b/cmds/statsd/src/external/StatsPullerManagerImpl.cpp
index bee9939..880dfd1 100644
--- a/cmds/statsd/src/external/StatsPullerManagerImpl.cpp
+++ b/cmds/statsd/src/external/StatsPullerManagerImpl.cpp
@@ -23,10 +23,10 @@
 #include <climits>
 #include "CpuTimePerUidFreqPuller.h"
 #include "CpuTimePerUidPuller.h"
-#include "ResourceHealthManagerPuller.h"
 #include "KernelUidCpuActiveTimeReader.h"
 #include "KernelUidCpuClusterTimeReader.h"
-#include "SubsystemSleepStatePuller.h"
+#include "ResourceHealthManagerPuller.h"
+#include "ResourceThermalManagerPuller.h"
 #include "StatsCompanionServicePuller.h"
 #include "StatsPullerManagerImpl.h"
 #include "StatsService.h"
@@ -118,7 +118,9 @@
          {{}, {}, 1, new ResourceHealthManagerPuller(android::util::FULL_BATTERY_CAPACITY)}},
         // process_memory_state
         {android::util::PROCESS_MEMORY_STATE,
-         {{4,5,6,7,8}, {2,3}, 0, new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_STATE)}}};
+         {{4,5,6,7,8}, {2,3}, 0, new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_STATE)}},
+        // temperature
+        {android::util::TEMPERATURE, {{}, {}, 1, new ResourceThermalManagerPuller()}}};
 
 StatsPullerManagerImpl::StatsPullerManagerImpl()
     : mCurrentPullingInterval(LONG_MAX) {
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index 66cb1d0..0881d44 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -47,11 +47,13 @@
 const int FIELD_ID_ANOMALY_ALARM_STATS = 9;
 // const int FIELD_ID_PULLED_ATOM_STATS = 10; // The proto is written in stats_log_util.cpp
 const int FIELD_ID_LOGGER_ERROR_STATS = 11;
+const int FIELD_ID_SUBSCRIBER_ALARM_STATS = 12;
 
 const int FIELD_ID_ATOM_STATS_TAG = 1;
 const int FIELD_ID_ATOM_STATS_COUNT = 2;
 
 const int FIELD_ID_ANOMALY_ALARMS_REGISTERED = 1;
+const int FIELD_ID_SUBSCRIBER_ALARMS_REGISTERED = 1;
 
 const int FIELD_ID_LOGGER_STATS_TIME = 1;
 const int FIELD_ID_LOGGER_STATS_ERROR_CODE = 2;
@@ -248,6 +250,11 @@
     mAnomalyAlarmRegisteredStats++;
 }
 
+void StatsdStats::noteRegisteredPeriodicAlarmChanged() {
+    lock_guard<std::mutex> lock(mLock);
+    mPeriodicAlarmRegisteredStats++;
+}
+
 void StatsdStats::updateMinPullIntervalSec(int pullAtomId, long intervalSec) {
     lock_guard<std::mutex> lock(mLock);
     mPulledAtomStats[pullAtomId].minPullIntervalSec = intervalSec;
@@ -297,6 +304,7 @@
     std::fill(mPushedAtomStats.begin(), mPushedAtomStats.end(), 0);
     mAlertStats.clear();
     mAnomalyAlarmRegisteredStats = 0;
+    mPeriodicAlarmRegisteredStats = 0;
     mMatcherStats.clear();
     mLoggerErrors.clear();
     for (auto& config : mConfigStats) {
@@ -367,7 +375,7 @@
     fprintf(out, "%lu Config in icebox: \n", (unsigned long)mIceBox.size());
     for (const auto& configStats : mIceBox) {
         fprintf(out,
-                "Config {%d-%lld}: creation=%d, deletion=%d, #metric=%d, #condition=%d, "
+                "Config {%d_%lld}: creation=%d, deletion=%d, #metric=%d, #condition=%d, "
                 "#matcher=%d, #alert=%d,  valid=%d\n",
                 configStats.uid(), (long long)configStats.id(), configStats.creation_time_sec(),
                 configStats.deletion_time_sec(), configStats.metric_count(),
@@ -462,6 +470,11 @@
         fprintf(out, "Anomaly alarm registrations: %d\n", mAnomalyAlarmRegisteredStats);
     }
 
+    if (mPeriodicAlarmRegisteredStats > 0) {
+        fprintf(out, "********SubscriberAlarmStats stats***********\n");
+        fprintf(out, "Subscriber alarm registrations: %d\n", mPeriodicAlarmRegisteredStats);
+    }
+
     fprintf(out,
             "UID map stats: bytes=%d, snapshots=%d, changes=%d, snapshots lost=%d, changes "
             "lost=%d\n",
@@ -531,6 +544,13 @@
         proto.end(token);
     }
 
+    if (mPeriodicAlarmRegisteredStats > 0) {
+        long long token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_SUBSCRIBER_ALARM_STATS);
+        proto.write(FIELD_TYPE_INT32 | FIELD_ID_SUBSCRIBER_ALARMS_REGISTERED,
+                    mPeriodicAlarmRegisteredStats);
+        proto.end(token);
+    }
+
     const int numBytes = mUidMapStats.ByteSize();
     vector<char> buffer(numBytes);
     mUidMapStats.SerializeToArray(&buffer[0], numBytes);
@@ -566,4 +586,4 @@
 
 }  // namespace statsd
 }  // namespace os
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index 7baa5e5..24ac688 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -16,7 +16,7 @@
 #pragma once
 
 #include "config/ConfigKey.h"
-#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
+#include "frameworks/base/cmds/statsd/src/stats_log_common.pb.h"
 #include "statslog.h"
 
 #include <gtest/gtest_prod.h>
@@ -170,6 +170,11 @@
     void noteRegisteredAnomalyAlarmChanged();
 
     /**
+     * Report that statsd modified the periodic alarm registered with StatsCompanionService.
+     */
+    void noteRegisteredPeriodicAlarmChanged();
+
+    /**
      * Records the number of snapshot and delta entries that are being dropped from the uid map.
      */
     void noteUidMapDropped(int snapshots, int deltas);
@@ -264,6 +269,9 @@
     // StatsCompanionService.
     int mAnomalyAlarmRegisteredStats = 0;
 
+    // Stores the number of times statsd registers the periodic alarm changes
+    int mPeriodicAlarmRegisteredStats = 0;
+
     // Stores the number of times an anomaly detection alert has been declared
     // (per config, per alert name). The map size is capped by kMaxConfigCount.
     std::map<const ConfigKey, std::map<const int64_t, int>> mAlertStats;
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
index f07fc66..d282b86 100644
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -26,9 +26,10 @@
 namespace statsd {
 
 using namespace android::util;
+using android::util::ProtoOutputStream;
 using std::ostringstream;
 using std::string;
-using android::util::ProtoOutputStream;
+using std::vector;
 
 LogEvent::LogEvent(log_msg& msg) {
     mContext =
@@ -130,7 +131,7 @@
     return false;
 }
 
-bool LogEvent::write(const std::vector<AttributionNode>& nodes) {
+bool LogEvent::write(const std::vector<AttributionNodeInternal>& nodes) {
     if (mContext) {
          if (android_log_write_list_begin(mContext) < 0) {
             return false;
@@ -148,7 +149,7 @@
     return false;
 }
 
-bool LogEvent::write(const AttributionNode& node) {
+bool LogEvent::write(const AttributionNodeInternal& node) {
     if (mContext) {
          if (android_log_write_list_begin(mContext) < 0) {
             return false;
diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h
index b3084d5..24d624d 100644
--- a/cmds/statsd/src/logd/LogEvent.h
+++ b/cmds/statsd/src/logd/LogEvent.h
@@ -17,7 +17,6 @@
 #pragma once
 
 #include "FieldValue.h"
-#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
 
 #include <android/util/ProtoOutputStream.h>
 #include <log/log_event_list.h>
@@ -32,8 +31,26 @@
 namespace os {
 namespace statsd {
 
-using std::string;
-using std::vector;
+struct AttributionNodeInternal {
+    void set_uid(int32_t id) {
+        mUid = id;
+    }
+
+    void set_tag(const std::string& value) {
+        mTag = value;
+    }
+
+    int32_t uid() const {
+        return mUid;
+    }
+
+    const std::string& tag() const {
+        return mTag;
+    }
+
+    int32_t mUid;
+    std::string mTag;
+};
 /**
  * Wrapper for the log_msg structure.
  */
@@ -89,15 +106,15 @@
     bool write(int32_t value);
     bool write(uint64_t value);
     bool write(int64_t value);
-    bool write(const string& value);
+    bool write(const std::string& value);
     bool write(float value);
-    bool write(const std::vector<AttributionNode>& nodes);
-    bool write(const AttributionNode& node);
+    bool write(const std::vector<AttributionNodeInternal>& nodes);
+    bool write(const AttributionNodeInternal& node);
 
     /**
      * Return a string representation of this event.
      */
-    string ToString() const;
+    std::string ToString() const;
 
     /**
      * Write this object to a ProtoOutputStream.
diff --git a/cmds/statsd/src/matchers/matcher_util.cpp b/cmds/statsd/src/matchers/matcher_util.cpp
index 4612009..5d5e64e 100644
--- a/cmds/statsd/src/matchers/matcher_util.cpp
+++ b/cmds/statsd/src/matchers/matcher_util.cpp
@@ -87,6 +87,10 @@
                     const string& str_match) {
     if (isAttributionUidField(field, value)) {
         int uid = value.int_value;
+        auto aidIt = UidMap::sAidToUidMapping.find(str_match);
+        if (aidIt != UidMap::sAidToUidMapping.end()) {
+            return ((int)aidIt->second) == uid;
+        }
         std::set<string> packageNames = uidMap.getAppNamesFromUid(uid, true /* normalize*/);
         return packageNames.find(str_match) != packageNames.end();
     } else if (value.getType() == STRING) {
@@ -207,6 +211,9 @@
             }
             return false;
         }
+        // Finally, we get to the point of real value matching.
+        // If the field matcher ends with ANY, then we have [start, end) range > 1.
+        // In the following, we should return true, when ANY of the values matches.
         case FieldValueMatcher::ValueMatcherCase::kEqBool: {
             for (int i = start; i < end; i++) {
                 if ((values[i].mValue.getType() == INT &&
@@ -225,9 +232,36 @@
                     return true;
                 }
             }
-        }
             return false;
-        case FieldValueMatcher::ValueMatcherCase::kEqInt:
+        }
+        case FieldValueMatcher::ValueMatcherCase::kNeqAllString: {
+            const auto& str_list = matcher.neq_all_string();
+            for (int i = start; i < end; i++) {
+                bool notEqAll = true;
+                for (const auto& str : str_list.str_value()) {
+                    if (tryMatchString(uidMap, values[i].mField, values[i].mValue, str)) {
+                        notEqAll = false;
+                        break;
+                    }
+                }
+                if (notEqAll) {
+                    return true;
+                }
+            }
+            return false;
+        }
+        case FieldValueMatcher::ValueMatcherCase::kEqAnyString: {
+            const auto& str_list = matcher.eq_any_string();
+            for (int i = start; i < end; i++) {
+                for (const auto& str : str_list.str_value()) {
+                    if (tryMatchString(uidMap, values[i].mField, values[i].mValue, str)) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+        case FieldValueMatcher::ValueMatcherCase::kEqInt: {
             for (int i = start; i < end; i++) {
                 if (values[i].mValue.getType() == INT &&
                     (matcher.eq_int() == values[i].mValue.int_value)) {
@@ -240,7 +274,8 @@
                 }
             }
             return false;
-        case FieldValueMatcher::ValueMatcherCase::kLtInt:
+        }
+        case FieldValueMatcher::ValueMatcherCase::kLtInt: {
             for (int i = start; i < end; i++) {
                 if (values[i].mValue.getType() == INT &&
                     (values[i].mValue.int_value < matcher.lt_int())) {
@@ -253,7 +288,8 @@
                 }
             }
             return false;
-        case FieldValueMatcher::ValueMatcherCase::kGtInt:
+        }
+        case FieldValueMatcher::ValueMatcherCase::kGtInt: {
             for (int i = start; i < end; i++) {
                 if (values[i].mValue.getType() == INT &&
                     (values[i].mValue.int_value > matcher.gt_int())) {
@@ -266,7 +302,8 @@
                 }
             }
             return false;
-        case FieldValueMatcher::ValueMatcherCase::kLtFloat:
+        }
+        case FieldValueMatcher::ValueMatcherCase::kLtFloat: {
             for (int i = start; i < end; i++) {
                 if (values[i].mValue.getType() == FLOAT &&
                     (values[i].mValue.float_value < matcher.lt_float())) {
@@ -274,7 +311,8 @@
                 }
             }
             return false;
-        case FieldValueMatcher::ValueMatcherCase::kGtFloat:
+        }
+        case FieldValueMatcher::ValueMatcherCase::kGtFloat: {
             for (int i = start; i < end; i++) {
                 if (values[i].mValue.getType() == FLOAT &&
                     (values[i].mValue.float_value > matcher.gt_float())) {
@@ -282,7 +320,8 @@
                 }
             }
             return false;
-        case FieldValueMatcher::ValueMatcherCase::kLteInt:
+        }
+        case FieldValueMatcher::ValueMatcherCase::kLteInt: {
             for (int i = start; i < end; i++) {
                 if (values[i].mValue.getType() == INT &&
                     (values[i].mValue.int_value <= matcher.lte_int())) {
@@ -295,7 +334,8 @@
                 }
             }
             return false;
-        case FieldValueMatcher::ValueMatcherCase::kGteInt:
+        }
+        case FieldValueMatcher::ValueMatcherCase::kGteInt: {
             for (int i = start; i < end; i++) {
                 if (values[i].mValue.getType() == INT &&
                     (values[i].mValue.int_value >= matcher.gte_int())) {
@@ -308,6 +348,7 @@
                 }
             }
             return false;
+        }
         default:
             return false;
     }
diff --git a/cmds/statsd/src/matchers/matcher_util.h b/cmds/statsd/src/matchers/matcher_util.h
index 872cd8e..ae946d1 100644
--- a/cmds/statsd/src/matchers/matcher_util.h
+++ b/cmds/statsd/src/matchers/matcher_util.h
@@ -24,10 +24,10 @@
 #include <string>
 #include <unordered_map>
 #include <vector>
-#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
+#include "frameworks/base/cmds/statsd/src/stats_log_common.pb.h"
 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "stats_util.h"
 #include "packages/UidMap.h"
+#include "stats_util.h"
 
 namespace android {
 namespace os {
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index 9c65371..80329c3 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -101,6 +101,18 @@
     }
     mConditionSliced = (metric.links().size() > 0) || (mDimensionsInCondition.size() > 0);
 
+    if (mDimensionsInWhat.size() == mInternalDimensions.size()) {
+        bool mUseWhatDimensionAsInternalDimension = true;
+        for (size_t i = 0; mUseWhatDimensionAsInternalDimension &&
+            i < mDimensionsInWhat.size(); ++i) {
+            if (mDimensionsInWhat[i] != mInternalDimensions[i]) {
+                mUseWhatDimensionAsInternalDimension = false;
+            }
+        }
+    } else {
+        mUseWhatDimensionAsInternalDimension = false;
+    }
+
     VLOG("metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
          (long long)mBucketSizeNs, (long long)mStartTimeNs);
 }
@@ -109,9 +121,11 @@
     VLOG("~DurationMetric() called");
 }
 
-sp<AnomalyTracker> DurationMetricProducer::addAnomalyTracker(const Alert &alert) {
+sp<AnomalyTracker> DurationMetricProducer::addAnomalyTracker(
+        const Alert &alert, const sp<AlarmMonitor>& anomalyAlarmMonitor) {
     std::lock_guard<std::mutex> lock(mMutex);
-    sp<DurationAnomalyTracker> anomalyTracker = new DurationAnomalyTracker(alert, mConfigKey);
+    sp<DurationAnomalyTracker> anomalyTracker =
+        new DurationAnomalyTracker(alert, mConfigKey, anomalyAlarmMonitor);
     if (anomalyTracker != nullptr) {
         mAnomalyTrackers.push_back(anomalyTracker);
     }
@@ -139,29 +153,56 @@
     flushIfNeededLocked(eventTime);
 
     // Now for each of the on-going event, check if the condition has changed for them.
-    for (auto& pair : mCurrentSlicedDurationTrackerMap) {
-        pair.second->onSlicedConditionMayChange(eventTime);
+    for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
+        for (auto& pair : whatIt.second) {
+            pair.second->onSlicedConditionMayChange(eventTime);
+        }
     }
 
-
-    std::unordered_set<HashableDimensionKey> conditionDimensionsKeySet;
-    mWizard->getMetConditionDimension(mConditionTrackerIndex, mDimensionsInCondition,
-                                      &conditionDimensionsKeySet);
-
-    for (auto& pair : mCurrentSlicedDurationTrackerMap) {
-        conditionDimensionsKeySet.erase(pair.first.getDimensionKeyInCondition());
+    if (mDimensionsInCondition.empty()) {
+        return;
     }
-    std::unordered_set<MetricDimensionKey> newKeys;
-    for (const auto& conditionDimensionsKey : conditionDimensionsKeySet) {
-        for (auto& pair : mCurrentSlicedDurationTrackerMap) {
-            auto newKey =
-                MetricDimensionKey(pair.first.getDimensionKeyInWhat(), conditionDimensionsKey);
-            if (newKeys.find(newKey) == newKeys.end()) {
-                mCurrentSlicedDurationTrackerMap[newKey] = pair.second->clone(eventTime);
-                mCurrentSlicedDurationTrackerMap[newKey]->setEventKey(newKey);
-                mCurrentSlicedDurationTrackerMap[newKey]->onSlicedConditionMayChange(eventTime);
+
+    if (mMetric2ConditionLinks.empty()) {
+        std::unordered_set<HashableDimensionKey> conditionDimensionsKeySet;
+        mWizard->getMetConditionDimension(mConditionTrackerIndex, mDimensionsInCondition,
+                                          &conditionDimensionsKeySet);
+        for (const auto& whatIt : mCurrentSlicedDurationTrackerMap) {
+            for (const auto& pair : whatIt.second) {
+                conditionDimensionsKeySet.erase(pair.first);
             }
-            newKeys.insert(newKey);
+        }
+        for (const auto& conditionDimension : conditionDimensionsKeySet) {
+            for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
+                if (!whatIt.second.empty()) {
+                    unique_ptr<DurationTracker> newTracker =
+                        whatIt.second.begin()->second->clone(eventTime);
+                    newTracker->setEventKey(MetricDimensionKey(whatIt.first, conditionDimension));
+                    newTracker->onSlicedConditionMayChange(eventTime);
+                    whatIt.second[conditionDimension] = std::move(newTracker);
+                }
+            }
+        }
+    } else {
+        for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
+            ConditionKey conditionKey;
+            for (const auto& link : mMetric2ConditionLinks) {
+                getDimensionForCondition(whatIt.first.getValues(), link,
+                                         &conditionKey[link.conditionId]);
+            }
+            std::unordered_set<HashableDimensionKey> conditionDimensionsKeys;
+            mWizard->query(mConditionTrackerIndex, conditionKey, mDimensionsInCondition,
+                           &conditionDimensionsKeys);
+
+            for (const auto& conditionDimension : conditionDimensionsKeys) {
+                if (!whatIt.second.empty() &&
+                    whatIt.second.find(conditionDimension) == whatIt.second.end()) {
+                    auto newTracker = whatIt.second.begin()->second->clone(eventTime);
+                    newTracker->setEventKey(MetricDimensionKey(whatIt.first, conditionDimension));
+                    newTracker->onSlicedConditionMayChange(eventTime);
+                    whatIt.second[conditionDimension] = std::move(newTracker);
+                }
+            }
         }
     }
 }
@@ -173,8 +214,10 @@
     flushIfNeededLocked(eventTime);
     // TODO: need to populate the condition change time from the event which triggers the condition
     // change, instead of using current time.
-    for (auto& pair : mCurrentSlicedDurationTrackerMap) {
-        pair.second->onConditionChanged(conditionMet, eventTime);
+    for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
+        for (auto& pair : whatIt.second) {
+            pair.second->onConditionChanged(conditionMet, eventTime);
+        }
     }
 }
 
@@ -239,13 +282,20 @@
         return;
     }
     VLOG("flushing...........");
-    for (auto it = mCurrentSlicedDurationTrackerMap.begin();
-            it != mCurrentSlicedDurationTrackerMap.end();) {
-        if (it->second->flushIfNeeded(eventTimeNs, &mPastBuckets)) {
-            VLOG("erase bucket for key %s", it->first.c_str());
-            it = mCurrentSlicedDurationTrackerMap.erase(it);
+    for (auto whatIt = mCurrentSlicedDurationTrackerMap.begin();
+            whatIt != mCurrentSlicedDurationTrackerMap.end();) {
+        for (auto it = whatIt->second.begin(); it != whatIt->second.end();) {
+            if (it->second->flushIfNeeded(eventTimeNs, &mPastBuckets)) {
+                VLOG("erase bucket for key %s %s", whatIt->first.c_str(), it->first.c_str());
+                it = whatIt->second.erase(it);
+            } else {
+                ++it;
+            }
+        }
+        if (whatIt->second.empty()) {
+            whatIt = mCurrentSlicedDurationTrackerMap.erase(whatIt);
         } else {
-            ++it;
+            whatIt++;
         }
     }
 
@@ -255,13 +305,20 @@
 }
 
 void DurationMetricProducer::flushCurrentBucketLocked(const uint64_t& eventTimeNs) {
-    for (auto it = mCurrentSlicedDurationTrackerMap.begin();
-         it != mCurrentSlicedDurationTrackerMap.end();) {
-        if (it->second->flushCurrentBucket(eventTimeNs, &mPastBuckets)) {
-            VLOG("erase bucket for key %s", it->first.c_str());
-            it = mCurrentSlicedDurationTrackerMap.erase(it);
+    for (auto whatIt = mCurrentSlicedDurationTrackerMap.begin();
+            whatIt != mCurrentSlicedDurationTrackerMap.end();) {
+        for (auto it = whatIt->second.begin(); it != whatIt->second.end();) {
+            if (it->second->flushCurrentBucket(eventTimeNs, &mPastBuckets)) {
+                VLOG("erase bucket for key %s %s", whatIt->first.c_str(), it->first.c_str());
+                it = whatIt->second.erase(it);
+            } else {
+                ++it;
+            }
+        }
+        if (whatIt->second.empty()) {
+            whatIt = mCurrentSlicedDurationTrackerMap.erase(whatIt);
         } else {
-            ++it;
+            whatIt++;
         }
     }
 }
@@ -274,18 +331,16 @@
     fprintf(out, "DurationMetric %lld dimension size %lu\n", (long long)mMetricId,
             (unsigned long)mCurrentSlicedDurationTrackerMap.size());
     if (verbose) {
-        for (const auto& slice : mCurrentSlicedDurationTrackerMap) {
-            fprintf(out, "\t%s\n", slice.first.c_str());
-            slice.second->dumpStates(out, verbose);
+        for (const auto& whatIt : mCurrentSlicedDurationTrackerMap) {
+            for (const auto& slice : whatIt.second) {
+                fprintf(out, "\t%s\t%s\n", whatIt.first.c_str(), slice.first.c_str());
+                slice.second->dumpStates(out, verbose);
+            }
         }
     }
 }
 
 bool DurationMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey) {
-    // the key is not new, we are good.
-    if (mCurrentSlicedDurationTrackerMap.find(newKey) != mCurrentSlicedDurationTrackerMap.end()) {
-        return false;
-    }
     // 1. Report the tuple count if the tuple count > soft limit
     if (mCurrentSlicedDurationTrackerMap.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
         size_t newTupleCount = mCurrentSlicedDurationTrackerMap.size() + 1;
@@ -300,49 +355,162 @@
     return false;
 }
 
-void DurationMetricProducer::onMatchedLogEventInternalLocked(
-        const size_t matcherIndex, const MetricDimensionKey& eventKey,
-        const ConditionKey& conditionKeys, bool condition,
-        const LogEvent& event) {
-    flushIfNeededLocked(event.GetElapsedTimestampNs());
+void DurationMetricProducer::handleStartEvent(const MetricDimensionKey& eventKey,
+                                              const ConditionKey& conditionKeys,
+                                              bool condition, const LogEvent& event) {
+    const auto& whatKey = eventKey.getDimensionKeyInWhat();
+    const auto& condKey = eventKey.getDimensionKeyInCondition();
 
-    if (matcherIndex == mStopAllIndex) {
-        for (auto& pair : mCurrentSlicedDurationTrackerMap) {
-            pair.second->noteStopAll(event.GetElapsedTimestampNs());
-        }
-        return;
-    }
-
-    if (mCurrentSlicedDurationTrackerMap.find(eventKey) == mCurrentSlicedDurationTrackerMap.end()) {
+    auto whatIt = mCurrentSlicedDurationTrackerMap.find(whatKey);
+    if (whatIt == mCurrentSlicedDurationTrackerMap.end()) {
         if (hitGuardRailLocked(eventKey)) {
             return;
         }
-        mCurrentSlicedDurationTrackerMap[eventKey] = createDurationTracker(eventKey);
+        mCurrentSlicedDurationTrackerMap[whatKey][condKey] = createDurationTracker(eventKey);
+    } else {
+        if (whatIt->second.find(condKey) == whatIt->second.end()) {
+            if (hitGuardRailLocked(eventKey)) {
+                return;
+            }
+            mCurrentSlicedDurationTrackerMap[whatKey][condKey] = createDurationTracker(eventKey);
+        }
     }
 
-    auto it = mCurrentSlicedDurationTrackerMap.find(eventKey);
+    auto it = mCurrentSlicedDurationTrackerMap.find(whatKey)->second.find(condKey);
+    if (mUseWhatDimensionAsInternalDimension) {
+        it->second->noteStart(whatKey, condition,
+                              event.GetElapsedTimestampNs(), conditionKeys);
+        return;
+    }
 
     std::vector<HashableDimensionKey> values;
     filterValues(mInternalDimensions, event.getValues(), &values);
     if (values.empty()) {
-        if (matcherIndex == mStartIndex) {
-            it->second->noteStart(DEFAULT_DIMENSION_KEY, condition,
-                                  event.GetElapsedTimestampNs(), conditionKeys);
-        } else if (matcherIndex == mStopIndex) {
-            it->second->noteStop(DEFAULT_DIMENSION_KEY, event.GetElapsedTimestampNs(), false);
-        }
+        it->second->noteStart(DEFAULT_DIMENSION_KEY, condition,
+                              event.GetElapsedTimestampNs(), conditionKeys);
     } else {
         for (const auto& value : values) {
-            if (matcherIndex == mStartIndex) {
-                it->second->noteStart(value, condition, event.GetElapsedTimestampNs(), conditionKeys);
-            } else if (matcherIndex == mStopIndex) {
-                it->second->noteStop(value, event.GetElapsedTimestampNs(), false);
-            }
+            it->second->noteStart(value, condition, event.GetElapsedTimestampNs(), conditionKeys);
         }
     }
 
 }
 
+void DurationMetricProducer::onMatchedLogEventInternalLocked(
+        const size_t matcherIndex, const MetricDimensionKey& eventKey,
+        const ConditionKey& conditionKeys, bool condition,
+        const LogEvent& event) {
+    ALOGW("Not used in duration tracker.");
+}
+
+void DurationMetricProducer::onMatchedLogEventLocked(const size_t matcherIndex,
+                                                     const LogEvent& event) {
+    uint64_t eventTimeNs = event.GetElapsedTimestampNs();
+    if (eventTimeNs < mStartTimeNs) {
+        return;
+    }
+
+    flushIfNeededLocked(event.GetElapsedTimestampNs());
+
+    // Handles Stopall events.
+    if (matcherIndex == mStopAllIndex) {
+        for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
+            for (auto& pair : whatIt.second) {
+                pair.second->noteStopAll(event.GetElapsedTimestampNs());
+            }
+        }
+        return;
+    }
+
+    vector<HashableDimensionKey> dimensionInWhatValues;
+    if (!mDimensionsInWhat.empty()) {
+        filterValues(mDimensionsInWhat, event.getValues(), &dimensionInWhatValues);
+    } else {
+        dimensionInWhatValues.push_back(DEFAULT_DIMENSION_KEY);
+    }
+
+    // Handles Stop events.
+    if (matcherIndex == mStopIndex) {
+        if (mUseWhatDimensionAsInternalDimension) {
+            for (const HashableDimensionKey& whatKey : dimensionInWhatValues) {
+                auto whatIt = mCurrentSlicedDurationTrackerMap.find(whatKey);
+                if (whatIt != mCurrentSlicedDurationTrackerMap.end()) {
+                    for (const auto& condIt : whatIt->second) {
+                        condIt.second->noteStop(whatKey, event.GetElapsedTimestampNs(), false);
+                    }
+                }
+            }
+            return;
+        }
+
+        std::vector<HashableDimensionKey> internalDimensionKeys;
+        filterValues(mInternalDimensions, event.getValues(), &internalDimensionKeys);
+        if (internalDimensionKeys.empty()) {
+            internalDimensionKeys.push_back(DEFAULT_DIMENSION_KEY);
+        }
+        for (const HashableDimensionKey& whatDimension : dimensionInWhatValues) {
+            auto whatIt = mCurrentSlicedDurationTrackerMap.find(whatDimension);
+            if (whatIt != mCurrentSlicedDurationTrackerMap.end()) {
+                for (const auto& condIt : whatIt->second) {
+                    for (const auto& internalDimensionKey : internalDimensionKeys) {
+                        condIt.second->noteStop(
+                            internalDimensionKey, event.GetElapsedTimestampNs(), false);
+                    }
+                }
+            }
+        }
+        return;
+    }
+
+    bool condition;
+    ConditionKey conditionKey;
+    std::unordered_set<HashableDimensionKey> dimensionKeysInCondition;
+    if (mConditionSliced) {
+        for (const auto& link : mMetric2ConditionLinks) {
+            getDimensionForCondition(event.getValues(), link, &conditionKey[link.conditionId]);
+        }
+
+        auto conditionState =
+            mWizard->query(mConditionTrackerIndex, conditionKey, mDimensionsInCondition,
+                           &dimensionKeysInCondition);
+        condition = (conditionState == ConditionState::kTrue);
+        if (mDimensionsInCondition.empty() && condition) {
+            dimensionKeysInCondition.insert(DEFAULT_DIMENSION_KEY);
+        }
+    } else {
+        condition = mCondition;
+        if (condition) {
+            dimensionKeysInCondition.insert(DEFAULT_DIMENSION_KEY);
+        }
+    }
+
+    for (const auto& whatDimension : dimensionInWhatValues) {
+        auto whatIt = mCurrentSlicedDurationTrackerMap.find(whatDimension);
+        // If the what dimension is already there, we should update all the trackers even
+        // the condition is false.
+        if (whatIt != mCurrentSlicedDurationTrackerMap.end()) {
+            for (const auto& condIt : whatIt->second) {
+                const bool cond = dimensionKeysInCondition.find(condIt.first) !=
+                        dimensionKeysInCondition.end();
+                handleStartEvent(MetricDimensionKey(whatDimension, condIt.first),
+                                 conditionKey, cond, event);
+            }
+        } else {
+            // If it is a new what dimension key, we need to handle the start events for all current
+            // condition dimensions.
+            for (const auto& conditionDimension : dimensionKeysInCondition) {
+                handleStartEvent(MetricDimensionKey(whatDimension, conditionDimension),
+                                 conditionKey, condition, event);
+            }
+        }
+        if (dimensionKeysInCondition.empty()) {
+            handleStartEvent(MetricDimensionKey(whatDimension, DEFAULT_DIMENSION_KEY),
+                             conditionKey, condition, event);
+        }
+    }
+}
+
+
 size_t DurationMetricProducer::byteSizeLocked() const {
     size_t totalSize = 0;
     for (const auto& pair : mPastBuckets) {
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h
index 5f29281..73d074f 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.h
@@ -46,15 +46,20 @@
 
     virtual ~DurationMetricProducer();
 
-    sp<AnomalyTracker> addAnomalyTracker(const Alert &alert) override;
+    sp<AnomalyTracker> addAnomalyTracker(const Alert &alert,
+                                         const sp<AlarmMonitor>& anomalyAlarmMonitor) override;
 
 protected:
+    void onMatchedLogEventLocked(const size_t matcherIndex, const LogEvent& event) override;
     void onMatchedLogEventInternalLocked(
             const size_t matcherIndex, const MetricDimensionKey& eventKey,
             const ConditionKey& conditionKeys, bool condition,
             const LogEvent& event) override;
 
 private:
+    void handleStartEvent(const MetricDimensionKey& eventKey, const ConditionKey& conditionKeys,
+                          bool condition, const LogEvent& event);
+
     void onDumpReportLocked(const uint64_t dumpTimeNs,
                             android::util::ProtoOutputStream* protoOutput) override;
 
@@ -91,12 +96,16 @@
     // The dimension from the atom predicate. e.g., uid, wakelock name.
     vector<Matcher> mInternalDimensions;
 
+    // This boolean is true iff When mInternalDimensions == mDimensionsInWhat
+    bool mUseWhatDimensionAsInternalDimension;
+
     // Save the past buckets and we can clear when the StatsLogReport is dumped.
     // TODO: Add a lock to mPastBuckets.
     std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>> mPastBuckets;
 
-    // The current bucket.
-    std::unordered_map<MetricDimensionKey, std::unique_ptr<DurationTracker>>
+    // The duration trackers in the current bucket.
+    std::unordered_map<HashableDimensionKey,
+        std::unordered_map<HashableDimensionKey, std::unique_ptr<DurationTracker>>>
             mCurrentSlicedDurationTrackerMap;
 
     // Helper function to create a duration tracker given the metric aggregation type.
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp
index fddfd93..96d0cfc 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/EventMetricProducer.cpp
@@ -129,8 +129,6 @@
 
     long long wrapperToken =
             mProto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
-
-    long long eventToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOMS);
     const bool truncateTimestamp =
         android::util::kNotTruncatingTimestampAtomWhiteList.find(event.GetTagId()) ==
         android::util::kNotTruncatingTimestampAtomWhiteList.end();
@@ -145,6 +143,8 @@
         mProto->write(FIELD_TYPE_INT64 | FIELD_ID_WALL_CLOCK_TIMESTAMP_NANOS,
             (long long)getWallClockNs());
     }
+
+    long long eventToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOMS);
     event.ToProto(*mProto);
     mProto->end(eventToken);
     mProto->end(wrapperToken);
diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp
index f3307dc..18694a1 100644
--- a/cmds/statsd/src/metrics/MetricProducer.cpp
+++ b/cmds/statsd/src/metrics/MetricProducer.cpp
@@ -37,7 +37,7 @@
     std::unordered_set<HashableDimensionKey> dimensionKeysInCondition;
     if (mConditionSliced) {
         for (const auto& link : mMetric2ConditionLinks) {
-            getDimensionForCondition(event, link, &conditionKey[link.conditionId]);
+            getDimensionForCondition(event.getValues(), link, &conditionKey[link.conditionId]);
         }
 
         auto conditionState =
@@ -48,37 +48,30 @@
         condition = mCondition;
     }
 
-    vector<HashableDimensionKey> dimensionInWhatValues;
-    if (mDimensionsInWhat.size() > 0) {
-        filterValues(mDimensionsInWhat, event.getValues(), &dimensionInWhatValues);
+    if (mDimensionsInCondition.empty() && condition) {
+        dimensionKeysInCondition.insert(DEFAULT_DIMENSION_KEY);
     }
 
-    if (dimensionInWhatValues.empty() && dimensionKeysInCondition.empty()) {
-        onMatchedLogEventInternalLocked(
-            matcherIndex, DEFAULT_METRIC_DIMENSION_KEY, conditionKey, condition, event);
-    } else if (dimensionKeysInCondition.empty()) {
-        for (const HashableDimensionKey& whatValue : dimensionInWhatValues) {
-            onMatchedLogEventInternalLocked(matcherIndex,
-                                            MetricDimensionKey(whatValue, DEFAULT_DIMENSION_KEY),
-                                            conditionKey, condition, event);
-        }
-    } else if (dimensionInWhatValues.empty()) {
+    vector<HashableDimensionKey> dimensionInWhatValues;
+    if (!mDimensionsInWhat.empty()) {
+        filterValues(mDimensionsInWhat, event.getValues(), &dimensionInWhatValues);
+    } else {
+        dimensionInWhatValues.push_back(DEFAULT_DIMENSION_KEY);
+    }
+
+    for (const auto& whatDimension : dimensionInWhatValues) {
         for (const auto& conditionDimensionKey : dimensionKeysInCondition) {
             onMatchedLogEventInternalLocked(
-                matcherIndex,
-                MetricDimensionKey(DEFAULT_DIMENSION_KEY, conditionDimensionKey),
-                conditionKey, condition, event);
+                    matcherIndex, MetricDimensionKey(whatDimension, conditionDimensionKey),
+                    conditionKey, condition, event);
         }
-    } else {
-        for (const auto& whatValue : dimensionInWhatValues) {
-            for (const auto& conditionDimensionKey : dimensionKeysInCondition) {
-                onMatchedLogEventInternalLocked(
-                        matcherIndex, MetricDimensionKey(whatValue, conditionDimensionKey),
-                        conditionKey, condition, event);
-            }
+        if (dimensionKeysInCondition.empty()) {
+            onMatchedLogEventInternalLocked(
+                    matcherIndex, MetricDimensionKey(whatDimension, DEFAULT_DIMENSION_KEY),
+                     conditionKey, condition, event);
         }
     }
-}
+ }
 
 }  // namespace statsd
 }  // namespace os
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index 8663e5e..2bf6241 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -124,7 +124,8 @@
     }
 
     /* If alert is valid, adds an AnomalyTracker and returns it. If invalid, returns nullptr. */
-    virtual sp<AnomalyTracker> addAnomalyTracker(const Alert &alert) {
+    virtual sp<AnomalyTracker> addAnomalyTracker(const Alert &alert,
+                                                 const sp<AlarmMonitor>& anomalyAlarmMonitor) {
         std::lock_guard<std::mutex> lock(mMutex);
         sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert, mConfigKey);
         if (anomalyTracker != nullptr) {
@@ -232,7 +233,7 @@
             const LogEvent& event) = 0;
 
     // Consume the parsed stats log entry that already matched the "what" of the metric.
-    void onMatchedLogEventLocked(const size_t matcherIndex, const LogEvent& event);
+    virtual void onMatchedLogEventLocked(const size_t matcherIndex, const LogEvent& event);
 
     mutable std::mutex mMutex;
 };
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index e75b710..4c8a7d8 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -49,13 +49,17 @@
 const int FIELD_ID_METRICS = 1;
 
 MetricsManager::MetricsManager(const ConfigKey& key, const StatsdConfig& config,
-                               const long timeBaseSec, sp<UidMap> uidMap)
+                               const long timeBaseSec,
+                               const sp<UidMap> &uidMap,
+                               const sp<AlarmMonitor>& anomalyAlarmMonitor,
+                               const sp<AlarmMonitor>& periodicAlarmMonitor)
     : mConfigKey(key), mUidMap(uidMap), mLastReportTimeNs(timeBaseSec * NS_PER_SEC) {
     mConfigValid =
-            initStatsdConfig(key, config, *uidMap, timeBaseSec, mTagIds, mAllAtomMatchers,
-                             mAllConditionTrackers,
-                             mAllMetricProducers, mAllAnomalyTrackers, mConditionToMetricMap,
-                             mTrackerToMetricMap, mTrackerToConditionMap, mNoReportMetricIds);
+            initStatsdConfig(key, config, *uidMap, anomalyAlarmMonitor, periodicAlarmMonitor,
+                             timeBaseSec, mTagIds, mAllAtomMatchers,
+                             mAllConditionTrackers, mAllMetricProducers, mAllAnomalyTrackers,
+                             mAllPeriodicAlarmTrackers, mConditionToMetricMap, mTrackerToMetricMap,
+                             mTrackerToConditionMap, mNoReportMetricIds);
 
     if (config.allowed_log_source_size() == 0) {
         // TODO(b/70794411): uncomment the following line and remove the hard coded log source
@@ -198,31 +202,59 @@
         // Uid is 3rd from last field and must match the caller's uid,
         // unless that caller is statsd itself (statsd is allowed to spoof uids).
         long appHookUid = event.GetLong(event.size()-2, &err);
+        if (err != NO_ERROR ) {
+            VLOG("APP_BREADCRUMB_REPORTED had error when parsing the uid");
+            return;
+        }
         int32_t loggerUid = event.GetUid();
-        if (err != NO_ERROR || (loggerUid != appHookUid && loggerUid != AID_STATSD)) {
-            VLOG("AppHook has invalid uid: claimed %ld but caller is %d", appHookUid, loggerUid);
+        if (loggerUid != appHookUid && loggerUid != AID_STATSD) {
+            VLOG("APP_BREADCRUMB_REPORTED has invalid uid: claimed %ld but caller is %d",
+                 appHookUid, loggerUid);
             return;
         }
 
         // Label is 2nd from last field and must be from [0, 15].
         long appHookLabel = event.GetLong(event.size()-1, &err);
-        if (err != NO_ERROR || appHookLabel < 0 || appHookLabel > 15) {
-            VLOG("AppHook does not have valid label %ld", appHookLabel);
+        if (err != NO_ERROR ) {
+            VLOG("APP_BREADCRUMB_REPORTED had error when parsing the label field");
+            return;
+        } else if (appHookLabel < 0 || appHookLabel > 15) {
+            VLOG("APP_BREADCRUMB_REPORTED does not have valid label %ld", appHookLabel);
             return;
         }
 
         // The state must be from 0,3. This part of code must be manually updated.
         long appHookState = event.GetLong(event.size(), &err);
-        if (err != NO_ERROR || appHookState < 0 || appHookState > 3) {
-            VLOG("AppHook does not have valid state %ld", appHookState);
+        if (err != NO_ERROR ) {
+            VLOG("APP_BREADCRUMB_REPORTED had error when parsing the state field");
+            return;
+        } else if (appHookState < 0 || appHookState > 3) {
+            VLOG("APP_BREADCRUMB_REPORTED does not have valid state %ld", appHookState);
             return;
         }
     } else if (event.GetTagId() == android::util::DAVEY_OCCURRED) {
         // Daveys can be logged from any app since they are logged in libs/hwui/JankTracker.cpp.
         // Check that the davey duration is reasonable. Max length check is for privacy.
         status_t err = NO_ERROR;
+
+        // Uid is the first field provided.
+        long jankUid = event.GetLong(1, &err);
+        if (err != NO_ERROR ) {
+            VLOG("Davey occurred had error when parsing the uid");
+            return;
+        }
+        int32_t loggerUid = event.GetUid();
+        if (loggerUid != jankUid && loggerUid != AID_STATSD) {
+            VLOG("DAVEY_OCCURRED has invalid uid: claimed %ld but caller is %d", jankUid,
+                 loggerUid);
+            return;
+        }
+
         long duration = event.GetLong(event.size(), &err);
-        if (err != NO_ERROR || duration > 100000) {
+        if (err != NO_ERROR ) {
+            VLOG("Davey occurred had error when parsing the duration");
+            return;
+        } else if (duration > 100000) {
             VLOG("Davey duration is unreasonably long: %ld", duration);
             return;
         }
@@ -312,16 +344,19 @@
     }
 }
 
-void MetricsManager::onAnomalyAlarmFired(const uint64_t timestampNs,
-                         unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>>& anomalySet) {
+void MetricsManager::onAnomalyAlarmFired(
+        const uint64_t timestampNs,
+        unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet) {
     for (const auto& itr : mAllAnomalyTrackers) {
-        itr->informAlarmsFired(timestampNs, anomalySet);
+        itr->informAlarmsFired(timestampNs, alarmSet);
     }
 }
 
-void MetricsManager::setAnomalyMonitor(const sp<AnomalyMonitor>& anomalyMonitor) {
-    for (auto& itr : mAllAnomalyTrackers) {
-        itr->setAnomalyMonitor(anomalyMonitor);
+void MetricsManager::onPeriodicAlarmFired(
+        const uint64_t timestampNs,
+        unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet) {
+    for (const auto& itr : mAllPeriodicAlarmTrackers) {
+        itr->informAlarmsFired(timestampNs, alarmSet);
     }
 }
 
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index d4f844f..b50ef4a 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -16,7 +16,8 @@
 
 #pragma once
 
-#include "anomaly/AnomalyMonitor.h"
+#include "anomaly/AlarmMonitor.h"
+#include "anomaly/AlarmTracker.h"
 #include "anomaly/AnomalyTracker.h"
 #include "condition/ConditionTracker.h"
 #include "config/ConfigKey.h"
@@ -36,7 +37,8 @@
 class MetricsManager : public PackageInfoListener {
 public:
     MetricsManager(const ConfigKey& configKey, const StatsdConfig& config, const long timeBaseSec,
-                   sp<UidMap> uidMap);
+                   const sp<UidMap>& uidMap, const sp<AlarmMonitor>& anomalyAlarmMonitor,
+                   const sp<AlarmMonitor>& periodicAlarmMonitor);
 
     virtual ~MetricsManager();
 
@@ -47,9 +49,11 @@
 
     void onAnomalyAlarmFired(
         const uint64_t timestampNs,
-        unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>>& anomalySet);
+        unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet);
 
-    void setAnomalyMonitor(const sp<AnomalyMonitor>& anomalyMonitor);
+    void onPeriodicAlarmFired(
+        const uint64_t timestampNs,
+        unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet);
 
     void notifyAppUpgrade(const uint64_t& eventTimeNs, const string& apk, const int uid,
                           const int64_t version) override;
@@ -120,6 +124,9 @@
     // Hold all alert trackers.
     std::vector<sp<AnomalyTracker>> mAllAnomalyTrackers;
 
+    // Hold all periodic alarm trackers.
+    std::vector<sp<AlarmTracker>> mAllPeriodicAlarmTrackers;
+
     // To make the log processing more efficient, we want to do as much filtering as possible
     // before we go into individual trackers and conditions to match.
 
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp
index 71e5c33..9912afa 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.cpp
+++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp
@@ -17,16 +17,19 @@
 #define DEBUG false  // STOPSHIP if true
 #include "Log.h"
 
+#include "metrics_manager_util.h"
+
 #include "../condition/CombinationConditionTracker.h"
 #include "../condition/SimpleConditionTracker.h"
 #include "../external/StatsPullerManager.h"
 #include "../matchers/CombinationLogMatchingTracker.h"
 #include "../matchers/SimpleLogMatchingTracker.h"
-#include "CountMetricProducer.h"
-#include "DurationMetricProducer.h"
-#include "EventMetricProducer.h"
-#include "GaugeMetricProducer.h"
-#include "ValueMetricProducer.h"
+#include "../metrics/CountMetricProducer.h"
+#include "../metrics/DurationMetricProducer.h"
+#include "../metrics/EventMetricProducer.h"
+#include "../metrics/GaugeMetricProducer.h"
+#include "../metrics/ValueMetricProducer.h"
+
 #include "stats_util.h"
 
 using std::set;
@@ -494,6 +497,7 @@
 
 bool initAlerts(const StatsdConfig& config,
                 const unordered_map<int64_t, int>& metricProducerMap,
+                const sp<AlarmMonitor>& anomalyAlarmMonitor,
                 vector<sp<MetricProducer>>& allMetricProducers,
                 vector<sp<AnomalyTracker>>& allAnomalyTrackers) {
     unordered_map<int64_t, int> anomalyTrackerMap;
@@ -512,7 +516,7 @@
         }
         const int metricIndex = itr->second;
         sp<MetricProducer> metric = allMetricProducers[metricIndex];
-        sp<AnomalyTracker> anomalyTracker = metric->addAnomalyTracker(alert);
+        sp<AnomalyTracker> anomalyTracker = metric->addAnomalyTracker(alert, anomalyAlarmMonitor);
         if (anomalyTracker == nullptr) {
             // The ALOGW for this invalid alert was already displayed in addAnomalyTracker().
             return false;
@@ -522,6 +526,9 @@
     }
     for (int i = 0; i < config.subscription_size(); ++i) {
         const Subscription& subscription = config.subscription(i);
+        if (subscription.rule_type() != Subscription::ALERT) {
+            continue;
+        }
         if (subscription.subscriber_information_case() ==
             Subscription::SubscriberInformationCase::SUBSCRIBER_INFORMATION_NOT_SET) {
             ALOGW("subscription \"%lld\" has no subscriber info.\"",
@@ -540,13 +547,60 @@
     return true;
 }
 
+bool initAlarms(const StatsdConfig& config, const ConfigKey& key,
+                const sp<AlarmMonitor>& periodicAlarmMonitor,
+                const long timeBaseSec,
+                vector<sp<AlarmTracker>>& allAlarmTrackers) {
+    unordered_map<int64_t, int> alarmTrackerMap;
+    uint64_t startMillis = (uint64_t)timeBaseSec * MS_PER_SEC;
+    for (int i = 0; i < config.alarm_size(); i++) {
+        const Alarm& alarm = config.alarm(i);
+        if (alarm.offset_millis() <= 0) {
+            ALOGW("Alarm offset_millis should be larger than 0.");
+            return false;
+        }
+        if (alarm.period_millis() <= 0) {
+            ALOGW("Alarm period_millis should be larger than 0.");
+            return false;
+        }
+        alarmTrackerMap.insert(std::make_pair(alarm.id(), allAlarmTrackers.size()));
+        allAlarmTrackers.push_back(
+            new AlarmTracker(startMillis, alarm, key, periodicAlarmMonitor));
+    }
+    for (int i = 0; i < config.subscription_size(); ++i) {
+        const Subscription& subscription = config.subscription(i);
+        if (subscription.rule_type() != Subscription::ALARM) {
+            continue;
+        }
+        if (subscription.subscriber_information_case() ==
+            Subscription::SubscriberInformationCase::SUBSCRIBER_INFORMATION_NOT_SET) {
+            ALOGW("subscription \"%lld\" has no subscriber info.\"",
+                (long long)subscription.id());
+            return false;
+        }
+        const auto& itr = alarmTrackerMap.find(subscription.rule_id());
+        if (itr == alarmTrackerMap.end()) {
+            ALOGW("subscription \"%lld\" has unknown rule id: \"%lld\"",
+                (long long)subscription.id(), (long long)subscription.rule_id());
+            return false;
+        }
+        const int trackerIndex = itr->second;
+        allAlarmTrackers[trackerIndex]->addSubscription(subscription);
+    }
+    return true;
+}
+
 bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config,
                       const UidMap& uidMap,
-                      const long timeBaseSec, set<int>& allTagIds,
+                      const sp<AlarmMonitor>& anomalyAlarmMonitor,
+                      const sp<AlarmMonitor>& periodicAlarmMonitor,
+                      const long timeBaseSec,
+                      set<int>& allTagIds,
                       vector<sp<LogMatchingTracker>>& allAtomMatchers,
                       vector<sp<ConditionTracker>>& allConditionTrackers,
                       vector<sp<MetricProducer>>& allMetricProducers,
                       vector<sp<AnomalyTracker>>& allAnomalyTrackers,
+                      vector<sp<AlarmTracker>>& allPeriodicAlarmTrackers,
                       unordered_map<int, std::vector<int>>& conditionToMetricMap,
                       unordered_map<int, std::vector<int>>& trackerToMetricMap,
                       unordered_map<int, std::vector<int>>& trackerToConditionMap,
@@ -573,10 +627,16 @@
         ALOGE("initMetricProducers failed");
         return false;
     }
-    if (!initAlerts(config, metricProducerMap, allMetricProducers, allAnomalyTrackers)) {
+    if (!initAlerts(config, metricProducerMap, anomalyAlarmMonitor, allMetricProducers,
+                    allAnomalyTrackers)) {
         ALOGE("initAlerts failed");
         return false;
     }
+    if (!initAlarms(config, key, periodicAlarmMonitor, timeBaseSec, allPeriodicAlarmTrackers)) {
+        ALOGE("initAlarms failed");
+        return false;
+    }
+
     return true;
 }
 
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.h b/cmds/statsd/src/metrics/metrics_manager_util.h
index 4f19ada..edda53d 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.h
+++ b/cmds/statsd/src/metrics/metrics_manager_util.h
@@ -13,16 +13,19 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef METRIC_UTIL_H
-#define METRIC_UTIL_H
+
+#pragma once
+
 #include <memory>
 #include <set>
 #include <unordered_map>
 #include <vector>
 
+#include "../anomaly/AlarmTracker.h"
 #include "../condition/ConditionTracker.h"
 #include "../external/StatsPullerManagerImpl.h"
 #include "../matchers/LogMatchingTracker.h"
+#include "../metrics/MetricProducer.h"
 
 namespace android {
 namespace os {
@@ -93,11 +96,15 @@
 // Parameters are the members of MetricsManager. See MetricsManager for declaration.
 bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config,
                       const UidMap& uidMap,
-                      const long timeBaseSec, std::set<int>& allTagIds,
+                      const sp<AlarmMonitor>& anomalyAlarmMonitor,
+                      const sp<AlarmMonitor>& periodicAlarmMonitor,
+                      const long timeBaseSec,
+                      std::set<int>& allTagIds,
                       std::vector<sp<LogMatchingTracker>>& allAtomMatchers,
                       std::vector<sp<ConditionTracker>>& allConditionTrackers,
                       std::vector<sp<MetricProducer>>& allMetricProducers,
                       vector<sp<AnomalyTracker>>& allAnomalyTrackers,
+                      vector<sp<AlarmTracker>>& allPeriodicAlarmTrackers,
                       std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
                       std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
                       std::unordered_map<int, std::vector<int>>& trackerToConditionMap,
@@ -106,4 +113,3 @@
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
-#endif  // METRIC_UTIL_H
diff --git a/cmds/statsd/src/packages/UidMap.h b/cmds/statsd/src/packages/UidMap.h
index f1da452..c41e0aa 100644
--- a/cmds/statsd/src/packages/UidMap.h
+++ b/cmds/statsd/src/packages/UidMap.h
@@ -18,7 +18,7 @@
 
 #include "config/ConfigKey.h"
 #include "config/ConfigListener.h"
-#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
+#include "frameworks/base/cmds/statsd/src/stats_log_common.pb.h"
 #include "packages/PackageInfoListener.h"
 
 #include <binder/IResultReceiver.h>
diff --git a/cmds/statsd/src/perfetto/perfetto_config.proto b/cmds/statsd/src/perfetto/perfetto_config.proto
index dc868f9..56d12f8 100644
--- a/cmds/statsd/src/perfetto/perfetto_config.proto
+++ b/cmds/statsd/src/perfetto/perfetto_config.proto
@@ -15,7 +15,6 @@
  */
 
 syntax = "proto2";
-option optimize_for = LITE_RUNTIME;
 
 package perfetto.protos;
 
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index b427485..269f25b 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -15,7 +15,6 @@
  */
 
 syntax = "proto2";
-option optimize_for = LITE_RUNTIME;
 
 package android.os.statsd;
 
@@ -23,6 +22,7 @@
 option java_outer_classname = "StatsLog";
 
 import "frameworks/base/cmds/statsd/src/atoms.proto";
+import "frameworks/base/cmds/statsd/src/stats_log_common.proto";
 
 message DimensionsValue {
   optional int32 field = 1;
@@ -115,33 +115,6 @@
   repeated GaugeBucketInfo bucket_info = 3;
 }
 
-message UidMapping {
-  message PackageInfoSnapshot {
-    message PackageInfo {
-      optional string name = 1;
-
-      optional int64 version = 2;
-
-      optional int32 uid = 3;
-    }
-    optional int64 elapsed_timestamp_nanos = 1;
-
-    repeated PackageInfo package_info = 2;
-  }
-  repeated PackageInfoSnapshot snapshots = 1;
-
-  message Change {
-    optional bool deletion = 1;
-
-    optional int64 elapsed_timestamp_nanos = 2;
-    optional string app = 3;
-    optional int32 uid = 4;
-
-    optional int64 version = 5;
-  }
-  repeated Change changes = 2;
-}
-
 message StatsLogReport {
   optional int64 metric_id = 1;
 
@@ -192,86 +165,3 @@
 
   repeated ConfigMetricsReport reports = 2;
 }
-
-message StatsdStatsReport {
-  optional int32 stats_begin_time_sec = 1;
-
-  optional int32 stats_end_time_sec = 2;
-
-  message MatcherStats {
-    optional int64 id = 1;
-    optional int32 matched_times = 2;
-  }
-
-  message ConditionStats {
-    optional int64 id = 1;
-    optional int32 max_tuple_counts = 2;
-  }
-
-  message MetricStats {
-    optional int64 id = 1;
-    optional int32 max_tuple_counts = 2;
-  }
-
-  message AlertStats {
-    optional int64 id = 1;
-    optional int32 alerted_times = 2;
-  }
-
-  message ConfigStats {
-    optional int32 uid = 1;
-    optional int64 id = 2;
-    optional int32 creation_time_sec = 3;
-    optional int32 deletion_time_sec = 4;
-    optional int32 metric_count = 5;
-    optional int32 condition_count = 6;
-    optional int32 matcher_count = 7;
-    optional int32 alert_count = 8;
-    optional bool is_valid = 9;
-
-    repeated int32 broadcast_sent_time_sec = 10;
-    repeated int32 data_drop_time_sec = 11;
-    repeated int32 dump_report_time_sec = 12;
-    repeated MatcherStats matcher_stats = 13;
-    repeated ConditionStats condition_stats = 14;
-    repeated MetricStats metric_stats = 15;
-    repeated AlertStats alert_stats = 16;
-  }
-
-  repeated ConfigStats config_stats = 3;
-
-  message AtomStats {
-    optional int32 tag = 1;
-    optional int32 count = 2;
-  }
-
-  repeated AtomStats atom_stats = 7;
-
-  message UidMapStats {
-    optional int32 snapshots = 1;
-    optional int32 changes = 2;
-    optional int32 bytes_used = 3;
-    optional int32 dropped_snapshots = 4;
-    optional int32 dropped_changes = 5;
-  }
-  optional UidMapStats uidmap_stats = 8;
-
-  message AnomalyAlarmStats {
-    optional int32 alarms_registered = 1;
-  }
-  optional AnomalyAlarmStats anomaly_alarm_stats = 9;
-
-  message PulledAtomStats {
-    optional int32 atom_id = 1;
-    optional int64 total_pull = 2;
-    optional int64 total_pull_from_cache = 3;
-    optional int64 min_pull_interval_sec = 4;
-  }
-  repeated PulledAtomStats pulled_atom_stats = 10;
-
-  message LoggerErrorStats {
-    optional int32 logger_disconnection_sec = 1;
-    optional int32 error_code = 2;
-  }
-  repeated LoggerErrorStats logger_error_stats = 11;
-}
\ No newline at end of file
diff --git a/cmds/statsd/src/stats_log_common.proto b/cmds/statsd/src/stats_log_common.proto
new file mode 100644
index 0000000..aeecd23
--- /dev/null
+++ b/cmds/statsd/src/stats_log_common.proto
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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";
+
+package android.os.statsd;
+
+option java_package = "com.android.os";
+option java_outer_classname = "StatsLogCommon";
+
+message UidMapping {
+    message PackageInfoSnapshot {
+        message PackageInfo {
+            optional string name = 1;
+
+            optional int64 version = 2;
+
+            optional int32 uid = 3;
+        }
+        optional int64 elapsed_timestamp_nanos = 1;
+
+        repeated PackageInfo package_info = 2;
+    }
+    repeated PackageInfoSnapshot snapshots = 1;
+
+    message Change {
+        optional bool deletion = 1;
+
+        optional int64 elapsed_timestamp_nanos = 2;
+        optional string app = 3;
+        optional int32 uid = 4;
+
+        optional int64 version = 5;
+    }
+    repeated Change changes = 2;
+}
+
+message StatsdStatsReport {
+    optional int32 stats_begin_time_sec = 1;
+
+    optional int32 stats_end_time_sec = 2;
+
+    message MatcherStats {
+        optional int64 id = 1;
+        optional int32 matched_times = 2;
+    }
+
+    message ConditionStats {
+        optional int64 id = 1;
+        optional int32 max_tuple_counts = 2;
+    }
+
+    message MetricStats {
+        optional int64 id = 1;
+        optional int32 max_tuple_counts = 2;
+    }
+
+    message AlertStats {
+        optional int64 id = 1;
+        optional int32 alerted_times = 2;
+    }
+
+    message ConfigStats {
+        optional int32 uid = 1;
+        optional int64 id = 2;
+        optional int32 creation_time_sec = 3;
+        optional int32 deletion_time_sec = 4;
+        optional int32 metric_count = 5;
+        optional int32 condition_count = 6;
+        optional int32 matcher_count = 7;
+        optional int32 alert_count = 8;
+        optional bool is_valid = 9;
+
+        repeated int32 broadcast_sent_time_sec = 10;
+        repeated int32 data_drop_time_sec = 11;
+        repeated int32 dump_report_time_sec = 12;
+        repeated MatcherStats matcher_stats = 13;
+        repeated ConditionStats condition_stats = 14;
+        repeated MetricStats metric_stats = 15;
+        repeated AlertStats alert_stats = 16;
+    }
+
+    repeated ConfigStats config_stats = 3;
+
+    message AtomStats {
+        optional int32 tag = 1;
+        optional int32 count = 2;
+    }
+
+    repeated AtomStats atom_stats = 7;
+
+    message UidMapStats {
+        optional int32 snapshots = 1;
+        optional int32 changes = 2;
+        optional int32 bytes_used = 3;
+        optional int32 dropped_snapshots = 4;
+        optional int32 dropped_changes = 5;
+    }
+    optional UidMapStats uidmap_stats = 8;
+
+    message AnomalyAlarmStats {
+        optional int32 alarms_registered = 1;
+    }
+    optional AnomalyAlarmStats anomaly_alarm_stats = 9;
+
+    message PulledAtomStats {
+        optional int32 atom_id = 1;
+        optional int64 total_pull = 2;
+        optional int64 total_pull_from_cache = 3;
+        optional int64 min_pull_interval_sec = 4;
+    }
+    repeated PulledAtomStats pulled_atom_stats = 10;
+
+    message LoggerErrorStats {
+        optional int32 logger_disconnection_sec = 1;
+        optional int32 error_code = 2;
+    }
+    repeated LoggerErrorStats logger_error_stats = 11;
+}
\ No newline at end of file
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index 2c7b919..78ebe33 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -183,6 +183,8 @@
                 case STRING:
                     protoOutput->write(FIELD_TYPE_STRING | fieldNum, dim.mValue.str_value);
                     break;
+                default:
+                    break;
             }
             (*index)++;
         } else if (valueDepth > depth && valuePrefix == prefix) {
diff --git a/cmds/statsd/src/stats_log_util.h b/cmds/statsd/src/stats_log_util.h
index 5922642..c512e3c 100644
--- a/cmds/statsd/src/stats_log_util.h
+++ b/cmds/statsd/src/stats_log_util.h
@@ -19,7 +19,7 @@
 #include <android/util/ProtoOutputStream.h>
 #include "FieldValue.h"
 #include "HashableDimensionKey.h"
-#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
+#include "frameworks/base/cmds/statsd/src/stats_log_common.pb.h"
 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
 #include "guardrail/StatsdStats.h"
 
diff --git a/cmds/statsd/src/stats_util.h b/cmds/statsd/src/stats_util.h
index 31f51a7..c4b47dc 100644
--- a/cmds/statsd/src/stats_util.h
+++ b/cmds/statsd/src/stats_util.h
@@ -18,7 +18,7 @@
 
 #include <sstream>
 #include "HashableDimensionKey.h"
-#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
+#include "frameworks/base/cmds/statsd/src/stats_log_common.pb.h"
 #include "logd/LogReader.h"
 
 #include <unordered_map>
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
index 5a326a4..1e8aa12 100644
--- a/cmds/statsd/src/statsd_config.proto
+++ b/cmds/statsd/src/statsd_config.proto
@@ -15,7 +15,6 @@
  */
 
 syntax = "proto2";
-option optimize_for = LITE_RUNTIME;
 
 package android.os.statsd;
 
@@ -75,6 +74,9 @@
     int64 gte_int = 11;
 
     MessageMatcher matches_tuple = 12;
+
+    StringListMatcher eq_any_string = 13;
+    StringListMatcher neq_all_string = 14;
   }
 }
 
@@ -82,6 +84,10 @@
   repeated FieldValueMatcher field_value_matcher = 1;
 }
 
+message StringListMatcher {
+    repeated string str_value = 1;
+}
+
 enum LogicalOperation {
   LOGICAL_OPERATION_UNSPECIFIED = 0;
   AND = 1;
@@ -308,6 +314,8 @@
     PerfettoDetails perfetto_details = 5;
     BroadcastSubscriberDetails broadcast_subscriber_details = 6;
   }
+
+  optional float probability_of_informing = 7 [default = 1.1];
 }
 
 message StatsdConfig {
diff --git a/cmds/statsd/src/storage/StorageManager.cpp b/cmds/statsd/src/storage/StorageManager.cpp
index 6a1db72..781eced 100644
--- a/cmds/statsd/src/storage/StorageManager.cpp
+++ b/cmds/statsd/src/storage/StorageManager.cpp
@@ -195,6 +195,20 @@
     }
 }
 
+bool StorageManager::readFileToString(const char* file, string* content) {
+    int fd = open(file, O_RDONLY | O_CLOEXEC);
+    bool res = false;
+    if (fd != -1) {
+        if (android::base::ReadFdToString(fd, content)) {
+            res = true;
+        } else {
+            VLOG("Failed to read file %s\n", file);
+        }
+        close(fd);
+    }
+    return res;
+}
+
 void StorageManager::readConfigFromDisk(map<ConfigKey, StatsdConfig>& configsMap) {
     unique_ptr<DIR, decltype(&closedir)> dir(opendir(STATS_SERVICE_DIR), closedir);
     if (dir == NULL) {
diff --git a/cmds/statsd/src/storage/StorageManager.h b/cmds/statsd/src/storage/StorageManager.h
index d319674..6c8ed0a 100644
--- a/cmds/statsd/src/storage/StorageManager.h
+++ b/cmds/statsd/src/storage/StorageManager.h
@@ -37,6 +37,11 @@
     static void writeFile(const char* file, const void* buffer, int numBytes);
 
     /**
+     * Reads the file content to the buffer.
+     */
+    static bool readFileToString(const char* file, string* content);
+
+    /**
      * Deletes a single file given a file name.
      */
     static void deleteFile(const char* file);
diff --git a/cmds/statsd/src/subscriber/IncidentdReporter.cpp b/cmds/statsd/src/subscriber/IncidentdReporter.cpp
index d9a8fc8..1c18f67 100644
--- a/cmds/statsd/src/subscriber/IncidentdReporter.cpp
+++ b/cmds/statsd/src/subscriber/IncidentdReporter.cpp
@@ -28,10 +28,10 @@
 namespace os {
 namespace statsd {
 
-bool GenerateIncidentReport(const IncidentdDetails& config, const Alert& alert,
+bool GenerateIncidentReport(const IncidentdDetails& config, const int64_t& rule_id,
                             const ConfigKey& configKey) {
     if (config.section_size() == 0) {
-        VLOG("The alert %lld contains zero section in config(%d,%lld)", alert.id(),
+        VLOG("The alert %lld contains zero section in config(%d,%lld)", (unsigned long long)rule_id,
             configKey.GetUid(), (long long) configKey.GetId());
         return false;
     }
@@ -39,7 +39,7 @@
     IncidentReportArgs incidentReport;
 
     android::os::IncidentHeaderProto header;
-    header.set_alert_id(alert.id());
+    header.set_alert_id(rule_id);
     header.mutable_config_key()->set_uid(configKey.GetUid());
     header.mutable_config_key()->set_id(configKey.GetId());
     incidentReport.addHeader(header);
diff --git a/cmds/statsd/src/subscriber/IncidentdReporter.h b/cmds/statsd/src/subscriber/IncidentdReporter.h
index 229ed77..1b83fe2 100644
--- a/cmds/statsd/src/subscriber/IncidentdReporter.h
+++ b/cmds/statsd/src/subscriber/IncidentdReporter.h
@@ -26,7 +26,7 @@
 /**
  * Calls incidentd to trigger an incident report and put in dropbox for uploading.
  */
-bool GenerateIncidentReport(const IncidentdDetails& config, const Alert& alert,
+bool GenerateIncidentReport(const IncidentdDetails& config, const int64_t& rule_id,
                             const ConfigKey& configKey);
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/subscriber/SubscriberReporter.cpp b/cmds/statsd/src/subscriber/SubscriberReporter.cpp
index 9f68fc4..95ecf80 100644
--- a/cmds/statsd/src/subscriber/SubscriberReporter.cpp
+++ b/cmds/statsd/src/subscriber/SubscriberReporter.cpp
@@ -27,6 +27,8 @@
 namespace os {
 namespace statsd {
 
+using std::vector;
+
 void SubscriberReporter::setBroadcastSubscriber(const ConfigKey& configKey,
                                                 int64_t subscriberId,
                                                 const sp<IBinder>& intentSender) {
diff --git a/cmds/statsd/src/subscriber/SubscriberReporter.h b/cmds/statsd/src/subscriber/SubscriberReporter.h
index c7d1a5b..50100df 100644
--- a/cmds/statsd/src/subscriber/SubscriberReporter.h
+++ b/cmds/statsd/src/subscriber/SubscriberReporter.h
@@ -21,7 +21,6 @@
 
 #include "config/ConfigKey.h"
 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"  // subscription
-#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"  // DimensionsValue
 #include "android/os/StatsDimensionsValue.h"
 #include "HashableDimensionKey.h"
 
diff --git a/cmds/statsd/tests/AnomalyMonitor_test.cpp b/cmds/statsd/tests/AlarmMonitor_test.cpp
similarity index 70%
rename from cmds/statsd/tests/AnomalyMonitor_test.cpp
rename to cmds/statsd/tests/AlarmMonitor_test.cpp
index 920ca08..1fccb35 100644
--- a/cmds/statsd/tests/AnomalyMonitor_test.cpp
+++ b/cmds/statsd/tests/AlarmMonitor_test.cpp
@@ -12,28 +12,29 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "anomaly/AnomalyMonitor.h"
+#include "anomaly/AlarmMonitor.h"
 
 #include <gtest/gtest.h>
 
 using namespace android::os::statsd;
 
 #ifdef __ANDROID__
-TEST(AnomalyMonitor, popSoonerThan) {
+TEST(AlarmMonitor, popSoonerThan) {
     std::string emptyMetricId;
     std::string emptyDimensionId;
-    unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>> set;
-    AnomalyMonitor am(2);
+    unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> set;
+    AlarmMonitor am(2, [](const sp<IStatsCompanionService>&, int64_t){},
+                    [](const sp<IStatsCompanionService>&){});
 
     set = am.popSoonerThan(5);
     EXPECT_TRUE(set.empty());
 
-    sp<const AnomalyAlarm> a = new AnomalyAlarm{10};
-    sp<const AnomalyAlarm> b = new AnomalyAlarm{20};
-    sp<const AnomalyAlarm> c = new AnomalyAlarm{20};
-    sp<const AnomalyAlarm> d = new AnomalyAlarm{30};
-    sp<const AnomalyAlarm> e = new AnomalyAlarm{40};
-    sp<const AnomalyAlarm> f = new AnomalyAlarm{50};
+    sp<const InternalAlarm> a = new InternalAlarm{10};
+    sp<const InternalAlarm> b = new InternalAlarm{20};
+    sp<const InternalAlarm> c = new InternalAlarm{20};
+    sp<const InternalAlarm> d = new InternalAlarm{30};
+    sp<const InternalAlarm> e = new InternalAlarm{40};
+    sp<const InternalAlarm> f = new InternalAlarm{50};
 
     am.add(a);
     am.add(b);
diff --git a/cmds/statsd/tests/ConfigManager_test.cpp b/cmds/statsd/tests/ConfigManager_test.cpp
index 62bdba4..90c3a2f 100644
--- a/cmds/statsd/tests/ConfigManager_test.cpp
+++ b/cmds/statsd/tests/ConfigManager_test.cpp
@@ -65,8 +65,12 @@
 const int64_t testConfigId = 12345;
 
 TEST(ConfigManagerTest, TestFakeConfig) {
-    auto metricsManager = std::make_unique<MetricsManager>(ConfigKey(0, testConfigId),
-                                                           build_fake_config(), 1000, new UidMap());
+    auto metricsManager = std::make_unique<MetricsManager>(
+        ConfigKey(0, testConfigId), build_fake_config(), 1000, new UidMap(),
+        new AlarmMonitor(10, [](const sp<IStatsCompanionService>&, int64_t){},
+                         [](const sp<IStatsCompanionService>&){}),
+        new AlarmMonitor(10, [](const sp<IStatsCompanionService>&, int64_t){},
+                         [](const sp<IStatsCompanionService>&){}));
     EXPECT_TRUE(metricsManager->isConfigValid());
 }
 
diff --git a/cmds/statsd/tests/FieldValue_test.cpp b/cmds/statsd/tests/FieldValue_test.cpp
index f1ad0c8..5846761 100644
--- a/cmds/statsd/tests/FieldValue_test.cpp
+++ b/cmds/statsd/tests/FieldValue_test.cpp
@@ -14,9 +14,10 @@
  * limitations under the License.
  */
 #include <gtest/gtest.h>
-#include "src/logd/LogEvent.h"
+#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
 #include "matchers/matcher_util.h"
+#include "src/logd/LogEvent.h"
 #include "stats_log_util.h"
 #include "stats_util.h"
 #include "subscriber/SubscriberReporter.h"
@@ -64,19 +65,19 @@
     vector<Matcher> matchers;
     translateFieldMatcher(matcher1, &matchers);
 
-    AttributionNode attribution_node1;
+    AttributionNodeInternal attribution_node1;
     attribution_node1.set_uid(1111);
     attribution_node1.set_tag("location1");
 
-    AttributionNode attribution_node2;
+    AttributionNodeInternal attribution_node2;
     attribution_node2.set_uid(2222);
     attribution_node2.set_tag("location2");
 
-    AttributionNode attribution_node3;
+    AttributionNodeInternal attribution_node3;
     attribution_node3.set_uid(3333);
     attribution_node3.set_tag("location3");
-    std::vector<AttributionNode> attribution_nodes = {attribution_node1, attribution_node2,
-                                                      attribution_node3};
+    std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2,
+                                                              attribution_node3};
 
     // Set up the event
     LogEvent event(10, 12345);
@@ -154,19 +155,19 @@
 }
 
 TEST(AtomMatcherTest, TestMetric2ConditionLink) {
-    AttributionNode attribution_node1;
+    AttributionNodeInternal attribution_node1;
     attribution_node1.set_uid(1111);
     attribution_node1.set_tag("location1");
 
-    AttributionNode attribution_node2;
+    AttributionNodeInternal attribution_node2;
     attribution_node2.set_uid(2222);
     attribution_node2.set_tag("location2");
 
-    AttributionNode attribution_node3;
+    AttributionNodeInternal attribution_node3;
     attribution_node3.set_uid(3333);
     attribution_node3.set_tag("location3");
-    std::vector<AttributionNode> attribution_nodes = {attribution_node1, attribution_node2,
-                                                      attribution_node3};
+    std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2,
+                                                              attribution_node3};
 
     // Set up the event
     LogEvent event(10, 12345);
@@ -298,15 +299,15 @@
 }
 
 TEST(AtomMatcherTest, TestWriteAtomToProto) {
-    AttributionNode attribution_node1;
+    AttributionNodeInternal attribution_node1;
     attribution_node1.set_uid(1111);
     attribution_node1.set_tag("location1");
 
-    AttributionNode attribution_node2;
+    AttributionNodeInternal attribution_node2;
     attribution_node2.set_uid(2222);
     attribution_node2.set_tag("location2");
 
-    std::vector<AttributionNode> attribution_nodes = {attribution_node1, attribution_node2};
+    std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2};
 
     // Set up the event
     LogEvent event(4, 12345);
diff --git a/cmds/statsd/tests/LogEntryMatcher_test.cpp b/cmds/statsd/tests/LogEntryMatcher_test.cpp
index 1023ea4..36c6e0c 100644
--- a/cmds/statsd/tests/LogEntryMatcher_test.cpp
+++ b/cmds/statsd/tests/LogEntryMatcher_test.cpp
@@ -60,19 +60,19 @@
 
 TEST(AtomMatcherTest, TestAttributionMatcher) {
     UidMap uidMap;
-    AttributionNode attribution_node1;
+    AttributionNodeInternal attribution_node1;
     attribution_node1.set_uid(1111);
     attribution_node1.set_tag("location1");
 
-    AttributionNode attribution_node2;
+    AttributionNodeInternal attribution_node2;
     attribution_node2.set_uid(2222);
     attribution_node2.set_tag("location2");
 
-    AttributionNode attribution_node3;
+    AttributionNodeInternal attribution_node3;
     attribution_node3.set_uid(3333);
     attribution_node3.set_tag("location3");
-    std::vector<AttributionNode> attribution_nodes =
-        { attribution_node1, attribution_node2, attribution_node3 };
+    std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2,
+                                                              attribution_node3};
 
     // Set up the event
     LogEvent event(TAG_ID, 0);
@@ -294,6 +294,159 @@
     EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
 }
 
+TEST(AtomMatcherTest, TestNeqAnyStringMatcher) {
+    UidMap uidMap;
+    uidMap.updateMap(
+            {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */,
+            {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"),
+             android::String16("Pkg2"), android::String16("PkG3")} /* package name list */);
+
+    AttributionNodeInternal attribution_node1;
+    attribution_node1.set_uid(1111);
+    attribution_node1.set_tag("location1");
+
+    AttributionNodeInternal attribution_node2;
+    attribution_node2.set_uid(2222);
+    attribution_node2.set_tag("location2");
+
+    AttributionNodeInternal attribution_node3;
+    attribution_node3.set_uid(3333);
+    attribution_node3.set_tag("location3");
+
+    AttributionNodeInternal attribution_node4;
+    attribution_node4.set_uid(1066);
+    attribution_node4.set_tag("location3");
+    std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2,
+                                                              attribution_node3, attribution_node4};
+
+    // Set up the event
+    LogEvent event(TAG_ID, 0);
+    event.write(attribution_nodes);
+    event.write("some value");
+    // Convert to a LogEvent
+    event.init();
+
+    // Set up the matcher
+    AtomMatcher matcher;
+    auto simpleMatcher = matcher.mutable_simple_atom_matcher();
+    simpleMatcher->set_atom_id(TAG_ID);
+
+    // Match first node.
+    auto attributionMatcher = simpleMatcher->add_field_value_matcher();
+    attributionMatcher->set_field(FIELD_ID_1);
+    attributionMatcher->set_position(Position::FIRST);
+    attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field(
+            ATTRIBUTION_UID_FIELD_ID);
+    auto neqStringList = attributionMatcher->mutable_matches_tuple()
+                                 ->mutable_field_value_matcher(0)
+                                 ->mutable_neq_all_string();
+    neqStringList->add_str_value("pkg2");
+    neqStringList->add_str_value("pkg3");
+
+    auto fieldMatcher = simpleMatcher->add_field_value_matcher();
+    fieldMatcher->set_field(FIELD_ID_2);
+    fieldMatcher->set_eq_string("some value");
+
+    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
+
+    neqStringList->Clear();
+    neqStringList->add_str_value("pkg1");
+    neqStringList->add_str_value("pkg3");
+    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
+
+    attributionMatcher->set_position(Position::ANY);
+    neqStringList->Clear();
+    neqStringList->add_str_value("maps.com");
+    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
+
+    neqStringList->Clear();
+    neqStringList->add_str_value("PkG3");
+    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
+
+    attributionMatcher->set_position(Position::LAST);
+    neqStringList->Clear();
+    neqStringList->add_str_value("AID_STATSD");
+    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
+}
+
+TEST(AtomMatcherTest, TestEqAnyStringMatcher) {
+    UidMap uidMap;
+    uidMap.updateMap(
+            {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */,
+            {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"),
+             android::String16("Pkg2"), android::String16("PkG3")} /* package name list */);
+
+    AttributionNodeInternal attribution_node1;
+    attribution_node1.set_uid(1067);
+    attribution_node1.set_tag("location1");
+
+    AttributionNodeInternal attribution_node2;
+    attribution_node2.set_uid(2222);
+    attribution_node2.set_tag("location2");
+
+    AttributionNodeInternal attribution_node3;
+    attribution_node3.set_uid(3333);
+    attribution_node3.set_tag("location3");
+
+    AttributionNodeInternal attribution_node4;
+    attribution_node4.set_uid(1066);
+    attribution_node4.set_tag("location3");
+    std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2,
+                                                              attribution_node3, attribution_node4};
+
+    // Set up the event
+    LogEvent event(TAG_ID, 0);
+    event.write(attribution_nodes);
+    event.write("some value");
+    // Convert to a LogEvent
+    event.init();
+
+    // Set up the matcher
+    AtomMatcher matcher;
+    auto simpleMatcher = matcher.mutable_simple_atom_matcher();
+    simpleMatcher->set_atom_id(TAG_ID);
+
+    // Match first node.
+    auto attributionMatcher = simpleMatcher->add_field_value_matcher();
+    attributionMatcher->set_field(FIELD_ID_1);
+    attributionMatcher->set_position(Position::FIRST);
+    attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field(
+            ATTRIBUTION_UID_FIELD_ID);
+    auto eqStringList = attributionMatcher->mutable_matches_tuple()
+                                ->mutable_field_value_matcher(0)
+                                ->mutable_eq_any_string();
+    eqStringList->add_str_value("AID_ROOT");
+    eqStringList->add_str_value("AID_INCIDENTD");
+
+    auto fieldMatcher = simpleMatcher->add_field_value_matcher();
+    fieldMatcher->set_field(FIELD_ID_2);
+    fieldMatcher->set_eq_string("some value");
+
+    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
+
+    attributionMatcher->set_position(Position::ANY);
+    eqStringList->Clear();
+    eqStringList->add_str_value("AID_STATSD");
+    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
+
+    eqStringList->Clear();
+    eqStringList->add_str_value("pkg1");
+    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
+
+    auto normalStringField = fieldMatcher->mutable_eq_any_string();
+    normalStringField->add_str_value("some value123");
+    normalStringField->add_str_value("some value");
+    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
+
+    normalStringField->Clear();
+    normalStringField->add_str_value("AID_STATSD");
+    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
+
+    eqStringList->Clear();
+    eqStringList->add_str_value("maps.com");
+    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
+}
+
 TEST(AtomMatcherTest, TestBoolMatcher) {
     UidMap uidMap;
     // Set up the matcher
diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp
index b649215..2fcde29 100644
--- a/cmds/statsd/tests/LogEvent_test.cpp
+++ b/cmds/statsd/tests/LogEvent_test.cpp
@@ -25,14 +25,14 @@
 TEST(LogEventTest, TestLogParsing) {
     LogEvent event1(1, 2000);
 
-    std::vector<AttributionNode> nodes;
+    std::vector<AttributionNodeInternal> nodes;
 
-    AttributionNode node1;
+    AttributionNodeInternal node1;
     node1.set_uid(1000);
     node1.set_tag("tag1");
     nodes.push_back(node1);
 
-    AttributionNode node2;
+    AttributionNodeInternal node2;
     node2.set_uid(2000);
     node2.set_tag("tag2");
     nodes.push_back(node2);
@@ -92,17 +92,17 @@
 TEST(LogEventTest, TestLogParsing2) {
     LogEvent event1(1, 2000);
 
-    std::vector<AttributionNode> nodes;
+    std::vector<AttributionNodeInternal> nodes;
 
     event1.write("hello");
 
     // repeated msg can be in the middle
-    AttributionNode node1;
+    AttributionNodeInternal node1;
     node1.set_uid(1000);
     node1.set_tag("tag1");
     nodes.push_back(node1);
 
-    AttributionNode node2;
+    AttributionNodeInternal node2;
     node2.set_uid(2000);
     node2.set_tag("tag2");
     nodes.push_back(node2);
diff --git a/cmds/statsd/tests/MetricsManager_test.cpp b/cmds/statsd/tests/MetricsManager_test.cpp
index f90ca40..5d8c3f7 100644
--- a/cmds/statsd/tests/MetricsManager_test.cpp
+++ b/cmds/statsd/tests/MetricsManager_test.cpp
@@ -271,19 +271,25 @@
 
 TEST(MetricsManagerTest, TestGoodConfig) {
     UidMap uidMap;
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    sp<AlarmMonitor> periodicAlarmMonitor;
     StatsdConfig config = buildGoodConfig();
     set<int> allTagIds;
     vector<sp<LogMatchingTracker>> allAtomMatchers;
     vector<sp<ConditionTracker>> allConditionTrackers;
     vector<sp<MetricProducer>> allMetricProducers;
     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+    std::vector<sp<AlarmTracker>> allAlarmTrackers;
     unordered_map<int, std::vector<int>> conditionToMetricMap;
     unordered_map<int, std::vector<int>> trackerToMetricMap;
     unordered_map<int, std::vector<int>> trackerToConditionMap;
     std::set<int64_t> noReportMetricIds;
 
-    EXPECT_TRUE(initStatsdConfig(kConfigKey, config, uidMap, timeBaseSec, allTagIds, allAtomMatchers,
+    EXPECT_TRUE(initStatsdConfig(kConfigKey, config, uidMap,
+                                 anomalyAlarmMonitor, periodicAlarmMonitor,
+                                 timeBaseSec, allTagIds, allAtomMatchers,
                                  allConditionTrackers, allMetricProducers, allAnomalyTrackers,
+                                 allAlarmTrackers,
                                  conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
                                  noReportMetricIds));
     EXPECT_EQ(1u, allMetricProducers.size());
@@ -293,112 +299,148 @@
 
 TEST(MetricsManagerTest, TestDimensionMetricsWithMultiTags) {
     UidMap uidMap;
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    sp<AlarmMonitor> periodicAlarmMonitor;
     StatsdConfig config = buildDimensionMetricsWithMultiTags();
     set<int> allTagIds;
     vector<sp<LogMatchingTracker>> allAtomMatchers;
     vector<sp<ConditionTracker>> allConditionTrackers;
     vector<sp<MetricProducer>> allMetricProducers;
     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+    std::vector<sp<AlarmTracker>> allAlarmTrackers;
     unordered_map<int, std::vector<int>> conditionToMetricMap;
     unordered_map<int, std::vector<int>> trackerToMetricMap;
     unordered_map<int, std::vector<int>> trackerToConditionMap;
     std::set<int64_t> noReportMetricIds;
 
-    EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, timeBaseSec, allTagIds, allAtomMatchers,
+    EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
+                                  anomalyAlarmMonitor, periodicAlarmMonitor,
+                                  timeBaseSec, allTagIds, allAtomMatchers,
                                   allConditionTrackers, allMetricProducers, allAnomalyTrackers,
+                                  allAlarmTrackers,
                                   conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
                                   noReportMetricIds));
 }
 
 TEST(MetricsManagerTest, TestCircleLogMatcherDependency) {
     UidMap uidMap;
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    sp<AlarmMonitor> periodicAlarmMonitor;
     StatsdConfig config = buildCircleMatchers();
     set<int> allTagIds;
     vector<sp<LogMatchingTracker>> allAtomMatchers;
     vector<sp<ConditionTracker>> allConditionTrackers;
     vector<sp<MetricProducer>> allMetricProducers;
     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+    std::vector<sp<AlarmTracker>> allAlarmTrackers;
     unordered_map<int, std::vector<int>> conditionToMetricMap;
     unordered_map<int, std::vector<int>> trackerToMetricMap;
     unordered_map<int, std::vector<int>> trackerToConditionMap;
     std::set<int64_t> noReportMetricIds;
 
-    EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, timeBaseSec, allTagIds, allAtomMatchers,
+    EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
+                                  anomalyAlarmMonitor, periodicAlarmMonitor,
+                                  timeBaseSec, allTagIds, allAtomMatchers,
                                   allConditionTrackers, allMetricProducers, allAnomalyTrackers,
+                                  allAlarmTrackers,
                                   conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
                                   noReportMetricIds));
 }
 
 TEST(MetricsManagerTest, TestMissingMatchers) {
     UidMap uidMap;
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    sp<AlarmMonitor> periodicAlarmMonitor;
     StatsdConfig config = buildMissingMatchers();
     set<int> allTagIds;
     vector<sp<LogMatchingTracker>> allAtomMatchers;
     vector<sp<ConditionTracker>> allConditionTrackers;
     vector<sp<MetricProducer>> allMetricProducers;
     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+    std::vector<sp<AlarmTracker>> allAlarmTrackers;
     unordered_map<int, std::vector<int>> conditionToMetricMap;
     unordered_map<int, std::vector<int>> trackerToMetricMap;
     unordered_map<int, std::vector<int>> trackerToConditionMap;
     std::set<int64_t> noReportMetricIds;
-    EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, timeBaseSec, allTagIds, allAtomMatchers,
+    EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
+                                  anomalyAlarmMonitor, periodicAlarmMonitor,
+                                  timeBaseSec, allTagIds, allAtomMatchers,
                                   allConditionTrackers, allMetricProducers, allAnomalyTrackers,
+                                  allAlarmTrackers,
                                   conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
                                   noReportMetricIds));
 }
 
 TEST(MetricsManagerTest, TestMissingPredicate) {
     UidMap uidMap;
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    sp<AlarmMonitor> periodicAlarmMonitor;
     StatsdConfig config = buildMissingPredicate();
     set<int> allTagIds;
     vector<sp<LogMatchingTracker>> allAtomMatchers;
     vector<sp<ConditionTracker>> allConditionTrackers;
     vector<sp<MetricProducer>> allMetricProducers;
     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+    std::vector<sp<AlarmTracker>> allAlarmTrackers;
     unordered_map<int, std::vector<int>> conditionToMetricMap;
     unordered_map<int, std::vector<int>> trackerToMetricMap;
     unordered_map<int, std::vector<int>> trackerToConditionMap;
     std::set<int64_t> noReportMetricIds;
-    EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, timeBaseSec, allTagIds, allAtomMatchers,
+    EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
+                                  anomalyAlarmMonitor, periodicAlarmMonitor,
+                                  timeBaseSec, allTagIds, allAtomMatchers,
                                   allConditionTrackers, allMetricProducers, allAnomalyTrackers,
+                                  allAlarmTrackers,
                                   conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
                                   noReportMetricIds));
 }
 
 TEST(MetricsManagerTest, TestCirclePredicateDependency) {
     UidMap uidMap;
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    sp<AlarmMonitor> periodicAlarmMonitor;
     StatsdConfig config = buildCirclePredicates();
     set<int> allTagIds;
     vector<sp<LogMatchingTracker>> allAtomMatchers;
     vector<sp<ConditionTracker>> allConditionTrackers;
     vector<sp<MetricProducer>> allMetricProducers;
     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+    std::vector<sp<AlarmTracker>> allAlarmTrackers;
     unordered_map<int, std::vector<int>> conditionToMetricMap;
     unordered_map<int, std::vector<int>> trackerToMetricMap;
     unordered_map<int, std::vector<int>> trackerToConditionMap;
     std::set<int64_t> noReportMetricIds;
 
-    EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, timeBaseSec, allTagIds, allAtomMatchers,
+    EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
+                                  anomalyAlarmMonitor, periodicAlarmMonitor,
+                                  timeBaseSec, allTagIds, allAtomMatchers,
                                   allConditionTrackers, allMetricProducers, allAnomalyTrackers,
+                                  allAlarmTrackers,
                                   conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
                                   noReportMetricIds));
 }
 
 TEST(MetricsManagerTest, testAlertWithUnknownMetric) {
     UidMap uidMap;
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    sp<AlarmMonitor> periodicAlarmMonitor;
     StatsdConfig config = buildAlertWithUnknownMetric();
     set<int> allTagIds;
     vector<sp<LogMatchingTracker>> allAtomMatchers;
     vector<sp<ConditionTracker>> allConditionTrackers;
     vector<sp<MetricProducer>> allMetricProducers;
     std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+    std::vector<sp<AlarmTracker>> allAlarmTrackers;
     unordered_map<int, std::vector<int>> conditionToMetricMap;
     unordered_map<int, std::vector<int>> trackerToMetricMap;
     unordered_map<int, std::vector<int>> trackerToConditionMap;
     std::set<int64_t> noReportMetricIds;
 
-    EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, timeBaseSec, allTagIds, allAtomMatchers,
+    EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
+                                  anomalyAlarmMonitor, periodicAlarmMonitor,
+                                  timeBaseSec, allTagIds, allAtomMatchers,
                                   allConditionTrackers, allMetricProducers, allAnomalyTrackers,
+                                  allAlarmTrackers,
                                   conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
                                   noReportMetricIds));
 }
diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp
index cb72697..3238b74 100644
--- a/cmds/statsd/tests/StatsLogProcessor_test.cpp
+++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp
@@ -41,7 +41,13 @@
  */
 class MockMetricsManager : public MetricsManager {
 public:
-    MockMetricsManager() : MetricsManager(ConfigKey(1, 12345), StatsdConfig(), 1000, new UidMap()) {
+    MockMetricsManager() : MetricsManager(
+        ConfigKey(1, 12345), StatsdConfig(), 1000,
+        new UidMap(),
+        new AlarmMonitor(10, [](const sp<IStatsCompanionService>&, int64_t){},
+                         [](const sp<IStatsCompanionService>&){}),
+        new AlarmMonitor(10, [](const sp<IStatsCompanionService>&, int64_t){},
+                         [](const sp<IStatsCompanionService>&){})) {
     }
 
     MOCK_METHOD0(byteSize, size_t());
@@ -50,9 +56,11 @@
 
 TEST(StatsLogProcessorTest, TestRateLimitByteSize) {
     sp<UidMap> m = new UidMap();
-    sp<AnomalyMonitor> anomalyMonitor;
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    sp<AlarmMonitor> periodicAlarmMonitor;
     // Construct the processor with a dummy sendBroadcast function that does nothing.
-    StatsLogProcessor p(m, anomalyMonitor, 0, [](const ConfigKey& key) {});
+    StatsLogProcessor p(m, anomalyAlarmMonitor, periodicAlarmMonitor, 0,
+        [](const ConfigKey& key) {});
 
     MockMetricsManager mockMetricsManager;
 
@@ -67,11 +75,11 @@
 
 TEST(StatsLogProcessorTest, TestRateLimitBroadcast) {
     sp<UidMap> m = new UidMap();
-    sp<AnomalyMonitor> anomalyMonitor;
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    sp<AlarmMonitor> subscriberAlarmMonitor;
     int broadcastCount = 0;
-    StatsLogProcessor p(m, anomalyMonitor, 0, [&broadcastCount](const ConfigKey& key) {
-        broadcastCount++;
-    });
+    StatsLogProcessor p(m, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
+                        [&broadcastCount](const ConfigKey& key) { broadcastCount++; });
 
     MockMetricsManager mockMetricsManager;
 
@@ -93,9 +101,10 @@
 
 TEST(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge) {
     sp<UidMap> m = new UidMap();
-    sp<AnomalyMonitor> anomalyMonitor;
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    sp<AlarmMonitor> subscriberAlarmMonitor;
     int broadcastCount = 0;
-    StatsLogProcessor p(m, anomalyMonitor, 0,
+    StatsLogProcessor p(m, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
                         [&broadcastCount](const ConfigKey& key) { broadcastCount++; });
 
     MockMetricsManager mockMetricsManager;
diff --git a/cmds/statsd/tests/UidMap_test.cpp b/cmds/statsd/tests/UidMap_test.cpp
index f26c10d..ca656ed 100644
--- a/cmds/statsd/tests/UidMap_test.cpp
+++ b/cmds/statsd/tests/UidMap_test.cpp
@@ -36,9 +36,11 @@
 
 TEST(UidMapTest, TestIsolatedUID) {
     sp<UidMap> m = new UidMap();
-    sp<AnomalyMonitor> anomalyMonitor;
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    sp<AlarmMonitor> subscriberAlarmMonitor;
     // Construct the processor with a dummy sendBroadcast function that does nothing.
-    StatsLogProcessor p(m, anomalyMonitor, 0, [](const ConfigKey& key) {});
+    StatsLogProcessor p(m, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
+        [](const ConfigKey& key) {});
     LogEvent addEvent(android::util::ISOLATED_UID_CHANGED, 1);
     addEvent.write(100);  // parent UID
     addEvent.write(101);  // isolated UID
diff --git a/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp b/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp
new file mode 100644
index 0000000..3330ee9
--- /dev/null
+++ b/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp
@@ -0,0 +1,68 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT 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 "src/anomaly/AlarmTracker.h"
+
+#include <gtest/gtest.h>
+#include <stdio.h>
+#include <vector>
+
+using namespace testing;
+using android::sp;
+using std::set;
+using std::unordered_map;
+using std::vector;
+
+#ifdef __ANDROID__
+
+namespace android {
+namespace os {
+namespace statsd {
+
+const ConfigKey kConfigKey(0, 12345);
+
+TEST(AlarmTrackerTest, TestTriggerTimestamp) {
+    sp<AlarmMonitor> subscriberAlarmMonitor =
+        new AlarmMonitor(100, [](const sp<IStatsCompanionService>&, int64_t){},
+                         [](const sp<IStatsCompanionService>&){});
+    Alarm alarm;
+    alarm.set_offset_millis(15 * MS_PER_SEC);
+    alarm.set_period_millis(60 * 60 * MS_PER_SEC);  // 1hr
+    uint64_t startMillis = 100000000 * MS_PER_SEC;
+    AlarmTracker tracker(startMillis, alarm, kConfigKey,
+                         subscriberAlarmMonitor);
+
+    EXPECT_EQ(tracker.mAlarmSec, startMillis / MS_PER_SEC + 15);
+
+    uint64_t currentTimeSec = startMillis / MS_PER_SEC + 10;
+    std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> firedAlarmSet =
+        subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
+    EXPECT_TRUE(firedAlarmSet.empty());
+    tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet);
+    EXPECT_EQ(tracker.mAlarmSec, startMillis / MS_PER_SEC + 15);
+
+    currentTimeSec = startMillis / MS_PER_SEC + 7000;
+    firedAlarmSet = subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
+    EXPECT_EQ(firedAlarmSet.size(), 1u);
+    tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet);
+    EXPECT_TRUE(firedAlarmSet.empty());
+    EXPECT_EQ(tracker.mAlarmSec, startMillis / MS_PER_SEC + 15 + 2 * 60 * 60);
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
+#else
+GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
diff --git a/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp b/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp
index 038d449..3dc3fd1 100644
--- a/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp
+++ b/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp
@@ -58,9 +58,9 @@
 }
 
 void writeAttributionNodesToEvent(LogEvent* event, const std::vector<int> &uids) {
-    std::vector<AttributionNode> nodes;
+    std::vector<AttributionNodeInternal> nodes;
     for (size_t i = 0; i < uids.size(); ++i) {
-        AttributionNode node;
+        AttributionNodeInternal node;
         node.set_uid(uids[i]);
         nodes.push_back(node);
     }
diff --git a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp b/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
index 0228004..7a7e000 100644
--- a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
@@ -75,41 +75,40 @@
         android::String16("APP3"), 333 /* uid */, 2 /* version code*/);
 
     // GMS core node is in the middle.
-    std::vector<AttributionNode> attributions1 =
-        {CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"),
-         CreateAttribution(333, "App3")};
+    std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1"),
+                                                          CreateAttribution(222, "GMSCoreModule1"),
+                                                          CreateAttribution(333, "App3")};
 
     // GMS core node is the last one.
-    std::vector<AttributionNode> attributions2 =
-        {CreateAttribution(111, "App1"), CreateAttribution(333, "App3"),
-         CreateAttribution(222, "GMSCoreModule1")};
+    std::vector<AttributionNodeInternal> attributions2 = {CreateAttribution(111, "App1"),
+                                                          CreateAttribution(333, "App3"),
+                                                          CreateAttribution(222, "GMSCoreModule1")};
 
     // GMS core node is the first one.
-    std::vector<AttributionNode> attributions3 =
-        {CreateAttribution(222, "GMSCoreModule1"), CreateAttribution(333, "App3")};
+    std::vector<AttributionNodeInternal> attributions3 = {CreateAttribution(222, "GMSCoreModule1"),
+                                                          CreateAttribution(333, "App3")};
 
     // Single GMS core node.
-    std::vector<AttributionNode> attributions4 =
-        {CreateAttribution(222, "GMSCoreModule1")};
+    std::vector<AttributionNodeInternal> attributions4 = {CreateAttribution(222, "GMSCoreModule1")};
 
     // GMS core has another uid.
-    std::vector<AttributionNode> attributions5 =
-        {CreateAttribution(111, "App1"), CreateAttribution(444, "GMSCoreModule2"),
-         CreateAttribution(333, "App3")};
+    std::vector<AttributionNodeInternal> attributions5 = {CreateAttribution(111, "App1"),
+                                                          CreateAttribution(444, "GMSCoreModule2"),
+                                                          CreateAttribution(333, "App3")};
 
     // Multiple GMS core nodes.
-    std::vector<AttributionNode> attributions6 =
-        {CreateAttribution(444, "GMSCoreModule2"), CreateAttribution(222, "GMSCoreModule1")};
+    std::vector<AttributionNodeInternal> attributions6 = {CreateAttribution(444, "GMSCoreModule2"),
+                                                          CreateAttribution(222, "GMSCoreModule1")};
 
     // No GMS core nodes.
-    std::vector<AttributionNode> attributions7 =
-        {CreateAttribution(111, "App1"), CreateAttribution(333, "App3")};
-    std::vector<AttributionNode> attributions8 = {CreateAttribution(111, "App1")};
+    std::vector<AttributionNodeInternal> attributions7 = {CreateAttribution(111, "App1"),
+                                                          CreateAttribution(333, "App3")};
+    std::vector<AttributionNodeInternal> attributions8 = {CreateAttribution(111, "App1")};
 
     // GMS core node with isolated uid.
     const int isolatedUid = 666;
-    std::vector<AttributionNode> attributions9 =
-        {CreateAttribution(isolatedUid, "GMSCoreModule3")};
+    std::vector<AttributionNodeInternal> attributions9 = {
+            CreateAttribution(isolatedUid, "GMSCoreModule3")};
 
     std::vector<std::unique_ptr<LogEvent>> events;
     // Events 1~4 are in the 1st bucket.
diff --git a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_test.cpp b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_test.cpp
index 4dffd13..01348bd 100644
--- a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_test.cpp
@@ -78,13 +78,13 @@
     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
 
-    std::vector<AttributionNode> attributions1 = {CreateAttribution(111, "App1"),
-                                                  CreateAttribution(222, "GMSCoreModule1"),
-                                                  CreateAttribution(222, "GMSCoreModule2")};
+    std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1"),
+                                                          CreateAttribution(222, "GMSCoreModule1"),
+                                                          CreateAttribution(222, "GMSCoreModule2")};
 
-    std::vector<AttributionNode> attributions2 = {CreateAttribution(333, "App2"),
-                                                  CreateAttribution(222, "GMSCoreModule1"),
-                                                  CreateAttribution(555, "GMSCoreModule2")};
+    std::vector<AttributionNodeInternal> attributions2 = {CreateAttribution(333, "App2"),
+                                                          CreateAttribution(222, "GMSCoreModule1"),
+                                                          CreateAttribution(555, "GMSCoreModule2")};
 
     std::vector<std::unique_ptr<LogEvent>> events;
     events.push_back(
@@ -284,13 +284,13 @@
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs / NS_PER_SEC, config, cfgKey);
     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    std::vector<AttributionNode> attributions1 = {CreateAttribution(111, "App1"),
-                                                  CreateAttribution(222, "GMSCoreModule1"),
-                                                  CreateAttribution(222, "GMSCoreModule2")};
+    std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1"),
+                                                          CreateAttribution(222, "GMSCoreModule1"),
+                                                          CreateAttribution(222, "GMSCoreModule2")};
 
-    std::vector<AttributionNode> attributions2 = {CreateAttribution(333, "App2"),
-                                                  CreateAttribution(222, "GMSCoreModule1"),
-                                                  CreateAttribution(555, "GMSCoreModule2")};
+    std::vector<AttributionNodeInternal> attributions2 = {CreateAttribution(333, "App2"),
+                                                          CreateAttribution(222, "GMSCoreModule1"),
+                                                          CreateAttribution(555, "GMSCoreModule2")};
 
     std::vector<std::unique_ptr<LogEvent>> events;
 
@@ -464,13 +464,13 @@
         EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
         EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
 
-        std::vector<AttributionNode> attributions1 = {CreateAttribution(111, "App1"),
-                                                      CreateAttribution(222, "GMSCoreModule1"),
-                                                      CreateAttribution(222, "GMSCoreModule2")};
+        std::vector<AttributionNodeInternal> attributions1 = {
+                CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"),
+                CreateAttribution(222, "GMSCoreModule2")};
 
-        std::vector<AttributionNode> attributions2 = {CreateAttribution(333, "App2"),
-                                                      CreateAttribution(222, "GMSCoreModule1"),
-                                                      CreateAttribution(555, "GMSCoreModule2")};
+        std::vector<AttributionNodeInternal> attributions2 = {
+                CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"),
+                CreateAttribution(555, "GMSCoreModule2")};
 
         std::vector<std::unique_ptr<LogEvent>> events;
 
@@ -629,13 +629,13 @@
         EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
         EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
 
-        std::vector<AttributionNode> attributions1 = {CreateAttribution(111, "App1"),
-                                                      CreateAttribution(222, "GMSCoreModule1"),
-                                                      CreateAttribution(222, "GMSCoreModule2")};
+        std::vector<AttributionNodeInternal> attributions1 = {
+                CreateAttribution(111, "App1"), CreateAttribution(222, "GMSCoreModule1"),
+                CreateAttribution(222, "GMSCoreModule2")};
 
-        std::vector<AttributionNode> attributions2 = {CreateAttribution(333, "App2"),
-                                                      CreateAttribution(222, "GMSCoreModule1"),
-                                                      CreateAttribution(555, "GMSCoreModule2")};
+        std::vector<AttributionNodeInternal> attributions2 = {
+                CreateAttribution(333, "App2"), CreateAttribution(222, "GMSCoreModule1"),
+                CreateAttribution(555, "GMSCoreModule2")};
 
         std::vector<std::unique_ptr<LogEvent>> events;
 
diff --git a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
index 1b51780..c874d92 100644
--- a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
@@ -134,8 +134,8 @@
         CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
                                       bucketStartTimeNs + 2 * bucketSizeNs - 100);
 
-    std::vector<AttributionNode> attributions =
-        {CreateAttribution(appUid, "App1"), CreateAttribution(appUid + 1, "GMSCoreModule1")};
+    std::vector<AttributionNodeInternal> attributions = {
+            CreateAttribution(appUid, "App1"), CreateAttribution(appUid + 1, "GMSCoreModule1")};
     auto syncOnEvent1 =
         CreateSyncStartEvent(attributions, "ReadEmail", bucketStartTimeNs + 50);
     auto syncOffEvent1 =
@@ -249,8 +249,8 @@
             CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
                                           bucketStartTimeNs + 2 * bucketSizeNs - 100);
 
-    std::vector<AttributionNode> attributions = {CreateAttribution(appUid, "App1"),
-                                                 CreateAttribution(appUid + 1, "GMSCoreModule1")};
+    std::vector<AttributionNodeInternal> attributions = {
+            CreateAttribution(appUid, "App1"), CreateAttribution(appUid + 1, "GMSCoreModule1")};
     auto syncOnEvent1 = CreateSyncStartEvent(attributions, "ReadEmail", bucketStartTimeNs + 50);
     auto syncOffEvent1 =
             CreateSyncEndEvent(attributions, "ReadEmail", bucketStartTimeNs + bucketSizeNs + 300);
diff --git a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp b/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
index efdab98..9153795 100644
--- a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
@@ -60,13 +60,13 @@
     return config;
 }
 
-std::vector<AttributionNode> attributions1 = {CreateAttribution(111, "App1"),
-                                              CreateAttribution(222, "GMSCoreModule1"),
-                                              CreateAttribution(222, "GMSCoreModule2")};
+std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1"),
+                                                      CreateAttribution(222, "GMSCoreModule1"),
+                                                      CreateAttribution(222, "GMSCoreModule2")};
 
-std::vector<AttributionNode> attributions2 = {CreateAttribution(111, "App2"),
-                                              CreateAttribution(222, "GMSCoreModule1"),
-                                              CreateAttribution(222, "GMSCoreModule2")};
+std::vector<AttributionNodeInternal> attributions2 = {CreateAttribution(111, "App2"),
+                                                      CreateAttribution(222, "GMSCoreModule1"),
+                                                      CreateAttribution(222, "GMSCoreModule2")};
 
 /*
 Events:
diff --git a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
index 20ddbe9..9a0de0d 100644
--- a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
@@ -201,6 +201,7 @@
 }
 
 TEST(CountMetricProducerTest, TestEventWithAppUpgrade) {
+    sp<AlarmMonitor> alarmMonitor;
     uint64_t bucketStartTimeNs = 10000000000;
     uint64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
     uint64_t eventUpgradeTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
@@ -222,7 +223,7 @@
                                       bucketStartTimeNs);
     countProducer.setBucketSize(60 * NS_PER_SEC);
 
-    sp<AnomalyTracker> anomalyTracker = countProducer.addAnomalyTracker(alert);
+    sp<AnomalyTracker> anomalyTracker = countProducer.addAnomalyTracker(alert, alarmMonitor);
     EXPECT_TRUE(anomalyTracker != nullptr);
 
     // Bucket is flushed yet.
@@ -315,6 +316,7 @@
 }
 
 TEST(CountMetricProducerTest, TestAnomalyDetectionUnSliced) {
+    sp<AlarmMonitor> alarmMonitor;
     Alert alert;
     alert.set_id(11);
     alert.set_metric_id(1);
@@ -337,7 +339,7 @@
                                       bucketStartTimeNs);
     countProducer.setBucketSize(60 * NS_PER_SEC);
 
-    sp<AnomalyTracker> anomalyTracker = countProducer.addAnomalyTracker(alert);
+    sp<AnomalyTracker> anomalyTracker = countProducer.addAnomalyTracker(alert, alarmMonitor);
 
     int tagId = 1;
     LogEvent event1(tagId, bucketStartTimeNs + 1);
diff --git a/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp b/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp
index 7969596..1b22d75 100644
--- a/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp
@@ -239,6 +239,7 @@
 }
 
 TEST(DurationMetricTrackerTest, TestSumDurationAnomalyWithUpgrade) {
+    sp<AlarmMonitor> alarmMonitor;
     uint64_t bucketStartTimeNs = 10000000000;
     uint64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
     uint64_t eventUpgradeTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
@@ -263,7 +264,7 @@
             3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs);
     durationProducer.setBucketSize(60 * NS_PER_SEC);
 
-    sp<AnomalyTracker> anomalyTracker = durationProducer.addAnomalyTracker(alert);
+    sp<AnomalyTracker> anomalyTracker = durationProducer.addAnomalyTracker(alert, alarmMonitor);
     EXPECT_TRUE(anomalyTracker != nullptr);
 
     LogEvent start_event(tagId, startTimeNs);
diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
index 0eb8ce2..77b3ace 100644
--- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
@@ -129,6 +129,7 @@
 }
 
 TEST(GaugeMetricProducerTest, TestPushedEventsWithUpgrade) {
+    sp<AlarmMonitor> alarmMonitor;
     GaugeMetric metric;
     metric.set_id(metricId);
     metric.set_bucket(ONE_MINUTE);
@@ -145,8 +146,9 @@
     GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
                                       -1 /* -1 means no pulling */, bucketStartTimeNs,
                                       pullerManager);
+
     gaugeProducer.setBucketSize(60 * NS_PER_SEC);
-    sp<AnomalyTracker> anomalyTracker = gaugeProducer.addAnomalyTracker(alert);
+    sp<AnomalyTracker> anomalyTracker = gaugeProducer.addAnomalyTracker(alert, alarmMonitor);
     EXPECT_TRUE(anomalyTracker != nullptr);
 
     shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
@@ -339,6 +341,7 @@
 }
 
 TEST(GaugeMetricProducerTest, TestAnomalyDetection) {
+    sp<AlarmMonitor> alarmMonitor;
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
 
     shared_ptr<MockStatsPullerManager> pullerManager =
@@ -363,7 +366,7 @@
     alert.set_num_buckets(2);
     const int32_t refPeriodSec = 60;
     alert.set_refractory_period_secs(refPeriodSec);
-    sp<AnomalyTracker> anomalyTracker = gaugeProducer.addAnomalyTracker(alert);
+    sp<AnomalyTracker> anomalyTracker = gaugeProducer.addAnomalyTracker(alert, alarmMonitor);
 
     int tagId = 1;
     std::shared_ptr<LogEvent> event1 = std::make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
diff --git a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp b/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
index a164c12..83b1cbf 100644
--- a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
+++ b/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
@@ -276,13 +276,15 @@
     alert.set_num_buckets(2);
     const int32_t refPeriodSec = 45;
     alert.set_refractory_period_secs(refPeriodSec);
-    sp<DurationAnomalyTracker> anomalyTracker = new DurationAnomalyTracker(alert, kConfigKey);
+    sp<AlarmMonitor> alarmMonitor;
+    sp<DurationAnomalyTracker> anomalyTracker =
+        new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
     MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition,
                                false, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs,
                                true, {anomalyTracker});
 
     tracker.noteStart(key1, true, eventStartTimeNs, conditionKey1);
-    sp<const AnomalyAlarm> alarm = anomalyTracker->mAlarms.begin()->second;
+    sp<const InternalAlarm> alarm = anomalyTracker->mAlarms.begin()->second;
     EXPECT_EQ((long long)(53ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
 
     // Remove the anomaly alarm when the duration is no longer fully met.
@@ -336,7 +338,9 @@
     alert.set_num_buckets(2);
     const int32_t refPeriodSec = 45;
     alert.set_refractory_period_secs(refPeriodSec);
-    sp<DurationAnomalyTracker> anomalyTracker = new DurationAnomalyTracker(alert, kConfigKey);
+    sp<AlarmMonitor> alarmMonitor;
+    sp<DurationAnomalyTracker> anomalyTracker =
+        new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
     MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition,
                                false, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs,
                                true, {anomalyTracker});
@@ -390,7 +394,9 @@
     alert.set_num_buckets(2);
     const int32_t refPeriodSec = 45;
     alert.set_refractory_period_secs(refPeriodSec);
-    sp<DurationAnomalyTracker> anomalyTracker = new DurationAnomalyTracker(alert, kConfigKey);
+    sp<AlarmMonitor> alarmMonitor;
+    sp<DurationAnomalyTracker> anomalyTracker =
+        new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
     MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition,
                                false, bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs,
                                true, {anomalyTracker});
diff --git a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp b/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
index cb731c5..aa41038 100644
--- a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
+++ b/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
@@ -334,7 +334,9 @@
     uint64_t bucketNum = 0;
     uint64_t eventStartTimeNs = bucketStartTimeNs + NS_PER_SEC + 1;
 
-    sp<DurationAnomalyTracker> anomalyTracker = new DurationAnomalyTracker(alert, kConfigKey);
+    sp<AlarmMonitor> alarmMonitor;
+    sp<DurationAnomalyTracker> anomalyTracker =
+        new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
     OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition,
                                  true, bucketStartTimeNs, bucketNum, bucketStartTimeNs,
                                  bucketSizeNs, true, {anomalyTracker});
@@ -403,7 +405,9 @@
     uint64_t bucketNum = 0;
     uint64_t eventStartTimeNs = bucketStartTimeNs + NS_PER_SEC + 1;
 
-    sp<DurationAnomalyTracker> anomalyTracker = new DurationAnomalyTracker(alert, kConfigKey);
+    sp<AlarmMonitor> alarmMonitor;
+    sp<DurationAnomalyTracker> anomalyTracker =
+        new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
     OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition,
                                  true /*nesting*/, bucketStartTimeNs, bucketNum, bucketStartTimeNs,
                                  bucketSizeNs, false, {anomalyTracker});
@@ -453,14 +457,16 @@
     uint64_t bucketStartTimeNs = 10 * NS_PER_SEC;
     uint64_t bucketSizeNs = 30 * NS_PER_SEC;
 
-    sp<DurationAnomalyTracker> anomalyTracker = new DurationAnomalyTracker(alert, kConfigKey);
+    sp<AlarmMonitor> alarmMonitor;
+    sp<DurationAnomalyTracker> anomalyTracker =
+        new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
     OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, dimensionInCondition,
                                  true /*nesting*/, bucketStartTimeNs, 0, bucketStartTimeNs,
                                  bucketSizeNs, false, {anomalyTracker});
 
     tracker.noteStart(kEventKey1, true, 15 * NS_PER_SEC, conkey); // start key1
     EXPECT_EQ(1u, anomalyTracker->mAlarms.size());
-    sp<const AnomalyAlarm> alarm = anomalyTracker->mAlarms.begin()->second;
+    sp<const InternalAlarm> alarm = anomalyTracker->mAlarms.begin()->second;
     EXPECT_EQ((long long)(55ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
     EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
 
@@ -487,7 +493,7 @@
     EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
 
     // Now, at 60s, which is 38s after key1 started again, we have reached 40s of 'on' time.
-    std::unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>> firedAlarms({alarm});
+    std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> firedAlarms({alarm});
     anomalyTracker->informAlarmsFired(62 * NS_PER_SEC, firedAlarms);
     EXPECT_EQ(0u, anomalyTracker->mAlarms.size());
     EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 62U + refPeriodSec);
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
index ce4fa32..a0addcc 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -346,6 +346,7 @@
 }
 
 TEST(ValueMetricProducerTest, TestAnomalyDetection) {
+    sp<AlarmMonitor> alarmMonitor;
     Alert alert;
     alert.set_id(101);
     alert.set_metric_id(metricId);
@@ -365,7 +366,7 @@
                                       -1 /*not pulled*/, bucketStartTimeNs);
     valueProducer.setBucketSize(60 * NS_PER_SEC);
 
-    sp<AnomalyTracker> anomalyTracker = valueProducer.addAnomalyTracker(alert);
+    sp<AnomalyTracker> anomalyTracker = valueProducer.addAnomalyTracker(alert, alarmMonitor);
 
 
     shared_ptr<LogEvent> event1
diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp
index b7acef7..242b6eb 100644
--- a/cmds/statsd/tests/statsd_test_util.cpp
+++ b/cmds/statsd/tests/statsd_test_util.cpp
@@ -291,8 +291,8 @@
 }
 
 std::unique_ptr<LogEvent> CreateWakelockStateChangedEvent(
-    const std::vector<AttributionNode>& attributions, const string& wakelockName,
-    const WakelockStateChanged::State state, uint64_t timestampNs) {
+        const std::vector<AttributionNodeInternal>& attributions, const string& wakelockName,
+        const WakelockStateChanged::State state, uint64_t timestampNs) {
     auto event = std::make_unique<LogEvent>(android::util::WAKELOCK_STATE_CHANGED, timestampNs);
     event->write(attributions);
     event->write(android::os::WakeLockLevelEnum::PARTIAL_WAKE_LOCK);
@@ -303,15 +303,15 @@
 }
 
 std::unique_ptr<LogEvent> CreateAcquireWakelockEvent(
-    const std::vector<AttributionNode>& attributions,
-    const string& wakelockName, uint64_t timestampNs) {
+        const std::vector<AttributionNodeInternal>& attributions, const string& wakelockName,
+        uint64_t timestampNs) {
     return CreateWakelockStateChangedEvent(
         attributions, wakelockName, WakelockStateChanged::ACQUIRE, timestampNs);
 }
 
 std::unique_ptr<LogEvent> CreateReleaseWakelockEvent(
-    const std::vector<AttributionNode>& attributions,
-    const string& wakelockName, uint64_t timestampNs) {
+        const std::vector<AttributionNodeInternal>& attributions, const string& wakelockName,
+        uint64_t timestampNs) {
     return CreateWakelockStateChangedEvent(
         attributions, wakelockName, WakelockStateChanged::RELEASE, timestampNs);
 }
@@ -339,8 +339,8 @@
 }
 
 std::unique_ptr<LogEvent> CreateSyncStateChangedEvent(
-    const std::vector<AttributionNode>& attributions,
-    const string& name, const SyncStateChanged::State state, uint64_t timestampNs) {
+        const std::vector<AttributionNodeInternal>& attributions, const string& name,
+        const SyncStateChanged::State state, uint64_t timestampNs) {
     auto event = std::make_unique<LogEvent>(android::util::SYNC_STATE_CHANGED, timestampNs);
     event->write(attributions);
     event->write(name);
@@ -350,12 +350,14 @@
 }
 
 std::unique_ptr<LogEvent> CreateSyncStartEvent(
-    const std::vector<AttributionNode>& attributions, const string& name, uint64_t timestampNs){
+        const std::vector<AttributionNodeInternal>& attributions, const string& name,
+        uint64_t timestampNs) {
     return CreateSyncStateChangedEvent(attributions, name, SyncStateChanged::ON, timestampNs);
 }
 
 std::unique_ptr<LogEvent> CreateSyncEndEvent(
-    const std::vector<AttributionNode>& attributions, const string& name, uint64_t timestampNs) {
+        const std::vector<AttributionNodeInternal>& attributions, const string& name,
+        uint64_t timestampNs) {
     return CreateSyncStateChangedEvent(attributions, name, SyncStateChanged::OFF, timestampNs);
 }
 
@@ -389,15 +391,16 @@
 sp<StatsLogProcessor> CreateStatsLogProcessor(const long timeBaseSec, const StatsdConfig& config,
                                               const ConfigKey& key) {
     sp<UidMap> uidMap = new UidMap();
-    sp<AnomalyMonitor> anomalyMonitor = new AnomalyMonitor(10); // 10 seconds
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    sp<AlarmMonitor> periodicAlarmMonitor;
     sp<StatsLogProcessor> processor = new StatsLogProcessor(
-        uidMap, anomalyMonitor, timeBaseSec, [](const ConfigKey&){});
+        uidMap, anomalyAlarmMonitor, periodicAlarmMonitor, timeBaseSec, [](const ConfigKey&){});
     processor->OnConfigUpdated(key, config);
     return processor;
 }
 
-AttributionNode CreateAttribution(const int& uid, const string& tag) {
-    AttributionNode attribution;
+AttributionNodeInternal CreateAttribution(const int& uid, const string& tag) {
+    AttributionNodeInternal attribution;
     attribution.set_uid(uid);
     attribution.set_tag(tag);
     return attribution;
diff --git a/cmds/statsd/tests/statsd_test_util.h b/cmds/statsd/tests/statsd_test_util.h
index 5d83ed7..1708cc3 100644
--- a/cmds/statsd/tests/statsd_test_util.h
+++ b/cmds/statsd/tests/statsd_test_util.h
@@ -15,10 +15,11 @@
 #pragma once
 
 #include <gtest/gtest.h>
+#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "statslog.h"
-#include "src/logd/LogEvent.h"
 #include "src/StatsLogProcessor.h"
+#include "src/logd/LogEvent.h"
+#include "statslog.h"
 
 namespace android {
 namespace os {
@@ -119,11 +120,13 @@
 
 // Create log event when the app sync starts.
 std::unique_ptr<LogEvent> CreateSyncStartEvent(
-    const std::vector<AttributionNode>& attributions, const string& name, uint64_t timestampNs);
+        const std::vector<AttributionNodeInternal>& attributions, const string& name,
+        uint64_t timestampNs);
 
 // Create log event when the app sync ends.
 std::unique_ptr<LogEvent> CreateSyncEndEvent(
-    const std::vector<AttributionNode>& attributions, const string& name, uint64_t timestampNs);
+        const std::vector<AttributionNodeInternal>& attributions, const string& name,
+        uint64_t timestampNs);
 
 // Create log event when the app sync ends.
 std::unique_ptr<LogEvent> CreateAppCrashEvent(
@@ -131,20 +134,20 @@
 
 // Create log event for acquiring wakelock.
 std::unique_ptr<LogEvent> CreateAcquireWakelockEvent(
-    const std::vector<AttributionNode>& attributions,
-    const string& wakelockName, uint64_t timestampNs);
+        const std::vector<AttributionNodeInternal>& attributions, const string& wakelockName,
+        uint64_t timestampNs);
 
 // Create log event for releasing wakelock.
 std::unique_ptr<LogEvent> CreateReleaseWakelockEvent(
-    const std::vector<AttributionNode>& attributions,
-    const string& wakelockName, uint64_t timestampNs);
+        const std::vector<AttributionNodeInternal>& attributions, const string& wakelockName,
+        uint64_t timestampNs);
 
 // Create log event for releasing wakelock.
 std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(
     int isolatedUid, int hostUid, bool is_create, uint64_t timestampNs);
 
-// Helper function to create an AttributionNode proto.
-AttributionNode CreateAttribution(const int& uid, const string& tag);
+// Helper function to create an AttributionNodeInternal proto.
+AttributionNodeInternal CreateAttribution(const int& uid, const string& tag);
 
 // Create a statsd log event processor upon the start time in seconds, config and key.
 sp<StatsLogProcessor> CreateStatsLogProcessor(const long timeBaseSec, const StatsdConfig& config,
diff --git a/cmds/statsd/tools/Android.mk b/cmds/statsd/tools/Android.mk
index faf2d2c..7253c96 100644
--- a/cmds/statsd/tools/Android.mk
+++ b/cmds/statsd/tools/Android.mk
@@ -16,5 +16,5 @@
 
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
-# Include the sub-makefiles
+#Include the sub-makefiles
 include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
diff --git a/cmds/statsd/tools/dogfood/Android.mk b/cmds/statsd/tools/dogfood/Android.mk
index a65095f..c7e4c7b 100644
--- a/cmds/statsd/tools/dogfood/Android.mk
+++ b/cmds/statsd/tools/dogfood/Android.mk
@@ -24,7 +24,6 @@
 LOCAL_STATIC_JAVA_LIBRARIES := platformprotoslite \
                                statsdprotolite
 
-LOCAL_PROTOC_OPTIMIZE_TYPE := lite
 LOCAL_PRIVILEGED_MODULE := true
 LOCAL_DEX_PREOPT := false
 LOCAL_CERTIFICATE := platform
diff --git a/cmds/statsd/tools/loadtest/Android.mk b/cmds/statsd/tools/loadtest/Android.mk
index f5722c2..091f184 100644
--- a/cmds/statsd/tools/loadtest/Android.mk
+++ b/cmds/statsd/tools/loadtest/Android.mk
@@ -19,15 +19,11 @@
 LOCAL_PACKAGE_NAME := StatsdLoadtest
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_SRC_FILES += ../../src/stats_log.proto \
-                   ../../src/atoms.proto \
-                   ../../src/perfetto/perfetto_config.proto \
-                   ../../src/statsd_config.proto
-LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/../../src/
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_STATIC_JAVA_LIBRARIES := platformprotoslite
 
-LOCAL_PROTOC_OPTIMIZE_TYPE := lite
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_STATIC_JAVA_LIBRARIES := platformprotoslite \
+                               statsdprotolite
+
 LOCAL_CERTIFICATE := platform
 LOCAL_PRIVILEGED_MODULE := true
 LOCAL_DEX_PREOPT := false
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/LoadtestActivity.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/LoadtestActivity.java
index bed4d98..a12def0 100644
--- a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/LoadtestActivity.java
+++ b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/LoadtestActivity.java
@@ -50,7 +50,7 @@
 
 import com.android.os.StatsLog.ConfigMetricsReport;
 import com.android.os.StatsLog.ConfigMetricsReportList;
-import com.android.os.StatsLog.StatsdStatsReport;
+import com.android.os.StatsLogCommon.StatsdStatsReport;
 import com.android.internal.os.StatsdConfigProto.TimeUnit;
 
 import java.util.ArrayList;
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/StatsdStatsRecorder.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/StatsdStatsRecorder.java
index e63150f..58cbcd8 100644
--- a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/StatsdStatsRecorder.java
+++ b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/StatsdStatsRecorder.java
@@ -16,11 +16,8 @@
 package com.android.statsd.loadtest;
 
 import android.content.Context;
-import android.util.Log;
-import com.android.os.StatsLog.StatsdStatsReport;
+import com.android.os.StatsLogCommon.StatsdStatsReport;
 import com.android.internal.os.StatsdConfigProto.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 public class StatsdStatsRecorder extends PerfDataRecorder {
     private static final String TAG = "loadtest.StatsdStatsRecorder";
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index f3997a4..cc57f6c 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -659,7 +659,6 @@
 Landroid/graphics/drawable/GradientDrawable$GradientState;->mPadding:Landroid/graphics/Rect;
 Landroid/graphics/drawable/GradientDrawable$GradientState;->mPositions:[F
 Landroid/graphics/drawable/GradientDrawable;->mPadding:Landroid/graphics/Rect;
-Landroid/graphics/drawable/Icon;->getResPackage()Ljava/lang/String;
 Landroid/graphics/drawable/NinePatchDrawable;->mNinePatchState:Landroid/graphics/drawable/NinePatchDrawable$NinePatchState;
 Landroid/graphics/drawable/NinePatchDrawable$NinePatchState;->mNinePatch:Landroid/graphics/NinePatch;
 Landroid/graphics/drawable/StateListDrawable;->extractStateSet(Landroid/util/AttributeSet;)[I
@@ -977,8 +976,6 @@
 Landroid/media/RemoteDisplay;->notifyDisplayDisconnected()V
 Landroid/media/RemoteDisplay;->notifyDisplayError(I)V
 Landroid/media/RingtoneManager;->getRingtone(Landroid/content/Context;Landroid/net/Uri;I)Landroid/media/Ringtone;
-Landroid/media/Ringtone;->setLooping(Z)V
-Landroid/media/Ringtone;->setVolume(F)V
 Landroid/media/session/MediaSessionLegacyHelper;->getHelper(Landroid/content/Context;)Landroid/media/session/MediaSessionLegacyHelper;
 Landroid/media/SubtitleController;->mHandler:Landroid/os/Handler;
 Landroid/media/ThumbnailUtils;->createImageThumbnail(Ljava/lang/String;I)Landroid/graphics/Bitmap;
@@ -1691,10 +1688,12 @@
 Landroid/view/accessibility/IAccessibilityManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/view/ActionMode;->isUiFocusable()Z
 Landroid/view/animation/Animation;->mListener:Landroid/view/animation/Animation$AnimationListener;
+Landroid/view/Choreographer$CallbackQueue;->addCallbackLocked(JLjava/lang/Object;Ljava/lang/Object;)V
 Landroid/view/Choreographer;->doFrame(JI)V
 Landroid/view/Choreographer;->getFrameTime()J
 Landroid/view/Choreographer;->mCallbackQueues:[Landroid/view/Choreographer$CallbackQueue;
 Landroid/view/Choreographer;->mLastFrameTimeNanos:J
+Landroid/view/Choreographer;->mLock:Ljava/lang/Object;
 Landroid/view/Choreographer;->postCallback(ILjava/lang/Runnable;Ljava/lang/Object;)V
 Landroid/view/Choreographer;->removeCallbacks(ILjava/lang/Runnable;Ljava/lang/Object;)V
 Landroid/view/Choreographer;->scheduleVsyncLocked()V
@@ -1822,7 +1821,7 @@
 Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;->selectionModified(IILandroid/view/textclassifier/TextSelection;)Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;
 Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;->selectionStarted(I)Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;
 Landroid/view/textservice/TextServicesManager;->isSpellCheckerEnabled()Z
-Landroid/view/TextureView;->mLayer:Landroid/view/HardwareLayer;
+Landroid/view/TextureView;->mLayer:Landroid/view/TextureLayer;
 Landroid/view/TextureView;->mNativeWindow:J
 Landroid/view/TextureView;->mSurface:Landroid/graphics/SurfaceTexture;
 Landroid/view/TextureView;->mUpdateListener:Landroid/graphics/SurfaceTexture$OnFrameAvailableListener;
@@ -2403,11 +2402,45 @@
 Lcom/android/okhttp/OkHttpClient;->setProtocols(Ljava/util/List;)Lcom/android/okhttp/OkHttpClient;
 Lcom/android/okhttp/okio/ByteString;->readObject(Ljava/io/ObjectInputStream;)V
 Lcom/android/okhttp/okio/ByteString;->writeObject(Ljava/io/ObjectOutputStream;)V
+Lcom/android/org/conscrypt/AbstractConscryptSocket;->getAlpnSelectedProtocol()[B
+Lcom/android/org/conscrypt/AbstractConscryptSocket;->getApplicationProtocol()Ljava/lang/String;
+Lcom/android/org/conscrypt/AbstractConscryptSocket;->getApplicationProtocols()[Ljava/lang/String;
+Lcom/android/org/conscrypt/AbstractConscryptSocket;->getChannelId()[B
+Lcom/android/org/conscrypt/AbstractConscryptSocket;->getHandshakeApplicationProtocol()Ljava/lang/String;
+Lcom/android/org/conscrypt/AbstractConscryptSocket;->getHostname()Ljava/lang/String;
+Lcom/android/org/conscrypt/AbstractConscryptSocket;->getHostnameOrIP()Ljava/lang/String;
+Lcom/android/org/conscrypt/AbstractConscryptSocket;->getNpnSelectedProtocol()[B
+Lcom/android/org/conscrypt/AbstractConscryptSocket;->getSoWriteTimeout()I
+Lcom/android/org/conscrypt/AbstractConscryptSocket;->setAlpnProtocols([Ljava/lang/String;)V
+Lcom/android/org/conscrypt/AbstractConscryptSocket;->setAlpnProtocols([B)V
+Lcom/android/org/conscrypt/AbstractConscryptSocket;->setApplicationProtocols([Ljava/lang/String;)V
+Lcom/android/org/conscrypt/AbstractConscryptSocket;->setChannelIdEnabled(Z)V
+Lcom/android/org/conscrypt/AbstractConscryptSocket;->setChannelIdPrivateKey(Ljava/security/PrivateKey;)V
+Lcom/android/org/conscrypt/AbstractConscryptSocket;->setHandshakeTimeout(I)V
+Lcom/android/org/conscrypt/AbstractConscryptSocket;->setHostname(Ljava/lang/String;)V
+Lcom/android/org/conscrypt/AbstractConscryptSocket;->setNpnProtocols([B)V
+Lcom/android/org/conscrypt/AbstractConscryptSocket;->setSoWriteTimeout(I)V
+Lcom/android/org/conscrypt/AbstractConscryptSocket;->setUseSessionTickets(Z)V
+Lcom/android/org/conscrypt/ConscryptSocketBase;->getHostname()Ljava/lang/String;
+Lcom/android/org/conscrypt/ConscryptSocketBase;->getHostnameOrIP()Ljava/lang/String;
+Lcom/android/org/conscrypt/ConscryptSocketBase;->getSoWriteTimeout()I
+Lcom/android/org/conscrypt/ConscryptSocketBase;->setHandshakeTimeout(I)V
+Lcom/android/org/conscrypt/ConscryptSocketBase;->setHostname(Ljava/lang/String;)V
+Lcom/android/org/conscrypt/ConscryptSocketBase;->setSoWriteTimeout(I)V
 Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getAlpnSelectedProtocol()[B
+Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getChannelId()[B
+Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getHostname()Ljava/lang/String;
+Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getHostnameOrIP()Ljava/lang/String;
 Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getNpnSelectedProtocol()[B
+Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getSoWriteTimeout()I
+Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setAlpnProtocols([Ljava/lang/String;)V
 Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setAlpnProtocols([B)V
+Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setChannelIdEnabled(Z)V
+Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setChannelIdPrivateKey(Ljava/security/PrivateKey;)V
+Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setHandshakeTimeout(I)V
 Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setHostname(Ljava/lang/String;)V
 Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setNpnProtocols([B)V
+Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setSoWriteTimeout(I)V
 Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setUseSessionTickets(Z)V
 Lcom/android/org/conscrypt/TrustManagerImpl;-><init>(Ljava/security/KeyStore;)V
 Ldalvik/system/BaseDexClassLoader;->getLdLibraryPath()Ljava/lang/String;
diff --git a/config/preloaded-classes b/config/preloaded-classes
index 784c3f8..95c2b2c 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -2289,7 +2289,7 @@
 android.view.Gravity
 android.view.HandlerActionQueue
 android.view.HandlerActionQueue$HandlerAction
-android.view.HardwareLayer
+android.view.TextureLayer
 android.view.IGraphicsStats
 android.view.IGraphicsStats$Stub
 android.view.IGraphicsStats$Stub$Proxy
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 83fe4dd..3d04e2c 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -751,6 +751,14 @@
 
     private static final String KEYBOARD_SHORTCUTS_RECEIVER_PKG_NAME = "com.android.systemui";
 
+    private static final int LOG_AM_ON_CREATE_CALLED = 30057;
+    private static final int LOG_AM_ON_START_CALLED = 30059;
+    private static final int LOG_AM_ON_RESUME_CALLED = 30022;
+    private static final int LOG_AM_ON_PAUSE_CALLED = 30021;
+    private static final int LOG_AM_ON_STOP_CALLED = 30049;
+    private static final int LOG_AM_ON_RESTART_CALLED = 30058;
+    private static final int LOG_AM_ON_DESTROY_CALLED = 30060;
+
     private static class ManagedDialog {
         Dialog mDialog;
         Bundle mArgs;
@@ -1392,6 +1400,7 @@
      *
      * {@hide}
      */
+    @Override
     public int getNextAutofillId() {
         if (mLastAutofillId == Integer.MAX_VALUE - 1) {
             mLastAutofillId = View.LAST_APP_AUTOFILL_ID;
@@ -1403,6 +1412,14 @@
     }
 
     /**
+     * @hide
+     */
+    @Override
+    public AutofillId autofillClientGetNextAutofillId() {
+        return new AutofillId(getNextAutofillId());
+    }
+
+    /**
      * 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
      * {@link VoiceInteractor} returned by {@link #getVoiceInteractor}.
@@ -4144,9 +4161,10 @@
      * <p>You can override this function to force global search, e.g. in response to a dedicated
      * search key, or to block search entirely (by simply returning false).
      *
-     * <p>Note: when running in a {@link Configuration#UI_MODE_TYPE_TELEVISION}, the default
-     * implementation changes to simply return false and you must supply your own custom
-     * implementation if you want to support search.</p>
+     * <p>Note: when running in a {@link Configuration#UI_MODE_TYPE_TELEVISION} or
+     * {@link Configuration#UI_MODE_TYPE_WATCH}, the default implementation changes to simply
+     * return false and you must supply your own custom implementation if you want to support
+     * search.
      *
      * @param searchEvent The {@link SearchEvent} that signaled this search.
      * @return Returns {@code true} if search launched, and {@code false} if the activity does
@@ -4166,8 +4184,10 @@
      * @see #onSearchRequested(SearchEvent)
      */
     public boolean onSearchRequested() {
-        if ((getResources().getConfiguration().uiMode&Configuration.UI_MODE_TYPE_MASK)
-                != Configuration.UI_MODE_TYPE_TELEVISION) {
+        final int uiMode = getResources().getConfiguration().uiMode
+            & Configuration.UI_MODE_TYPE_MASK;
+        if (uiMode != Configuration.UI_MODE_TYPE_TELEVISION
+                && uiMode != Configuration.UI_MODE_TYPE_WATCH) {
             startSearch(null, false, null, false);
             return true;
         } else {
@@ -4196,6 +4216,9 @@
      * is to inject specific data such as context data, it is preferred to <i>override</i>
      * onSearchRequested(), so that any callers to it will benefit from the override.
      *
+     * <p>Note: when running in a {@link Configuration#UI_MODE_TYPE_WATCH}, use of this API is
+     * not supported.
+     *
      * @param initialQuery Any non-null non-empty string will be inserted as
      * pre-entered text in the search query box.
      * @param selectInitialQuery If true, the initial query will be preselected, which means that
@@ -5553,13 +5576,7 @@
         if (mParent != null) {
             throw new IllegalStateException("Can only be called on top-level activity");
         }
-        if (Looper.myLooper() != mMainThread.getLooper()) {
-            throw new IllegalStateException("Must be called from main thread");
-        }
-        try {
-            ActivityManager.getService().requestActivityRelaunch(mToken);
-        } catch (RemoteException e) {
-        }
+        mMainThread.handleRelaunchActivityLocally(mToken);
     }
 
     /**
@@ -7103,6 +7120,7 @@
         } else {
             onCreate(icicle);
         }
+        writeEventLog(LOG_AM_ON_CREATE_CALLED, "performCreate");
         mActivityTransitionState.readState(icicle);
 
         mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
@@ -7116,12 +7134,14 @@
         onNewIntent(intent);
     }
 
-    final void performStart() {
+    final void performStart(String reason) {
         mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
         mFragments.noteStateNotSaved();
         mCalled = false;
         mFragments.execPendingActions();
         mInstrumentation.callActivityOnStart(this);
+        writeEventLog(LOG_AM_ON_START_CALLED, reason);
+
         if (!mCalled) {
             throw new SuperNotCalledException(
                 "Activity " + mComponent.toShortString() +
@@ -7190,7 +7210,7 @@
      *              The option to not start immediately is needed in case a transaction with
      *              multiple lifecycle transitions is in progress.
      */
-    final void performRestart(boolean start) {
+    final void performRestart(boolean start, String reason) {
         mCanEnterPictureInPicture = true;
         mFragments.noteStateNotSaved();
 
@@ -7223,19 +7243,20 @@
 
             mCalled = false;
             mInstrumentation.callActivityOnRestart(this);
+            writeEventLog(LOG_AM_ON_RESTART_CALLED, reason);
             if (!mCalled) {
                 throw new SuperNotCalledException(
                     "Activity " + mComponent.toShortString() +
                     " did not call through to super.onRestart()");
             }
             if (start) {
-                performStart();
+                performStart(reason);
             }
         }
     }
 
-    final void performResume(boolean followedByPause) {
-        performRestart(true /* start */);
+    final void performResume(boolean followedByPause, String reason) {
+        performRestart(true /* start */, reason);
 
         mFragments.execPendingActions();
 
@@ -7254,6 +7275,7 @@
         mCalled = false;
         // mResumed is set by the instrumentation
         mInstrumentation.callActivityOnResume(this);
+        writeEventLog(LOG_AM_ON_RESUME_CALLED, reason);
         if (!mCalled) {
             throw new SuperNotCalledException(
                 "Activity " + mComponent.toShortString() +
@@ -7290,6 +7312,7 @@
         mFragments.dispatchPause();
         mCalled = false;
         onPause();
+        writeEventLog(LOG_AM_ON_PAUSE_CALLED, "performPause");
         mResumed = false;
         if (!mCalled && getApplicationInfo().targetSdkVersion
                 >= android.os.Build.VERSION_CODES.GINGERBREAD) {
@@ -7297,7 +7320,6 @@
                     "Activity " + mComponent.toShortString() +
                     " did not call through to super.onPause()");
         }
-        mResumed = false;
     }
 
     final void performUserLeaving() {
@@ -7305,7 +7327,7 @@
         onUserLeaveHint();
     }
 
-    final void performStop(boolean preserveWindow) {
+    final void performStop(boolean preserveWindow, String reason) {
         mDoReportFullyDrawn = false;
         mFragments.doLoaderStop(mChangingConfigurations /*retain*/);
 
@@ -7328,6 +7350,7 @@
 
             mCalled = false;
             mInstrumentation.callActivityOnStop(this);
+            writeEventLog(LOG_AM_ON_STOP_CALLED, reason);
             if (!mCalled) {
                 throw new SuperNotCalledException(
                     "Activity " + mComponent.toShortString() +
@@ -7355,6 +7378,7 @@
         mWindow.destroy();
         mFragments.dispatchDestroy();
         onDestroy();
+        writeEventLog(LOG_AM_ON_DESTROY_CALLED, "performDestroy");
         mFragments.doLoaderDestroy();
         if (mVoiceInteractor != null) {
             mVoiceInteractor.detachActivity();
@@ -7615,6 +7639,19 @@
 
     /** @hide */
     @Override
+    public final void autofillClientDispatchUnhandledKey(@NonNull View anchor,
+            @NonNull KeyEvent keyEvent) {
+        ViewRootImpl rootImpl = anchor.getViewRootImpl();
+        if (rootImpl != null) {
+            // dont care if anchorView is current focus, for example a custom view may only receive
+            // touchEvent, not focusable but can still trigger autofill window. The Key handling
+            // might be inside parent of the custom view.
+            rootImpl.dispatchKeyFromAutofill(keyEvent);
+        }
+    }
+
+    /** @hide */
+    @Override
     public final boolean autofillClientRequestHideFillUi() {
         if (mAutofillPopupWindow == null) {
             return false;
@@ -7730,7 +7767,7 @@
 
     /** @hide */
     @Override
-    public final boolean autofillIsCompatibilityModeEnabled() {
+    public final boolean autofillClientIsCompatibilityModeEnabled() {
         return isAutofillCompatibilityEnabled();
     }
 
@@ -7829,6 +7866,12 @@
         }
     }
 
+    /** Log a lifecycle event for current user id and component class. */
+    private void writeEventLog(int event, String reason) {
+        EventLog.writeEvent(event, UserHandle.myUserId(), getComponentName().getClassName(),
+                reason);
+    }
+
     class HostCallbacks extends FragmentHostCallback<Activity> {
         public HostCallbacks() {
             super(Activity.this /*activity*/);
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 03faeee..de4d178 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -71,6 +71,7 @@
 import com.android.internal.os.RoSystemProperties;
 import com.android.internal.os.TransferPipe;
 import com.android.internal.util.FastPrintWriter;
+import com.android.internal.util.MemInfoReader;
 import com.android.server.LocalServices;
 
 import org.xmlpull.v1.XmlSerializer;
@@ -964,6 +965,17 @@
     }
 
     /**
+     * Return the total number of bytes of RAM this device has.
+     * @hide
+     */
+    @TestApi
+    public long getTotalRam() {
+        MemInfoReader memreader = new MemInfoReader();
+        memreader.readMemInfo();
+        return memreader.getTotalSize();
+    }
+
+    /**
      * Return the maximum number of recents entries that we will maintain and show.
      * @hide
      */
@@ -3335,6 +3347,28 @@
     }
 
     /**
+     * Query whether the user has enabled background restrictions for this app.
+     *
+     * <p> The user may chose to do this, if they see that an app is consuming an unreasonable
+     * amount of battery while in the background. </p>
+     *
+     * <p> If true, any work that the app tries to do will be aggressively restricted while it is in
+     * the background. At a minimum, jobs and alarms will not execute and foreground services
+     * cannot be started unless an app activity is in the foreground. </p>
+     *
+     * <p><b> Note that these restrictions stay in effect even when the device is charging.</b></p>
+     *
+     * @return true if user has enforced background restrictions for this app, false otherwise.
+     */
+    public boolean isBackgroundRestricted() {
+        try {
+            return getService().isBackgroundRestricted(mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Sets the memory trim mode for a process and schedules a memory trim operation.
      *
      * <p><b>Note: this method is only intended for testing framework.</b></p>
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index feeb0f2..c78255f 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -353,6 +353,11 @@
     public abstract boolean isCallerRecents(int callingUid);
 
     /**
+     * Returns whether the recents component is the home activity for the given user.
+     */
+    public abstract boolean isRecentsComponentHomeActivity(int userId);
+
+    /**
      * Whether an UID is active or idle.
      */
     public abstract boolean isUidActive(int uid);
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index d5430f0..09dcbf2 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -164,7 +164,7 @@
 
     /**
      * Whether the activity should be launched into LockTask mode.
-     * @see #setLockTaskMode(boolean)
+     * @see #setLockTaskEnabled(boolean)
      */
     private static final String KEY_LOCK_TASK_MODE = "android:activity.lockTaskMode";
 
@@ -1148,7 +1148,7 @@
      * @see Activity#startLockTask()
      * @see android.app.admin.DevicePolicyManager#setLockTaskPackages(ComponentName, String[])
      */
-    public ActivityOptions setLockTaskMode(boolean lockTaskMode) {
+    public ActivityOptions setLockTaskEnabled(boolean lockTaskMode) {
         mLockTaskMode = lockTaskMode;
         return this;
     }
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index a69b0ee..379944e 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -143,7 +143,7 @@
 import com.android.internal.util.FastPrintWriter;
 import com.android.org.conscrypt.OpenSSLSocketImpl;
 import com.android.org.conscrypt.TrustedCertificateStore;
-import com.android.server.am.proto.MemInfoProto;
+import com.android.server.am.proto.MemInfoDumpProto;
 
 import dalvik.system.BaseDexClassLoader;
 import dalvik.system.CloseGuard;
@@ -208,9 +208,6 @@
     public static final boolean DEBUG_ORDER = false;
     private static final long MIN_TIME_BETWEEN_GCS = 5*1000;
     private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003;
-    private static final int LOG_AM_ON_PAUSE_CALLED = 30021;
-    private static final int LOG_AM_ON_RESUME_CALLED = 30022;
-    private static final int LOG_AM_ON_STOP_CALLED = 30049;
 
     /** Type for IActivityManager.serviceDoneExecuting: anonymous operation */
     public static final int SERVICE_DONE_EXECUTING_ANON = 0;
@@ -1254,55 +1251,62 @@
             long parcelCount = Parcel.getGlobalAllocCount();
             SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo();
 
-            final long mToken = proto.start(MemInfoProto.AppData.PROCESS_MEMORY);
-            proto.write(MemInfoProto.ProcessMemory.PID, Process.myPid());
-            proto.write(MemInfoProto.ProcessMemory.PROCESS_NAME,
+            final long mToken = proto.start(MemInfoDumpProto.AppData.PROCESS_MEMORY);
+            proto.write(MemInfoDumpProto.ProcessMemory.PID, Process.myPid());
+            proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME,
                     (mBoundApplication != null) ? mBoundApplication.processName : "unknown");
             dumpMemInfoTable(proto, memInfo, dumpDalvik, dumpSummaryOnly,
                     nativeMax, nativeAllocated, nativeFree,
                     dalvikMax, dalvikAllocated, dalvikFree);
             proto.end(mToken);
 
-            final long oToken = proto.start(MemInfoProto.AppData.OBJECTS);
-            proto.write(MemInfoProto.AppData.ObjectStats.VIEW_INSTANCE_COUNT, viewInstanceCount);
-            proto.write(MemInfoProto.AppData.ObjectStats.VIEW_ROOT_INSTANCE_COUNT,
+            final long oToken = proto.start(MemInfoDumpProto.AppData.OBJECTS);
+            proto.write(MemInfoDumpProto.AppData.ObjectStats.VIEW_INSTANCE_COUNT,
+                    viewInstanceCount);
+            proto.write(MemInfoDumpProto.AppData.ObjectStats.VIEW_ROOT_INSTANCE_COUNT,
                     viewRootInstanceCount);
-            proto.write(MemInfoProto.AppData.ObjectStats.APP_CONTEXT_INSTANCE_COUNT,
+            proto.write(MemInfoDumpProto.AppData.ObjectStats.APP_CONTEXT_INSTANCE_COUNT,
                     appContextInstanceCount);
-            proto.write(MemInfoProto.AppData.ObjectStats.ACTIVITY_INSTANCE_COUNT,
+            proto.write(MemInfoDumpProto.AppData.ObjectStats.ACTIVITY_INSTANCE_COUNT,
                     activityInstanceCount);
-            proto.write(MemInfoProto.AppData.ObjectStats.GLOBAL_ASSET_COUNT, globalAssetCount);
-            proto.write(MemInfoProto.AppData.ObjectStats.GLOBAL_ASSET_MANAGER_COUNT,
+            proto.write(MemInfoDumpProto.AppData.ObjectStats.GLOBAL_ASSET_COUNT,
+                    globalAssetCount);
+            proto.write(MemInfoDumpProto.AppData.ObjectStats.GLOBAL_ASSET_MANAGER_COUNT,
                     globalAssetManagerCount);
-            proto.write(MemInfoProto.AppData.ObjectStats.LOCAL_BINDER_OBJECT_COUNT,
+            proto.write(MemInfoDumpProto.AppData.ObjectStats.LOCAL_BINDER_OBJECT_COUNT,
                     binderLocalObjectCount);
-            proto.write(MemInfoProto.AppData.ObjectStats.PROXY_BINDER_OBJECT_COUNT,
+            proto.write(MemInfoDumpProto.AppData.ObjectStats.PROXY_BINDER_OBJECT_COUNT,
                     binderProxyObjectCount);
-            proto.write(MemInfoProto.AppData.ObjectStats.PARCEL_MEMORY_KB, parcelSize / 1024);
-            proto.write(MemInfoProto.AppData.ObjectStats.PARCEL_COUNT, parcelCount);
-            proto.write(MemInfoProto.AppData.ObjectStats.BINDER_OBJECT_DEATH_COUNT,
+            proto.write(MemInfoDumpProto.AppData.ObjectStats.PARCEL_MEMORY_KB,
+                    parcelSize / 1024);
+            proto.write(MemInfoDumpProto.AppData.ObjectStats.PARCEL_COUNT, parcelCount);
+            proto.write(MemInfoDumpProto.AppData.ObjectStats.BINDER_OBJECT_DEATH_COUNT,
                     binderDeathObjectCount);
-            proto.write(MemInfoProto.AppData.ObjectStats.OPEN_SSL_SOCKET_COUNT, openSslSocketCount);
-            proto.write(MemInfoProto.AppData.ObjectStats.WEBVIEW_INSTANCE_COUNT,
+            proto.write(MemInfoDumpProto.AppData.ObjectStats.OPEN_SSL_SOCKET_COUNT,
+                    openSslSocketCount);
+            proto.write(MemInfoDumpProto.AppData.ObjectStats.WEBVIEW_INSTANCE_COUNT,
                     webviewInstanceCount);
             proto.end(oToken);
 
             // SQLite mem info
-            final long sToken = proto.start(MemInfoProto.AppData.SQL);
-            proto.write(MemInfoProto.AppData.SqlStats.MEMORY_USED_KB, stats.memoryUsed / 1024);
-            proto.write(MemInfoProto.AppData.SqlStats.PAGECACHE_OVERFLOW_KB,
+            final long sToken = proto.start(MemInfoDumpProto.AppData.SQL);
+            proto.write(MemInfoDumpProto.AppData.SqlStats.MEMORY_USED_KB,
+                    stats.memoryUsed / 1024);
+            proto.write(MemInfoDumpProto.AppData.SqlStats.PAGECACHE_OVERFLOW_KB,
                     stats.pageCacheOverflow / 1024);
-            proto.write(MemInfoProto.AppData.SqlStats.MALLOC_SIZE_KB, stats.largestMemAlloc / 1024);
+            proto.write(MemInfoDumpProto.AppData.SqlStats.MALLOC_SIZE_KB,
+                    stats.largestMemAlloc / 1024);
             int n = stats.dbStats.size();
             for (int i = 0; i < n; i++) {
                 DbStats dbStats = stats.dbStats.get(i);
 
-                final long dToken = proto.start(MemInfoProto.AppData.SqlStats.DATABASES);
-                proto.write(MemInfoProto.AppData.SqlStats.Database.NAME, dbStats.dbName);
-                proto.write(MemInfoProto.AppData.SqlStats.Database.PAGE_SIZE, dbStats.pageSize);
-                proto.write(MemInfoProto.AppData.SqlStats.Database.DB_SIZE, dbStats.dbSize);
-                proto.write(MemInfoProto.AppData.SqlStats.Database.LOOKASIDE_B, dbStats.lookaside);
-                proto.write(MemInfoProto.AppData.SqlStats.Database.CACHE, dbStats.cache);
+                final long dToken = proto.start(MemInfoDumpProto.AppData.SqlStats.DATABASES);
+                proto.write(MemInfoDumpProto.AppData.SqlStats.Database.NAME, dbStats.dbName);
+                proto.write(MemInfoDumpProto.AppData.SqlStats.Database.PAGE_SIZE, dbStats.pageSize);
+                proto.write(MemInfoDumpProto.AppData.SqlStats.Database.DB_SIZE, dbStats.dbSize);
+                proto.write(MemInfoDumpProto.AppData.SqlStats.Database.LOOKASIDE_B,
+                        dbStats.lookaside);
+                proto.write(MemInfoDumpProto.AppData.SqlStats.Database.CACHE, dbStats.cache);
                 proto.end(dToken);
             }
             proto.end(sToken);
@@ -1310,7 +1314,7 @@
             // Asset details.
             String assetAlloc = AssetManager.getAssetAllocations();
             if (assetAlloc != null) {
-                proto.write(MemInfoProto.AppData.ASSET_ALLOCATIONS, assetAlloc);
+                proto.write(MemInfoDumpProto.AppData.ASSET_ALLOCATIONS, assetAlloc);
             }
 
             // Unreachable native memory
@@ -1318,7 +1322,7 @@
                 int flags = mBoundApplication == null ? 0 : mBoundApplication.appInfo.flags;
                 boolean showContents = (flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0
                         || android.os.Build.IS_DEBUGGABLE;
-                proto.write(MemInfoProto.AppData.UNREACHABLE_MEMORY,
+                proto.write(MemInfoDumpProto.AppData.UNREACHABLE_MEMORY,
                         Debug.getUnreachableMemory(100, showContents));
             }
         }
@@ -2508,17 +2512,17 @@
             boolean hasSwappedOutPss, int dirtySwap, int dirtySwapPss) {
         final long token = proto.start(fieldId);
 
-        proto.write(MemInfoProto.ProcessMemory.MemoryInfo.NAME, name);
-        proto.write(MemInfoProto.ProcessMemory.MemoryInfo.TOTAL_PSS_KB, pss);
-        proto.write(MemInfoProto.ProcessMemory.MemoryInfo.CLEAN_PSS_KB, cleanPss);
-        proto.write(MemInfoProto.ProcessMemory.MemoryInfo.SHARED_DIRTY_KB, sharedDirty);
-        proto.write(MemInfoProto.ProcessMemory.MemoryInfo.PRIVATE_DIRTY_KB, privateDirty);
-        proto.write(MemInfoProto.ProcessMemory.MemoryInfo.SHARED_CLEAN_KB, sharedClean);
-        proto.write(MemInfoProto.ProcessMemory.MemoryInfo.PRIVATE_CLEAN_KB, privateClean);
+        proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.NAME, name);
+        proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.TOTAL_PSS_KB, pss);
+        proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.CLEAN_PSS_KB, cleanPss);
+        proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.SHARED_DIRTY_KB, sharedDirty);
+        proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.PRIVATE_DIRTY_KB, privateDirty);
+        proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.SHARED_CLEAN_KB, sharedClean);
+        proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.PRIVATE_CLEAN_KB, privateClean);
         if (hasSwappedOutPss) {
-            proto.write(MemInfoProto.ProcessMemory.MemoryInfo.DIRTY_SWAP_PSS_KB, dirtySwapPss);
+            proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.DIRTY_SWAP_PSS_KB, dirtySwapPss);
         } else {
-            proto.write(MemInfoProto.ProcessMemory.MemoryInfo.DIRTY_SWAP_KB, dirtySwap);
+            proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.DIRTY_SWAP_KB, dirtySwap);
         }
 
         proto.end(token);
@@ -2533,26 +2537,26 @@
             long dalvikMax, long dalvikAllocated, long dalvikFree) {
 
         if (!dumpSummaryOnly) {
-            final long nhToken = proto.start(MemInfoProto.ProcessMemory.NATIVE_HEAP);
-            dumpMemoryInfo(proto, MemInfoProto.ProcessMemory.HeapInfo.MEM_INFO, "Native Heap",
+            final long nhToken = proto.start(MemInfoDumpProto.ProcessMemory.NATIVE_HEAP);
+            dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.HeapInfo.MEM_INFO, "Native Heap",
                     memInfo.nativePss, memInfo.nativeSwappablePss, memInfo.nativeSharedDirty,
                     memInfo.nativePrivateDirty, memInfo.nativeSharedClean,
                     memInfo.nativePrivateClean, memInfo.hasSwappedOutPss,
                     memInfo.nativeSwappedOut, memInfo.nativeSwappedOutPss);
-            proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_SIZE_KB, nativeMax);
-            proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_ALLOC_KB, nativeAllocated);
-            proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_FREE_KB, nativeFree);
+            proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_SIZE_KB, nativeMax);
+            proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_ALLOC_KB, nativeAllocated);
+            proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_FREE_KB, nativeFree);
             proto.end(nhToken);
 
-            final long dvToken = proto.start(MemInfoProto.ProcessMemory.DALVIK_HEAP);
-            dumpMemoryInfo(proto, MemInfoProto.ProcessMemory.HeapInfo.MEM_INFO, "Dalvik Heap",
+            final long dvToken = proto.start(MemInfoDumpProto.ProcessMemory.DALVIK_HEAP);
+            dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.HeapInfo.MEM_INFO, "Dalvik Heap",
                     memInfo.dalvikPss, memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty,
                     memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean,
                     memInfo.dalvikPrivateClean, memInfo.hasSwappedOutPss,
                     memInfo.dalvikSwappedOut, memInfo.dalvikSwappedOutPss);
-            proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_SIZE_KB, dalvikMax);
-            proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_ALLOC_KB, dalvikAllocated);
-            proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_FREE_KB, dalvikFree);
+            proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_SIZE_KB, dalvikMax);
+            proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_ALLOC_KB, dalvikAllocated);
+            proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_FREE_KB, dalvikFree);
             proto.end(dvToken);
 
             int otherPss = memInfo.otherPss;
@@ -2576,7 +2580,7 @@
                 if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
                         || mySharedClean != 0 || myPrivateClean != 0
                         || (memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut) != 0) {
-                    dumpMemoryInfo(proto, MemInfoProto.ProcessMemory.OTHER_HEAPS,
+                    dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.OTHER_HEAPS,
                             Debug.MemoryInfo.getOtherLabel(i),
                             myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
                             mySharedClean, myPrivateClean,
@@ -2593,21 +2597,23 @@
                 }
             }
 
-            dumpMemoryInfo(proto, MemInfoProto.ProcessMemory.UNKNOWN_HEAP, "Unknown",
+            dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.UNKNOWN_HEAP, "Unknown",
                     otherPss, otherSwappablePss,
                     otherSharedDirty, otherPrivateDirty, otherSharedClean, otherPrivateClean,
                     memInfo.hasSwappedOutPss, otherSwappedOut, otherSwappedOutPss);
-            final long tToken = proto.start(MemInfoProto.ProcessMemory.TOTAL_HEAP);
-            dumpMemoryInfo(proto, MemInfoProto.ProcessMemory.HeapInfo.MEM_INFO, "TOTAL",
+            final long tToken = proto.start(MemInfoDumpProto.ProcessMemory.TOTAL_HEAP);
+            dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.HeapInfo.MEM_INFO, "TOTAL",
                     memInfo.getTotalPss(), memInfo.getTotalSwappablePss(),
                     memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(),
                     memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(),
                     memInfo.hasSwappedOutPss, memInfo.getTotalSwappedOut(),
                     memInfo.getTotalSwappedOutPss());
-            proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_SIZE_KB, nativeMax + dalvikMax);
-            proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_ALLOC_KB,
+            proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_SIZE_KB,
+                    nativeMax + dalvikMax);
+            proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_ALLOC_KB,
                     nativeAllocated + dalvikAllocated);
-            proto.write(MemInfoProto.ProcessMemory.HeapInfo.HEAP_FREE_KB, nativeFree + dalvikFree);
+            proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_FREE_KB,
+                    nativeFree + dalvikFree);
             proto.end(tToken);
 
             if (dumpDalvik) {
@@ -2625,7 +2631,7 @@
                     if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
                             || mySharedClean != 0 || myPrivateClean != 0
                             || (memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut) != 0) {
-                        dumpMemoryInfo(proto, MemInfoProto.ProcessMemory.DALVIK_DETAILS,
+                        dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.DALVIK_DETAILS,
                                 Debug.MemoryInfo.getOtherLabel(i),
                                 myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
                                 mySharedClean, myPrivateClean,
@@ -2635,24 +2641,26 @@
             }
         }
 
-        final long asToken = proto.start(MemInfoProto.ProcessMemory.APP_SUMMARY);
-        proto.write(MemInfoProto.ProcessMemory.AppSummary.JAVA_HEAP_PSS_KB,
+        final long asToken = proto.start(MemInfoDumpProto.ProcessMemory.APP_SUMMARY);
+        proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.JAVA_HEAP_PSS_KB,
                 memInfo.getSummaryJavaHeap());
-        proto.write(MemInfoProto.ProcessMemory.AppSummary.NATIVE_HEAP_PSS_KB,
+        proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.NATIVE_HEAP_PSS_KB,
                 memInfo.getSummaryNativeHeap());
-        proto.write(MemInfoProto.ProcessMemory.AppSummary.CODE_PSS_KB, memInfo.getSummaryCode());
-        proto.write(MemInfoProto.ProcessMemory.AppSummary.STACK_PSS_KB, memInfo.getSummaryStack());
-        proto.write(MemInfoProto.ProcessMemory.AppSummary.GRAPHICS_PSS_KB,
+        proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.CODE_PSS_KB,
+                memInfo.getSummaryCode());
+        proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.STACK_PSS_KB,
+                memInfo.getSummaryStack());
+        proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.GRAPHICS_PSS_KB,
                 memInfo.getSummaryGraphics());
-        proto.write(MemInfoProto.ProcessMemory.AppSummary.PRIVATE_OTHER_PSS_KB,
+        proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.PRIVATE_OTHER_PSS_KB,
                 memInfo.getSummaryPrivateOther());
-        proto.write(MemInfoProto.ProcessMemory.AppSummary.SYSTEM_PSS_KB,
+        proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.SYSTEM_PSS_KB,
                 memInfo.getSummarySystem());
         if (memInfo.hasSwappedOutPss) {
-            proto.write(MemInfoProto.ProcessMemory.AppSummary.TOTAL_SWAP_PSS,
+            proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.TOTAL_SWAP_PSS,
                     memInfo.getSummaryTotalSwapPss());
         } else {
-            proto.write(MemInfoProto.ProcessMemory.AppSummary.TOTAL_SWAP_PSS,
+            proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.TOTAL_SWAP_PSS,
                     memInfo.getSummaryTotalSwap());
         }
         proto.end(asToken);
@@ -2924,7 +2932,7 @@
         }
 
         // Start
-        activity.performStart();
+        activity.performStart("handleStartActivity");
         r.setState(ON_START);
 
         if (pendingActions == null) {
@@ -3113,7 +3121,7 @@
         checkAndBlockForNetworkAccess();
         deliverNewIntents(r, intents);
         if (resumed) {
-            r.activity.performResume(false);
+            r.activity.performResume(false, "performNewIntents");
             r.activity.mTemporaryPause = false;
         }
 
@@ -3719,6 +3727,10 @@
         if (localLOGV) Slog.v(TAG, "Performing resume of " + r
                 + " finished=" + r.activity.mFinished);
         if (r != null && !r.activity.mFinished) {
+            if (r.getLifecycleState() == ON_RESUME) {
+                throw new IllegalStateException(
+                        "Trying to resume activity which is already resumed");
+            }
             if (clearHide) {
                 r.hideForNow = false;
                 r.activity.mStartedActivity = false;
@@ -3735,10 +3747,7 @@
                     deliverResults(r, r.pendingResults);
                     r.pendingResults = null;
                 }
-                r.activity.performResume(r.startsNotResumed);
-
-                EventLog.writeEvent(LOG_AM_ON_RESUME_CALLED, UserHandle.myUserId(),
-                        r.activity.getComponentName().getClassName(), reason);
+                r.activity.performResume(r.startsNotResumed, reason);
 
                 r.state = null;
                 r.persistentState = null;
@@ -3906,7 +3915,7 @@
 
     @Override
     public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
-            int configChanges, boolean dontReport, PendingTransactionActions pendingActions) {
+            int configChanges, PendingTransactionActions pendingActions, String reason) {
         ActivityClientRecord r = mActivities.get(token);
         if (r != null) {
             if (userLeaving) {
@@ -3914,21 +3923,12 @@
             }
 
             r.activity.mConfigChangeFlags |= configChanges;
-            performPauseActivity(r, finished, "handlePauseActivity", pendingActions);
+            performPauseActivity(r, finished, reason, pendingActions);
 
             // Make sure any pending writes are now committed.
             if (r.isPreHoneycomb()) {
                 QueuedWork.waitToFinish();
             }
-
-            // Tell the activity manager we have paused.
-            if (!dontReport) {
-                try {
-                    ActivityManager.getService().activityPaused(token);
-                } catch (RemoteException ex) {
-                    throw ex.rethrowFromSystemServer();
-                }
-            }
             mSomeActivitiesChanged = true;
         }
     }
@@ -4007,8 +4007,6 @@
         try {
             r.activity.mCalled = false;
             mInstrumentation.callActivityOnPause(r.activity);
-            EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),
-                    r.activity.getComponentName().getClassName(), reason);
             if (!r.activity.mCalled) {
                 throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
                         + " did not call through to super.onPause()");
@@ -4119,7 +4117,7 @@
         }
 
         try {
-            r.activity.performStop(false /*preserveWindow*/);
+            r.activity.performStop(false /*preserveWindow*/, reason);
         } catch (SuperNotCalledException e) {
             throw e;
         } catch (Exception e) {
@@ -4131,8 +4129,6 @@
             }
         }
         r.setState(ON_STOP);
-        EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(),
-                r.activity.getComponentName().getClassName(), reason);
 
         if (shouldSaveState && !isPreP) {
             callActivityOnSaveInstanceState(r);
@@ -4169,12 +4165,12 @@
 
     @Override
     public void handleStopActivity(IBinder token, boolean show, int configChanges,
-            PendingTransactionActions pendingActions) {
+            PendingTransactionActions pendingActions, String reason) {
         final ActivityClientRecord r = mActivities.get(token);
         r.activity.mConfigChangeFlags |= configChanges;
 
         final StopInfo stopInfo = new StopInfo();
-        performStopActivityInner(r, stopInfo, show, true, "handleStopActivity");
+        performStopActivityInner(r, stopInfo, show, true, reason);
 
         if (localLOGV) Slog.v(
             TAG, "Finishing stop of " + r + ": show=" + show
@@ -4209,7 +4205,7 @@
     public void performRestartActivity(IBinder token, boolean start) {
         ActivityClientRecord r = mActivities.get(token);
         if (r.stopped) {
-            r.activity.performRestart(start);
+            r.activity.performRestart(start, "performRestartActivity");
             if (start) {
                 r.setState(ON_START);
             }
@@ -4232,7 +4228,7 @@
             // we are back active so skip it.
             unscheduleGcIdler();
 
-            r.activity.performRestart(true /* start */);
+            r.activity.performRestart(true /* start */, "handleWindowVisibility");
             r.setState(ON_START);
         }
         if (r.activity.mDecor != null) {
@@ -4272,7 +4268,7 @@
             }
         } else {
             if (r.stopped && r.activity.mVisibleFromServer) {
-                r.activity.performRestart(true /* start */);
+                r.activity.performRestart(true /* start */, "handleSleeping");
                 r.setState(ON_START);
             }
         }
@@ -4292,19 +4288,15 @@
             View.mDebugViewAttributes = debugViewAttributes;
 
             // request all activities to relaunch for the changes to take place
-            requestRelaunchAllActivities();
+            relaunchAllActivities();
         }
     }
 
-    private void requestRelaunchAllActivities() {
+    private void relaunchAllActivities() {
         for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {
             final Activity activity = entry.getValue().activity;
             if (!activity.mFinished) {
-                try {
-                    ActivityManager.getService().requestActivityRelaunch(entry.getKey());
-                } catch (RemoteException e) {
-                    throw e.rethrowFromSystemServer();
-                }
+                handleRelaunchActivityLocally(entry.getKey());
             }
         }
     }
@@ -4384,7 +4376,7 @@
             checkAndBlockForNetworkAccess();
             deliverResults(r, results);
             if (resumed) {
-                r.activity.performResume(false);
+                r.activity.performResume(false, "handleSendResult");
                 r.activity.mTemporaryPause = false;
             }
         }
@@ -4679,42 +4671,81 @@
             throw e.rethrowFromSystemServer();
         }
 
-        // Need to ensure state is saved.
-        if (!r.paused) {
-            performPauseActivity(r, false, "handleRelaunchActivity",
-                    null /* pendingActions */);
+        handleRelaunchActivityInner(r, configChanges, tmp.pendingResults, tmp.pendingIntents,
+                pendingActions, tmp.startsNotResumed, tmp.overrideConfig, "handleRelaunchActivity");
+
+        if (pendingActions != null) {
+            // Only report a successful relaunch to WindowManager.
+            pendingActions.setReportRelaunchToWindowManager(true);
         }
-        if (!r.stopped) {
-            callActivityOnStop(r, true /* saveState */, "handleRelaunchActivity");
+    }
+
+    /** Performs the activity relaunch locally vs. requesting from system-server. */
+    void handleRelaunchActivityLocally(IBinder token) {
+        if (Looper.myLooper() != getLooper()) {
+            throw new IllegalStateException("Must be called from main thread");
         }
 
-        handleDestroyActivity(r.token, false, configChanges, true, "handleRelaunchActivity");
+        final ActivityClientRecord r = mActivities.get(token);
+        if (r == null) {
+            return;
+        }
+
+        final int prevState = r.getLifecycleState();
+
+        if (prevState < ON_RESUME) {
+            Log.w(TAG, "Activity needs to be already resumed in other to be relaunched.");
+            return;
+        }
+
+        // TODO(b/73747058): Investigate converting this to use transaction to relaunch.
+        handleRelaunchActivityInner(r, 0 /* configChanges */, null /* pendingResults */,
+                null /* pendingIntents */, null /* pendingActions */, prevState != ON_RESUME,
+                r.overrideConfig, "handleRelaunchActivityLocally");
+
+        // Restore back to the previous state before relaunch if needed.
+        if (prevState != r.getLifecycleState()) {
+            mTransactionExecutor.cycleToPath(r, prevState);
+        }
+    }
+
+    private void handleRelaunchActivityInner(ActivityClientRecord r, int configChanges,
+            List<ResultInfo> pendingResults, List<ReferrerIntent> pendingIntents,
+            PendingTransactionActions pendingActions, boolean startsNotResumed,
+            Configuration overrideConfig, String reason) {
+        // Need to ensure state is saved.
+        if (!r.paused) {
+            performPauseActivity(r, false, reason, null /* pendingActions */);
+        }
+        if (!r.stopped) {
+            callActivityOnStop(r, true /* saveState */, reason);
+        }
+
+        handleDestroyActivity(r.token, false, configChanges, true, reason);
 
         r.activity = null;
         r.window = null;
         r.hideForNow = false;
         r.nextIdle = null;
         // Merge any pending results and pending intents; don't just replace them
-        if (tmp.pendingResults != null) {
+        if (pendingResults != null) {
             if (r.pendingResults == null) {
-                r.pendingResults = tmp.pendingResults;
+                r.pendingResults = pendingResults;
             } else {
-                r.pendingResults.addAll(tmp.pendingResults);
+                r.pendingResults.addAll(pendingResults);
             }
         }
-        if (tmp.pendingIntents != null) {
+        if (pendingIntents != null) {
             if (r.pendingIntents == null) {
-                r.pendingIntents = tmp.pendingIntents;
+                r.pendingIntents = pendingIntents;
             } else {
-                r.pendingIntents.addAll(tmp.pendingIntents);
+                r.pendingIntents.addAll(pendingIntents);
             }
         }
-        r.startsNotResumed = tmp.startsNotResumed;
-        r.overrideConfig = tmp.overrideConfig;
+        r.startsNotResumed = startsNotResumed;
+        r.overrideConfig = overrideConfig;
 
         handleLaunchActivity(r, pendingActions);
-        // Only report a successful relaunch to WindowManager.
-        pendingActions.setReportRelaunchToWindowManager(true);
     }
 
     @Override
@@ -5117,7 +5148,7 @@
         newConfig.assetsSeq = (mConfiguration != null ? mConfiguration.assetsSeq : 0) + 1;
         handleConfigurationChanged(newConfig, null);
 
-        requestRelaunchAllActivities();
+        relaunchAllActivities();
     }
 
     static void freeTextLayoutCachesIfNeeded(int configDiff) {
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index c5b3a4a..05a9861 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -31,7 +31,6 @@
 import android.os.Parcelable;
 import android.os.Process;
 import android.os.RemoteException;
-import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.ArrayMap;
 
@@ -168,12 +167,14 @@
     /** @hide */
     public static final int OP_WRITE_SETTINGS = 23;
     /** @hide Required to draw on top of other apps. */
+    @TestApi
     public static final int OP_SYSTEM_ALERT_WINDOW = 24;
     /** @hide */
     public static final int OP_ACCESS_NOTIFICATIONS = 25;
     /** @hide */
     public static final int OP_CAMERA = 26;
     /** @hide */
+    @TestApi
     public static final int OP_RECORD_AUDIO = 27;
     /** @hide */
     public static final int OP_PLAY_AUDIO = 28;
@@ -1540,6 +1541,7 @@
      *
      * @hide
      */
+    @TestApi
     public interface OnOpActiveChangedListener {
         /**
          * Called when the active state of an app op changes.
@@ -1731,15 +1733,14 @@
      * Monitor for changes to the operating mode for the given op in the given app package.
      *
      * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
-     * to watch changes only for your UID.
+     * you can watch changes only for your UID.
      *
      * @param op The operation to monitor, one of OP_*.
      * @param packageName The name of the application to monitor.
      * @param callback Where to report changes.
      * @hide
      */
-    // TODO: Uncomment below annotation once b/73559440 is fixed
-    // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
+    @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true)
     public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) {
         synchronized (mModeWatchers) {
             IAppOpsCallback cb = mModeWatchers.get(callback);
@@ -1788,6 +1789,9 @@
      * watched ops for a registered callback you need to unregister and register it
      * again.
      *
+     * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
+     * you can watch changes only for your UID.
+     *
      * @param ops The ops to watch.
      * @param callback Where to report changes.
      *
@@ -1798,7 +1802,9 @@
      *
      * @hide
      */
-    @RequiresPermission(Manifest.permission.WATCH_APPOPS)
+    @TestApi
+    // TODO: Uncomment below annotation once b/73559440 is fixed
+    // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
     public void startWatchingActive(@NonNull int[] ops,
             @NonNull OnOpActiveChangedListener callback) {
         Preconditions.checkNotNull(ops, "ops cannot be null");
@@ -1836,6 +1842,7 @@
      *
      * @hide
      */
+    @TestApi
     public void stopWatchingActive(@NonNull OnOpActiveChangedListener callback) {
         synchronized (mActiveWatchers) {
             final IAppOpsActiveCallback cb = mActiveWatchers.get(callback);
@@ -2087,15 +2094,11 @@
      * @hide
      */
     public int noteOp(int op, int uid, String packageName) {
-        try {
-            int mode = mService.noteOperation(op, uid, packageName);
-            if (mode == MODE_ERRORED) {
-                throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
-            }
-            return mode;
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
+        final int mode = noteOpNoThrow(op, uid, packageName);
+        if (mode == MODE_ERRORED) {
+            throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
         }
+        return mode;
     }
 
     /**
@@ -2174,6 +2177,11 @@
         }
     }
 
+    /** @hide */
+    public int startOp(int op) {
+        return startOp(op, Process.myUid(), mContext.getOpPackageName());
+    }
+
     /**
      * Report that an application has started executing a long-running operation.  Note that you
      * must pass in both the uid and name of the application to be checked; this function will
@@ -2182,6 +2190,7 @@
      * the current time and the operation will be marked as "running".  In this case you must
      * later call {@link #finishOp(int, int, String)} to report when the application is no
      * longer performing the operation.
+     *
      * @param op The operation to start.  One of the OP_* constants.
      * @param uid The user id of the application attempting to perform the operation.
      * @param packageName The name of the application attempting to perform the operation.
@@ -2192,15 +2201,34 @@
      * @hide
      */
     public int startOp(int op, int uid, String packageName) {
-        try {
-            int mode = mService.startOperation(getToken(mService), op, uid, packageName);
-            if (mode == MODE_ERRORED) {
-                throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
-            }
-            return mode;
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
+        return startOp(op, uid, packageName, false);
+    }
+
+    /**
+     * Report that an application has started executing a long-running operation. Similar
+     * to {@link #startOp(String, int, String) except that if the mode is {@link #MODE_DEFAULT}
+     * the operation should succeed since the caller has performed its standard permission
+     * checks which passed and would perform the protected operation for this mode.
+     *
+     * @param op The operation to start.  One of the OP_* constants.
+     * @param uid The user id of the application attempting to perform the operation.
+     * @param packageName The name of the application attempting to perform the operation.
+     * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
+     * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
+     * causing the app to crash).
+     * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
+     *
+     * @throws SecurityException If the app has been configured to crash on this op or
+     * the package is not in the passed in UID.
+     *
+     * @hide
+     */
+    public int startOp(int op, int uid, String packageName, boolean startIfModeDefault) {
+        final int mode = startOpNoThrow(op, uid, packageName, startIfModeDefault);
+        if (mode == MODE_ERRORED) {
+            throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
         }
+        return mode;
     }
 
     /**
@@ -2209,18 +2237,32 @@
      * @hide
      */
     public int startOpNoThrow(int op, int uid, String packageName) {
+        return startOpNoThrow(op, uid, packageName, false);
+    }
+
+    /**
+     * Like {@link #startOp(int, int, String, boolean)} but instead of throwing a
+     * {@link SecurityException} it returns {@link #MODE_ERRORED}.
+     *
+     * @param op The operation to start.  One of the OP_* constants.
+     * @param uid The user id of the application attempting to perform the operation.
+     * @param packageName The name of the application attempting to perform the operation.
+     * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
+     * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
+     * causing the app to crash).
+     * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
+     *
+     * @hide
+     */
+    public int startOpNoThrow(int op, int uid, String packageName, boolean startIfModeDefault) {
         try {
-            return mService.startOperation(getToken(mService), op, uid, packageName);
+            return mService.startOperation(getToken(mService), op, uid, packageName,
+                    startIfModeDefault);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
-    /** @hide */
-    public int startOp(int op) {
-        return startOp(op, Process.myUid(), mContext.getOpPackageName());
-    }
-
     /**
      * Report that an application is no longer performing an operation that had previously
      * been started with {@link #startOp(int, int, String)}.  There is no validation of input
@@ -2241,8 +2283,21 @@
         finishOp(op, Process.myUid(), mContext.getOpPackageName());
     }
 
-    /** @hide */
-    @RequiresPermission(Manifest.permission.WATCH_APPOPS)
+    /**
+     * Checks whether the given op for a UID and package is active.
+     *
+     * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
+     * you can query only for your UID.
+     *
+     * @see #startWatchingActive(int[], OnOpActiveChangedListener)
+     * @see #stopWatchingMode(OnOpChangedListener)
+     * @see #finishOp(int)
+     * @see #startOp(int)
+     *
+     * @hide */
+    @TestApi
+    // TODO: Uncomment below annotation once b/73559440 is fixed
+    // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
     public boolean isOperationActive(int code, int uid, String packageName) {
         try {
             return mService.isOperationActive(code, uid, packageName);
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 13117bc..21fb18a 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1354,11 +1354,10 @@
         if (badgeColor == null) {
             return null;
         }
-        badgeColor.setTint(getUserBadgeColor(user));
         Drawable badgeForeground = getDrawableForDensity(
                 com.android.internal.R.drawable.ic_corp_badge_case, density);
-        Drawable badge = new LayerDrawable(
-                new Drawable[] {badgeColor, badgeForeground });
+        badgeForeground.setTint(getUserBadgeColor(user));
+        Drawable badge = new LayerDrawable(new Drawable[] {badgeColor, badgeForeground });
         return badge;
     }
 
@@ -2802,4 +2801,13 @@
             return mArtManager;
         }
     }
+
+    @Override
+    public String getSystemTextClassifierPackageName() {
+        try {
+            return mPM.getSystemTextClassifierPackageName();
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
 }
diff --git a/core/java/android/app/ClientTransactionHandler.java b/core/java/android/app/ClientTransactionHandler.java
index 310965e..6bc66ec 100644
--- a/core/java/android/app/ClientTransactionHandler.java
+++ b/core/java/android/app/ClientTransactionHandler.java
@@ -65,7 +65,7 @@
 
     /** Pause the activity. */
     public abstract void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
-            int configChanges, boolean dontReport, PendingTransactionActions pendingActions);
+            int configChanges, PendingTransactionActions pendingActions, String reason);
 
     /** Resume the activity. */
     public abstract void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
@@ -73,7 +73,7 @@
 
     /** Stop the activity. */
     public abstract void handleStopActivity(IBinder token, boolean show, int configChanges,
-            PendingTransactionActions pendingActions);
+            PendingTransactionActions pendingActions, String reason);
 
     /** Report that activity was stopped to server. */
     public abstract void reportStop(PendingTransactionActions pendingActions);
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index eb26026..4a168fe 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -291,7 +291,10 @@
                 if (mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
                     mWindow.invalidatePanelMenu(Window.FEATURE_ACTION_BAR);
                 }
-                mDecor.setVisibility(View.VISIBLE);
+                if (mDecor.getVisibility() != View.VISIBLE) {
+                    mDecor.setVisibility(View.VISIBLE);
+                    sendShowMessage();
+                }
             }
             return;
         }
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 54fd0c4..eaa23c6 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -614,7 +614,7 @@
     int sendIntentSender(in IIntentSender target, in IBinder whitelistToken, int code,
             in Intent intent, in String resolvedType, in IIntentReceiver finishedReceiver,
             in String requiredPermission, in Bundle options);
-
+    boolean isBackgroundRestricted(in String packageName);
 
     // Start of N MR1 transactions
     void setVrThread(int tid);
@@ -630,7 +630,6 @@
     void setHasTopUi(boolean hasTopUi);
 
     // Start of O transactions
-    void requestActivityRelaunch(in IBinder token);
     /**
      * Updates override configuration applied to specific display.
      * @param values Update values for display configuration. If null is passed it will request the
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 28ecd98..13a6be5 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -360,6 +360,23 @@
     @Deprecated
     public RemoteViews headsUpContentView;
 
+    private boolean mUsesStandardHeader;
+
+    private static final ArraySet<Integer> STANDARD_LAYOUTS = new ArraySet<>();
+    static {
+        STANDARD_LAYOUTS.add(R.layout.notification_template_material_base);
+        STANDARD_LAYOUTS.add(R.layout.notification_template_material_big_base);
+        STANDARD_LAYOUTS.add(R.layout.notification_template_material_big_picture);
+        STANDARD_LAYOUTS.add(R.layout.notification_template_material_big_text);
+        STANDARD_LAYOUTS.add(R.layout.notification_template_material_inbox);
+        STANDARD_LAYOUTS.add(R.layout.notification_template_material_messaging);
+        STANDARD_LAYOUTS.add(R.layout.notification_template_material_media);
+        STANDARD_LAYOUTS.add(R.layout.notification_template_material_big_media);
+        STANDARD_LAYOUTS.add(R.layout.notification_template_ambient_header);
+        STANDARD_LAYOUTS.add(R.layout.notification_template_header);
+        STANDARD_LAYOUTS.add(R.layout.notification_template_material_ambient);
+    }
+
     /**
      * A large bitmap to be shown in the notification content area.
      *
@@ -1825,6 +1842,7 @@
              * @param label the label to display while the action is being prepared to execute
              * @return this object for method chaining
              */
+            @Deprecated
             public WearableExtender setInProgressLabel(CharSequence label) {
                 mInProgressLabel = label;
                 return this;
@@ -1836,6 +1854,7 @@
              *
              * @return the label to display while the action is being prepared to execute
              */
+            @Deprecated
             public CharSequence getInProgressLabel() {
                 return mInProgressLabel;
             }
@@ -1847,6 +1866,7 @@
              * @param label the label to confirm the action should be executed
              * @return this object for method chaining
              */
+            @Deprecated
             public WearableExtender setConfirmLabel(CharSequence label) {
                 mConfirmLabel = label;
                 return this;
@@ -1858,6 +1878,7 @@
              *
              * @return the label to confirm the action should be executed
              */
+            @Deprecated
             public CharSequence getConfirmLabel() {
                 return mConfirmLabel;
             }
@@ -1869,6 +1890,7 @@
              * @param label the label to display to cancel the action
              * @return this object for method chaining
              */
+            @Deprecated
             public WearableExtender setCancelLabel(CharSequence label) {
                 mCancelLabel = label;
                 return this;
@@ -1880,6 +1902,7 @@
              *
              * @return the label to display to cancel the action
              */
+            @Deprecated
             public CharSequence getCancelLabel() {
                 return mCancelLabel;
             }
@@ -2528,6 +2551,8 @@
         }
 
         parcel.writeInt(mGroupAlertBehavior);
+
+        // mUsesStandardHeader is not written because it should be recomputed in listeners
     }
 
     /**
@@ -4086,6 +4111,25 @@
             }
         }
 
+        /**
+         * @hide
+         */
+        public boolean usesStandardHeader() {
+            if (mN.mUsesStandardHeader) {
+                return true;
+            }
+            if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.N) {
+                if (mN.contentView == null && mN.bigContentView == null) {
+                    return true;
+                }
+            }
+            boolean contentViewUsesHeader = mN.contentView == null
+                    || STANDARD_LAYOUTS.contains(mN.contentView.getLayoutId());
+            boolean bigContentViewUsesHeader = mN.bigContentView == null
+                    || STANDARD_LAYOUTS.contains(mN.bigContentView.getLayoutId());
+            return contentViewUsesHeader && bigContentViewUsesHeader;
+        }
+
         private void resetStandardTemplate(RemoteViews contentView) {
             resetNotificationHeader(contentView);
             resetContentMargins(contentView);
@@ -4117,6 +4161,7 @@
             contentView.setViewVisibility(R.id.time, View.GONE);
             contentView.setImageViewIcon(R.id.profile_badge, null);
             contentView.setViewVisibility(R.id.profile_badge, View.GONE);
+            mN.mUsesStandardHeader = false;
         }
 
         private void resetContentMargins(RemoteViews contentView) {
@@ -4438,6 +4483,7 @@
                 bindProfileBadge(contentView);
             }
             bindExpandButton(contentView);
+            mN.mUsesStandardHeader = true;
         }
 
         private void bindExpandButton(RemoteViews contentView) {
@@ -4587,7 +4633,8 @@
             big.setViewVisibility(R.id.notification_material_reply_text_3, View.GONE);
             big.setTextViewText(R.id.notification_material_reply_text_3, null);
 
-            big.setViewLayoutMarginBottomDimen(R.id.notification_action_list_margin_target, 0);
+            big.setViewLayoutMarginBottomDimen(R.id.notification_action_list_margin_target,
+                    R.dimen.notification_content_margin);
         }
 
         private RemoteViews applyStandardTemplateWithActions(int layoutId) {
@@ -4608,16 +4655,7 @@
             if (N > 0) {
                 big.setViewVisibility(R.id.actions_container, View.VISIBLE);
                 big.setViewVisibility(R.id.actions, View.VISIBLE);
-                if (p.ambient) {
-                    big.setInt(R.id.actions, "setBackgroundColor", Color.TRANSPARENT);
-                } else if (isColorized()) {
-                    big.setInt(R.id.actions, "setBackgroundColor", getActionBarColor());
-                } else {
-                    big.setInt(R.id.actions, "setBackgroundColor", mContext.getColor(
-                            R.color.notification_action_list));
-                }
-                big.setViewLayoutMarginBottomDimen(R.id.notification_action_list_margin_target,
-                        R.dimen.notification_action_list_height);
+                big.setViewLayoutMarginBottomDimen(R.id.notification_action_list_margin_target, 0);
                 if (N>MAX_ACTION_BUTTONS) N=MAX_ACTION_BUTTONS;
                 for (int i=0; i<N; i++) {
                     Action action = mActions.get(i);
@@ -5226,6 +5264,7 @@
             if (mStyle != null) {
                 mStyle.reduceImageSizes(mContext);
                 mStyle.purgeResources();
+                mStyle.validate(mContext);
                 mStyle.buildStyled(mN);
             }
             mN.reduceImageSizes(mContext);
@@ -5795,6 +5834,13 @@
          */
         public void reduceImageSizes(Context context) {
         }
+
+        /**
+         * Validate that this style was properly composed. This is called at build time.
+         * @hide
+         */
+        public void validate(Context context) {
+        }
     }
 
     /**
@@ -6185,12 +6231,23 @@
          * @param user Required - The person displayed for any messages that are sent by the
          * user. Any messages added with {@link #addMessage(Notification.MessagingStyle.Message)}
          * who don't have a Person associated with it will be displayed as if they were sent
-         * by this user. The user also needs to have a valid name associated with it.
+         * by this user. The user also needs to have a valid name associated with it, which will
+         * be enforced starting in Android P.
          */
         public MessagingStyle(@NonNull Person user) {
             mUser = user;
-            if (user == null || user.getName() == null) {
-                throw new RuntimeException("user must be valid and have a name");
+        }
+
+        /**
+         * Validate that this style was properly composed. This is called at build time.
+         * @hide
+         */
+        @Override
+        public void validate(Context context) {
+            super.validate(context);
+            if (context.getApplicationInfo().targetSdkVersion
+                    >= Build.VERSION_CODES.P && (mUser == null || mUser.getName() == null)) {
+                throw new RuntimeException("User must be valid and have a name.");
             }
         }
 
@@ -8071,6 +8128,7 @@
         /**
          * Set an icon that goes with the content of this notification.
          */
+        @Deprecated
         public WearableExtender setContentIcon(int icon) {
             mContentIcon = icon;
             return this;
@@ -8079,6 +8137,7 @@
         /**
          * Get an icon that goes with the content of this notification.
          */
+        @Deprecated
         public int getContentIcon() {
             return mContentIcon;
         }
@@ -8089,6 +8148,7 @@
          * {@link android.view.Gravity#END}. The default value is {@link android.view.Gravity#END}.
          * @see #setContentIcon
          */
+        @Deprecated
         public WearableExtender setContentIconGravity(int contentIconGravity) {
             mContentIconGravity = contentIconGravity;
             return this;
@@ -8100,6 +8160,7 @@
          * {@link android.view.Gravity#END}. The default value is {@link android.view.Gravity#END}.
          * @see #getContentIcon
          */
+        @Deprecated
         public int getContentIconGravity() {
             return mContentIconGravity;
         }
@@ -8147,6 +8208,7 @@
          * {@link android.view.Gravity#CENTER_VERTICAL} and {@link android.view.Gravity#BOTTOM}.
          * The default value is {@link android.view.Gravity#BOTTOM}.
          */
+        @Deprecated
         public WearableExtender setGravity(int gravity) {
             mGravity = gravity;
             return this;
@@ -8158,6 +8220,7 @@
          * {@link android.view.Gravity#CENTER_VERTICAL} and {@link android.view.Gravity#BOTTOM}.
          * The default value is {@link android.view.Gravity#BOTTOM}.
          */
+        @Deprecated
         public int getGravity() {
             return mGravity;
         }
@@ -8171,6 +8234,7 @@
          * documentation for the preset in question. See also
          * {@link #setCustomContentHeight} and {@link #getCustomSizePreset}.
          */
+        @Deprecated
         public WearableExtender setCustomSizePreset(int sizePreset) {
             mCustomSizePreset = sizePreset;
             return this;
@@ -8184,6 +8248,7 @@
          * using {@link #setDisplayIntent}. Check the documentation for the preset in question.
          * See also {@link #setCustomContentHeight} and {@link #setCustomSizePreset}.
          */
+        @Deprecated
         public int getCustomSizePreset() {
             return mCustomSizePreset;
         }
@@ -8195,6 +8260,7 @@
          * {@link android.app.Notification.WearableExtender#setCustomSizePreset} and
          * {@link #getCustomContentHeight}.
          */
+        @Deprecated
         public WearableExtender setCustomContentHeight(int height) {
             mCustomContentHeight = height;
             return this;
@@ -8206,6 +8272,7 @@
          * using {@link #setDisplayIntent}. See also {@link #setCustomSizePreset} and
          * {@link #setCustomContentHeight}.
          */
+        @Deprecated
         public int getCustomContentHeight() {
             return mCustomContentHeight;
         }
@@ -8256,6 +8323,7 @@
          * @param hintHideIcon {@code true} to hide the icon, {@code false} otherwise.
          * @return this object for method chaining
          */
+        @Deprecated
         public WearableExtender setHintHideIcon(boolean hintHideIcon) {
             setFlag(FLAG_HINT_HIDE_ICON, hintHideIcon);
             return this;
@@ -8266,6 +8334,7 @@
          * @return {@code true} if this icon should not be displayed, false otherwise.
          * The default value is {@code false} if this was never set.
          */
+        @Deprecated
         public boolean getHintHideIcon() {
             return (mFlags & FLAG_HINT_HIDE_ICON) != 0;
         }
@@ -8275,6 +8344,7 @@
          * displayed, and other semantic content should be hidden. This hint is only applicable
          * to sub-pages added using {@link #addPage}.
          */
+        @Deprecated
         public WearableExtender setHintShowBackgroundOnly(boolean hintShowBackgroundOnly) {
             setFlag(FLAG_HINT_SHOW_BACKGROUND_ONLY, hintShowBackgroundOnly);
             return this;
@@ -8285,6 +8355,7 @@
          * displayed, and other semantic content should be hidden. This hint is only applicable
          * to sub-pages added using {@link android.app.Notification.WearableExtender#addPage}.
          */
+        @Deprecated
         public boolean getHintShowBackgroundOnly() {
             return (mFlags & FLAG_HINT_SHOW_BACKGROUND_ONLY) != 0;
         }
@@ -8296,6 +8367,7 @@
          * @param hintAvoidBackgroundClipping {@code true} to avoid clipping if possible.
          * @return this object for method chaining
          */
+        @Deprecated
         public WearableExtender setHintAvoidBackgroundClipping(
                 boolean hintAvoidBackgroundClipping) {
             setFlag(FLAG_HINT_AVOID_BACKGROUND_CLIPPING, hintAvoidBackgroundClipping);
@@ -8309,6 +8381,7 @@
          * @return {@code true} if it's ok if the background is clipped on the screen, false
          * otherwise. The default value is {@code false} if this was never set.
          */
+        @Deprecated
         public boolean getHintAvoidBackgroundClipping() {
             return (mFlags & FLAG_HINT_AVOID_BACKGROUND_CLIPPING) != 0;
         }
@@ -8320,6 +8393,7 @@
          *     {@link #SCREEN_TIMEOUT_SHORT} or {@link #SCREEN_TIMEOUT_LONG}.
          * @return this object for method chaining
          */
+        @Deprecated
         public WearableExtender setHintScreenTimeout(int timeout) {
             mHintScreenTimeout = timeout;
             return this;
@@ -8331,6 +8405,7 @@
          * @return the duration in milliseconds if > 0, or either one of the sentinel values
          *     {@link #SCREEN_TIMEOUT_SHORT} or {@link #SCREEN_TIMEOUT_LONG}.
          */
+        @Deprecated
         public int getHintScreenTimeout() {
             return mHintScreenTimeout;
         }
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index ea990ad..4e2cb64 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -48,6 +48,9 @@
  * and the {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH}
  * {@link android.content.Intent Intent}.
  *
+ * <p>
+ * {@link Configuration#UI_MODE_TYPE_WATCH} does not support this system service.
+ *
  * <div class="special reference">
  * <h3>Developer Guides</h3>
  * <p>For more information about using the search dialog and adding search
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 14b2119..2c4bf82 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -25,6 +25,7 @@
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.StringDef;
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
@@ -55,9 +56,13 @@
 import android.os.Process;
 import android.os.RemoteCallback;
 import android.os.RemoteException;
+import android.os.ServiceSpecificException;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.os.UserManager.UserOperationException;
+import android.os.UserManager.UserOperationResult;
 import android.provider.ContactsContract.Directory;
+import android.provider.Settings;
 import android.security.AttestedKeyPair;
 import android.security.Credentials;
 import android.security.KeyChain;
@@ -1644,11 +1649,15 @@
     public static final int LOCK_TASK_FEATURE_HOME = 1 << 2;
 
     /**
-     * Enable the Recents button and the Recents screen during LockTask mode.
+     * Enable the Overview button and the Overview screen during LockTask mode. This feature flag
+     * can only be used in combination with {@link #LOCK_TASK_FEATURE_HOME}, and
+     * {@link #setLockTaskFeatures(ComponentName, int)} will throw an
+     * {@link IllegalArgumentException} if this feature flag is defined without
+     * {@link #LOCK_TASK_FEATURE_HOME}.
      *
      * @see #setLockTaskFeatures(ComponentName, int)
      */
-    public static final int LOCK_TASK_FEATURE_RECENTS = 1 << 3;
+    public static final int LOCK_TASK_FEATURE_OVERVIEW = 1 << 3;
 
     /**
      * Enable the global actions dialog during LockTask mode. This is the dialog that shows up when
@@ -1680,7 +1689,7 @@
             LOCK_TASK_FEATURE_SYSTEM_INFO,
             LOCK_TASK_FEATURE_NOTIFICATIONS,
             LOCK_TASK_FEATURE_HOME,
-            LOCK_TASK_FEATURE_RECENTS,
+            LOCK_TASK_FEATURE_OVERVIEW,
             LOCK_TASK_FEATURE_GLOBAL_ACTIONS,
             LOCK_TASK_FEATURE_KEYGUARD
     })
@@ -2852,8 +2861,8 @@
      * When called by a profile owner of a managed profile returns true if the profile uses unified
      * challenge with its parent user.
      *
-     * <strong>Note: This method is not concerned with password quality and will return false if
-     * the profile has empty password as a separate challenge.
+     * <strong>Note</strong>: This method is not concerned with password quality and will return
+     * false if the profile has empty password as a separate challenge.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @throws SecurityException if {@code admin} is not a profile owner of a managed profile.
@@ -3489,18 +3498,18 @@
      *             that uses {@link DeviceAdminInfo#USES_POLICY_WIPE_DATA}
      * @throws IllegalArgumentException if the input reason string is null or empty.
      */
-    public void wipeDataWithReason(int flags, @NonNull CharSequence reason) {
-        throwIfParentInstance("wipeDataWithReason");
+    public void wipeData(int flags, @NonNull CharSequence reason) {
+        throwIfParentInstance("wipeData");
         Preconditions.checkNotNull(reason, "CharSequence is null");
         wipeDataInternal(flags, reason.toString());
     }
 
     /**
      * Internal function for both {@link #wipeData(int)} and
-     * {@link #wipeDataWithReason(int, CharSequence)} to call.
+     * {@link #wipeData(int, CharSequence)} to call.
      *
      * @see #wipeData(int)
-     * @see #wipeDataWithReason(int, CharSequence)
+     * @see #wipeData(int, CharSequence)
      * @hide
      */
     private void wipeDataInternal(int flags, @NonNull String wipeReasonForUser) {
@@ -5621,6 +5630,29 @@
     }
 
     /**
+     * Called by a device owner to set the default SMS application.
+     * <p>
+     * The calling device admin must be a device owner. If it is not, a security exception will be
+     * thrown.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param packageName The name of the package to set as the default SMS application.
+     * @throws SecurityException if {@code admin} is not a device owner.
+     *
+     * @hide
+     */
+    public void setDefaultSmsApplication(@NonNull ComponentName admin, String packageName) {
+        throwIfParentInstance("setDefaultSmsApplication");
+        if (mService != null) {
+            try {
+                mService.setDefaultSmsApplication(admin, packageName);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
+
+    /**
      * Called by a profile owner or device owner to grant permission to a package to manage
      * application restrictions for the calling user via {@link #setApplicationRestrictions} and
      * {@link #getApplicationRestrictions}.
@@ -6543,6 +6575,9 @@
      * <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.
+     * <p>From {@link android.os.Build.VERSION_CODES#P} onwards, if targeting
+     * {@link android.os.Build.VERSION_CODES#P}, throws {@link UserOperationException} instead of
+     * returning {@code null} on failure.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param name The user's name.
@@ -6557,6 +6592,9 @@
      * @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the
      *         user could not be created.
      * @throws SecurityException if {@code admin} is not a device owner.
+     * @throws UserOperationException if the user could not be created and the calling app is
+     * targeting {@link android.os.Build.VERSION_CODES#P} and running on
+     * {@link android.os.Build.VERSION_CODES#P}.
      */
     public @Nullable UserHandle createAndManageUser(@NonNull ComponentName admin,
             @NonNull String name,
@@ -6565,6 +6603,8 @@
         throwIfParentInstance("createAndManageUser");
         try {
             return mService.createAndManageUser(admin, name, profileOwner, adminExtras, flags);
+        } catch (ServiceSpecificException e) {
+            throw new UserOperationException(e.getMessage(), e.errorCode);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
@@ -6608,77 +6648,15 @@
     }
 
     /**
-     * Indicates user operation is successful.
-     *
-     * @see #startUserInBackground(ComponentName, UserHandle)
-     * @see #stopUser(ComponentName, UserHandle)
-     * @see #logoutUser(ComponentName)
-     */
-    public static final int USER_OPERATION_SUCCESS = 0;
-
-    /**
-     * Indicates user operation failed for unknown reason.
-     *
-     * @see #startUserInBackground(ComponentName, UserHandle)
-     * @see #stopUser(ComponentName, UserHandle)
-     * @see #logoutUser(ComponentName)
-     */
-    public static final int USER_OPERATION_ERROR_UNKNOWN = 1;
-
-    /**
-     * Indicates user operation failed because target user is a managed profile.
-     *
-     * @see #startUserInBackground(ComponentName, UserHandle)
-     * @see #stopUser(ComponentName, UserHandle)
-     * @see #logoutUser(ComponentName)
-     */
-    public static final int USER_OPERATION_ERROR_MANAGED_PROFILE = 2;
-
-    /**
-     * Indicates user operation failed because maximum running user limit has reached.
-     *
-     * @see #startUserInBackground(ComponentName, UserHandle)
-     */
-    public static final int USER_OPERATION_ERROR_MAX_RUNNING_USERS = 3;
-
-    /**
-     * Indicates user operation failed because the target user is in foreground.
-     *
-     * @see #stopUser(ComponentName, UserHandle)
-     * @see #logoutUser(ComponentName)
-     */
-    public static final int USER_OPERATION_ERROR_CURRENT_USER = 4;
-
-    /**
-     * Result returned from
-     * <ul>
-     * <li>{@link #startUserInBackground(ComponentName, UserHandle)}</li>
-     * <li>{@link #stopUser(ComponentName, UserHandle)}</li>
-     * <li>{@link #logoutUser(ComponentName)}</li>
-     * </ul>
-     *
-     * @hide
-     */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = { "USER_OPERATION_" }, value = {
-            USER_OPERATION_SUCCESS,
-            USER_OPERATION_ERROR_UNKNOWN,
-            USER_OPERATION_ERROR_MANAGED_PROFILE,
-            USER_OPERATION_ERROR_MAX_RUNNING_USERS,
-            USER_OPERATION_ERROR_CURRENT_USER
-    })
-    public @interface UserOperationResult {}
-
-    /**
      * Called by a device owner to start the specified secondary user in background.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param userHandle the user to be started in background.
      * @return one of the following result codes:
-     * {@link #USER_OPERATION_ERROR_UNKNOWN},
-     * {@link #USER_OPERATION_SUCCESS},
-     * {@link #USER_OPERATION_ERROR_MANAGED_PROFILE},
-     * {@link #USER_OPERATION_ERROR_MAX_RUNNING_USERS},
+     * {@link UserManager#USER_OPERATION_ERROR_UNKNOWN},
+     * {@link UserManager#USER_OPERATION_SUCCESS},
+     * {@link UserManager#USER_OPERATION_ERROR_MANAGED_PROFILE},
+     * {@link UserManager#USER_OPERATION_ERROR_MAX_RUNNING_USERS},
      * @throws SecurityException if {@code admin} is not a device owner.
      * @see #getSecondaryUsers(ComponentName)
      */
@@ -6698,10 +6676,10 @@
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param userHandle the user to be stopped.
      * @return one of the following result codes:
-     * {@link #USER_OPERATION_ERROR_UNKNOWN},
-     * {@link #USER_OPERATION_SUCCESS},
-     * {@link #USER_OPERATION_ERROR_MANAGED_PROFILE},
-     * {@link #USER_OPERATION_ERROR_CURRENT_USER}
+     * {@link UserManager#USER_OPERATION_ERROR_UNKNOWN},
+     * {@link UserManager#USER_OPERATION_SUCCESS},
+     * {@link UserManager#USER_OPERATION_ERROR_MANAGED_PROFILE},
+     * {@link UserManager#USER_OPERATION_ERROR_CURRENT_USER}
      * @throws SecurityException if {@code admin} is not a device owner.
      * @see #getSecondaryUsers(ComponentName)
      */
@@ -6721,10 +6699,10 @@
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @return one of the following result codes:
-     * {@link #USER_OPERATION_ERROR_UNKNOWN},
-     * {@link #USER_OPERATION_SUCCESS},
-     * {@link #USER_OPERATION_ERROR_MANAGED_PROFILE},
-     * {@link #USER_OPERATION_ERROR_CURRENT_USER}
+     * {@link UserManager#USER_OPERATION_ERROR_UNKNOWN},
+     * {@link UserManager#USER_OPERATION_SUCCESS},
+     * {@link UserManager#USER_OPERATION_ERROR_MANAGED_PROFILE},
+     * {@link UserManager#USER_OPERATION_ERROR_CURRENT_USER}
      * @throws SecurityException if {@code admin} is not a profile owner affiliated with the device.
      * @see #getSecondaryUsers(ComponentName)
      */
@@ -7191,7 +7169,7 @@
      *              {@link #LOCK_TASK_FEATURE_SYSTEM_INFO},
      *              {@link #LOCK_TASK_FEATURE_NOTIFICATIONS},
      *              {@link #LOCK_TASK_FEATURE_HOME},
-     *              {@link #LOCK_TASK_FEATURE_RECENTS},
+     *              {@link #LOCK_TASK_FEATURE_OVERVIEW},
      *              {@link #LOCK_TASK_FEATURE_GLOBAL_ACTIONS},
      *              {@link #LOCK_TASK_FEATURE_KEYGUARD}
      * @throws SecurityException if {@code admin} is not the device owner, the profile owner of an
@@ -7281,6 +7259,15 @@
         }
     }
 
+    /** @hide */
+    @StringDef({
+            Settings.System.SCREEN_BRIGHTNESS_MODE,
+            Settings.System.SCREEN_BRIGHTNESS,
+            Settings.System.SCREEN_OFF_TIMEOUT
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SystemSettingsWhitelist {}
+
     /**
      * Called by device owner to update {@link android.provider.Settings.System} settings.
      * Validation that the value of the setting is in the correct form for the setting type should
@@ -7300,8 +7287,8 @@
      * @param value The value to update the setting to.
      * @throws SecurityException if {@code admin} is not a device owner.
      */
-    public void setSystemSetting(@NonNull ComponentName admin, @NonNull String setting,
-            String value) {
+    public void setSystemSetting(@NonNull ComponentName admin,
+            @NonNull @SystemSettingsWhitelist String setting, String value) {
         throwIfParentInstance("setSystemSetting");
         if (mService != null) {
             try {
@@ -9405,6 +9392,11 @@
     /**
      * Called by device owner to add an override APN.
      *
+     * <p>This method may returns {@code -1} if {@code apnSetting} conflicts with an existing
+     * override APN. Update the existing conflicted APN with
+     * {@link #updateOverrideApn(ComponentName, int, ApnSetting)} instead of adding a new entry.
+     * <p>See {@link ApnSetting} for the definition of conflict.
+     *
      * @param admin which {@link DeviceAdminReceiver} this request is associated with
      * @param apnSetting the override APN to insert
      * @return The {@code id} of inserted override APN. Or {@code -1} when failed to insert into
@@ -9428,6 +9420,12 @@
     /**
      * Called by device owner to update an override APN.
      *
+     * <p>This method may returns {@code false} if there is no override APN with the given
+     * {@code apnId}.
+     * <p>This method may also returns {@code false} if {@code apnSetting} conflicts with an
+     * existing override APN. Update the existing conflicted APN instead.
+     * <p>See {@link ApnSetting} for the definition of conflict.
+     *
      * @param admin which {@link DeviceAdminReceiver} this request is associated with
      * @param apnId the {@code id} of the override APN to update
      * @param apnSetting the override APN to update
@@ -9453,6 +9451,9 @@
     /**
      * Called by device owner to remove an override APN.
      *
+     * <p>This method may returns {@code false} if there is no override APN with the given
+     * {@code apnId}.
+     *
      * @param admin which {@link DeviceAdminReceiver} this request is associated with
      * @param apnId the {@code id} of the override APN to remove
      * @return {@code true} if the required override APN is successfully removed, {@code false}
@@ -9539,12 +9540,19 @@
     /**
      * Returns the data passed from the current administrator to the new administrator during an
      * ownership transfer. This is the same {@code bundle} passed in
-     * {@link #transferOwnership(ComponentName, ComponentName, PersistableBundle)}.
+     * {@link #transferOwnership(ComponentName, ComponentName, PersistableBundle)}. The bundle is
+     * persisted until the profile owner or device owner is removed.
+     *
+     * <p>This is the same <code>bundle</code> received in the
+     * {@link DeviceAdminReceiver#onTransferOwnershipComplete(Context, PersistableBundle)}.
+     * Use this method to retrieve it after the transfer as long as the new administrator is the
+     * active device or profile owner.
      *
      * <p>Returns <code>null</code> if no ownership transfer was started for the calling user.
      *
      * @see #transferOwnership
      * @see DeviceAdminReceiver#onTransferOwnershipComplete(Context, PersistableBundle)
+     * @throws SecurityException if the caller is not a device or profile owner.
      */
     @Nullable
     public PersistableBundle getTransferOwnershipBundle() {
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 5218a73..c29369f 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -192,6 +192,8 @@
     void addPersistentPreferredActivity(in ComponentName admin, in IntentFilter filter, in ComponentName activity);
     void clearPackagePersistentPreferredActivities(in ComponentName admin, String packageName);
 
+    void setDefaultSmsApplication(in ComponentName admin, String packageName);
+
     void setApplicationRestrictions(in ComponentName who, in String callerPackage, in String packageName, in Bundle settings);
     Bundle getApplicationRestrictions(in ComponentName who, in String callerPackage, in String packageName);
     boolean setApplicationRestrictionsManagingPackage(in ComponentName admin, in String packageName);
diff --git a/core/java/android/app/admin/SecurityLog.java b/core/java/android/app/admin/SecurityLog.java
index faaa004..38b4f8f 100644
--- a/core/java/android/app/admin/SecurityLog.java
+++ b/core/java/android/app/admin/SecurityLog.java
@@ -295,7 +295,7 @@
      * <li> [1] admin user ID ({@code Integer})
      * <li> [2] target user ID ({@code Integer})
      * <li> [3] new maximum number of failed password attempts ({@code Integer})
-     * @see DevicePolicyManager#setMaximumTimeToLock(ComponentName, long)
+     * @see DevicePolicyManager#setMaximumFailedPasswordsForWipe(ComponentName, int)
      */
     public static final int TAG_MAX_PASSWORD_ATTEMPTS_SET =
             SecurityLogTags.SECURITY_MAX_PASSWORD_ATTEMPTS_SET;
@@ -370,7 +370,7 @@
             SecurityLogTags.SECURITY_CERT_AUTHORITY_INSTALLED;
 
     /**
-     * Indicates that a new oot certificate has been removed from system's trusted credential
+     * Indicates that a new root certificate has been removed from system's trusted credential
      * storage. The log entry contains the following information about the event, encapsulated in an
      * {@link Object} array and accessible via {@link SecurityEvent#getData()}:
      * <li> [0] result ({@code Integer}, 0 if operation failed, 1 if succeeded)
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java
index d36a794..d1c957b 100644
--- a/core/java/android/app/backup/BackupAgent.java
+++ b/core/java/android/app/backup/BackupAgent.java
@@ -18,6 +18,7 @@
 
 import android.app.IBackupAgent;
 import android.app.QueuedWork;
+import android.app.backup.FullBackup.BackupScheme.PathWithRequiredFlags;
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.pm.ApplicationInfo;
@@ -343,8 +344,8 @@
             return;
         }
 
-        Map<String, Set<String>> manifestIncludeMap;
-        ArraySet<String> manifestExcludeSet;
+        Map<String, Set<PathWithRequiredFlags>> manifestIncludeMap;
+        ArraySet<PathWithRequiredFlags> manifestExcludeSet;
         try {
             manifestIncludeMap =
                     backupScheme.maybeParseAndGetCanonicalIncludePaths();
@@ -514,14 +515,13 @@
     /**
      * 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.
+     * is a directory, but only if all the required flags of the include rule are satisfied by
+     * the transport.
      */
     private void applyXmlFiltersAndDoFullBackupForDomain(String packageName, String domainToken,
-                                                         Map<String, Set<String>> includeMap,
-                                                         ArraySet<String> filterSet,
-                                                         ArraySet<String> traversalExcludeSet,
-                                                         FullBackupDataOutput data)
-            throws IOException {
+            Map<String, Set<PathWithRequiredFlags>> includeMap,
+            ArraySet<PathWithRequiredFlags> filterSet, ArraySet<String> traversalExcludeSet,
+            FullBackupDataOutput data) throws IOException {
         if (includeMap == null || includeMap.size() == 0) {
             // Do entire sub-tree for the provided token.
             fullBackupFileTree(packageName, domainToken,
@@ -530,13 +530,22 @@
         } else if (includeMap.get(domainToken) != null) {
             // This will be null if the xml parsing didn't yield any rules for
             // this domain (there may still be rules for other domains).
-            for (String includeFile : includeMap.get(domainToken)) {
-                fullBackupFileTree(packageName, domainToken, includeFile, filterSet,
-                        traversalExcludeSet, data);
+            for (PathWithRequiredFlags includeFile : includeMap.get(domainToken)) {
+                if (areIncludeRequiredTransportFlagsSatisfied(includeFile.getRequiredFlags(),
+                        data.getTransportFlags())) {
+                    fullBackupFileTree(packageName, domainToken, includeFile.getPath(), filterSet,
+                            traversalExcludeSet, data);
+                }
             }
         }
     }
 
+    private boolean areIncludeRequiredTransportFlagsSatisfied(int includeFlags,
+            int transportFlags) {
+        // all bits that are set in includeFlags must also be set in transportFlags
+        return (transportFlags & includeFlags) == includeFlags;
+    }
+
     /**
      * Write an entire file as part of a full-backup operation.  The file's contents
      * will be delivered to the backup destination along with the metadata necessary
@@ -683,7 +692,7 @@
      * @hide
      */
     protected final void fullBackupFileTree(String packageName, String domain, String startingPath,
-                                            ArraySet<String> manifestExcludes,
+                                            ArraySet<PathWithRequiredFlags> manifestExcludes,
                                             ArraySet<String> systemExcludes,
             FullBackupDataOutput output) {
         // Pull out the domain and set it aside to use when making the tarball.
@@ -714,7 +723,8 @@
                     filePath = file.getCanonicalPath();
 
                     // prune this subtree?
-                    if (manifestExcludes != null && manifestExcludes.contains(filePath)) {
+                    if (manifestExcludes != null
+                            && manifestExcludesContainFilePath(manifestExcludes, filePath)) {
                         continue;
                     }
                     if (systemExcludes != null && systemExcludes.contains(filePath)) {
@@ -750,6 +760,17 @@
         }
     }
 
+    private boolean manifestExcludesContainFilePath(
+        ArraySet<PathWithRequiredFlags> manifestExcludes, String filePath) {
+        for (PathWithRequiredFlags exclude : manifestExcludes) {
+            String excludePath = exclude.getPath();
+            if (excludePath != null && excludePath.equals(filePath)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * Handle the data delivered via the given file descriptor during a full restore
      * operation.  The agent is given the path to the file's original location as well
@@ -796,8 +817,8 @@
             return false;
         }
 
-        Map<String, Set<String>> includes = null;
-        ArraySet<String> excludes = null;
+        Map<String, Set<PathWithRequiredFlags>> includes = null;
+        ArraySet<PathWithRequiredFlags> excludes = null;
         final String destinationCanonicalPath = destination.getCanonicalPath();
         try {
             includes = bs.maybeParseAndGetCanonicalIncludePaths();
@@ -826,7 +847,7 @@
             // Rather than figure out the <include/> domain based on the path (a lot of code, and
             // it's a small list), we'll go through and look for it.
             boolean explicitlyIncluded = false;
-            for (Set<String> domainIncludes : includes.values()) {
+            for (Set<PathWithRequiredFlags> domainIncludes : includes.values()) {
                 explicitlyIncluded |= isFileSpecifiedInPathList(destination, domainIncludes);
                 if (explicitlyIncluded) {
                     break;
@@ -849,9 +870,10 @@
      * @return True if the provided file is either directly in the provided list, or the provided
      * file is within a directory in the list.
      */
-    private boolean isFileSpecifiedInPathList(File file, Collection<String> canonicalPathList)
-            throws IOException {
-        for (String canonicalPath : canonicalPathList) {
+    private boolean isFileSpecifiedInPathList(File file,
+            Collection<PathWithRequiredFlags> canonicalPathList) throws IOException {
+        for (PathWithRequiredFlags canonical : canonicalPathList) {
+            String canonicalPath = canonical.getPath();
             File fileFromList = new File(canonicalPath);
             if (fileFromList.isDirectory()) {
                 if (file.isDirectory()) {
diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java
index 6ec0969..debc32b 100644
--- a/core/java/android/app/backup/BackupManager.java
+++ b/core/java/android/app/backup/BackupManager.java
@@ -19,6 +19,7 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -715,6 +716,92 @@
         }
     }
 
+    /**
+     * Returns an {@link Intent} for the specified transport's configuration UI.
+     * This value is set by {@link #updateTransportAttributes(ComponentName, String, Intent, String,
+     * Intent, String)}.
+     * @param transportName The name of the registered transport.
+     * @hide
+     */
+    @SystemApi
+    @TestApi
+    @RequiresPermission(android.Manifest.permission.BACKUP)
+    public Intent getConfigurationIntent(String transportName) {
+        if (sService != null) {
+            try {
+                return sService.getConfigurationIntent(transportName);
+            } catch (RemoteException e) {
+                Log.e(TAG, "getConfigurationIntent() couldn't connect");
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns a {@link String} describing where the specified transport is sending data.
+     * This value is set by {@link #updateTransportAttributes(ComponentName, String, Intent, String,
+     * Intent, String)}.
+     * @param transportName The name of the registered transport.
+     * @hide
+     */
+    @SystemApi
+    @TestApi
+    @RequiresPermission(android.Manifest.permission.BACKUP)
+    public String getDestinationString(String transportName) {
+        if (sService != null) {
+            try {
+                return sService.getDestinationString(transportName);
+            } catch (RemoteException e) {
+                Log.e(TAG, "getDestinationString() couldn't connect");
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns an {@link Intent} for the specified transport's data management UI.
+     * This value is set by {@link #updateTransportAttributes(ComponentName, String, Intent, String,
+     * Intent, String)}.
+     * @param transportName The name of the registered transport.
+     * @hide
+     */
+    @SystemApi
+    @TestApi
+    @RequiresPermission(android.Manifest.permission.BACKUP)
+    public Intent getDataManagementIntent(String transportName) {
+        if (sService != null) {
+            try {
+                return sService.getDataManagementIntent(transportName);
+            } catch (RemoteException e) {
+                Log.e(TAG, "getDataManagementIntent() couldn't connect");
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns a {@link String} describing what the specified transport's data management intent is
+     * used for.
+     * This value is set by {@link #updateTransportAttributes(ComponentName, String, Intent, String,
+     * Intent, String)}.
+     *
+     * @param transportName The name of the registered transport.
+     * @hide
+     */
+    @SystemApi
+    @TestApi
+    @RequiresPermission(android.Manifest.permission.BACKUP)
+    public String getDataManagementLabel(String transportName) {
+        if (sService != null) {
+            try {
+                return sService.getDataManagementLabel(transportName);
+            } catch (RemoteException e) {
+                Log.e(TAG, "getDataManagementLabel() couldn't connect");
+            }
+        }
+        return null;
+    }
+
     /*
      * We wrap incoming binder calls with a private class implementation that
      * redirects them into main-thread actions.  This serializes the backup
diff --git a/core/java/android/app/backup/BackupTransport.java b/core/java/android/app/backup/BackupTransport.java
index f456395..0963594 100644
--- a/core/java/android/app/backup/BackupTransport.java
+++ b/core/java/android/app/backup/BackupTransport.java
@@ -83,6 +83,13 @@
      */
     public static final int FLAG_NON_INCREMENTAL = 1 << 2;
 
+    /**
+     * Used as a boolean extra in the binding intent of transports. We pass {@code true} to
+     * notify transports that the current connection is used for registering the transport.
+     */
+    public static final String EXTRA_TRANSPORT_REGISTRATION =
+            "android.app.backup.extra.TRANSPORT_REGISTRATION";
+
     IBackupTransport mBinderImpl = new TransportImpl();
 
     public IBinder getBinder() {
diff --git a/core/java/android/app/backup/FullBackup.java b/core/java/android/app/backup/FullBackup.java
index a5dd5bd..fb1c2d0 100644
--- a/core/java/android/app/backup/FullBackup.java
+++ b/core/java/android/app/backup/FullBackup.java
@@ -82,6 +82,9 @@
     public static final String FULL_RESTORE_INTENT_ACTION = "fullrest";
     public static final String CONF_TOKEN_INTENT_EXTRA = "conftoken";
 
+    public static final String FLAG_REQUIRED_CLIENT_SIDE_ENCRYPTION = "clientSideEncryption";
+    public static final String FLAG_REQUIRED_DEVICE_TO_DEVICE_TRANSFER = "deviceToDeviceTransfer";
+
     /**
      * @hide
      */
@@ -224,6 +227,9 @@
 
         private final File EXTERNAL_DIR;
 
+        private final static String TAG_INCLUDE = "include";
+        private final static String TAG_EXCLUDE = "exclude";
+
         final int mFullBackupContent;
         final PackageManager mPackageManager;
         final StorageManager mStorageManager;
@@ -303,15 +309,45 @@
         }
 
         /**
-        * A map of domain -> list of canonical file names in that domain that are to be included.
-        * We keep track of the domain so that we can go through the file system in order later on.
-        */
-        Map<String, Set<String>> mIncludes;
-        /**e
-         * List that will be populated with the canonical names of each file or directory that is
-         * to be excluded.
+         * Represents a path attribute specified in an <include /> rule along with optional
+         * transport flags required from the transport to include file(s) under that path as
+         * specified by requiredFlags attribute. If optional requiredFlags attribute is not
+         * provided, default requiredFlags to 0.
+         * Note: since our parsing codepaths were the same for <include /> and <exclude /> tags,
+         * this structure is also used for <exclude /> tags to preserve that, however you can expect
+         * the getRequiredFlags() to always return 0 for exclude rules.
          */
-        ArraySet<String> mExcludes;
+        public static class PathWithRequiredFlags {
+            private final String mPath;
+            private final int mRequiredFlags;
+
+            public PathWithRequiredFlags(String path, int requiredFlags) {
+                mPath = path;
+                mRequiredFlags = requiredFlags;
+            }
+
+            public String getPath() {
+                return mPath;
+            }
+
+            public int getRequiredFlags() {
+                return mRequiredFlags;
+            }
+        }
+
+        /**
+         * A map of domain -> set of pairs (canonical file; required transport flags) in that
+         * domain that are to be included if the transport has decared the required flags.
+         * We keep track of the domain so that we can go through the file system in order later on.
+         */
+        Map<String, Set<PathWithRequiredFlags>> mIncludes;
+
+        /**
+         * Set that will be populated with pairs (canonical file; requiredFlags=0) for each file or
+         * directory that is to be excluded. Note that for excludes, the requiredFlags attribute is
+         * ignored and the value should be always set to 0.
+         */
+        ArraySet<PathWithRequiredFlags> mExcludes;
 
         BackupScheme(Context context) {
             mFullBackupContent = context.getApplicationInfo().fullBackupContent;
@@ -356,13 +392,14 @@
         }
 
         /**
-         * @return A mapping of domain -> canonical paths within that domain. Each of these paths
-         * specifies a file that the client has explicitly included in their backup set. If this
-         * map is empty we will back up the entire data directory (including managed external
-         * storage).
+         * @return A mapping of domain -> set of pairs (canonical file; required transport flags)
+         * in that domain that are to be included if the transport has decared the required flags.
+         * Each of these paths specifies a file that the client has explicitly included in their
+         * backup set. If this map is empty we will back up the entire data directory (including
+         * managed external storage).
          */
-        public synchronized Map<String, Set<String>> maybeParseAndGetCanonicalIncludePaths()
-                throws IOException, XmlPullParserException {
+        public synchronized Map<String, Set<PathWithRequiredFlags>>
+                maybeParseAndGetCanonicalIncludePaths() throws IOException, XmlPullParserException {
             if (mIncludes == null) {
                 maybeParseBackupSchemeLocked();
             }
@@ -370,9 +407,10 @@
         }
 
         /**
-         * @return A set of canonical paths that are to be excluded from the backup/restore set.
+         * @return A set of (canonical paths; requiredFlags=0) that are to be excluded from the
+         * backup/restore set.
          */
-        public synchronized ArraySet<String> maybeParseAndGetCanonicalExcludePaths()
+        public synchronized ArraySet<PathWithRequiredFlags> maybeParseAndGetCanonicalExcludePaths()
                 throws IOException, XmlPullParserException {
             if (mExcludes == null) {
                 maybeParseBackupSchemeLocked();
@@ -382,8 +420,8 @@
 
         private void maybeParseBackupSchemeLocked() throws IOException, XmlPullParserException {
             // This not being null is how we know that we've tried to parse the xml already.
-            mIncludes = new ArrayMap<String, Set<String>>();
-            mExcludes = new ArraySet<String>();
+            mIncludes = new ArrayMap<String, Set<PathWithRequiredFlags>>();
+            mExcludes = new ArraySet<PathWithRequiredFlags>();
 
             if (mFullBackupContent == 0) {
                 // android:fullBackupContent="true" which means that we'll do everything.
@@ -415,8 +453,8 @@
 
         @VisibleForTesting
         public void parseBackupSchemeFromXmlLocked(XmlPullParser parser,
-                                                   Set<String> excludes,
-                                                   Map<String, Set<String>> includes)
+                                                   Set<PathWithRequiredFlags> excludes,
+                                                   Map<String, Set<PathWithRequiredFlags>> includes)
                 throws IOException, XmlPullParserException {
             int event = parser.getEventType(); // START_DOCUMENT
             while (event != XmlPullParser.START_TAG) {
@@ -441,8 +479,7 @@
                     case XmlPullParser.START_TAG:
                         validateInnerTagContents(parser);
                         final String domainFromXml = parser.getAttributeValue(null, "domain");
-                        final File domainDirectory =
-                                getDirectoryForCriteriaDomain(domainFromXml);
+                        final File domainDirectory = getDirectoryForCriteriaDomain(domainFromXml);
                         if (domainDirectory == null) {
                             if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
                                 Log.v(TAG_XML_PARSER, "...parsing \"" + parser.getName() + "\": "
@@ -457,12 +494,23 @@
                             break;
                         }
 
-                        Set<String> activeSet = parseCurrentTagForDomain(
+                        int requiredFlags = 0; // no transport flags are required by default
+                        if (TAG_INCLUDE.equals(parser.getName())) {
+                            // requiredFlags are only supported for <include /> tag, for <exclude />
+                            // we should always leave them as the default = 0
+                            requiredFlags = getRequiredFlagsFromString(
+                                    parser.getAttributeValue(null, "requireFlags"));
+                        }
+
+                        // retrieve the include/exclude set we'll be adding this rule to
+                        Set<PathWithRequiredFlags> activeSet = parseCurrentTagForDomain(
                                 parser, excludes, includes, domainFromXml);
-                        activeSet.add(canonicalFile.getCanonicalPath());
+                        activeSet.add(new PathWithRequiredFlags(canonicalFile.getCanonicalPath(),
+                                requiredFlags));
                         if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
                             Log.v(TAG_XML_PARSER, "...parsed " + canonicalFile.getCanonicalPath()
-                                    + " for domain \"" + domainFromXml + "\"");
+                                    + " for domain \"" + domainFromXml + "\", requiredFlags + \""
+                                    + requiredFlags + "\"");
                         }
 
                         // Special case journal files (not dirs) for sqlite database. frowny-face.
@@ -472,14 +520,16 @@
                         if ("database".equals(domainFromXml) && !canonicalFile.isDirectory()) {
                             final String canonicalJournalPath =
                                     canonicalFile.getCanonicalPath() + "-journal";
-                            activeSet.add(canonicalJournalPath);
+                            activeSet.add(new PathWithRequiredFlags(canonicalJournalPath,
+                                    requiredFlags));
                             if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
                                 Log.v(TAG_XML_PARSER, "...automatically generated "
                                         + canonicalJournalPath + ". Ignore if nonexistent.");
                             }
                             final String canonicalWalPath =
                                     canonicalFile.getCanonicalPath() + "-wal";
-                            activeSet.add(canonicalWalPath);
+                            activeSet.add(new PathWithRequiredFlags(canonicalWalPath,
+                                    requiredFlags));
                             if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
                                 Log.v(TAG_XML_PARSER, "...automatically generated "
                                         + canonicalWalPath + ". Ignore if nonexistent.");
@@ -491,7 +541,8 @@
                             !canonicalFile.getCanonicalPath().endsWith(".xml")) {
                             final String canonicalXmlPath =
                                     canonicalFile.getCanonicalPath() + ".xml";
-                            activeSet.add(canonicalXmlPath);
+                            activeSet.add(new PathWithRequiredFlags(canonicalXmlPath,
+                                    requiredFlags));
                             if (Log.isLoggable(TAG_XML_PARSER, Log.VERBOSE)) {
                                 Log.v(TAG_XML_PARSER, "...automatically generated "
                                         + canonicalXmlPath + ". Ignore if nonexistent.");
@@ -508,10 +559,12 @@
                     Log.v(TAG_XML_PARSER, "  ...nothing specified (This means the entirety of app"
                             + " data minus excludes)");
                 } else {
-                    for (Map.Entry<String, Set<String>> entry : includes.entrySet()) {
+                    for (Map.Entry<String, Set<PathWithRequiredFlags>> entry
+                            : includes.entrySet()) {
                         Log.v(TAG_XML_PARSER, "  domain=" + entry.getKey());
-                        for (String includeData : entry.getValue()) {
-                            Log.v(TAG_XML_PARSER, "  " + includeData);
+                        for (PathWithRequiredFlags includeData : entry.getValue()) {
+                            Log.v(TAG_XML_PARSER, " path: " + includeData.getPath()
+                                    + " requiredFlags: " + includeData.getRequiredFlags());
                         }
                     }
                 }
@@ -520,8 +573,9 @@
                 if (excludes.isEmpty()) {
                     Log.v(TAG_XML_PARSER, "  ...nothing to exclude.");
                 } else {
-                    for (String excludeData : excludes) {
-                        Log.v(TAG_XML_PARSER, "  " + excludeData);
+                    for (PathWithRequiredFlags excludeData : excludes) {
+                        Log.v(TAG_XML_PARSER, " path: " + excludeData.getPath()
+                                + " requiredFlags: " + excludeData.getRequiredFlags());
                     }
                 }
 
@@ -531,20 +585,41 @@
             }
         }
 
-        private Set<String> parseCurrentTagForDomain(XmlPullParser parser,
-                                                     Set<String> excludes,
-                                                     Map<String, Set<String>> includes,
-                                                     String domain)
+        private int getRequiredFlagsFromString(String requiredFlags) {
+            int flags = 0;
+            if (requiredFlags == null || requiredFlags.length() == 0) {
+                // requiredFlags attribute was missing or empty in <include /> tag
+                return flags;
+            }
+            String[] flagsStr = requiredFlags.split("\\|");
+            for (String f : flagsStr) {
+                switch (f) {
+                    case FLAG_REQUIRED_CLIENT_SIDE_ENCRYPTION:
+                        flags |= BackupAgent.FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED;
+                        break;
+                    case FLAG_REQUIRED_DEVICE_TO_DEVICE_TRANSFER:
+                        flags |= BackupAgent.FLAG_DEVICE_TO_DEVICE_TRANSFER;
+                        break;
+                    default:
+                        Log.w(TAG, "Unrecognized requiredFlag provided, value: \"" + f + "\"");
+                }
+            }
+            return flags;
+        }
+
+        private Set<PathWithRequiredFlags> parseCurrentTagForDomain(XmlPullParser parser,
+                Set<PathWithRequiredFlags> excludes,
+                Map<String, Set<PathWithRequiredFlags>> includes, String domain)
                 throws XmlPullParserException {
-            if ("include".equals(parser.getName())) {
+            if (TAG_INCLUDE.equals(parser.getName())) {
                 final String domainToken = getTokenForXmlDomain(domain);
-                Set<String> includeSet = includes.get(domainToken);
+                Set<PathWithRequiredFlags> includeSet = includes.get(domainToken);
                 if (includeSet == null) {
-                    includeSet = new ArraySet<String>();
+                    includeSet = new ArraySet<PathWithRequiredFlags>();
                     includes.put(domainToken, includeSet);
                 }
                 return includeSet;
-            } else if ("exclude".equals(parser.getName())) {
+            } else if (TAG_EXCLUDE.equals(parser.getName())) {
                 return excludes;
             } else {
                 // Unrecognised tag => hard failure.
@@ -589,8 +664,8 @@
         /**
          *
          * @param domain Directory where the specified file should exist. Not null.
-         * @param filePathFromXml parsed from xml. Not sanitised before calling this function so may be
-         *                        null.
+         * @param filePathFromXml parsed from xml. Not sanitised before calling this function so may
+         *                        be null.
          * @return The canonical path of the file specified or null if no such file exists.
          */
         private File extractCanonicalFile(File domain, String filePathFromXml) {
@@ -650,15 +725,27 @@
          * Let's be strict about the type of xml the client can write. If we see anything untoward,
          * throw an XmlPullParserException.
          */
-        private void validateInnerTagContents(XmlPullParser parser)
-                throws XmlPullParserException {
-            if (parser.getAttributeCount() > 2) {
-                throw new XmlPullParserException("At most 2 tag attributes allowed for \""
-                        + parser.getName() + "\" tag (\"domain\" & \"path\".");
+        private void validateInnerTagContents(XmlPullParser parser) throws XmlPullParserException {
+            if (parser == null) {
+                return;
             }
-            if (!"include".equals(parser.getName()) && !"exclude".equals(parser.getName())) {
-                throw new XmlPullParserException("A valid tag is one of \"<include/>\" or" +
-                        " \"<exclude/>. You provided \"" + parser.getName() + "\"");
+            switch (parser.getName()) {
+                case TAG_INCLUDE:
+                    if (parser.getAttributeCount() > 3) {
+                        throw new XmlPullParserException("At most 3 tag attributes allowed for "
+                                + "\"include\" tag (\"domain\" & \"path\""
+                                + " & optional \"requiredFlags\").");
+                    }
+                    break;
+                case TAG_EXCLUDE:
+                    if (parser.getAttributeCount() > 2) {
+                        throw new XmlPullParserException("At most 2 tag attributes allowed for "
+                                + "\"exclude\" tag (\"domain\" & \"path\".");
+                    }
+                    break;
+                default:
+                    throw new XmlPullParserException("A valid tag is one of \"<include/>\" or" +
+                            " \"<exclude/>. You provided \"" + parser.getName() + "\"");
             }
         }
     }
diff --git a/core/java/android/app/servertransaction/ActivityResultItem.java b/core/java/android/app/servertransaction/ActivityResultItem.java
index 73b5ec4..545463c 100644
--- a/core/java/android/app/servertransaction/ActivityResultItem.java
+++ b/core/java/android/app/servertransaction/ActivityResultItem.java
@@ -16,7 +16,7 @@
 
 package android.app.servertransaction;
 
-import static android.app.servertransaction.ActivityLifecycleItem.ON_PAUSE;
+import static android.app.servertransaction.ActivityLifecycleItem.ON_RESUME;
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 
 import android.app.ClientTransactionHandler;
@@ -38,8 +38,8 @@
     private List<ResultInfo> mResultInfoList;
 
     @Override
-    public int getPreExecutionState() {
-        return ON_PAUSE;
+    public int getPostExecutionState() {
+        return ON_RESUME;
     }
 
     @Override
diff --git a/core/java/android/app/servertransaction/ClientTransactionItem.java b/core/java/android/app/servertransaction/ClientTransactionItem.java
index 6f2cc00..d94f08b 100644
--- a/core/java/android/app/servertransaction/ClientTransactionItem.java
+++ b/core/java/android/app/servertransaction/ClientTransactionItem.java
@@ -32,12 +32,6 @@
  */
 public abstract class ClientTransactionItem implements BaseClientRequest, Parcelable {
 
-    /** Get the state in which this callback can be executed. */
-    @LifecycleState
-    public int getPreExecutionState() {
-        return UNDEFINED;
-    }
-
     /** Get the state that must follow this callback. */
     @LifecycleState
     public int getPostExecutionState() {
diff --git a/core/java/android/app/servertransaction/NewIntentItem.java b/core/java/android/app/servertransaction/NewIntentItem.java
index 7dfde73..e5ce3b0 100644
--- a/core/java/android/app/servertransaction/NewIntentItem.java
+++ b/core/java/android/app/servertransaction/NewIntentItem.java
@@ -38,11 +38,6 @@
 
     // TODO(lifecycler): Switch new intent handling to this scheme.
     /*@Override
-    public int getPreExecutionState() {
-        return ON_PAUSE;
-    }
-
-    @Override
     public int getPostExecutionState() {
         return ON_RESUME;
     }*/
diff --git a/core/java/android/app/servertransaction/PauseActivityItem.java b/core/java/android/app/servertransaction/PauseActivityItem.java
index 91e73cd..65e4291 100644
--- a/core/java/android/app/servertransaction/PauseActivityItem.java
+++ b/core/java/android/app/servertransaction/PauseActivityItem.java
@@ -42,8 +42,8 @@
     public void execute(ClientTransactionHandler client, IBinder token,
             PendingTransactionActions pendingActions) {
         Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
-        client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, mDontReport,
-                pendingActions);
+        client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
+                "PAUSE_ACTIVITY_ITEM");
         Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
     }
 
diff --git a/core/java/android/app/servertransaction/StopActivityItem.java b/core/java/android/app/servertransaction/StopActivityItem.java
index f955a90..0a61fab 100644
--- a/core/java/android/app/servertransaction/StopActivityItem.java
+++ b/core/java/android/app/servertransaction/StopActivityItem.java
@@ -38,7 +38,8 @@
     public void execute(ClientTransactionHandler client, IBinder token,
             PendingTransactionActions pendingActions) {
         Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
-        client.handleStopActivity(token, mShowWindow, mConfigChanges, pendingActions);
+        client.handleStopActivity(token, mShowWindow, mConfigChanges, pendingActions,
+                "STOP_ACTIVITY_ITEM");
         Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
     }
 
diff --git a/core/java/android/app/servertransaction/TransactionExecutor.java b/core/java/android/app/servertransaction/TransactionExecutor.java
index 840fef8..0e52b34 100644
--- a/core/java/android/app/servertransaction/TransactionExecutor.java
+++ b/core/java/android/app/servertransaction/TransactionExecutor.java
@@ -24,6 +24,7 @@
 import static android.app.servertransaction.ActivityLifecycleItem.ON_START;
 import static android.app.servertransaction.ActivityLifecycleItem.ON_STOP;
 import static android.app.servertransaction.ActivityLifecycleItem.UNDEFINED;
+import static android.app.servertransaction.TransactionExecutorHelper.lastCallbackRequestingState;
 
 import android.app.ActivityThread.ActivityClientRecord;
 import android.app.ClientTransactionHandler;
@@ -48,11 +49,7 @@
 
     private ClientTransactionHandler mTransactionHandler;
     private PendingTransactionActions mPendingActions = new PendingTransactionActions();
-
-    // Temp holder for lifecycle path.
-    // No direct transition between two states should take more than one complete cycle of 6 states.
-    @ActivityLifecycleItem.LifecycleState
-    private IntArray mLifecycleSequence = new IntArray(6);
+    private TransactionExecutorHelper mHelper = new TransactionExecutorHelper();
 
     /** Initialize an instance with transaction handler, that will execute all requested actions. */
     public TransactionExecutor(ClientTransactionHandler clientTransactionHandler) {
@@ -89,13 +86,25 @@
 
         final IBinder token = transaction.getActivityToken();
         ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
+
+        // In case when post-execution state of the last callback matches the final state requested
+        // for the activity in this transaction, we won't do the last transition here and do it when
+        // moving to final state instead (because it may contain additional parameters from server).
+        final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
+        final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState()
+                : UNDEFINED;
+        // Index of the last callback that requests some post-execution state.
+        final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);
+
         final int size = callbacks.size();
         for (int i = 0; i < size; ++i) {
             final ClientTransactionItem item = callbacks.get(i);
             log("Resolving callback: " + item);
-            final int preExecutionState = item.getPreExecutionState();
-            if (preExecutionState != UNDEFINED) {
-                cycleToPath(r, preExecutionState);
+            final int postExecutionState = item.getPostExecutionState();
+            final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
+                    item.getPostExecutionState());
+            if (closestPreExecutionState != UNDEFINED) {
+                cycleToPath(r, closestPreExecutionState);
             }
 
             item.execute(mTransactionHandler, token, mPendingActions);
@@ -105,9 +114,11 @@
                 r = mTransactionHandler.getActivityClient(token);
             }
 
-            final int postExecutionState = item.getPostExecutionState();
-            if (postExecutionState != UNDEFINED) {
-                cycleToPath(r, postExecutionState);
+            if (postExecutionState != UNDEFINED && r != null) {
+                // Skip the very last transition and perform it by explicit state request instead.
+                final boolean shouldExcludeLastTransition =
+                        i == lastCallbackRequestingState && finalState == postExecutionState;
+                cycleToPath(r, postExecutionState, shouldExcludeLastTransition);
             }
         }
     }
@@ -162,15 +173,15 @@
             boolean excludeLastState) {
         final int start = r.getLifecycleState();
         log("Cycle from: " + start + " to: " + finish + " excludeLastState:" + excludeLastState);
-        initLifecyclePath(start, finish, excludeLastState);
-        performLifecycleSequence(r);
+        final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
+        performLifecycleSequence(r, path);
     }
 
     /** Transition the client through previously initialized state sequence. */
-    private void performLifecycleSequence(ActivityClientRecord r) {
-        final int size = mLifecycleSequence.size();
+    private void performLifecycleSequence(ActivityClientRecord r, IntArray path) {
+        final int size = path.size();
         for (int i = 0, state; i < size; i++) {
-            state = mLifecycleSequence.get(i);
+            state = path.get(i);
             log("Transitioning to state: " + state);
             switch (state) {
                 case ON_CREATE:
@@ -185,18 +196,17 @@
                     break;
                 case ON_PAUSE:
                     mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
-                            false /* userLeaving */, 0 /* configChanges */,
-                            true /* dontReport */, mPendingActions);
+                            false /* userLeaving */, 0 /* configChanges */, mPendingActions,
+                            "LIFECYCLER_PAUSE_ACTIVITY");
                     break;
                 case ON_STOP:
                     mTransactionHandler.handleStopActivity(r.token, false /* show */,
-                            0 /* configChanges */, mPendingActions);
+                            0 /* configChanges */, mPendingActions, "LIFECYCLER_STOP_ACTIVITY");
                     break;
                 case ON_DESTROY:
                     mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
                             0 /* configChanges */, false /* getNonConfigInstance */,
-                            "performLifecycleSequence. cycling to:"
-                                    + mLifecycleSequence.get(size - 1));
+                            "performLifecycleSequence. cycling to:" + path.get(size - 1));
                     break;
                 case ON_RESTART:
                     mTransactionHandler.performRestartActivity(r.token, false /* start */);
@@ -207,60 +217,6 @@
         }
     }
 
-    /**
-     * Calculate the path through main lifecycle states for an activity and fill
-     * @link #mLifecycleSequence} with values starting with the state that follows the initial
-     * state.
-     */
-    public void initLifecyclePath(int start, int finish, boolean excludeLastState) {
-        mLifecycleSequence.clear();
-        if (finish >= start) {
-            // just go there
-            for (int i = start + 1; i <= finish; i++) {
-                mLifecycleSequence.add(i);
-            }
-        } else { // finish < start, can't just cycle down
-            if (start == ON_PAUSE && finish == ON_RESUME) {
-                // Special case when we can just directly go to resumed state.
-                mLifecycleSequence.add(ON_RESUME);
-            } else if (start <= ON_STOP && finish >= ON_START) {
-                // Restart and go to required state.
-
-                // Go to stopped state first.
-                for (int i = start + 1; i <= ON_STOP; i++) {
-                    mLifecycleSequence.add(i);
-                }
-                // Restart
-                mLifecycleSequence.add(ON_RESTART);
-                // Go to required state
-                for (int i = ON_START; i <= finish; i++) {
-                    mLifecycleSequence.add(i);
-                }
-            } else {
-                // Relaunch and go to required state
-
-                // Go to destroyed state first.
-                for (int i = start + 1; i <= ON_DESTROY; i++) {
-                    mLifecycleSequence.add(i);
-                }
-                // Go to required state
-                for (int i = ON_CREATE; i <= finish; i++) {
-                    mLifecycleSequence.add(i);
-                }
-            }
-        }
-
-        // Remove last transition in case we want to perform it with some specific params.
-        if (excludeLastState && mLifecycleSequence.size() != 0) {
-            mLifecycleSequence.remove(mLifecycleSequence.size() - 1);
-        }
-    }
-
-    @VisibleForTesting
-    public int[] getLifecycleSequence() {
-        return mLifecycleSequence.toArray();
-    }
-
     private static void log(String message) {
         if (DEBUG_RESOLVER) Slog.d(TAG, message);
     }
diff --git a/core/java/android/app/servertransaction/TransactionExecutorHelper.java b/core/java/android/app/servertransaction/TransactionExecutorHelper.java
new file mode 100644
index 0000000..7e66fd7
--- /dev/null
+++ b/core/java/android/app/servertransaction/TransactionExecutorHelper.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.servertransaction;
+
+import static android.app.servertransaction.ActivityLifecycleItem.ON_CREATE;
+import static android.app.servertransaction.ActivityLifecycleItem.ON_DESTROY;
+import static android.app.servertransaction.ActivityLifecycleItem.ON_PAUSE;
+import static android.app.servertransaction.ActivityLifecycleItem.ON_RESTART;
+import static android.app.servertransaction.ActivityLifecycleItem.ON_RESUME;
+import static android.app.servertransaction.ActivityLifecycleItem.ON_START;
+import static android.app.servertransaction.ActivityLifecycleItem.ON_STOP;
+import static android.app.servertransaction.ActivityLifecycleItem.PRE_ON_CREATE;
+import static android.app.servertransaction.ActivityLifecycleItem.UNDEFINED;
+
+import android.app.ActivityThread;
+import android.util.IntArray;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.List;
+
+/**
+ * Helper class for {@link TransactionExecutor} that contains utils for lifecycle path resolution.
+ * @hide
+ */
+public class TransactionExecutorHelper {
+    // A penalty applied to path with destruction when looking for the shortest one.
+    private static final int DESTRUCTION_PENALTY = 10;
+
+    private static final int[] ON_RESUME_PRE_EXCUTION_STATES = new int[] { ON_START, ON_PAUSE };
+
+    // Temp holder for lifecycle path.
+    // No direct transition between two states should take more than one complete cycle of 6 states.
+    @ActivityLifecycleItem.LifecycleState
+    private IntArray mLifecycleSequence = new IntArray(6);
+
+    /**
+     * Calculate the path through main lifecycle states for an activity and fill
+     * @link #mLifecycleSequence} with values starting with the state that follows the initial
+     * state.
+     * <p>NOTE: The returned value is used internally in this class and is not a copy. It's contents
+     * may change after calling other methods of this class.</p>
+     */
+    @VisibleForTesting
+    public IntArray getLifecyclePath(int start, int finish, boolean excludeLastState) {
+        if (start == UNDEFINED || finish == UNDEFINED) {
+            throw new IllegalArgumentException("Can't resolve lifecycle path for undefined state");
+        }
+        if (start == ON_RESTART || finish == ON_RESTART) {
+            throw new IllegalArgumentException(
+                    "Can't start or finish in intermittent RESTART state");
+        }
+        if (finish == PRE_ON_CREATE && start != finish) {
+            throw new IllegalArgumentException("Can only start in pre-onCreate state");
+        }
+
+        mLifecycleSequence.clear();
+        if (finish >= start) {
+            // just go there
+            for (int i = start + 1; i <= finish; i++) {
+                mLifecycleSequence.add(i);
+            }
+        } else { // finish < start, can't just cycle down
+            if (start == ON_PAUSE && finish == ON_RESUME) {
+                // Special case when we can just directly go to resumed state.
+                mLifecycleSequence.add(ON_RESUME);
+            } else if (start <= ON_STOP && finish >= ON_START) {
+                // Restart and go to required state.
+
+                // Go to stopped state first.
+                for (int i = start + 1; i <= ON_STOP; i++) {
+                    mLifecycleSequence.add(i);
+                }
+                // Restart
+                mLifecycleSequence.add(ON_RESTART);
+                // Go to required state
+                for (int i = ON_START; i <= finish; i++) {
+                    mLifecycleSequence.add(i);
+                }
+            } else {
+                // Relaunch and go to required state
+
+                // Go to destroyed state first.
+                for (int i = start + 1; i <= ON_DESTROY; i++) {
+                    mLifecycleSequence.add(i);
+                }
+                // Go to required state
+                for (int i = ON_CREATE; i <= finish; i++) {
+                    mLifecycleSequence.add(i);
+                }
+            }
+        }
+
+        // Remove last transition in case we want to perform it with some specific params.
+        if (excludeLastState && mLifecycleSequence.size() != 0) {
+            mLifecycleSequence.remove(mLifecycleSequence.size() - 1);
+        }
+
+        return mLifecycleSequence;
+    }
+
+    /**
+     * Pick a state that goes before provided post-execution state and would require the least
+     * lifecycle transitions to get to.
+     * It will also make sure to try avoiding a path with activity destruction and relaunch if
+     * possible.
+     * @param r An activity that we're trying to resolve the transition for.
+     * @param postExecutionState Post execution state to compute for.
+     * @return One of states that precede the provided post-execution state, or
+     *         {@link ActivityLifecycleItem#UNDEFINED} if there is not path.
+     */
+    @VisibleForTesting
+    public int getClosestPreExecutionState(ActivityThread.ActivityClientRecord r,
+            int postExecutionState) {
+        switch (postExecutionState) {
+            case UNDEFINED:
+                return UNDEFINED;
+            case ON_RESUME:
+                return getClosestOfStates(r, ON_RESUME_PRE_EXCUTION_STATES);
+            default:
+                throw new UnsupportedOperationException("Pre-execution states for state: "
+                        + postExecutionState + " is not supported.");
+        }
+    }
+
+    /**
+     * Pick a state that would require the least lifecycle transitions to get to.
+     * It will also make sure to try avoiding a path with activity destruction and relaunch if
+     * possible.
+     * @param r An activity that we're trying to resolve the transition for.
+     * @param finalStates An array of valid final states.
+     * @return One of the provided final states, or {@link ActivityLifecycleItem#UNDEFINED} if none
+     *         were provided or there is not path.
+     */
+    @VisibleForTesting
+    public int getClosestOfStates(ActivityThread.ActivityClientRecord r, int[] finalStates) {
+        if (finalStates == null || finalStates.length == 0) {
+            return UNDEFINED;
+        }
+
+        final int currentState = r.getLifecycleState();
+        int closestState = UNDEFINED;
+        for (int i = 0, shortestPath = Integer.MAX_VALUE, pathLength; i < finalStates.length; i++) {
+            getLifecyclePath(currentState, finalStates[i], false /* excludeLastState */);
+            pathLength = mLifecycleSequence.size();
+            if (pathInvolvesDestruction(mLifecycleSequence)) {
+                pathLength += DESTRUCTION_PENALTY;
+            }
+            if (shortestPath > pathLength) {
+                shortestPath = pathLength;
+                closestState = finalStates[i];
+            }
+        }
+        return closestState;
+    }
+
+    /**
+     * Check if there is a destruction involved in the path. We want to avoid a lifecycle sequence
+     * that involves destruction and recreation if there is another path.
+     */
+    private static boolean pathInvolvesDestruction(IntArray lifecycleSequence) {
+        final int size = lifecycleSequence.size();
+        for (int i = 0; i < size; i++) {
+            if (lifecycleSequence.get(i) == ON_DESTROY) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Return the index of the last callback that requests the state in which activity will be after
+     * execution. If there is a group of callbacks in the end that requests the same specific state
+     * or doesn't request any - we will find the first one from such group.
+     *
+     * E.g. ActivityResult requests RESUMED post-execution state, Configuration does not request any
+     * specific state. If there is a sequence
+     *   Configuration - ActivityResult - Configuration - ActivityResult
+     * index 1 will be returned, because ActivityResult request on position 1 will be the last
+     * request that moves activity to the RESUMED state where it will eventually end.
+     */
+    static int lastCallbackRequestingState(ClientTransaction transaction) {
+        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
+        if (callbacks == null || callbacks.size() == 0) {
+            return -1;
+        }
+
+        // Go from the back of the list to front, look for the request closes to the beginning that
+        // requests the state in which activity will end after all callbacks are executed.
+        int lastRequestedState = UNDEFINED;
+        int lastRequestingCallback = -1;
+        for (int i = callbacks.size() - 1; i >= 0; i--) {
+            final ClientTransactionItem callback = callbacks.get(i);
+            final int postExecutionState = callback.getPostExecutionState();
+            if (postExecutionState != UNDEFINED) {
+                // Found a callback that requests some post-execution state.
+                if (lastRequestedState == UNDEFINED || lastRequestedState == postExecutionState) {
+                    // It's either a first-from-end callback that requests state or it requests
+                    // the same state as the last one. In both cases, we will use it as the new
+                    // candidate.
+                    lastRequestedState = postExecutionState;
+                    lastRequestingCallback = i;
+                } else {
+                    break;
+                }
+            }
+        }
+
+        return lastRequestingCallback;
+    }
+}
diff --git a/core/java/android/app/slice/ISliceManager.aidl b/core/java/android/app/slice/ISliceManager.aidl
index 38d9025..20ec75a 100644
--- a/core/java/android/app/slice/ISliceManager.aidl
+++ b/core/java/android/app/slice/ISliceManager.aidl
@@ -16,17 +16,13 @@
 
 package android.app.slice;
 
-import android.app.slice.ISliceListener;
 import android.app.slice.SliceSpec;
 import android.net.Uri;
 
 /** @hide */
 interface ISliceManager {
-    void addSliceListener(in Uri uri, String pkg, in ISliceListener listener,
-            in SliceSpec[] specs);
-    void removeSliceListener(in Uri uri, String pkg, in ISliceListener listener);
-    void pinSlice(String pkg, in Uri uri, in SliceSpec[] specs);
-    void unpinSlice(String pkg, in Uri uri);
+    void pinSlice(String pkg, in Uri uri, in SliceSpec[] specs, in IBinder token);
+    void unpinSlice(String pkg, in Uri uri, in IBinder token);
     boolean hasSliceAccess(String pkg);
     SliceSpec[] getPinnedSpecs(in Uri uri, String pkg);
     int checkSlicePermission(in Uri uri, String pkg, int pid, int uid);
diff --git a/core/java/android/app/slice/Slice.java b/core/java/android/app/slice/Slice.java
index 126deef..b5c69d8 100644
--- a/core/java/android/app/slice/Slice.java
+++ b/core/java/android/app/slice/Slice.java
@@ -71,16 +71,6 @@
     public @interface SliceHint {}
 
     /**
-     * The meta-data key that allows an activity to easily be linked directly to a slice.
-     * <p>
-     * An activity can be statically linked to a slice uri by including a meta-data item
-     * for this key that contains a valid slice uri for the same application declaring
-     * the activity.
-     * @hide
-     */
-    public static final String SLICE_METADATA_KEY = "android.metadata.SLICE_URI";
-
-    /**
      * Hint that this content is a title of other content in the slice. This can also indicate that
      * the content should be used in the shortcut representation of the slice (icon, label, action),
      * normally this should be indicated by adding the hint on the action containing that content.
@@ -446,7 +436,7 @@
         }
 
         /**
-         * Add a color to the slice being constructed
+         * Add an integer to the slice being constructed
          * @param subType Optional template-specific type information
          * @see {@link SliceItem#getSubType()}
          */
@@ -456,7 +446,7 @@
         }
 
         /**
-         * Add a color to the slice being constructed
+         * Add an integer to the slice being constructed
          * @param subType Optional template-specific type information
          * @see {@link SliceItem#getSubType()}
          */
diff --git a/core/java/android/app/slice/SliceManager.java b/core/java/android/app/slice/SliceManager.java
index 3f13fff..ae1d8d7 100644
--- a/core/java/android/app/slice/SliceManager.java
+++ b/core/java/android/app/slice/SliceManager.java
@@ -24,10 +24,13 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.ServiceManager.ServiceNotFoundException;
@@ -60,10 +63,20 @@
     public static final String ACTION_REQUEST_SLICE_PERMISSION =
             "android.intent.action.REQUEST_SLICE_PERMISSION";
 
+    /**
+     * The meta-data key that allows an activity to easily be linked directly to a slice.
+     * <p>
+     * An activity can be statically linked to a slice uri by including a meta-data item
+     * for this key that contains a valid slice uri for the same application declaring
+     * the activity.
+     */
+    public static final String SLICE_METADATA_KEY = "android.metadata.SLICE_URI";
+
     private final ISliceManager mService;
     private final Context mContext;
     private final ArrayMap<Pair<Uri, SliceCallback>, ISliceListener> mListenerLookup =
             new ArrayMap<>();
+    private final IBinder mToken = new Binder();
 
     /**
      * Permission denied.
@@ -96,7 +109,6 @@
     @Deprecated
     public void registerSliceCallback(@NonNull Uri uri, @NonNull SliceCallback callback,
             @NonNull List<SliceSpec> specs) {
-        registerSliceCallback(uri, specs, mContext.getMainExecutor(), callback);
     }
 
     /**
@@ -105,7 +117,6 @@
     @Deprecated
     public void registerSliceCallback(@NonNull Uri uri, @NonNull SliceCallback callback,
             @NonNull List<SliceSpec> specs, Executor executor) {
-        registerSliceCallback(uri, specs, executor, callback);
     }
 
     /**
@@ -123,7 +134,6 @@
      */
     public void registerSliceCallback(@NonNull Uri uri, @NonNull List<SliceSpec> specs,
             @NonNull SliceCallback callback) {
-        registerSliceCallback(uri, specs, mContext.getMainExecutor(), callback);
     }
 
     /**
@@ -141,32 +151,7 @@
      */
     public void registerSliceCallback(@NonNull Uri uri, @NonNull List<SliceSpec> specs,
             @NonNull @CallbackExecutor Executor executor, @NonNull SliceCallback callback) {
-        try {
-            mService.addSliceListener(uri, mContext.getPackageName(),
-                    getListener(uri, callback, new ISliceListener.Stub() {
-                        @Override
-                        public void onSliceUpdated(Slice s) throws RemoteException {
-                            executor.execute(() -> callback.onSliceUpdated(s));
-                        }
-                    }), specs.toArray(new SliceSpec[specs.size()]));
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
 
-    private ISliceListener getListener(Uri uri, SliceCallback callback,
-            ISliceListener listener) {
-        Pair<Uri, SliceCallback> key = new Pair<>(uri, callback);
-        if (mListenerLookup.containsKey(key)) {
-            try {
-                mService.removeSliceListener(uri, mContext.getPackageName(),
-                        mListenerLookup.get(key));
-            } catch (RemoteException e) {
-                throw e.rethrowFromSystemServer();
-            }
-        }
-        mListenerLookup.put(key, listener);
-        return listener;
     }
 
     /**
@@ -180,12 +165,7 @@
      * @see #registerSliceCallback
      */
     public void unregisterSliceCallback(@NonNull Uri uri, @NonNull SliceCallback callback) {
-        try {
-            mService.removeSliceListener(uri, mContext.getPackageName(),
-                    mListenerLookup.remove(new Pair<>(uri, callback)));
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+
     }
 
     /**
@@ -206,7 +186,7 @@
     public void pinSlice(@NonNull Uri uri, @NonNull List<SliceSpec> specs) {
         try {
             mService.pinSlice(mContext.getPackageName(), uri,
-                    specs.toArray(new SliceSpec[specs.size()]));
+                    specs.toArray(new SliceSpec[specs.size()]), mToken);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -228,7 +208,7 @@
      */
     public void unpinSlice(@NonNull Uri uri) {
         try {
-            mService.unpinSlice(mContext.getPackageName(), uri);
+            mService.unpinSlice(mContext.getPackageName(), uri, mToken);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -316,12 +296,10 @@
     }
 
     /**
-     * Turns a slice intent into a slice uri. Expects an explicit intent. If there is no
-     * {@link android.content.ContentProvider} associated with the given intent this will throw
-     * {@link IllegalArgumentException}.
+     * Turns a slice intent into a slice uri. Expects an explicit intent.
      *
      * @param intent The intent associated with a slice.
-     * @return The Slice Uri provided by the app or null if none is given.
+     * @return The Slice Uri provided by the app or null if none exists.
      * @see Slice
      * @see SliceProvider#onMapIntentToUri(Intent)
      * @see Intent
@@ -341,7 +319,16 @@
         List<ResolveInfo> providers =
                 mContext.getPackageManager().queryIntentContentProviders(intent, 0);
         if (providers == null || providers.isEmpty()) {
-            throw new IllegalArgumentException("Unable to resolve intent " + intent);
+            // There are no providers, see if this activity has a direct link.
+            ResolveInfo resolve = mContext.getPackageManager().resolveActivity(intent,
+                    PackageManager.GET_META_DATA);
+            if (resolve != null && resolve.activityInfo != null
+                    && resolve.activityInfo.metaData != null
+                    && resolve.activityInfo.metaData.containsKey(SLICE_METADATA_KEY)) {
+                return Uri.parse(
+                        resolve.activityInfo.metaData.getString(SLICE_METADATA_KEY));
+            }
+            return null;
         }
         String authority = providers.get(0).providerInfo.authority;
         Uri uri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
@@ -392,7 +379,16 @@
         List<ResolveInfo> providers =
                 mContext.getPackageManager().queryIntentContentProviders(intent, 0);
         if (providers == null || providers.isEmpty()) {
-            throw new IllegalArgumentException("Unable to resolve intent " + intent);
+            // There are no providers, see if this activity has a direct link.
+            ResolveInfo resolve = mContext.getPackageManager().resolveActivity(intent,
+                    PackageManager.GET_META_DATA);
+            if (resolve != null && resolve.activityInfo != null
+                    && resolve.activityInfo.metaData != null
+                    && resolve.activityInfo.metaData.containsKey(SLICE_METADATA_KEY)) {
+                return bindSlice(Uri.parse(resolve.activityInfo.metaData
+                        .getString(SLICE_METADATA_KEY)), supportedSpecs);
+            }
+            return null;
         }
         String authority = providers.get(0).providerInfo.authority;
         Uri uri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
diff --git a/core/java/android/app/timezone/RulesManager.java b/core/java/android/app/timezone/RulesManager.java
index dc79256..fe83113 100644
--- a/core/java/android/app/timezone/RulesManager.java
+++ b/core/java/android/app/timezone/RulesManager.java
@@ -36,7 +36,7 @@
  * <p>This interface is intended for use with the default APK-based time zone rules update
  * application but it can also be used by OEMs if that mechanism is turned off using configuration.
  * All callers must possess the {@link android.Manifest.permission#UPDATE_TIME_ZONE_RULES} system
- * permission.
+ * permission unless otherwise stated.
  *
  * <p>When using the default mechanism, when properly configured the Android system will send a
  * {@link RulesUpdaterContract#ACTION_TRIGGER_RULES_UPDATE_CHECK} intent with a
@@ -120,9 +120,12 @@
 
     /**
      * Returns information about the current time zone rules state such as the IANA version of
-     * the system and any currently installed distro. This method is intended to allow clients to
-     * determine if the current state can be improved; for example by passing the information to a
-     * server that may provide a new distro for download.
+     * the system and any currently installed distro. This method allows clients to determine the
+     * current device state, perhaps to see if it can be improved; for example by passing the
+     * information to a server that may provide a new distro for download.
+     *
+     * <p>Callers must possess the {@link android.Manifest.permission#QUERY_TIME_ZONE_RULES} system
+     * permission.
      */
     public RulesState getRulesState() {
         try {
diff --git a/core/java/android/app/usage/AppStandbyInfo.java b/core/java/android/app/usage/AppStandbyInfo.java
new file mode 100644
index 0000000..51fe0e2
--- /dev/null
+++ b/core/java/android/app/usage/AppStandbyInfo.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.usage;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A pair of {package, bucket} to denote the app standby bucket for a given package.
+ * Used as a vehicle of data across the binder IPC.
+ * @hide
+ */
+public final class AppStandbyInfo implements Parcelable {
+
+    public String mPackageName;
+    public @UsageStatsManager.StandbyBuckets int mStandbyBucket;
+
+    private AppStandbyInfo(Parcel in) {
+        mPackageName = in.readString();
+        mStandbyBucket = in.readInt();
+    }
+
+    public AppStandbyInfo(String packageName, int bucket) {
+        mPackageName = packageName;
+        mStandbyBucket = bucket;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(mPackageName);
+        dest.writeInt(mStandbyBucket);
+    }
+
+    public static final Creator<AppStandbyInfo> CREATOR = new Creator<AppStandbyInfo>() {
+        @Override
+        public AppStandbyInfo createFromParcel(Parcel source) {
+            return new AppStandbyInfo(source);
+        }
+
+        @Override
+        public AppStandbyInfo[] newArray(int size) {
+            return new AppStandbyInfo[size];
+        }
+    };
+}
diff --git a/core/java/android/app/usage/IUsageStatsManager.aidl b/core/java/android/app/usage/IUsageStatsManager.aidl
index f089c127..e72b84d 100644
--- a/core/java/android/app/usage/IUsageStatsManager.aidl
+++ b/core/java/android/app/usage/IUsageStatsManager.aidl
@@ -40,6 +40,6 @@
             in String[] annotations, String action);
     int getAppStandbyBucket(String packageName, String callingPackage, int userId);
     void setAppStandbyBucket(String packageName, int bucket, int userId);
-    Map getAppStandbyBuckets(String callingPackage, int userId);
-    void setAppStandbyBuckets(in Map appBuckets, int userId);
+    ParceledListSlice getAppStandbyBuckets(String callingPackage, int userId);
+    void setAppStandbyBuckets(in ParceledListSlice appBuckets, int userId);
 }
diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java
index 6b573e9..521ab4e 100644
--- a/core/java/android/app/usage/UsageEvents.java
+++ b/core/java/android/app/usage/UsageEvents.java
@@ -109,7 +109,8 @@
         public static final int NOTIFICATION_SEEN = 10;
 
         /**
-         * An event type denoting a change in App Standby Bucket.
+         * An event type denoting a change in App Standby Bucket. Additional bucket information
+         * is contained in mBucketAndReason.
          * @hide
          */
         @SystemApi
@@ -180,11 +181,12 @@
         public String[] mContentAnnotations;
 
         /**
-         * The app standby bucket assigned.
+         * The app standby bucket assigned and reason. Bucket is the high order 16 bits, reason
+         * is the low order 16 bits.
          * Only present for {@link #STANDBY_BUCKET_CHANGED} event types
          * {@hide}
          */
-        public int mBucket;
+        public int mBucketAndReason;
 
         /** @hide */
         @EventFlags
@@ -205,7 +207,7 @@
             mContentType = orig.mContentType;
             mContentAnnotations = orig.mContentAnnotations;
             mFlags = orig.mFlags;
-            mBucket = orig.mBucket;
+            mBucketAndReason = orig.mBucketAndReason;
         }
 
         /**
@@ -268,7 +270,19 @@
          */
         @SystemApi
         public int getStandbyBucket() {
-            return mBucket;
+            return (mBucketAndReason & 0xFFFF0000) >>> 16;
+        }
+
+        /**
+         * Returns the reason for the bucketing, if the event is of type
+         * {@link #STANDBY_BUCKET_CHANGED}, otherwise returns 0. Reason values include
+         * the main reason which is one of REASON_MAIN_*, OR'ed with REASON_SUB_*, if there
+         * are sub-reasons for the main reason, such as REASON_SUB_USAGE_* when the main reason
+         * is REASON_MAIN_USAGE.
+         * @hide
+         */
+        public int getStandbyReason() {
+            return mBucketAndReason & 0x0000FFFF;
         }
 
         /** @hide */
@@ -428,7 +442,7 @@
                 p.writeStringArray(event.mContentAnnotations);
                 break;
             case Event.STANDBY_BUCKET_CHANGED:
-                p.writeInt(event.mBucket);
+                p.writeInt(event.mBucketAndReason);
                 break;
         }
     }
@@ -474,7 +488,7 @@
                 eventOut.mContentAnnotations = p.createStringArray();
                 break;
             case Event.STANDBY_BUCKET_CHANGED:
-                eventOut.mBucket = p.readInt();
+                eventOut.mBucketAndReason = p.readInt();
                 break;
         }
     }
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index cf35902..5a57b06 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -28,6 +28,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -131,24 +132,37 @@
     @SystemApi
     public static final int STANDBY_BUCKET_NEVER = 50;
 
-    /** {@hide} Reason for bucketing -- default initial state */
-    public static final String REASON_DEFAULT = "default";
+    /** @hide */
+    public static final int REASON_MAIN_MASK = 0xFF00;
+    /** @hide */
+    public static final int REASON_MAIN_DEFAULT =   0x0100;
+    /** @hide */
+    public static final int REASON_MAIN_TIMEOUT =   0x0200;
+    /** @hide */
+    public static final int REASON_MAIN_USAGE =     0x0300;
+    /** @hide */
+    public static final int REASON_MAIN_FORCED =    0x0400;
+    /** @hide */
+    public static final int REASON_MAIN_PREDICTED = 0x0500;
 
-    /** {@hide} Reason for bucketing -- timeout */
-    public static final String REASON_TIMEOUT = "timeout";
-
-    /** {@hide} Reason for bucketing -- usage */
-    public static final String REASON_USAGE = "usage";
-
-    /** {@hide} Reason for bucketing -- forced by user / shell command */
-    public static final String REASON_FORCED = "forced";
-
-    /**
-     * {@hide}
-     * Reason for bucketing -- predicted. This is a prefix and the UID of the bucketeer will
-     * be appended.
-     */
-    public static final String REASON_PREDICTED = "predicted";
+    /** @hide */
+    public static final int REASON_SUB_MASK = 0x00FF;
+    /** @hide */
+    public static final int REASON_SUB_USAGE_SYSTEM_INTERACTION = 0x0001;
+    /** @hide */
+    public static final int REASON_SUB_USAGE_NOTIFICATION_SEEN  = 0x0002;
+    /** @hide */
+    public static final int REASON_SUB_USAGE_USER_INTERACTION   = 0x0003;
+    /** @hide */
+    public static final int REASON_SUB_USAGE_MOVE_TO_FOREGROUND = 0x0004;
+    /** @hide */
+    public static final int REASON_SUB_USAGE_MOVE_TO_BACKGROUND = 0x0005;
+    /** @hide */
+    public static final int REASON_SUB_USAGE_SYSTEM_UPDATE      = 0x0006;
+    /** @hide */
+    public static final int REASON_SUB_USAGE_ACTIVE_TIMEOUT     = 0x0007;
+    /** @hide */
+    public static final int REASON_SUB_USAGE_SYNC_ADAPTER       = 0x0008;
 
     /** @hide */
     @IntDef(flag = false, prefix = { "STANDBY_BUCKET_" }, value = {
@@ -388,8 +402,16 @@
     @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)
     public Map<String, Integer> getAppStandbyBuckets() {
         try {
-            return (Map<String, Integer>) mService.getAppStandbyBuckets(
+            final ParceledListSlice<AppStandbyInfo> slice = mService.getAppStandbyBuckets(
                     mContext.getOpPackageName(), mContext.getUserId());
+            final List<AppStandbyInfo> bucketList = slice.getList();
+            final ArrayMap<String, Integer> bucketMap = new ArrayMap<>();
+            final int n = bucketList.size();
+            for (int i = 0; i < n; i++) {
+                final AppStandbyInfo bucketInfo = bucketList.get(i);
+                bucketMap.put(bucketInfo.mPackageName, bucketInfo.mStandbyBucket);
+            }
+            return bucketMap;
         } catch (RemoteException e) {
         }
         return Collections.EMPTY_MAP;
@@ -404,12 +426,69 @@
     @SystemApi
     @RequiresPermission(android.Manifest.permission.CHANGE_APP_IDLE_STATE)
     public void setAppStandbyBuckets(Map<String, Integer> appBuckets) {
+        if (appBuckets == null) {
+            return;
+        }
+        final List<AppStandbyInfo> bucketInfoList = new ArrayList<>(appBuckets.size());
+        for (Map.Entry<String, Integer> bucketEntry : appBuckets.entrySet()) {
+            bucketInfoList.add(new AppStandbyInfo(bucketEntry.getKey(), bucketEntry.getValue()));
+        }
+        final ParceledListSlice<AppStandbyInfo> slice = new ParceledListSlice<>(bucketInfoList);
         try {
-            mService.setAppStandbyBuckets(appBuckets, mContext.getUserId());
+            mService.setAppStandbyBuckets(slice, mContext.getUserId());
         } catch (RemoteException e) {
         }
     }
 
+    /** @hide */
+    public static String reasonToString(int standbyReason) {
+        StringBuilder sb = new StringBuilder();
+        switch (standbyReason & REASON_MAIN_MASK) {
+            case REASON_MAIN_DEFAULT:
+                sb.append("d");
+                break;
+            case REASON_MAIN_FORCED:
+                sb.append("f");
+                break;
+            case REASON_MAIN_PREDICTED:
+                sb.append("p");
+                break;
+            case REASON_MAIN_TIMEOUT:
+                sb.append("t");
+                break;
+            case REASON_MAIN_USAGE:
+                sb.append("u-");
+                switch (standbyReason & REASON_SUB_MASK) {
+                    case REASON_SUB_USAGE_SYSTEM_INTERACTION:
+                        sb.append("si");
+                        break;
+                    case REASON_SUB_USAGE_NOTIFICATION_SEEN:
+                        sb.append("ns");
+                        break;
+                    case REASON_SUB_USAGE_USER_INTERACTION:
+                        sb.append("ui");
+                        break;
+                    case REASON_SUB_USAGE_MOVE_TO_FOREGROUND:
+                        sb.append("mf");
+                        break;
+                    case REASON_SUB_USAGE_MOVE_TO_BACKGROUND:
+                        sb.append("mb");
+                        break;
+                    case REASON_SUB_USAGE_SYSTEM_UPDATE:
+                        sb.append("su");
+                        break;
+                    case REASON_SUB_USAGE_ACTIVE_TIMEOUT:
+                        sb.append("at");
+                        break;
+                    case REASON_SUB_USAGE_SYNC_ADAPTER:
+                        sb.append("sa");
+                        break;
+                }
+                break;
+        }
+        return sb.toString();
+    }
+
     /**
      * {@hide}
      * Temporarily whitelist the specified app for a short duration. This is to allow an app
diff --git a/core/java/android/app/usage/UsageStatsManagerInternal.java b/core/java/android/app/usage/UsageStatsManagerInternal.java
index 5d6a989..b62b1ee 100644
--- a/core/java/android/app/usage/UsageStatsManagerInternal.java
+++ b/core/java/android/app/usage/UsageStatsManagerInternal.java
@@ -139,7 +139,7 @@
 
         /** Callback to inform listeners that the idle state has changed to a new bucket. */
         public abstract void onAppIdleStateChanged(String packageName, @UserIdInt int userId,
-                boolean idle, int bucket);
+                boolean idle, int bucket, int reason);
 
         /**
          * Callback to inform listeners that the parole state has changed. This means apps are
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
index 0a0d214..605dbd2 100644
--- a/core/java/android/bluetooth/BluetoothUuid.java
+++ b/core/java/android/bluetooth/BluetoothUuid.java
@@ -79,9 +79,8 @@
             ParcelUuid.fromString("00001132-0000-1000-8000-00805F9B34FB");
     public static final ParcelUuid SAP =
             ParcelUuid.fromString("0000112D-0000-1000-8000-00805F9B34FB");
-    /* TODO: b/69623109 update this value. It will change to 16bit UUID!! */
     public static final ParcelUuid HearingAid =
-            ParcelUuid.fromString("7312C48F-22CC-497F-85FD-A0616A3B9E05");
+            ParcelUuid.fromString("0000FDF0-0000-1000-8000-00805f9b34fb");
 
     public static final ParcelUuid BASE_UUID =
             ParcelUuid.fromString("00000000-0000-1000-8000-00805F9B34FB");
diff --git a/core/java/android/content/ClipboardManager.java b/core/java/android/content/ClipboardManager.java
index 718e465..73b6eb2 100644
--- a/core/java/android/content/ClipboardManager.java
+++ b/core/java/android/content/ClipboardManager.java
@@ -16,13 +16,16 @@
 
 package android.content;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemService;
 import android.os.Handler;
-import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.ServiceManager.ServiceNotFoundException;
 
+import com.android.internal.util.Preconditions;
+
 import java.util.ArrayList;
 
 /**
@@ -45,6 +48,7 @@
 @SystemService(Context.CLIPBOARD_SERVICE)
 public class ClipboardManager extends android.text.ClipboardManager {
     private final Context mContext;
+    private final Handler mHandler;
     private final IClipboard mService;
 
     private final ArrayList<OnPrimaryClipChangedListener> mPrimaryClipChangedListeners
@@ -52,20 +56,11 @@
 
     private final IOnPrimaryClipChangedListener.Stub mPrimaryClipChangedServiceListener
             = new IOnPrimaryClipChangedListener.Stub() {
-        public void dispatchPrimaryClipChanged() {
-            mHandler.sendEmptyMessage(MSG_REPORT_PRIMARY_CLIP_CHANGED);
-        }
-    };
-
-    static final int MSG_REPORT_PRIMARY_CLIP_CHANGED = 1;
-
-    private final Handler mHandler = new Handler() {
         @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_REPORT_PRIMARY_CLIP_CHANGED:
-                    reportPrimaryClipChanged();
-            }
+        public void dispatchPrimaryClipChanged() {
+            mHandler.post(() -> {
+                reportPrimaryClipChanged();
+            });
         }
     };
 
@@ -89,6 +84,7 @@
     /** {@hide} */
     public ClipboardManager(Context context, Handler handler) throws ServiceNotFoundException {
         mContext = context;
+        mHandler = handler;
         mService = IClipboard.Stub.asInterface(
                 ServiceManager.getServiceOrThrow(Context.CLIPBOARD_SERVICE));
     }
@@ -98,12 +94,13 @@
      * is involved in normal cut and paste operations.
      *
      * @param clip The clipped data item to set.
+     * @see #getPrimaryClip()
+     * @see #clearPrimaryClip()
      */
-    public void setPrimaryClip(ClipData clip) {
+    public void setPrimaryClip(@NonNull ClipData clip) {
         try {
-            if (clip != null) {
-                clip.prepareToLeaveProcess(true);
-            }
+            Preconditions.checkNotNull(clip);
+            clip.prepareToLeaveProcess(true);
             mService.setPrimaryClip(clip, mContext.getOpPackageName());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -111,9 +108,24 @@
     }
 
     /**
-     * Returns the current primary clip on the clipboard.
+     * Clears any current primary clip on the clipboard.
+     *
+     * @see #setPrimaryClip(ClipData)
      */
-    public ClipData getPrimaryClip() {
+    public void clearPrimaryClip() {
+        try {
+            mService.clearPrimaryClip(mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the current primary clip on the clipboard.
+     *
+     * @see #setPrimaryClip(ClipData)
+     */
+    public @Nullable ClipData getPrimaryClip() {
         try {
             return mService.getPrimaryClip(mContext.getOpPackageName());
         } catch (RemoteException e) {
@@ -124,8 +136,10 @@
     /**
      * Returns a description of the current primary clip on the clipboard
      * but not a copy of its data.
+     *
+     * @see #setPrimaryClip(ClipData)
      */
-    public ClipDescription getPrimaryClipDescription() {
+    public @Nullable ClipDescription getPrimaryClipDescription() {
         try {
             return mService.getPrimaryClipDescription(mContext.getOpPackageName());
         } catch (RemoteException e) {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index f184380..e1a00b1 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3370,7 +3370,11 @@
      * Use with {@link #getSystemService(String)} to retrieve a {@link
      * android.app.SearchManager} for handling searches.
      *
-     * @see #getSystemService(String)
+     * <p>
+     * {@link Configuration#UI_MODE_TYPE_WATCH} does not support
+     * {@link android.app.SearchManager}.
+     *
+     * @see #getSystemService
      * @see android.app.SearchManager
      */
     public static final String SEARCH_SERVICE = "search";
diff --git a/core/java/android/content/IClipboard.aidl b/core/java/android/content/IClipboard.aidl
index af0b8f0..135a436 100644
--- a/core/java/android/content/IClipboard.aidl
+++ b/core/java/android/content/IClipboard.aidl
@@ -27,6 +27,7 @@
  */
 interface IClipboard {
     void setPrimaryClip(in ClipData clip, String callingPackage);
+    void clearPrimaryClip(String callingPackage);
     ClipData getPrimaryClip(String pkg);
     ClipDescription getPrimaryClipDescription(String callingPackage);
     boolean hasPrimaryClip(String callingPackage);
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index a957aed..cec3bad 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -1872,9 +1872,10 @@
                 du.println(sb.toString());
             }
         }
-        if (mPriority != 0 || mHasPartialTypes) {
+        if (mPriority != 0 || mOrder != 0 || mHasPartialTypes) {
             sb.setLength(0);
             sb.append(prefix); sb.append("mPriority="); sb.append(mPriority);
+                    sb.append(", mOrder="); sb.append(mOrder);
                     sb.append(", mHasPartialTypes="); sb.append(mHasPartialTypes);
             du.println(sb.toString());
         }
@@ -1951,6 +1952,7 @@
         dest.writeInt(mHasPartialTypes ? 1 : 0);
         dest.writeInt(getAutoVerify() ? 1 : 0);
         dest.writeInt(mInstantAppVisibility);
+        dest.writeInt(mOrder);
     }
 
     /**
@@ -2020,6 +2022,7 @@
         mHasPartialTypes = source.readInt() > 0;
         setAutoVerify(source.readInt() > 0);
         setVisibilityToInstantApp(source.readInt());
+        mOrder = source.readInt();
     }
 
     private final boolean findMimeType(String type) {
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 1adc9f5..b2c9edd4 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -37,6 +37,7 @@
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.util.ArrayUtils;
+import com.android.server.SystemConfig;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -1384,6 +1385,8 @@
         classLoaderName = orig.classLoaderName;
         splitClassLoaderNames = orig.splitClassLoaderNames;
         appComponentFactory = orig.appComponentFactory;
+        compileSdkVersion = orig.compileSdkVersion;
+        compileSdkVersionCodename = orig.compileSdkVersionCodename;
     }
 
     public String toString() {
@@ -1601,7 +1604,10 @@
      * @hide
      */
     public boolean isAllowedToUseHiddenApi() {
-        return isSystemApp() || isUpdatedSystemApp();
+        boolean whitelisted =
+                SystemConfig.getInstance().getHiddenApiWhitelistedApps().contains(packageName);
+        return isSystemApp() || // TODO get rid of this once the whitelist has been populated
+                (whitelisted && (isSystemApp() || isUpdatedSystemApp()));
     }
 
     /**
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 379bff4..36a74a4 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -660,4 +660,6 @@
     boolean hasSigningCertificate(String packageName, in byte[] signingCertificate, int flags);
 
     boolean hasUidSigningCertificate(int uid, in byte[] signingCertificate, int flags);
+
+    String getSystemTextClassifierPackageName();
 }
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index d0be6c8..25af1a7 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -448,11 +448,17 @@
 
     /**
      * Uninstall the given package, removing it completely from the device. This
-     * method is only available to the current "installer of record" for the
-     * package.
+     * method is available to:
+     * <ul>
+     * <li>the current "installer of record" for the package
+     * <li>the device owner
+     * <li>the affiliated profile owner
+     * </ul>
      *
      * @param packageName The package to uninstall.
      * @param statusReceiver Where to deliver the result.
+     *
+     * @see android.app.admin.DevicePolicyManager
      */
     @RequiresPermission(anyOf = {
             Manifest.permission.DELETE_PACKAGES,
@@ -480,14 +486,22 @@
 
     /**
      * Uninstall the given package with a specific version code, removing it
-     * completely from the device. This method is only available to the current
-     * "installer of record" for the package. If the version code of the package
+     * completely from the device. If the version code of the package
      * does not match the one passed in the versioned package argument this
      * method is a no-op. Use {@link PackageManager#VERSION_CODE_HIGHEST} to
      * uninstall the latest version of the package.
+     * <p>
+     * This method is available to:
+     * <ul>
+     * <li>the current "installer of record" for the package
+     * <li>the device owner
+     * <li>the affiliated profile owner
+     * </ul>
      *
      * @param versionedPackage The versioned package to uninstall.
      * @param statusReceiver Where to deliver the result.
+     *
+     * @see android.app.admin.DevicePolicyManager
      */
     @RequiresPermission(anyOf = {
             Manifest.permission.DELETE_PACKAGES,
@@ -941,9 +955,14 @@
          * Once this method is called, the session is sealed and no additional
          * mutations may be performed on the session. If the device reboots
          * before the session has been finalized, you may commit the session again.
+         * <p>
+         * If the installer is the device owner or the affiliated profile owner, there will be no
+         * user intervention.
          *
          * @throws SecurityException if streams opened through
          *             {@link #openWrite(String, long, long)} are still open.
+         *
+         * @see android.app.admin.DevicePolicyManager
          */
         public void commit(@NonNull IntentSender statusReceiver) {
             try {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 07a9911..bd7961f 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -6022,4 +6022,14 @@
         throw new UnsupportedOperationException(
                 "hasSigningCertificate not implemented in subclass");
     }
+
+    /**
+     * @return the system defined text classifier package name, or null if there's none.
+     *
+     * @hide
+     */
+    public String getSystemTextClassifierPackageName() {
+        throw new UnsupportedOperationException(
+                "getSystemTextClassifierPackageName not implemented in subclass");
+    }
 }
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index 6f093ba..514112f 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -43,12 +43,14 @@
     public static final int PACKAGE_INSTALLER = 2;
     public static final int PACKAGE_VERIFIER = 3;
     public static final int PACKAGE_BROWSER = 4;
+    public static final int PACKAGE_SYSTEM_TEXT_CLASSIFIER = 5;
     @IntDef(value = {
         PACKAGE_SYSTEM,
         PACKAGE_SETUP_WIZARD,
         PACKAGE_INSTALLER,
         PACKAGE_VERIFIER,
         PACKAGE_BROWSER,
+        PACKAGE_SYSTEM_TEXT_CLASSIFIER,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface KnownPackage {}
@@ -234,6 +236,11 @@
             int userId);
 
     /**
+     * @return The default home activity component name.
+     */
+    public abstract ComponentName getDefaultHomeActivity(int userId);
+
+    /**
      * Called by DeviceOwnerManagerService to set the package names of device owner and profile
      * owners.
      */
@@ -537,4 +544,16 @@
     /** Updates the flags for the given permission. */
     public abstract void updatePermissionFlagsTEMP(@NonNull String permName,
             @NonNull String packageName, int flagMask, int flagValues, int userId);
+
+    /**
+     * Returns true if it's still safe to restore data backed up from this app's version
+     * that was signed with restoringFromSigHash.
+     */
+    public abstract boolean isDataRestoreSafe(byte[] restoringFromSigHash, String packageName);
+
+    /**
+     * Returns true if it's still safe to restore data backed up from this app's version
+     * that was signed with restoringFromSig.
+     */
+    public abstract boolean isDataRestoreSafe(Signature restoringFromSig, String packageName);
 }
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 9e4166e..04a028b 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -3185,12 +3185,12 @@
 
         perm.info.protectionLevel = PermissionInfo.fixProtectionLevel(perm.info.protectionLevel);
 
-        if ((perm.info.protectionLevel&PermissionInfo.PROTECTION_MASK_FLAGS) != 0) {
+        if (perm.info.getProtectionFlags() != 0) {
             if ( (perm.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_INSTANT) == 0
                     && (perm.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY) == 0
                     && (perm.info.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE) !=
                     PermissionInfo.PROTECTION_SIGNATURE) {
-                outError[0] = "<permission>  protectionLevel specifies a non-instnat flag but is "
+                outError[0] = "<permission>  protectionLevel specifies a non-instant flag but is "
                         + "not based on signature type";
                 mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                 return false;
@@ -3641,7 +3641,9 @@
         // getting added to the wrong package.
         final CachedComponentArgs cachedArgs = new CachedComponentArgs();
         int type;
-
+        boolean hasActivityOrder = false;
+        boolean hasReceiverOrder = false;
+        boolean hasServiceOrder = false;
         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                 && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
@@ -3657,6 +3659,7 @@
                     return false;
                 }
 
+                hasActivityOrder |= (a.order != 0);
                 owner.activities.add(a);
 
             } else if (tagName.equals("receiver")) {
@@ -3667,6 +3670,7 @@
                     return false;
                 }
 
+                hasReceiverOrder |= (a.order != 0);
                 owner.receivers.add(a);
 
             } else if (tagName.equals("service")) {
@@ -3676,6 +3680,7 @@
                     return false;
                 }
 
+                hasServiceOrder |= (s.order != 0);
                 owner.services.add(s);
 
             } else if (tagName.equals("provider")) {
@@ -3694,6 +3699,7 @@
                     return false;
                 }
 
+                hasActivityOrder |= (a.order != 0);
                 owner.activities.add(a);
 
             } else if (parser.getName().equals("meta-data")) {
@@ -3827,6 +3833,15 @@
             }
         }
 
+        if (hasActivityOrder) {
+            Collections.sort(owner.activities, (a1, a2) -> Integer.compare(a2.order, a1.order));
+        }
+        if (hasReceiverOrder) {
+            Collections.sort(owner.receivers,  (r1, r2) -> Integer.compare(r2.order, r1.order));
+        }
+        if (hasServiceOrder) {
+            Collections.sort(owner.services,  (s1, s2) -> Integer.compare(s2.order, s1.order));
+        }
         // Must be ran after the entire {@link ApplicationInfo} has been fully processed and after
         // every activity info has had a chance to set it from its attributes.
         setMaxAspectRatio(owner);
@@ -4368,6 +4383,7 @@
                             + mArchiveSourcePath + " "
                             + parser.getPositionDescription());
                 } else {
+                    a.order = Math.max(intent.getOrder(), a.order);
                     a.intents.add(intent);
                 }
                 // adjust activity flags when we implicitly expose it via a browsable filter
@@ -4678,6 +4694,7 @@
         info.windowLayout = target.info.windowLayout;
         info.resizeMode = target.info.resizeMode;
         info.maxAspectRatio = target.info.maxAspectRatio;
+        info.requestedVrComponent = target.info.requestedVrComponent;
 
         info.encryptionAware = info.directBootAware = target.info.directBootAware;
 
@@ -4745,6 +4762,7 @@
                             + mArchiveSourcePath + " "
                             + parser.getPositionDescription());
                 } else {
+                    a.order = Math.max(intent.getOrder(), a.order);
                     a.intents.add(intent);
                 }
                 // adjust activity flags when we implicitly expose it via a browsable filter
@@ -4952,6 +4970,7 @@
                     intent.setVisibilityToInstantApp(IntentFilter.VISIBILITY_EXPLICIT);
                     outInfo.info.flags |= ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP;
                 }
+                outInfo.order = Math.max(intent.getOrder(), outInfo.order);
                 outInfo.intents.add(intent);
 
             } else if (parser.getName().equals("meta-data")) {
@@ -5241,6 +5260,7 @@
                     intent.setVisibilityToInstantApp(IntentFilter.VISIBILITY_EXPLICIT);
                     s.info.flags |= ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP;
                 }
+                s.order = Math.max(intent.getOrder(), s.order);
                 s.intents.add(intent);
             } else if (parser.getName().equals("meta-data")) {
                 if ((s.metaData=parseMetaData(res, parser, s.metaData,
@@ -5466,6 +5486,10 @@
                 com.android.internal.R.styleable.AndroidManifestIntentFilter_priority, 0);
         outInfo.setPriority(priority);
 
+        int order = sa.getInt(
+                com.android.internal.R.styleable.AndroidManifestIntentFilter_order, 0);
+        outInfo.setOrder(order);
+
         TypedValue v = sa.peekValue(
                 com.android.internal.R.styleable.AndroidManifestIntentFilter_label);
         if (v != null && (outInfo.labelRes=v.resourceId) == 0) {
@@ -7053,6 +7077,8 @@
 
         public Bundle metaData;
         public Package owner;
+        /** The order of this component in relation to its peers */
+        public int order;
 
         ComponentName componentName;
         String componentShortName;
@@ -7571,6 +7597,7 @@
 
             for (ActivityIntentInfo aii : intents) {
                 aii.activity = this;
+                order = Math.max(aii.getOrder(), order);
             }
 
             if (info.permission != null) {
@@ -7660,6 +7687,7 @@
 
             for (ServiceIntentInfo aii : intents) {
                 aii.service = this;
+                order = Math.max(aii.getOrder(), order);
             }
 
             if (info.permission != null) {
diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java
index 21bd7f0..938409a 100644
--- a/core/java/android/content/pm/PermissionInfo.java
+++ b/core/java/android/content/pm/PermissionInfo.java
@@ -16,12 +16,16 @@
 
 package android.content.pm;
 
+import android.annotation.IntDef;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Information you can retrieve about a particular security permission
  * known to the system.  This corresponds to information collected from the
@@ -56,6 +60,16 @@
     @Deprecated
     public static final int PROTECTION_SIGNATURE_OR_SYSTEM = 3;
 
+    /** @hide */
+    @IntDef(flag = false, prefix = { "PROTECTION_" }, value = {
+            PROTECTION_NORMAL,
+            PROTECTION_DANGEROUS,
+            PROTECTION_SIGNATURE,
+            PROTECTION_SIGNATURE_OR_SYSTEM,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Protection {}
+
     /**
      * Additional flag for {@link #protectionLevel}, corresponding
      * to the <code>privileged</code> value of
@@ -155,30 +169,71 @@
     public static final int PROTECTION_FLAG_VENDOR_PRIVILEGED = 0x8000;
 
     /**
-     * Mask for {@link #protectionLevel}: the basic protection type.
+     * Additional flag for {@link #protectionLevel}, corresponding
+     * to the <code>text_classifier</code> value of
+     * {@link android.R.attr#protectionLevel}.
+     *
+     * @hide
      */
+    @SystemApi
+    @TestApi
+    public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 0x10000;
+
+    /** @hide */
+    @IntDef(flag = true, prefix = { "PROTECTION_FLAG_" }, value = {
+            PROTECTION_FLAG_PRIVILEGED,
+            PROTECTION_FLAG_SYSTEM,
+            PROTECTION_FLAG_DEVELOPMENT,
+            PROTECTION_FLAG_APPOP,
+            PROTECTION_FLAG_PRE23,
+            PROTECTION_FLAG_INSTALLER,
+            PROTECTION_FLAG_VERIFIER,
+            PROTECTION_FLAG_PREINSTALLED,
+            PROTECTION_FLAG_SETUP,
+            PROTECTION_FLAG_INSTANT,
+            PROTECTION_FLAG_RUNTIME_ONLY,
+            PROTECTION_FLAG_OEM,
+            PROTECTION_FLAG_VENDOR_PRIVILEGED,
+            PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ProtectionFlags {}
+
+    /**
+     * Mask for {@link #protectionLevel}: the basic protection type.
+     *
+     * @deprecated Use #getProtection() instead.
+     */
+    @Deprecated
     public static final int PROTECTION_MASK_BASE = 0xf;
 
     /**
      * Mask for {@link #protectionLevel}: additional flag bits.
+     *
+     * @deprecated Use #getProtectionFlags() instead.
      */
+    @Deprecated
     public static final int PROTECTION_MASK_FLAGS = 0xfff0;
 
     /**
      * The level of access this permission is protecting, as per
      * {@link android.R.attr#protectionLevel}. Consists of
-     * a base permission type and zero or more flags:
+     * a base permission type and zero or more flags. Use the following functions
+     * to extract them.
      *
      * <pre>
-     * int basePermissionType = protectionLevel & {@link #PROTECTION_MASK_BASE};
-     * int permissionFlags = protectionLevel & {@link #PROTECTION_MASK_FLAGS};
+     * int basePermissionType = permissionInfo.getProtection();
+     * int permissionFlags = permissionInfo.getProtectionFlags();
      * </pre>
      *
      * <p></p>Base permission types are {@link #PROTECTION_NORMAL},
      * {@link #PROTECTION_DANGEROUS}, {@link #PROTECTION_SIGNATURE}
      * and the deprecated {@link #PROTECTION_SIGNATURE_OR_SYSTEM}.
      * Flags are listed under {@link android.R.attr#protectionLevel}.
+     *
+     * @deprecated Use #getProtection() and #getProtectionFlags() instead.
      */
+    @Deprecated
     public int protectionLevel;
 
     /**
@@ -304,6 +359,9 @@
         if ((level & PermissionInfo.PROTECTION_FLAG_VENDOR_PRIVILEGED) != 0) {
             protLevel += "|vendorPrivileged";
         }
+        if ((level & PermissionInfo.PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER) != 0) {
+            protLevel += "|textClassifier";
+        }
         return protLevel;
     }
 
@@ -344,6 +402,22 @@
         return null;
     }
 
+    /**
+     * Return the base permission type.
+     */
+    @Protection
+    public int getProtection() {
+        return protectionLevel & PROTECTION_MASK_BASE;
+    }
+
+    /**
+     * Return the additional flags in {@link #protectionLevel}.
+     */
+    @ProtectionFlags
+    public int getProtectionFlags() {
+        return protectionLevel & ~PROTECTION_MASK_BASE;
+    }
+
     @Override
     public String toString() {
         return "PermissionInfo{"
diff --git a/core/java/android/content/pm/dex/ArtManagerInternal.java b/core/java/android/content/pm/dex/ArtManagerInternal.java
new file mode 100644
index 0000000..62ab9e0
--- /dev/null
+++ b/core/java/android/content/pm/dex/ArtManagerInternal.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.pm.dex;
+
+import android.content.pm.ApplicationInfo;
+
+/**
+ * Art manager local system service interface.
+ *
+ * @hide Only for use within the system server.
+ */
+public abstract class ArtManagerInternal {
+
+    /**
+     * Return optimization information about the application {@code info} when
+     * in executes using the specified {@code abi}.
+     */
+    public abstract PackageOptimizationInfo getPackageOptimizationInfo(
+            ApplicationInfo info, String abi);
+}
diff --git a/core/java/android/content/pm/dex/PackageOptimizationInfo.java b/core/java/android/content/pm/dex/PackageOptimizationInfo.java
new file mode 100644
index 0000000..b650457
--- /dev/null
+++ b/core/java/android/content/pm/dex/PackageOptimizationInfo.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.pm.dex;
+
+/**
+ * Encapsulates information about the optimizations performed on a package.
+ *
+ * @hide
+ */
+public class PackageOptimizationInfo {
+    private final String mCompilationFilter;
+    private final String mCompilationReason;
+
+    public PackageOptimizationInfo(String compilerFilter, String compilationReason) {
+        this.mCompilationReason = compilationReason;
+        this.mCompilationFilter = compilerFilter;
+    }
+
+    public String getCompilationReason() {
+        return mCompilationReason;
+    }
+
+    public String getCompilationFilter() {
+        return mCompilationFilter;
+    }
+
+    /**
+     * Create a default optimization info object for the case when we have no information.
+     */
+    public static PackageOptimizationInfo createWithNoInfo() {
+        return new PackageOptimizationInfo("no-info", "no-info");
+    }
+}
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index eb30979..19b5c45 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -16,15 +16,29 @@
 
 package android.content.res;
 
+import static android.content.ConfigurationProto.COLOR_MODE;
 import static android.content.ConfigurationProto.DENSITY_DPI;
 import static android.content.ConfigurationProto.FONT_SCALE;
+import static android.content.ConfigurationProto.HARD_KEYBOARD_HIDDEN;
+import static android.content.ConfigurationProto.KEYBOARD;
+import static android.content.ConfigurationProto.KEYBOARD_HIDDEN;
+import static android.content.ConfigurationProto.LOCALES;
+import static android.content.ConfigurationProto.MCC;
+import static android.content.ConfigurationProto.MNC;
+import static android.content.ConfigurationProto.NAVIGATION;
+import static android.content.ConfigurationProto.NAVIGATION_HIDDEN;
 import static android.content.ConfigurationProto.ORIENTATION;
 import static android.content.ConfigurationProto.SCREEN_HEIGHT_DP;
 import static android.content.ConfigurationProto.SCREEN_LAYOUT;
 import static android.content.ConfigurationProto.SCREEN_WIDTH_DP;
 import static android.content.ConfigurationProto.SMALLEST_SCREEN_WIDTH_DP;
+import static android.content.ConfigurationProto.TOUCHSCREEN;
 import static android.content.ConfigurationProto.UI_MODE;
 import static android.content.ConfigurationProto.WINDOW_CONFIGURATION;
+import static android.content.ResourcesConfigurationProto.CONFIGURATION;
+import static android.content.ResourcesConfigurationProto.SCREEN_HEIGHT_PX;
+import static android.content.ResourcesConfigurationProto.SCREEN_WIDTH_PX;
+import static android.content.ResourcesConfigurationProto.SDK_VERSION;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -38,6 +52,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
+import android.util.DisplayMetrics;
 import android.util.proto.ProtoOutputStream;
 import android.view.View;
 
@@ -1076,7 +1091,17 @@
     public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId) {
         final long token = protoOutputStream.start(fieldId);
         protoOutputStream.write(FONT_SCALE, fontScale);
+        protoOutputStream.write(MCC, mcc);
+        protoOutputStream.write(MNC, mnc);
+        mLocaleList.writeToProto(protoOutputStream, LOCALES);
         protoOutputStream.write(SCREEN_LAYOUT, screenLayout);
+        protoOutputStream.write(COLOR_MODE, colorMode);
+        protoOutputStream.write(TOUCHSCREEN, touchscreen);
+        protoOutputStream.write(KEYBOARD, keyboard);
+        protoOutputStream.write(KEYBOARD_HIDDEN, keyboardHidden);
+        protoOutputStream.write(HARD_KEYBOARD_HIDDEN, hardKeyboardHidden);
+        protoOutputStream.write(NAVIGATION, navigation);
+        protoOutputStream.write(NAVIGATION_HIDDEN, navigationHidden);
         protoOutputStream.write(ORIENTATION, orientation);
         protoOutputStream.write(UI_MODE, uiMode);
         protoOutputStream.write(SCREEN_WIDTH_DP, screenWidthDp);
@@ -1088,6 +1113,36 @@
     }
 
     /**
+     * Write full {@link android.content.ResourcesConfigurationProto} to protocol buffer output
+     * stream.
+     *
+     * @param protoOutputStream Stream to write the Configuration object to.
+     * @param fieldId           Field Id of the Configuration as defined in the parent message
+     * @param metrics           Current display information
+     * @hide
+     */
+    public void writeResConfigToProto(ProtoOutputStream protoOutputStream, long fieldId,
+            DisplayMetrics metrics) {
+        final int width, height;
+        if (metrics.widthPixels >= metrics.heightPixels) {
+            width = metrics.widthPixels;
+            height = metrics.heightPixels;
+        } else {
+            //noinspection SuspiciousNameCombination
+            width = metrics.heightPixels;
+            //noinspection SuspiciousNameCombination
+            height = metrics.widthPixels;
+        }
+
+        final long token = protoOutputStream.start(fieldId);
+        writeToProto(protoOutputStream, CONFIGURATION);
+        protoOutputStream.write(SDK_VERSION, Build.VERSION.RESOURCES_SDK_INT);
+        protoOutputStream.write(SCREEN_WIDTH_PX, width);
+        protoOutputStream.write(SCREEN_HEIGHT_PX, height);
+        protoOutputStream.end(token);
+    }
+
+    /**
      * Convert the UI mode to a human readable format.
      * @hide
      */
@@ -1558,12 +1613,7 @@
         dest.writeInt(mnc);
 
         fixUpLocaleList();
-        final int localeListSize = mLocaleList.size();
-        dest.writeInt(localeListSize);
-        for (int i = 0; i < localeListSize; ++i) {
-            final Locale l = mLocaleList.get(i);
-            dest.writeString(l.toLanguageTag());
-        }
+        dest.writeParcelable(mLocaleList, flags);
 
         if(userSetLocale) {
             dest.writeInt(1);
@@ -1597,12 +1647,7 @@
         mcc = source.readInt();
         mnc = source.readInt();
 
-        final int localeListSize = source.readInt();
-        final Locale[] localeArray = new Locale[localeListSize];
-        for (int i = 0; i < localeListSize; ++i) {
-            localeArray[i] = Locale.forLanguageTag(source.readString());
-        }
-        mLocaleList = new LocaleList(localeArray);
+        mLocaleList = source.readParcelable(LocaleList.class.getClassLoader());
         locale = mLocaleList.get(0);
 
         userSetLocale = (source.readInt()==1);
@@ -1925,11 +1970,21 @@
 
     /**
      * Returns a string representation of the configuration that can be parsed
-     * by build tools (like AAPT).
+     * by build tools (like AAPT), without display metrics included
      *
      * @hide
      */
     public static String resourceQualifierString(Configuration config) {
+        return resourceQualifierString(config, null);
+    }
+
+    /**
+     * Returns a string representation of the configuration that can be parsed
+     * by build tools (like AAPT).
+     *
+     * @hide
+     */
+    public static String resourceQualifierString(Configuration config, DisplayMetrics metrics) {
         ArrayList<String> parts = new ArrayList<String>();
 
         if (config.mcc != 0) {
@@ -2177,6 +2232,20 @@
                 break;
         }
 
+        if (metrics != null) {
+            final int width, height;
+            if (metrics.widthPixels >= metrics.heightPixels) {
+                width = metrics.widthPixels;
+                height = metrics.heightPixels;
+            } else {
+                //noinspection SuspiciousNameCombination
+                width = metrics.heightPixels;
+                //noinspection SuspiciousNameCombination
+                height = metrics.widthPixels;
+            }
+            parts.add(width + "x" + height);
+        }
+
         parts.add("v" + Build.VERSION.RESOURCES_SDK_INT);
         return TextUtils.join("-", parts);
     }
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index e558b7e..52aefcc 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -2646,6 +2646,10 @@
 
     /**
      * <p>Include OIS data in the capture result.</p>
+     * <p>{@link CaptureResult#STATISTICS_OIS_SAMPLES android.statistics.oisSamples} provides OIS sample data in the
+     * output result metadata.</p>
+     *
+     * @see CaptureResult#STATISTICS_OIS_SAMPLES
      * @see CaptureRequest#STATISTICS_OIS_DATA_MODE
      */
     public static final int STATISTICS_OIS_DATA_MODE_ON = 1;
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 3ed533a..ada7ebf 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -24,6 +24,7 @@
 import android.hardware.camera2.params.OutputConfiguration;
 import android.hardware.camera2.utils.HashCodeHelpers;
 import android.hardware.camera2.utils.TypeReference;
+import android.hardware.camera2.utils.SurfaceUtils;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.ArraySet;
@@ -643,6 +644,30 @@
                         break;
                     }
                 }
+
+                if (!streamFound) {
+                    // Check if we can match s by native object ID
+                    long reqSurfaceId = SurfaceUtils.getSurfaceId(s);
+                    for (int j = 0; j < configuredOutputs.size(); ++j) {
+                        int streamId = configuredOutputs.keyAt(j);
+                        OutputConfiguration outConfig = configuredOutputs.valueAt(j);
+                        int surfaceId = 0;
+                        for (Surface outSurface : outConfig.getSurfaces()) {
+                            if (reqSurfaceId == SurfaceUtils.getSurfaceId(outSurface)) {
+                                streamFound = true;
+                                mStreamIdxArray[i] = streamId;
+                                mSurfaceIdxArray[i] = surfaceId;
+                                i++;
+                                break;
+                            }
+                            surfaceId++;
+                        }
+                        if (streamFound) {
+                            break;
+                        }
+                    }
+                }
+
                 if (!streamFound) {
                     mStreamIdxArray = null;
                     mSurfaceIdxArray = null;
@@ -2759,9 +2784,6 @@
     /**
      * <p>A control for selecting whether OIS position information is included in output
      * result metadata.</p>
-     * <p>When set to ON,
-     * {@link CaptureResult#STATISTICS_OIS_TIMESTAMPS android.statistics.oisTimestamps}, android.statistics.oisShiftPixelX,
-     * and android.statistics.oisShiftPixelY provide OIS data in the output result metadata.</p>
      * <p><b>Possible values:</b>
      * <ul>
      *   <li>{@link #STATISTICS_OIS_DATA_MODE_OFF OFF}</li>
@@ -2770,8 +2792,6 @@
      * <p><b>Available values for this device:</b><br>
      * android.Statistics.info.availableOisDataModes</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
-     *
-     * @see CaptureResult#STATISTICS_OIS_TIMESTAMPS
      * @see #STATISTICS_OIS_DATA_MODE_OFF
      * @see #STATISTICS_OIS_DATA_MODE_ON
      */
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index c332d30..8c2f8c1 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -3911,9 +3911,6 @@
     /**
      * <p>A control for selecting whether OIS position information is included in output
      * result metadata.</p>
-     * <p>When set to ON,
-     * {@link CaptureResult#STATISTICS_OIS_TIMESTAMPS android.statistics.oisTimestamps}, android.statistics.oisShiftPixelX,
-     * and android.statistics.oisShiftPixelY provide OIS data in the output result metadata.</p>
      * <p><b>Possible values:</b>
      * <ul>
      *   <li>{@link #STATISTICS_OIS_DATA_MODE_OFF OFF}</li>
@@ -3922,8 +3919,6 @@
      * <p><b>Available values for this device:</b><br>
      * android.Statistics.info.availableOisDataModes</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
-     *
-     * @see CaptureResult#STATISTICS_OIS_TIMESTAMPS
      * @see #STATISTICS_OIS_DATA_MODE_OFF
      * @see #STATISTICS_OIS_DATA_MODE_ON
      */
@@ -3939,8 +3934,8 @@
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
      *
      * @see CaptureResult#SENSOR_TIMESTAMP
+     * @hide
      */
-    @PublicKey
     public static final Key<long[]> STATISTICS_OIS_TIMESTAMPS =
             new Key<long[]>("android.statistics.oisTimestamps", long[].class);
 
@@ -3948,16 +3943,14 @@
      * <p>An array of shifts of OIS samples, in x direction.</p>
      * <p>The array contains the amount of shifts in x direction, in pixels, based on OIS samples.
      * A positive value is a shift from left to right in active array coordinate system. For
-     * example, if the optical center is (1000, 500) in active array coordinates, an shift of
+     * example, if the optical center is (1000, 500) in active array coordinates, a shift of
      * (3, 0) puts the new optical center at (1003, 500).</p>
      * <p>The number of shifts must match the number of timestamps in
-     * {@link CaptureResult#STATISTICS_OIS_TIMESTAMPS android.statistics.oisTimestamps}.</p>
+     * android.statistics.oisTimestamps.</p>
      * <p><b>Units</b>: Pixels in active array.</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
-     *
-     * @see CaptureResult#STATISTICS_OIS_TIMESTAMPS
+     * @hide
      */
-    @PublicKey
     public static final Key<float[]> STATISTICS_OIS_X_SHIFTS =
             new Key<float[]>("android.statistics.oisXShifts", float[].class);
 
@@ -3965,20 +3958,35 @@
      * <p>An array of shifts of OIS samples, in y direction.</p>
      * <p>The array contains the amount of shifts in y direction, in pixels, based on OIS samples.
      * A positive value is a shift from top to bottom in active array coordinate system. For
-     * example, if the optical center is (1000, 500) in active array coordinates, an shift of
+     * example, if the optical center is (1000, 500) in active array coordinates, a shift of
      * (0, 5) puts the new optical center at (1000, 505).</p>
      * <p>The number of shifts must match the number of timestamps in
-     * {@link CaptureResult#STATISTICS_OIS_TIMESTAMPS android.statistics.oisTimestamps}.</p>
+     * android.statistics.oisTimestamps.</p>
      * <p><b>Units</b>: Pixels in active array.</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
-     *
-     * @see CaptureResult#STATISTICS_OIS_TIMESTAMPS
+     * @hide
      */
-    @PublicKey
     public static final Key<float[]> STATISTICS_OIS_Y_SHIFTS =
             new Key<float[]>("android.statistics.oisYShifts", float[].class);
 
     /**
+     * <p>An array of OIS samples.</p>
+     * <p>Each OIS sample contains the timestamp and the amount of shifts in x and y direction,
+     * in pixels, of the OIS sample.</p>
+     * <p>A positive value for a shift in x direction is a shift from left to right in active array
+     * coordinate system. For example, if the optical center is (1000, 500) in active array
+     * coordinates, a shift of (3, 0) puts the new optical center at (1003, 500).</p>
+     * <p>A positive value for a shift in y direction is a shift from top to bottom in active array
+     * coordinate system. For example, if the optical center is (1000, 500) in active array
+     * coordinates, a shift of (0, 5) puts the new optical center at (1000, 505).</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     */
+    @PublicKey
+    @SyntheticKey
+    public static final Key<android.hardware.camera2.params.OisSample[]> STATISTICS_OIS_SAMPLES =
+            new Key<android.hardware.camera2.params.OisSample[]>("android.statistics.oisSamples", android.hardware.camera2.params.OisSample[].class);
+
+    /**
      * <p>Tonemapping / contrast / gamma curve for the blue
      * channel, to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is
      * CONTRAST_CURVE.</p>
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index ebe2fa1..e4b1339 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -22,12 +22,12 @@
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CaptureRequest;
 import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.marshal.Marshaler;
 import android.hardware.camera2.marshal.MarshalQueryable;
 import android.hardware.camera2.marshal.MarshalRegistry;
+import android.hardware.camera2.marshal.Marshaler;
 import android.hardware.camera2.marshal.impl.MarshalQueryableArray;
-import android.hardware.camera2.marshal.impl.MarshalQueryableBoolean;
 import android.hardware.camera2.marshal.impl.MarshalQueryableBlackLevelPattern;
+import android.hardware.camera2.marshal.impl.MarshalQueryableBoolean;
 import android.hardware.camera2.marshal.impl.MarshalQueryableColorSpaceTransform;
 import android.hardware.camera2.marshal.impl.MarshalQueryableEnum;
 import android.hardware.camera2.marshal.impl.MarshalQueryableHighSpeedVideoConfiguration;
@@ -48,6 +48,7 @@
 import android.hardware.camera2.params.Face;
 import android.hardware.camera2.params.HighSpeedVideoConfiguration;
 import android.hardware.camera2.params.LensShadingMap;
+import android.hardware.camera2.params.OisSample;
 import android.hardware.camera2.params.ReprocessFormatsMap;
 import android.hardware.camera2.params.StreamConfiguration;
 import android.hardware.camera2.params.StreamConfigurationDuration;
@@ -56,8 +57,8 @@
 import android.hardware.camera2.utils.TypeReference;
 import android.location.Location;
 import android.location.LocationManager;
-import android.os.Parcelable;
 import android.os.Parcel;
+import android.os.Parcelable;
 import android.os.ServiceSpecificException;
 import android.util.Log;
 import android.util.Size;
@@ -614,6 +615,15 @@
                         return (T) metadata.getLensShadingMap();
                     }
                 });
+        sGetCommandMap.put(
+                CaptureResult.STATISTICS_OIS_SAMPLES.getNativeKey(),
+                        new GetCommand() {
+                    @Override
+                    @SuppressWarnings("unchecked")
+                    public <T> T getValue(CameraMetadataNative metadata, Key<T> key) {
+                        return (T) metadata.getOisSamples();
+                    }
+                });
     }
 
     private int[] getAvailableFormats() {
@@ -962,6 +972,50 @@
         return tc;
     }
 
+    private OisSample[] getOisSamples() {
+        long[] timestamps = getBase(CaptureResult.STATISTICS_OIS_TIMESTAMPS);
+        float[] xShifts = getBase(CaptureResult.STATISTICS_OIS_X_SHIFTS);
+        float[] yShifts = getBase(CaptureResult.STATISTICS_OIS_Y_SHIFTS);
+
+        if (timestamps == null) {
+            if (xShifts != null) {
+                throw new AssertionError("timestamps is null but xShifts is not");
+            }
+
+            if (yShifts != null) {
+                throw new AssertionError("timestamps is null but yShifts is not");
+            }
+
+            return null;
+        }
+
+        if (xShifts == null) {
+            throw new AssertionError("timestamps is not null but xShifts is");
+        }
+
+        if (yShifts == null) {
+            throw new AssertionError("timestamps is not null but yShifts is");
+        }
+
+        if (xShifts.length != timestamps.length) {
+            throw new AssertionError(String.format(
+                    "timestamps has %d entries but xShifts has %d", timestamps.length,
+                    xShifts.length));
+        }
+
+        if (yShifts.length != timestamps.length) {
+            throw new AssertionError(String.format(
+                    "timestamps has %d entries but yShifts has %d", timestamps.length,
+                    yShifts.length));
+        }
+
+        OisSample[] samples = new OisSample[timestamps.length];
+        for (int i = 0; i < timestamps.length; i++) {
+            samples[i] = new OisSample(timestamps[i], xShifts[i], yShifts[i]);
+        }
+        return samples;
+    }
+
     private <T> void setBase(CameraCharacteristics.Key<T> key, T value) {
         setBase(key.getNativeKey(), value);
     }
diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
index e7f2134..71a361b 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
@@ -730,7 +730,7 @@
         LegacyExceptionUtils.throwOnError(nativeSetSurfaceDimens(surface, width, height));
     }
 
-    static long getSurfaceId(Surface surface) throws BufferQueueAbandonedException {
+    public static long getSurfaceId(Surface surface) throws BufferQueueAbandonedException {
         checkNotNull(surface);
         try {
             return nativeGetSurfaceId(surface);
diff --git a/core/java/android/hardware/camera2/params/OisSample.java b/core/java/android/hardware/camera2/params/OisSample.java
new file mode 100644
index 0000000..7ebaae3
--- /dev/null
+++ b/core/java/android/hardware/camera2/params/OisSample.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hardware.camera2.params;
+
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.utils.HashCodeHelpers;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * Immutable class to store an
+ * {@link CaptureResult#STATISTICS_OIS_SAMPLES optical image stabilization sample}.
+ */
+public final class OisSample {
+    /**
+     * Create a new {@link OisSample}.
+     *
+     * <p>{@link OisSample} contains the timestamp and the amount of shifts in x and y direction,
+     * in pixels, of the OIS sample.
+     *
+     * <p>A positive value for a shift in x direction is a shift from left to right in active array
+     * coordinate system. For example, if the optical center is {@code (1000, 500)} in active array
+     * coordinates, a shift of {@code (3, 0)} puts the new optical center at {@code (1003, 500)}.
+     * </p>
+     *
+     * <p>A positive value for a shift in y direction is a shift from top to bottom in active array
+     * coordinate system. For example, if the optical center is {@code (1000, 500)} in active array
+     * coordinates, a shift of {@code (0, 5)} puts the new optical center at {@code (1000, 505)}.
+     * </p>
+     *
+     * <p>xShift and yShift must be finite; NaN and infinity is not allowed.</p>
+     *
+     * @param timestamp timestamp of the OIS sample.
+     * @param xShift shift of the OIS sample in x direction.
+     * @param yShift shift of the OIS sample in y direction.
+     *
+     * @throws IllegalArgumentException if xShift or yShift is not finite
+     */
+    public OisSample(final long timestamp, final float xShift, final float yShift) {
+        mTimestampNs = timestamp;
+        mXShift = Preconditions.checkArgumentFinite(xShift, "xShift must be finite");
+        mYShift = Preconditions.checkArgumentFinite(yShift, "yShift must be finite");
+    }
+
+    /**
+     * Get the timestamp in nanoseconds.
+     *
+     *<p>The timestamps are in the same timebase as and comparable to
+     *{@link CaptureResult#SENSOR_TIMESTAMP android.sensor.timestamp}.</p>
+     *
+     * @return a long value (guaranteed to be finite)
+     */
+    public long getTimestamp() {
+        return mTimestampNs;
+    }
+
+    /**
+     * Get the shift in x direction.
+     *
+     * @return a floating point value (guaranteed to be finite)
+     */
+    public float getXshift() {
+        return mXShift;
+    }
+
+    /**
+     * Get the shift in y direction.
+     *
+     * @return a floating point value (guaranteed to be finite)
+     */
+    public float getYshift() {
+        return mYShift;
+    }
+
+    /**
+     * Check if this {@link OisSample} is equal to another {@link OisSample}.
+     *
+     * <p>Two samples are only equal if and only if each of the OIS information is equal.</p>
+     *
+     * @return {@code true} if the objects were equal, {@code false} otherwise
+     */
+    @Override
+    public boolean equals(final Object obj) {
+        if (obj == null) {
+            return false;
+        } else if (this == obj) {
+            return true;
+        } else if (obj instanceof OisSample) {
+            final OisSample other = (OisSample) obj;
+            return mTimestampNs == other.mTimestampNs
+                    && mXShift == other.mXShift
+                    && mYShift == other.mYShift;
+        }
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode() {
+        int timestampHash = HashCodeHelpers.hashCode(mTimestampNs);
+        return HashCodeHelpers.hashCode(mXShift, mYShift, timestampHash);
+    }
+
+    /**
+     * Return the OisSample as a string representation.
+     *
+     * <p> {@code "OisSample{timestamp:%l, shift_x:%f, shift_y:%f}"} represents the OIS sample's
+     * timestamp, shift in x direction, and shift in y direction.</p>
+     *
+     * @return string representation of {@link OisSample}
+     */
+    @Override
+    public String toString() {
+        return String.format("OisSample{timestamp:%d, shift_x:%f, shift_y:%f}", mTimestampNs,
+                mXShift, mYShift);
+    }
+
+    private final long mTimestampNs;
+    private final float mXShift;
+    private final float mYShift;
+}
diff --git a/core/java/android/hardware/camera2/utils/SurfaceUtils.java b/core/java/android/hardware/camera2/utils/SurfaceUtils.java
index e1e1c4f..9247844 100644
--- a/core/java/android/hardware/camera2/utils/SurfaceUtils.java
+++ b/core/java/android/hardware/camera2/utils/SurfaceUtils.java
@@ -56,6 +56,20 @@
     }
 
     /**
+     * Get the native object id of a surface.
+     *
+     * @param surface The surface to be checked.
+     * @return the native object id of the surface, 0 if surface is not backed by a native object.
+     */
+    public static long getSurfaceId(Surface surface) {
+        try {
+            return LegacyCameraDevice.getSurfaceId(surface);
+        } catch (BufferQueueAbandonedException e) {
+            return 0;
+        }
+    }
+
+    /**
      * Get the Surface size.
      *
      * @param surface The surface to be queried for size.
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 6b2059e..36d5615 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -615,6 +615,7 @@
      * @hide
      */
     @SystemApi
+    @TestApi
     public Point getStableDisplaySize() {
         return mGlobal.getStableDisplaySize();
     }
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index bd54522..8048099c 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -108,7 +108,9 @@
     /**
      * A wrapper class for the crypto objects supported by FingerprintManager. Currently the
      * framework supports {@link Signature}, {@link Cipher} and {@link Mac} objects.
+     * @deprecated See {@link android.hardware.fingerprint.FingerprintDialog.CryptoObject}
      */
+    @Deprecated
     public static final class CryptoObject extends android.hardware.biometrics.CryptoObject {
         public CryptoObject(@NonNull Signature signature) {
             super(signature);
@@ -150,7 +152,9 @@
     /**
      * Container for callback data from {@link FingerprintManager#authenticate(CryptoObject,
      *     CancellationSignal, int, AuthenticationCallback, Handler)}.
+     * @deprecated See {@link android.hardware.fingerprint.FingerprintDialog.AuthenticationResult}
      */
+    @Deprecated
     public static class AuthenticationResult {
         private Fingerprint mFingerprint;
         private CryptoObject mCryptoObject;
@@ -197,7 +201,9 @@
      * FingerprintManager#authenticate(CryptoObject, CancellationSignal,
      * int, AuthenticationCallback, Handler) } must provide an implementation of this for listening to
      * fingerprint events.
+     * @deprecated See {@link android.hardware.fingerprint.FingerprintDialog.AuthenticationCallback}
      */
+    @Deprecated
     public static abstract class AuthenticationCallback
             extends BiometricAuthenticator.AuthenticationCallback {
         /**
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index 74a36df..572c585 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -454,8 +454,12 @@
     /**
      * Opens a file descriptor for reading and writing data to the USB accessory.
      *
+     * <p>If data is read from the {@link java.io.InputStream} created from this file descriptor all
+     * data of a USB transfer should be read at once. If only a partial request is read the rest of
+     * the transfer is dropped.
+     *
      * @param accessory the USB accessory to open
-     * @return file descriptor, or null if the accessor could not be opened.
+     * @return file descriptor, or null if the accessory could not be opened.
      */
     @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY)
     public ParcelFileDescriptor openAccessory(UsbAccessory accessory) {
diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl
index 90e3ffd..381cfb6 100644
--- a/core/java/android/net/INetworkStatsService.aidl
+++ b/core/java/android/net/INetworkStatsService.aidl
@@ -39,9 +39,6 @@
      */
     INetworkStatsSession openSessionForUsageStats(int flags, String callingPackage);
 
-    /** Return network layer usage total for traffic that matches template. */
-    long getNetworkTotalBytes(in NetworkTemplate template, long start, long end);
-
     /** Return data layer snapshot of UID network usage. */
     NetworkStats getDataLayerSnapshotForUid(int uid);
     /** Return set of any ifaces associated with mobile networks since boot. */
@@ -50,17 +47,11 @@
     /** Increment data layer count of operations performed for UID and tag. */
     void incrementOperationCount(int uid, int tag, int operationCount);
 
-    /** Mark given UID as being in foreground for stats purposes. */
-    void setUidForeground(int uid, boolean uidForeground);
-
     /** Force update of ifaces. */
     void forceUpdateIfaces(in Network[] defaultNetworks);
     /** Force update of statistics. */
     void forceUpdate();
 
-    /** Advise persistance threshold; may be overridden internally. */
-    void advisePersistThreshold(long thresholdBytes);
-
     /** Registers a callback on data usage. */
     DataUsageRequest registerUsageCallback(String callingPackage,
             in DataUsageRequest request, in Messenger messenger, in IBinder binder);
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index bae373d..74b52c9 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -117,6 +117,7 @@
             NET_CAPABILITY_FOREGROUND,
             NET_CAPABILITY_NOT_CONGESTED,
             NET_CAPABILITY_NOT_SUSPENDED,
+            NET_CAPABILITY_OEM_PAID,
     })
     public @interface NetCapability { }
 
@@ -264,8 +265,15 @@
      */
     public static final int NET_CAPABILITY_NOT_SUSPENDED = 21;
 
+    /**
+     * Indicates that traffic that goes through this network is paid by oem. For example,
+     * this network can be used by system apps to upload telemetry data.
+     * @hide
+     */
+    public static final int NET_CAPABILITY_OEM_PAID = 22;
+
     private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
-    private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_NOT_SUSPENDED;
+    private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_OEM_PAID;
 
     /**
      * Network capabilities that are expected to be mutable, i.e., can change while a particular
@@ -313,7 +321,8 @@
             (1 << NET_CAPABILITY_IA) |
             (1 << NET_CAPABILITY_IMS) |
             (1 << NET_CAPABILITY_RCS) |
-            (1 << NET_CAPABILITY_XCAP);
+            (1 << NET_CAPABILITY_XCAP) |
+            (1 << NET_CAPABILITY_OEM_PAID);
 
     /**
      * Capabilities that suggest that a network is unrestricted.
@@ -1218,34 +1227,68 @@
 
     @Override
     public String toString() {
-        // TODO: enumerate bits for transports and capabilities instead of creating arrays.
-        // TODO: use a StringBuilder instead of string concatenation.
-        int[] types = getTransportTypes();
-        String transports = (types.length > 0) ? " Transports: " + transportNamesOf(types) : "";
-
-        types = getCapabilities();
-        String capabilities = (types.length > 0 ? " Capabilities: " : "");
-        for (int i = 0; i < types.length; ) {
-            capabilities += capabilityNameOf(types[i]);
-            if (++i < types.length) capabilities += "&";
+        final StringBuilder sb = new StringBuilder("[");
+        if (0 != mTransportTypes) {
+            sb.append(" Transports: ");
+            appendStringRepresentationOfBitMaskToStringBuilder(sb, mTransportTypes,
+                    NetworkCapabilities::transportNameOf, "|");
+        }
+        if (0 != mNetworkCapabilities) {
+            sb.append(" Capabilities: ");
+            appendStringRepresentationOfBitMaskToStringBuilder(sb, mNetworkCapabilities,
+                    NetworkCapabilities::capabilityNameOf, "&");
+        }
+        if (mLinkUpBandwidthKbps > 0) {
+            sb.append(" LinkUpBandwidth>=").append(mLinkUpBandwidthKbps).append("Kbps");
+        }
+        if (mLinkDownBandwidthKbps > 0) {
+            sb.append(" LinkDnBandwidth>=").append(mLinkDownBandwidthKbps).append("Kbps");
+        }
+        if (mNetworkSpecifier != null) {
+            sb.append(" Specifier: <").append(mNetworkSpecifier).append(">");
+        }
+        if (hasSignalStrength()) {
+            sb.append(" SignalStrength: ").append(mSignalStrength);
         }
 
-        String upBand = ((mLinkUpBandwidthKbps > 0) ? " LinkUpBandwidth>=" +
-                mLinkUpBandwidthKbps + "Kbps" : "");
-        String dnBand = ((mLinkDownBandwidthKbps > 0) ? " LinkDnBandwidth>=" +
-                mLinkDownBandwidthKbps + "Kbps" : "");
+        if (null != mUids) {
+            if ((1 == mUids.size()) && (mUids.valueAt(0).count() == 1)) {
+                sb.append(" Uid: ").append(mUids.valueAt(0).start);
+            } else {
+                sb.append(" Uids: <").append(mUids).append(">");
+            }
+        }
+        if (mEstablishingVpnAppUid != INVALID_UID) {
+            sb.append(" EstablishingAppUid: ").append(mEstablishingVpnAppUid);
+        }
 
-        String specifier = (mNetworkSpecifier == null ?
-                "" : " Specifier: <" + mNetworkSpecifier + ">");
+        sb.append("]");
+        return sb.toString();
+    }
 
-        String signalStrength = (hasSignalStrength() ? " SignalStrength: " + mSignalStrength : "");
 
-        String uids = (null != mUids ? " Uids: <" + mUids + ">" : "");
-
-        String establishingAppUid = " EstablishingAppUid: " + mEstablishingVpnAppUid;
-
-        return "[" + transports + capabilities + upBand + dnBand + specifier + signalStrength
-            + uids + establishingAppUid + "]";
+    private interface NameOf {
+        String nameOf(int value);
+    }
+    /**
+     * @hide
+     */
+    public static void appendStringRepresentationOfBitMaskToStringBuilder(StringBuilder sb,
+            long bitMask, NameOf nameFetcher, String separator) {
+        int bitPos = 0;
+        boolean firstElementAdded = false;
+        while (bitMask != 0) {
+            if ((bitMask & 1) != 0) {
+                if (firstElementAdded) {
+                    sb.append(separator);
+                } else {
+                    firstElementAdded = true;
+                }
+                sb.append(nameFetcher.nameOf(bitPos));
+            }
+            bitMask >>= 1;
+            ++bitPos;
+        }
     }
 
     /** @hide */
@@ -1313,6 +1356,7 @@
             case NET_CAPABILITY_FOREGROUND:     return "FOREGROUND";
             case NET_CAPABILITY_NOT_CONGESTED:  return "NOT_CONGESTED";
             case NET_CAPABILITY_NOT_SUSPENDED:  return "NOT_SUSPENDED";
+            case NET_CAPABILITY_OEM_PAID:       return "OEM_PAID";
             default:                            return Integer.toString(capability);
         }
     }
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index 01b2b39..16fb858 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -234,7 +234,7 @@
     public NetworkStats(long elapsedRealtime, int initialSize) {
         this.elapsedRealtime = elapsedRealtime;
         this.size = 0;
-        if (initialSize >= 0) {
+        if (initialSize > 0) {
             this.capacity = initialSize;
             this.iface = new String[initialSize];
             this.uid = new int[initialSize];
@@ -250,19 +250,7 @@
             this.operations = new long[initialSize];
         } else {
             // Special case for use by NetworkStatsFactory to start out *really* empty.
-            this.capacity = 0;
-            this.iface = EmptyArray.STRING;
-            this.uid = EmptyArray.INT;
-            this.set = EmptyArray.INT;
-            this.tag = EmptyArray.INT;
-            this.metered = EmptyArray.INT;
-            this.roaming = EmptyArray.INT;
-            this.defaultNetwork = EmptyArray.INT;
-            this.rxBytes = EmptyArray.LONG;
-            this.rxPackets = EmptyArray.LONG;
-            this.txBytes = EmptyArray.LONG;
-            this.txPackets = EmptyArray.LONG;
-            this.operations = EmptyArray.LONG;
+            clear();
         }
     }
 
@@ -314,6 +302,25 @@
         return clone;
     }
 
+    /**
+     * Clear all data stored in this object.
+     */
+    public void clear() {
+        this.capacity = 0;
+        this.iface = EmptyArray.STRING;
+        this.uid = EmptyArray.INT;
+        this.set = EmptyArray.INT;
+        this.tag = EmptyArray.INT;
+        this.metered = EmptyArray.INT;
+        this.roaming = EmptyArray.INT;
+        this.defaultNetwork = EmptyArray.INT;
+        this.rxBytes = EmptyArray.LONG;
+        this.rxPackets = EmptyArray.LONG;
+        this.txBytes = EmptyArray.LONG;
+        this.txPackets = EmptyArray.LONG;
+        this.operations = EmptyArray.LONG;
+    }
+
     @VisibleForTesting
     public NetworkStats addIfaceValues(
             String iface, long rxBytes, long rxPackets, long txBytes, long txPackets) {
diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java
index 433f941..a13ad65 100644
--- a/core/java/android/net/NetworkStatsHistory.java
+++ b/core/java/android/net/NetworkStatsHistory.java
@@ -39,6 +39,8 @@
 
 import com.android.internal.util.IndentingPrintWriter;
 
+import libcore.util.EmptyArray;
+
 import java.io.CharArrayWriter;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
@@ -459,6 +461,21 @@
     }
 
     /**
+     * Clear all data stored in this object.
+     */
+    public void clear() {
+        bucketStart = EmptyArray.LONG;
+        if (activeTime != null) activeTime = EmptyArray.LONG;
+        if (rxBytes != null) rxBytes = EmptyArray.LONG;
+        if (rxPackets != null) rxPackets = EmptyArray.LONG;
+        if (txBytes != null) txBytes = EmptyArray.LONG;
+        if (txPackets != null) txPackets = EmptyArray.LONG;
+        if (operations != null) operations = EmptyArray.LONG;
+        bucketCount = 0;
+        totalBytes = 0;
+    }
+
+    /**
      * Remove buckets older than requested cutoff.
      */
     @Deprecated
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index 8efd39a..74233fd 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -23,7 +23,6 @@
 import static android.net.ConnectivityManager.TYPE_WIFI;
 import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
 import static android.net.ConnectivityManager.TYPE_WIMAX;
-import static android.net.NetworkIdentity.COMBINE_SUBTYPE_ENABLED;
 import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
 import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
 import static android.net.NetworkStats.DEFAULT_NETWORK_YES;
@@ -34,11 +33,6 @@
 import static android.net.NetworkStats.ROAMING_NO;
 import static android.net.NetworkStats.ROAMING_YES;
 import static android.net.wifi.WifiInfo.removeDoubleQuotes;
-import static android.telephony.TelephonyManager.NETWORK_CLASS_2_G;
-import static android.telephony.TelephonyManager.NETWORK_CLASS_3_G;
-import static android.telephony.TelephonyManager.NETWORK_CLASS_4_G;
-import static android.telephony.TelephonyManager.NETWORK_CLASS_UNKNOWN;
-import static android.telephony.TelephonyManager.getNetworkClass;
 
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -55,8 +49,8 @@
 import java.util.Objects;
 
 /**
- * Template definition used to generically match {@link NetworkIdentity},
- * usually when collecting statistics.
+ * Predicate used to match {@link NetworkIdentity}, usually when collecting
+ * statistics. (It should probably have been named {@code NetworkPredicate}.)
  *
  * @hide
  */
@@ -68,13 +62,7 @@
      */
     private static final int BACKUP_VERSION = 1;
 
-    public static final int MATCH_MOBILE_ALL = 1;
-    /** @deprecated don't use this any more */
-    @Deprecated
-    public static final int MATCH_MOBILE_3G_LOWER = 2;
-    /** @deprecated don't use this any more */
-    @Deprecated
-    public static final int MATCH_MOBILE_4G = 3;
+    public static final int MATCH_MOBILE = 1;
     public static final int MATCH_WIFI = 4;
     public static final int MATCH_ETHERNET = 5;
     public static final int MATCH_MOBILE_WILDCARD = 6;
@@ -84,9 +72,7 @@
 
     private static boolean isKnownMatchRule(final int rule) {
         switch (rule) {
-            case MATCH_MOBILE_ALL:
-            case MATCH_MOBILE_3G_LOWER:
-            case MATCH_MOBILE_4G:
+            case MATCH_MOBILE:
             case MATCH_WIFI:
             case MATCH_ETHERNET:
             case MATCH_MOBILE_WILDCARD:
@@ -111,25 +97,7 @@
      * the given IMSI.
      */
     public static NetworkTemplate buildTemplateMobileAll(String subscriberId) {
-        return new NetworkTemplate(MATCH_MOBILE_ALL, subscriberId, null);
-    }
-
-    /**
-     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
-     * the given IMSI that roughly meet a "3G" definition, or lower.
-     */
-    @Deprecated
-    public static NetworkTemplate buildTemplateMobile3gLower(String subscriberId) {
-        return new NetworkTemplate(MATCH_MOBILE_3G_LOWER, subscriberId, null);
-    }
-
-    /**
-     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
-     * the given IMSI that roughly meet a "4G" definition.
-     */
-    @Deprecated
-    public static NetworkTemplate buildTemplateMobile4g(String subscriberId) {
-        return new NetworkTemplate(MATCH_MOBILE_4G, subscriberId, null);
+        return new NetworkTemplate(MATCH_MOBILE, subscriberId, null);
     }
 
     /**
@@ -307,9 +275,7 @@
 
     public boolean isMatchRuleMobile() {
         switch (mMatchRule) {
-            case MATCH_MOBILE_3G_LOWER:
-            case MATCH_MOBILE_4G:
-            case MATCH_MOBILE_ALL:
+            case MATCH_MOBILE:
             case MATCH_MOBILE_WILDCARD:
                 return true;
             default:
@@ -348,12 +314,8 @@
         if (!matchesDefaultNetwork(ident)) return false;
 
         switch (mMatchRule) {
-            case MATCH_MOBILE_ALL:
+            case MATCH_MOBILE:
                 return matchesMobile(ident);
-            case MATCH_MOBILE_3G_LOWER:
-                return matchesMobile3gLower(ident);
-            case MATCH_MOBILE_4G:
-                return matchesMobile4g(ident);
             case MATCH_WIFI:
                 return matchesWifi(ident);
             case MATCH_ETHERNET:
@@ -410,43 +372,6 @@
     }
 
     /**
-     * Check if mobile network classified 3G or lower with matching IMSI.
-     */
-    @Deprecated
-    private boolean matchesMobile3gLower(NetworkIdentity ident) {
-        ensureSubtypeAvailable();
-        if (ident.mType == TYPE_WIMAX) {
-            return false;
-        } else if (matchesMobile(ident)) {
-            switch (getNetworkClass(ident.mSubType)) {
-                case NETWORK_CLASS_UNKNOWN:
-                case NETWORK_CLASS_2_G:
-                case NETWORK_CLASS_3_G:
-                    return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Check if mobile network classified 4G with matching IMSI.
-     */
-    @Deprecated
-    private boolean matchesMobile4g(NetworkIdentity ident) {
-        ensureSubtypeAvailable();
-        if (ident.mType == TYPE_WIMAX) {
-            // TODO: consider matching against WiMAX subscriber identity
-            return true;
-        } else if (matchesMobile(ident)) {
-            switch (getNetworkClass(ident.mSubType)) {
-                case NETWORK_CLASS_4_G:
-                    return true;
-            }
-        }
-        return false;
-    }
-
-    /**
      * Check if matches Wi-Fi network template.
      */
     private boolean matchesWifi(NetworkIdentity ident) {
@@ -506,12 +431,8 @@
 
     private static String getMatchRuleName(int matchRule) {
         switch (matchRule) {
-            case MATCH_MOBILE_3G_LOWER:
-                return "MOBILE_3G_LOWER";
-            case MATCH_MOBILE_4G:
-                return "MOBILE_4G";
-            case MATCH_MOBILE_ALL:
-                return "MOBILE_ALL";
+            case MATCH_MOBILE:
+                return "MOBILE";
             case MATCH_WIFI:
                 return "WIFI";
             case MATCH_ETHERNET:
@@ -529,13 +450,6 @@
         }
     }
 
-    private static void ensureSubtypeAvailable() {
-        if (COMBINE_SUBTYPE_ENABLED) {
-            throw new IllegalArgumentException(
-                    "Unable to enforce 3G_LOWER template on combined data.");
-        }
-    }
-
     /**
      * Examine the given template and normalize if it refers to a "merged"
      * mobile subscriber. We pick the "lowest" merged subscriber as the primary
diff --git a/core/java/android/net/UidRange.java b/core/java/android/net/UidRange.java
index fd465d9..3164929 100644
--- a/core/java/android/net/UidRange.java
+++ b/core/java/android/net/UidRange.java
@@ -21,8 +21,6 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
-import java.lang.IllegalArgumentException;
-
 /**
  * An inclusive range of UIDs.
  *
@@ -53,6 +51,13 @@
     }
 
     /**
+     * Returns the count of UIDs in this range.
+     */
+    public int count() {
+        return 1 + stop - start;
+    }
+
+    /**
      * @return {@code true} if this range contains every UID contained by the {@param other} range.
      */
     public boolean containsRange(UidRange other) {
diff --git a/core/java/android/net/metrics/NetworkMetrics.java b/core/java/android/net/metrics/NetworkMetrics.java
index 2425bba..66d92c4 100644
--- a/core/java/android/net/metrics/NetworkMetrics.java
+++ b/core/java/android/net/metrics/NetworkMetrics.java
@@ -98,6 +98,9 @@
 
     /** Accumulate a single netd sock_diag poll result reported by netd. */
     public void addTcpStatsResult(int sent, int lost, int rttUs, int sentAckDiffMs) {
+        if (pendingSummary == null) {
+            pendingSummary = new Summary(netId, transports);
+        }
         pendingSummary.tcpLossRate.count(lost, sent);
         pendingSummary.roundTripTimeUs.count(rttUs);
         pendingSummary.sentAckTimeDiffenceMs.count(sentAckDiffMs);
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 6ecf6d5..5e9d39c 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -240,8 +240,11 @@
      * New in version 30:
      *   - Uid.PROCESS_STATE_FOREGROUND_SERVICE only tracks
      *   ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE.
+     * New in version 31:
+     *   - New cellular network types.
+     *   - Deferred job metrics.
      */
-    static final int CHECKIN_VERSION = 30;
+    static final int CHECKIN_VERSION = 31;
 
     /**
      * Old version, we hit 9 and ran out of room, need to remove.
@@ -444,6 +447,11 @@
          */
         public abstract LongCounter getScanTimeCounter();
 
+        /**
+         * @return a non-null {@link LongCounter} representing time spent (milliseconds) in the
+         * sleep state.
+         */
+        public abstract LongCounter getSleepTimeCounter();
 
         /**
          * @return a non-null {@link LongCounter} representing time spent (milliseconds) in the
@@ -3405,8 +3413,6 @@
         for (LongCounter txState : counter.getTxTimeCounters()) {
             totalTxTimeMs += txState.getCountLocked(which);
         }
-        final long sleepTimeMs
-            = totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + totalTxTimeMs);
 
         if (controllerName.equals(WIFI_CONTROLLER_NAME)) {
             final long scanTimeMs = counter.getScanTimeCounter().getCountLocked(which);
@@ -3420,18 +3426,34 @@
             sb.append(formatRatioLocked(scanTimeMs, totalControllerActivityTimeMs));
             sb.append(")");
             pw.println(sb.toString());
+
+            final long sleepTimeMs
+                = totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + totalTxTimeMs);
+            sb.setLength(0);
+            sb.append(prefix);
+            sb.append("     ");
+            sb.append(controllerName);
+            sb.append(" Sleep time:  ");
+            formatTimeMs(sb, sleepTimeMs);
+            sb.append("(");
+            sb.append(formatRatioLocked(sleepTimeMs, totalControllerActivityTimeMs));
+            sb.append(")");
+            pw.println(sb.toString());
         }
 
-        sb.setLength(0);
-        sb.append(prefix);
-        sb.append("     ");
-        sb.append(controllerName);
-        sb.append(" Sleep time:  ");
-        formatTimeMs(sb, sleepTimeMs);
-        sb.append("(");
-        sb.append(formatRatioLocked(sleepTimeMs, totalControllerActivityTimeMs));
-        sb.append(")");
-        pw.println(sb.toString());
+        if (controllerName.equals(CELLULAR_CONTROLLER_NAME)) {
+            final long sleepTimeMs = counter.getSleepTimeCounter().getCountLocked(which);
+            sb.setLength(0);
+            sb.append(prefix);
+            sb.append("     ");
+            sb.append(controllerName);
+            sb.append(" Sleep time:  ");
+            formatTimeMs(sb, sleepTimeMs);
+            sb.append("(");
+            sb.append(formatRatioLocked(sleepTimeMs, totalControllerActivityTimeMs));
+            sb.append(")");
+            pw.println(sb.toString());
+        }
 
         sb.setLength(0);
         sb.append(prefix);
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 48f5684..6d8831b 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -19,6 +19,7 @@
 import android.Manifest;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.app.Application;
 import android.content.Context;
 import android.text.TextUtils;
@@ -287,6 +288,7 @@
          * we are operating under, we bump the assumed resource platform version by 1.
          * @hide
          */
+        @TestApi
         public static final int RESOURCES_SDK_INT = SDK_INT + ACTIVE_CODENAMES.length;
 
         /**
diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java
index fc88e90..0417ded 100644
--- a/core/java/android/os/Handler.java
+++ b/core/java/android/os/Handler.java
@@ -683,6 +683,23 @@
         return enqueueMessage(queue, msg, 0);
     }
 
+    /**
+     * Executes the message synchronously if called on the same thread this handler corresponds to,
+     * or {@link #sendMessage pushes it to the queue} otherwise
+     *
+     * @return Returns true if the message was successfully ran or placed in to the
+     *         message queue.  Returns false on failure, usually because the
+     *         looper processing the message queue is exiting.
+     * @hide
+     */
+    public final boolean executeOrSendMessage(Message msg) {
+        if (mLooper == Looper.myLooper()) {
+            dispatchMessage(msg);
+            return true;
+        }
+        return sendMessage(msg);
+    }
+
     private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
         msg.target = this;
         if (mAsynchronous) {
diff --git a/core/java/android/os/HardwarePropertiesManager.java b/core/java/android/os/HardwarePropertiesManager.java
index eae7d70..3d072c5 100644
--- a/core/java/android/os/HardwarePropertiesManager.java
+++ b/core/java/android/os/HardwarePropertiesManager.java
@@ -63,6 +63,8 @@
     /**
      * Device temperature types.
      */
+    // These constants are also defined in android/os/enums.proto.
+    // Any change to the types here or in the thermal hal should be made in the proto as well.
     /** Temperature of CPUs in Celsius. */
     public static final int DEVICE_TEMPERATURE_CPU = Constants.TemperatureType.CPU;
 
diff --git a/core/java/android/os/IStatsCompanionService.aidl b/core/java/android/os/IStatsCompanionService.aidl
index eae5217..29c298e 100644
--- a/core/java/android/os/IStatsCompanionService.aidl
+++ b/core/java/android/os/IStatsCompanionService.aidl
@@ -41,7 +41,7 @@
     oneway void cancelAnomalyAlarm();
 
     /**
-      * Register a repeating alarm for polling to fire at the given timestamp and every
+      * Register a repeating alarm for pulling to fire at the given timestamp and every
       * intervalMs thereafter (in ms since epoch).
       * If polling alarm had already been registered, it will be replaced by new one.
       * Uses AlarmManager.setRepeating API, so if the timestamp is in past, alarm fires immediately,
@@ -49,9 +49,19 @@
       */
     oneway void setPullingAlarms(long timestampMs, long intervalMs);
 
-    /** Cancel any repeating polling alarm. */
+    /** Cancel any repeating pulling alarm. */
     oneway void cancelPullingAlarms();
 
+    /**
+      * Register an alarm when we want to trigger subscribers at the given
+      * timestamp (in ms since epoch).
+      * If an alarm had already been registered, it will be replaced by new one.
+      */
+    oneway void setAlarmForSubscriberTriggering(long timestampMs);
+
+    /** Cancel any alarm for the purpose of subscriber triggering. */
+    oneway void cancelAlarmForSubscriberTriggering();
+
     /** Pull the specified data. Results will be sent to statsd when complete. */
     StatsLogEventWrapper[] pullData(int pullCode);
 
diff --git a/core/java/android/os/IStatsManager.aidl b/core/java/android/os/IStatsManager.aidl
index 682a24f1..2a68714 100644
--- a/core/java/android/os/IStatsManager.aidl
+++ b/core/java/android/os/IStatsManager.aidl
@@ -47,6 +47,13 @@
     void informPollAlarmFired();
 
     /**
+     * Tells statsd that it is time to handle periodic alarms. Statsd will be responsible for
+     * determing what alarm subscriber to trigger.
+     * Two-way binder call so that caller's method (and corresponding wakelocks) will linger.
+     */
+    void informAlarmForSubscriberTriggeringFired();
+
+    /**
      * Tells statsd to store data to disk.
      */
     void writeDataToDisk();
diff --git a/core/java/android/os/LocaleList.java b/core/java/android/os/LocaleList.java
index ca9cbec..87e1b7d 100644
--- a/core/java/android/os/LocaleList.java
+++ b/core/java/android/os/LocaleList.java
@@ -20,7 +20,9 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.Size;
+import android.content.LocaleProto;
 import android.icu.util.ULocale;
+import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.GuardedBy;
 
@@ -140,6 +142,25 @@
     }
 
     /**
+     * Helper to write LocaleList to a protocol buffer output stream.  Assumes the parent
+     * protobuf has declared the locale as repeated.
+     *
+     * @param protoOutputStream Stream to write the locale to.
+     * @param fieldId Field Id of the Locale as defined in the parent message.
+     * @hide
+     */
+    public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId) {
+        for (int i = 0; i < mList.length; i++) {
+            final Locale locale = mList[i];
+            final long token = protoOutputStream.start(fieldId);
+            protoOutputStream.write(LocaleProto.LANGUAGE, locale.getLanguage());
+            protoOutputStream.write(LocaleProto.COUNTRY, locale.getCountry());
+            protoOutputStream.write(LocaleProto.VARIANT, locale.getVariant());
+            protoOutputStream.end(token);
+        }
+    }
+
+    /**
      * Retrieves a String representation of the language tags in this list.
      */
     @NonNull
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 811cc5e..97d415e 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -538,6 +538,7 @@
             ServiceType.DATA_SAVER,
             ServiceType.FORCE_ALL_APPS_STANDBY,
             ServiceType.OPTIONAL_SENSORS,
+            ServiceType.AOD,
     })
     public @interface ServiceType {
         int NULL = 0;
@@ -551,6 +552,7 @@
         int SOUND = 8;
         int BATTERY_STATS = 9;
         int DATA_SAVER = 10;
+        int AOD = 14;
 
         /**
          * Whether to enable force-app-standby on all apps or not.
diff --git a/core/java/android/os/StatsLogEventWrapper.java b/core/java/android/os/StatsLogEventWrapper.java
index 3e8161f..d4d3dc8 100644
--- a/core/java/android/os/StatsLogEventWrapper.java
+++ b/core/java/android/os/StatsLogEventWrapper.java
@@ -46,16 +46,17 @@
      * @param tag    The integer representing the tag for this event.
      * @param fields The number of fields specified in this event.
      */
-    public StatsLogEventWrapper(int tag, int fields) {
+    public StatsLogEventWrapper(long elapsedNanos, int tag, int fields) {
         // Write four bytes from tag, starting with least-significant bit.
         // For pulled data, this tag number is not really used. We use the same tag number as
         // pushed ones to be consistent.
         write4Bytes(STATS_BUFFER_TAG_ID);
         mStorage.write(EVENT_TYPE_LIST); // This is required to start the log entry.
-        mStorage.write(fields + 1); // Indicate number of elements in this list. +1 for the tag
-        mStorage.write(EVENT_TYPE_INT);
-        // The first element is the real atom tag number
-        write4Bytes(tag);
+        mStorage.write(fields + 2); // Indicate number of elements in this list. +1 for the tag
+        // The first element is the elapsed realtime.
+        writeLong(elapsedNanos);
+        // The second element is the real atom tag number
+        writeInt(tag);
     }
 
     /**
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index f90604a..76c13be 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -636,7 +636,7 @@
              * executor every violation.
              */
             public Builder penaltyListener(
-                    @NonNull OnThreadViolationListener listener, @NonNull Executor executor) {
+                    @NonNull Executor executor, @NonNull OnThreadViolationListener listener) {
                 if (executor == null) {
                     throw new NullPointerException("executor must not be null");
                 }
@@ -645,6 +645,12 @@
                 return this;
             }
 
+            /** @removed */
+            public Builder penaltyListener(
+                    @NonNull OnThreadViolationListener listener, @NonNull Executor executor) {
+                return penaltyListener(executor, listener);
+            }
+
             private Builder enable(int bit) {
                 mMask |= bit;
                 return this;
@@ -971,7 +977,7 @@
              * Call #{@link OnVmViolationListener#onVmViolation(Violation)} on every violation.
              */
             public Builder penaltyListener(
-                    @NonNull OnVmViolationListener listener, @NonNull Executor executor) {
+                    @NonNull Executor executor, @NonNull OnVmViolationListener listener) {
                 if (executor == null) {
                     throw new NullPointerException("executor must not be null");
                 }
@@ -980,6 +986,12 @@
                 return this;
             }
 
+            /** @removed */
+            public Builder penaltyListener(
+                    @NonNull OnVmViolationListener listener, @NonNull Executor executor) {
+                return penaltyListener(executor, listener);
+            }
+
             private Builder enable(int bit) {
                 mMask |= bit;
                 return this;
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 1856200..a9eb360 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -36,6 +36,7 @@
 import android.content.IntentFilter;
 import android.content.IntentSender;
 import android.content.pm.UserInfo;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -691,14 +692,13 @@
     /**
      * Specifies that system error dialogs for crashed or unresponsive apps should not be shown.
      * In this case, the system will force-stop the app as if the user chooses the "close app"
-     * option on the UI. No feedback report will be collected as there is no way for the user to
-     * provide explicit consent.
+     * option on the UI. A feedback report isn't collected as there is no way for the user to
+     * provide explicit consent. The default value is <code>false</code>.
      *
-     * When this user restriction is set by device owners, it's applied to all users; when it's set
-     * by profile owners, it's only applied to the relevant profiles.
-     * The default value is <code>false</code>.
+     * <p>When this user restriction is set by device owners, it's applied to all users. When set by
+     * the profile owner of the primary user or a secondary user, the restriction affects only the
+     * calling user. This user restriction has no effect on managed profiles.
      *
-     * <p>This user restriction has no effect on managed profiles.
      * <p>Key for user restrictions.
      * <p>Type: Boolean
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -913,6 +913,9 @@
      * Specifies if user switching is blocked on the current user.
      *
      * <p> This restriction can only be set by the device owner, it will be applied to all users.
+     * Device owner can still switch user via
+     * {@link DevicePolicyManager#switchUser(ComponentName, UserHandle)} when this restriction is
+     * set.
      *
      * <p>The default value is <code>false</code>.
      *
@@ -1039,6 +1042,85 @@
      */
     public static final int USER_CREATION_FAILED_NO_MORE_USERS = Activity.RESULT_FIRST_USER + 1;
 
+    /**
+     * Indicates user operation is successful.
+     */
+    public static final int USER_OPERATION_SUCCESS = 0;
+
+    /**
+     * Indicates user operation failed for unknown reason.
+     */
+    public static final int USER_OPERATION_ERROR_UNKNOWN = 1;
+
+    /**
+     * Indicates user operation failed because target user is a managed profile.
+     */
+    public static final int USER_OPERATION_ERROR_MANAGED_PROFILE = 2;
+
+    /**
+     * Indicates user operation failed because maximum running user limit has been reached.
+     */
+    public static final int USER_OPERATION_ERROR_MAX_RUNNING_USERS = 3;
+
+    /**
+     * Indicates user operation failed because the target user is in the foreground.
+     */
+    public static final int USER_OPERATION_ERROR_CURRENT_USER = 4;
+
+    /**
+     * Indicates user operation failed because device has low data storage.
+     */
+    public static final int USER_OPERATION_ERROR_LOW_STORAGE = 5;
+
+    /**
+     * Indicates user operation failed because maximum user limit has been reached.
+     */
+    public static final int USER_OPERATION_ERROR_MAX_USERS = 6;
+
+    /**
+     * Result returned from various user operations.
+     *
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "USER_OPERATION_" }, value = {
+            USER_OPERATION_SUCCESS,
+            USER_OPERATION_ERROR_UNKNOWN,
+            USER_OPERATION_ERROR_MANAGED_PROFILE,
+            USER_OPERATION_ERROR_MAX_RUNNING_USERS,
+            USER_OPERATION_ERROR_CURRENT_USER,
+            USER_OPERATION_ERROR_LOW_STORAGE,
+            USER_OPERATION_ERROR_MAX_USERS
+    })
+    public @interface UserOperationResult {}
+
+    /**
+     * Thrown to indicate user operation failed.
+     */
+    public static class UserOperationException extends RuntimeException {
+        private final @UserOperationResult int mUserOperationResult;
+
+        /**
+         * Constructs a UserOperationException with specific result code.
+         *
+         * @param message the detail message
+         * @param userOperationResult the result code
+         * @hide
+         */
+        public UserOperationException(String message,
+                @UserOperationResult int userOperationResult) {
+            super(message);
+            mUserOperationResult = userOperationResult;
+        }
+
+        /**
+         * Returns the operation result code.
+         */
+        public @UserOperationResult int getUserOperationResult() {
+            return mUserOperationResult;
+        }
+    }
+
     /** @hide */
     public static UserManager get(Context context) {
         return (UserManager) context.getSystemService(Context.USER_SERVICE);
@@ -2530,8 +2612,13 @@
     public static int getMaxSupportedUsers() {
         // Don't allow multiple users on certain builds
         if (android.os.Build.ID.startsWith("JVP")) return 1;
-        // Svelte devices don't get multi-user.
-        if (ActivityManager.isLowRamDeviceStatic()) return 1;
+        if (ActivityManager.isLowRamDeviceStatic()) {
+            // Low-ram devices are Svelte. Most of the time they don't get multi-user.
+            if ((Resources.getSystem().getConfiguration().uiMode & Configuration.UI_MODE_TYPE_MASK)
+                    != Configuration.UI_MODE_TYPE_TELEVISION) {
+                return 1;
+            }
+        }
         return SystemProperties.getInt("fw.max_users",
                 Resources.getSystem().getInteger(R.integer.config_multiuserMaximumUsers));
     }
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index 57418c8..ca4c796 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -493,11 +493,12 @@
      * Instructs the zygote to pre-load the classes and native libraries at the given paths
      * for the specified abi. Not all zygotes support this function.
      */
-    public boolean preloadPackageForAbi(String packagePath, String libsPath, String cacheKey,
-                                        String abi) throws ZygoteStartFailedEx, IOException {
+    public boolean preloadPackageForAbi(String packagePath, String libsPath, String libFileName,
+                                        String cacheKey, String abi) throws ZygoteStartFailedEx,
+                                                                            IOException {
         synchronized(mLock) {
             ZygoteState state = openZygoteSocketIfNeeded(abi);
-            state.writer.write("4");
+            state.writer.write("5");
             state.writer.newLine();
 
             state.writer.write("--preload-package");
@@ -509,6 +510,9 @@
             state.writer.write(libsPath);
             state.writer.newLine();
 
+            state.writer.write(libFileName);
+            state.writer.newLine();
+
             state.writer.write(cacheKey);
             state.writer.newLine();
 
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index c6c8d9d..70de09e 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -225,6 +225,7 @@
 
         /**
          * Indicates the call underwent Assisted Dialing.
+         * @hide
          */
         public static final int FEATURES_ASSISTED_DIALING_USED = 1 << 4;
 
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 2ec9009e..bc3e740 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7103,6 +7103,14 @@
                 SHOW_ROTATION_SUGGESTIONS_ENABLED;
 
         /**
+         * The number of accepted rotation suggestions. Used to determine if the user has been
+         * introduced to rotation suggestions.
+         * @hide
+         */
+        public static final String NUM_ROTATION_SUGGESTIONS_ACCEPTED =
+                "num_rotation_suggestions_accepted";
+
+        /**
          * Read only list of the service components that the current user has explicitly allowed to
          * see and assist with all of the user's notifications.
          *
@@ -8573,6 +8581,7 @@
          * (0 = false, 1 = true)
          * @hide
          */
+        @SystemApi
         public static final String EUICC_PROVISIONED = "euicc_provisioned";
 
         /**
@@ -8827,6 +8836,14 @@
         */
        public static final String NETWORK_SCORER_APP = "network_scorer_app";
 
+        /**
+         * Whether night display forced auto mode is available.
+         * 0 = unavailable, 1 = available.
+         * @hide
+         */
+        public static final String NIGHT_DISPLAY_FORCED_AUTO_MODE_AVAILABLE =
+                "night_display_forced_auto_mode_available";
+
        /**
         * If the NITZ_UPDATE_DIFF time is exceeded then an automatic adjustment
         * to SystemClock will be allowed even if NITZ_UPDATE_SPACING has not been
@@ -9077,14 +9094,28 @@
          */
         public static final String TETHER_OFFLOAD_DISABLED = "tether_offload_disabled";
 
-       /**
-        * List of carrier apps which are whitelisted to prompt the user for install when
-        * a sim card with matching uicc carrier privilege rules is inserted.
-        *
-        * The value is "package1;package2;..."
-        * @hide
-        */
-       public static final String CARRIER_APP_WHITELIST = "carrier_app_whitelist";
+        /**
+         * List of certificate (hex string representation of the application's certificate - SHA-1
+         * or SHA-256) and carrier app package pairs which are whitelisted to prompt the user for
+         * install when a sim card with matching UICC carrier privilege rules is inserted.  The
+         * certificate is used as a key, so the certificate encoding here must be the same as the
+         * certificate encoding used on the SIM.
+         *
+         * The value is "cert1:package1;cert2:package2;..."
+         * @hide
+         */
+        @SystemApi
+        public static final String CARRIER_APP_WHITELIST = "carrier_app_whitelist";
+
+        /**
+         * Map of package name to application names.  Package names must be lower cased as they are
+         * used as a key in the map.  The application names cannot and will not be localized.
+         *
+         * The value is "packageName1:appName1;packageName2:appName2;..."
+         * @hide
+         */
+        @SystemApi
+        public static final String CARRIER_APP_NAMES = "carrier_app_names";
 
        /**
         * USB Mass Storage Enabled
@@ -10314,6 +10345,16 @@
         public static final String SYS_VDSO = "sys_vdso";
 
         /**
+        * UidCpuPower global setting. This links the sys.uidcpupower system property.
+        * The following values are supported:
+        * 0 -> /proc/uid_cpupower/* are disabled
+        * 1 -> /proc/uid_cpupower/* are enabled
+        * Any other value defaults to enabled.
+        * @hide
+        */
+        public static final String SYS_UIDCPUPOWER = "sys_uidcpupower";
+
+        /**
          * An integer to reduce the FPS by this factor. Only for experiments. Need to reboot the
          * device for this setting to take full effect.
          *
@@ -10471,20 +10512,30 @@
 
         /**
          * TextClassifier specific settings.
-         * This is encoded as a key=value list, separated by commas. Ex:
+         * This is encoded as a key=value list, separated by commas. String[] types like
+         * entity_list_default use ":" as delimiter for values. Ex:
          *
          * <pre>
-         * smart_selection_dark_launch              (boolean)
-         * smart_selection_enabled_for_edit_text    (boolean)
+         * smart_linkify_enabled                    (boolean)
+         * system_textclassifier_enabled            (boolean)
+         * model_dark_launch_enabled                (boolean)
+         * smart_selection_enabled                  (boolean)
+         * smart_text_share_enabled                 (boolean)
+         * smart_linkify_enabled                    (boolean)
+         * smart_select_animation_enabled           (boolean)
          * suggest_selection_max_range_length       (int)
          * classify_text_max_range_length           (int)
          * generate_links_max_text_length           (int)
+         * generate_links_log_sample_rate           (int)
+         * entity_list_default                      (String[])
+         * entity_list_not_editable                 (String[])
+         * entity_list_editable                     (String[])
          * </pre>
          *
          * <p>
          * Type: string
          * @hide
-         * see also android.view.textclassifier.TextClassifierConstants
+         * see also android.view.textclassifier.TextClassificationConstants
          */
         public static final String TEXT_CLASSIFIER_CONSTANTS = "text_classifier_constants";
 
@@ -10544,6 +10595,23 @@
                 = "forced_app_standby_for_small_battery_enabled";
 
         /**
+         * Whether or not to enable the Off Body, Radios Off feature on small battery devices.
+         * Type: int (0 for false, 1 for true)
+         * Default: 0
+         * @hide
+         */
+        public static final String OFF_BODY_RADIOS_OFF_FOR_SMALL_BATTERY_ENABLED
+                = "off_body_radios_off_for_small_battery_enabled";
+
+        /**
+         * How long after the device goes off body to disable radios, in milliseconds.
+         * Type: long
+         * Default: 10 minutes
+         * @hide
+         */
+        public static final String OFF_BODY_RADIOS_OFF_DELAY_MS = "off_body_radios_off_delay_ms";
+
+        /**
          * Whether or not to enable Time Only Mode for watch type devices.
          * Type: int (0 for false, 1 for true)
          * Default: 0
diff --git a/core/java/android/se/omapi/ISecureElementListener.aidl b/core/java/android/se/omapi/ISecureElementListener.aidl
index 3a99d63..e0c6e04 100644
--- a/core/java/android/se/omapi/ISecureElementListener.aidl
+++ b/core/java/android/se/omapi/ISecureElementListener.aidl
@@ -21,6 +21,7 @@
 
 /**
  * Interface to receive call-backs when the service is connected.
+ * @hide
  */
 interface ISecureElementListener {
   /**
diff --git a/core/java/android/se/omapi/SEService.java b/core/java/android/se/omapi/SEService.java
index b8937e6..d59e86a 100644
--- a/core/java/android/se/omapi/SEService.java
+++ b/core/java/android/se/omapi/SEService.java
@@ -59,6 +59,21 @@
      */
     public static final int NO_SUCH_ELEMENT_ERROR = 2;
 
+    /**
+     * Interface to send call-backs to the application when the service is connected.
+     */
+    public abstract static class SecureElementListener extends ISecureElementListener.Stub {
+        @Override
+        public IBinder asBinder() {
+            return this;
+        }
+
+        /**
+         * Called by the framework when the service is connected.
+         */
+        public void serviceConnected() {};
+    }
+
     private static final String TAG = "OMAPI.SEService";
 
     private final Object mLock = new Object();
@@ -98,9 +113,9 @@
      *            the context of the calling application. Cannot be
      *            <code>null</code>.
      * @param listener
-     *            a ISecureElementListener object. Can be <code>null</code>.
+     *            a SecureElementListener object. Can be <code>null</code>.
      */
-    public SEService(Context context, ISecureElementListener listener) {
+    public SEService(Context context, SecureElementListener listener) {
 
         if (context == null) {
             throw new NullPointerException("context must not be null");
diff --git a/core/java/android/security/ConfirmationDialog.java b/core/java/android/security/ConfirmationDialog.java
index e9df370..f6127e1 100644
--- a/core/java/android/security/ConfirmationDialog.java
+++ b/core/java/android/security/ConfirmationDialog.java
@@ -17,7 +17,10 @@
 package android.security;
 
 import android.annotation.NonNull;
+import android.content.ContentResolver;
 import android.content.Context;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -86,6 +89,7 @@
     private byte[] mExtraData;
     private ConfirmationCallback mCallback;
     private Executor mExecutor;
+    private Context mContext;
 
     private final KeyStore mKeyStore = KeyStore.getInstance();
 
@@ -190,15 +194,39 @@
             if (mExtraData == null) {
                 throw new IllegalArgumentException("extraData must be set");
             }
-            return new ConfirmationDialog(mPromptText, mExtraData);
+            return new ConfirmationDialog(context, mPromptText, mExtraData);
         }
     }
 
-    private ConfirmationDialog(CharSequence promptText, byte[] extraData) {
+    private ConfirmationDialog(Context context, CharSequence promptText, byte[] extraData) {
+        mContext = context;
         mPromptText = promptText;
         mExtraData = extraData;
     }
 
+    private static final int UI_OPTION_ACCESSIBILITY_INVERTED_FLAG = 1 << 0;
+    private static final int UI_OPTION_ACCESSIBILITY_MAGNIFIED_FLAG = 1 << 1;
+
+    private int getUiOptionsAsFlags() {
+        int uiOptionsAsFlags = 0;
+        try {
+            ContentResolver contentResolver = mContext.getContentResolver();
+            int inversionEnabled = Settings.Secure.getInt(contentResolver,
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
+            if (inversionEnabled == 1) {
+                uiOptionsAsFlags |= UI_OPTION_ACCESSIBILITY_INVERTED_FLAG;
+            }
+            float fontScale = Settings.System.getFloat(contentResolver,
+                    Settings.System.FONT_SCALE);
+            if (fontScale > 1.0) {
+                uiOptionsAsFlags |= UI_OPTION_ACCESSIBILITY_MAGNIFIED_FLAG;
+            }
+        } catch (SettingNotFoundException e) {
+            Log.w(TAG, "Unexpected SettingNotFoundException");
+        }
+        return uiOptionsAsFlags;
+    }
+
     /**
      * Requests a confirmation prompt to be presented to the user.
      *
@@ -220,8 +248,7 @@
         mCallback = callback;
         mExecutor = executor;
 
-        int uiOptionsAsFlags = 0;
-        // TODO: set AccessibilityInverted, AccessibilityMagnified in uiOptionsAsFlags as needed.
+        int uiOptionsAsFlags = getUiOptionsAsFlags();
         String locale = Locale.getDefault().toLanguageTag();
         int responseCode = mKeyStore.presentConfirmationPrompt(
                 mCallbackBinder, mPromptText.toString(), mExtraData, locale, uiOptionsAsFlags);
@@ -277,7 +304,6 @@
      * @return true if confirmation prompts are supported by the device.
      */
     public static boolean isSupported() {
-        // TODO: read and return system property.
-        return true;
+        return KeyStore.getInstance().isConfirmationPromptSupported();
     }
 }
diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java
index f4dcce1..1d13335 100644
--- a/core/java/android/security/keymaster/KeymasterDefs.java
+++ b/core/java/android/security/keymaster/KeymasterDefs.java
@@ -75,7 +75,6 @@
     public static final int KM_TAG_ALLOW_WHILE_ON_BODY = KM_BOOL | 506;
     public static final int KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED = KM_BOOL | 507;
     public static final int KM_TAG_TRUSTED_CONFIRMATION_REQUIRED = KM_BOOL | 508;
-    public static final int KM_TAG_UNLOCKED_DEVICE_REQUIRED = KM_BOOL | 509;
 
     public static final int KM_TAG_ALL_APPLICATIONS = KM_BOOL | 600;
     public static final int KM_TAG_APPLICATION_ID = KM_BYTES | 601;
@@ -217,7 +216,6 @@
     public static final int KM_ERROR_MISSING_MIN_MAC_LENGTH = -58;
     public static final int KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH = -59;
     public static final int KM_ERROR_CANNOT_ATTEST_IDS = -66;
-    public static final int KM_ERROR_DEVICE_LOCKED = -72;
     public static final int KM_ERROR_UNIMPLEMENTED = -100;
     public static final int KM_ERROR_VERSION_MISMATCH = -101;
     public static final int KM_ERROR_UNKNOWN_ERROR = -1000;
@@ -264,7 +262,6 @@
         sErrorCodeToString.put(KM_ERROR_INVALID_MAC_LENGTH,
                 "Invalid MAC or authentication tag length");
         sErrorCodeToString.put(KM_ERROR_CANNOT_ATTEST_IDS, "Unable to attest device ids");
-        sErrorCodeToString.put(KM_ERROR_DEVICE_LOCKED, "Device locked");
         sErrorCodeToString.put(KM_ERROR_UNIMPLEMENTED, "Not implemented");
         sErrorCodeToString.put(KM_ERROR_UNKNOWN_ERROR, "Unknown error");
     }
diff --git a/core/java/android/security/keystore/BadCertificateFormatException.java b/core/java/android/security/keystore/BadCertificateFormatException.java
index ddc7bd2..c51b773 100644
--- a/core/java/android/security/keystore/BadCertificateFormatException.java
+++ b/core/java/android/security/keystore/BadCertificateFormatException.java
@@ -17,8 +17,7 @@
 package android.security.keystore;
 
 /**
- * Error thrown when the recovery agent supplies an invalid X509 certificate.
- *
+ * @deprecated Use {@link android.security.keystore.recovery.BadCertificateFormatException}.
  * @hide
  */
 public class BadCertificateFormatException extends RecoveryControllerException {
diff --git a/core/java/android/security/keystore/DecryptionFailedException.java b/core/java/android/security/keystore/DecryptionFailedException.java
index 945fcf6..c0b52f7 100644
--- a/core/java/android/security/keystore/DecryptionFailedException.java
+++ b/core/java/android/security/keystore/DecryptionFailedException.java
@@ -17,9 +17,7 @@
 package android.security.keystore;
 
 /**
- * Error thrown when decryption failed, due to an agent error. i.e., using the incorrect key,
- * trying to decrypt garbage data, trying to decrypt data that has somehow been corrupted, etc.
- *
+ * @deprecated Use {@link android.security.keystore.recovery.DecryptionFailedException}.
  * @hide
  */
 public class DecryptionFailedException extends RecoveryControllerException {
diff --git a/core/java/android/security/keystore/InternalRecoveryServiceException.java b/core/java/android/security/keystore/InternalRecoveryServiceException.java
index 85829be..40076f7 100644
--- a/core/java/android/security/keystore/InternalRecoveryServiceException.java
+++ b/core/java/android/security/keystore/InternalRecoveryServiceException.java
@@ -17,11 +17,7 @@
 package android.security.keystore;
 
 /**
- * An error thrown when something went wrong internally in the recovery service.
- *
- * <p>This is an unexpected error, and indicates a problem with the service itself, rather than the
- * caller having performed some kind of illegal action.
- *
+ * @deprecated Use {@link android.security.keystore.recovery.InternalRecoveryServiceException}.
  * @hide
  */
 public class InternalRecoveryServiceException extends RecoveryControllerException {
diff --git a/core/java/android/security/keystore/KeyDerivationParams.java b/core/java/android/security/keystore/KeyDerivationParams.java
index b19cee2..e475dc3 100644
--- a/core/java/android/security/keystore/KeyDerivationParams.java
+++ b/core/java/android/security/keystore/KeyDerivationParams.java
@@ -27,9 +27,7 @@
 import java.lang.annotation.RetentionPolicy;
 
 /**
- * Collection of parameters which define a key derivation function.
- * Currently only supports salted SHA-256
- *
+ * @deprecated Use {@link android.security.keystore.recovery.KeyDerivationParams}.
  * @hide
  */
 public final class KeyDerivationParams implements Parcelable {
diff --git a/core/java/android/security/keystore/KeychainProtectionParams.java b/core/java/android/security/keystore/KeychainProtectionParams.java
index a940fdc..19a087d 100644
--- a/core/java/android/security/keystore/KeychainProtectionParams.java
+++ b/core/java/android/security/keystore/KeychainProtectionParams.java
@@ -28,23 +28,7 @@
 import java.util.Arrays;
 
 /**
- * A {@link KeychainSnapshot} is protected with a key derived from the user's lock screen. This
- * class wraps all the data necessary to derive the same key on a recovering device:
- *
- * <ul>
- *     <li>UI parameters for the user's lock screen - so that if e.g., the user was using a pattern,
- *         the recovering device can display the pattern UI to the user when asking them to enter
- *         the lock screen from their previous device.
- *     <li>The algorithm used to derive a key from the user's lock screen, e.g. SHA-256 with a salt.
- * </ul>
- *
- * <p>As such, this data is sent along with the {@link KeychainSnapshot} when syncing the current
- * version of the keychain.
- *
- * <p>For now, the recoverable keychain only supports a single layer of protection, which is the
- * user's lock screen. In the future, the keychain will support multiple layers of protection
- * (e.g. an additional keychain password, along with the lock screen).
- *
+ * @deprecated Use {@link android.security.keystore.recovery.KeyChainProtectionParams}.
  * @hide
  */
 public final class KeychainProtectionParams implements Parcelable {
diff --git a/core/java/android/security/keystore/KeychainSnapshot.java b/core/java/android/security/keystore/KeychainSnapshot.java
index 23aec25..cf18fd1 100644
--- a/core/java/android/security/keystore/KeychainSnapshot.java
+++ b/core/java/android/security/keystore/KeychainSnapshot.java
@@ -25,21 +25,7 @@
 import java.util.List;
 
 /**
- * A snapshot of a version of the keystore. Two events can trigger the generation of a new snapshot:
- *
- * <ul>
- *     <li>The user's lock screen changes. (A key derived from the user's lock screen is used to
- *         protected the keychain, which is why this forces a new snapshot.)
- *     <li>A key is added to or removed from the recoverable keychain.
- * </ul>
- *
- * <p>The snapshot data is also encrypted with the remote trusted hardware's public key, so even
- * the recovery agent itself should not be able to decipher the data. The recovery agent sends an
- * instance of this to the remote trusted hardware whenever a new snapshot is generated. During a
- * recovery flow, the recovery agent retrieves a snapshot from the remote trusted hardware. It then
- * sends it to the framework, where it is decrypted using the user's lock screen from their previous
- * device.
- *
+ * @deprecated Use {@link android.security.keystore.recovery.KeyChainSnapshot}.
  * @hide
  */
 public final class KeychainSnapshot implements Parcelable {
diff --git a/core/java/android/security/keystore/LockScreenRequiredException.java b/core/java/android/security/keystore/LockScreenRequiredException.java
index b07fb9c..0970284 100644
--- a/core/java/android/security/keystore/LockScreenRequiredException.java
+++ b/core/java/android/security/keystore/LockScreenRequiredException.java
@@ -17,10 +17,7 @@
 package android.security.keystore;
 
 /**
- * Error thrown when trying to generate keys for a profile that has no lock screen set.
- *
- * <p>A lock screen must be set, as the lock screen is used to encrypt the snapshot.
- *
+ * @deprecated Use {@link android.security.keystore.recovery.LockScreenRequiredException}.
  * @hide
  */
 public class LockScreenRequiredException extends RecoveryControllerException {
diff --git a/core/java/android/security/keystore/RecoveryClaim.java b/core/java/android/security/keystore/RecoveryClaim.java
index 6f566af..12be607 100644
--- a/core/java/android/security/keystore/RecoveryClaim.java
+++ b/core/java/android/security/keystore/RecoveryClaim.java
@@ -17,8 +17,7 @@
 package android.security.keystore;
 
 /**
- * An attempt to recover a keychain protected by remote secure hardware.
- *
+ * @deprecated Use {@link android.security.keystore.recovery.RecoverySession}.
  * @hide
  */
 public class RecoveryClaim {
diff --git a/core/java/android/security/keystore/RecoveryController.java b/core/java/android/security/keystore/RecoveryController.java
index 98e6a20..145261e 100644
--- a/core/java/android/security/keystore/RecoveryController.java
+++ b/core/java/android/security/keystore/RecoveryController.java
@@ -31,22 +31,7 @@
 import java.util.Map;
 
 /**
- * An assistant for generating {@link javax.crypto.SecretKey} instances that can be recovered by
- * other Android devices belonging to the user. The exported keychain is protected by the user's
- * lock screen.
- *
- * <p>The RecoveryController must be paired with a recovery agent. The recovery agent is responsible
- * for transporting the keychain to remote trusted hardware. This hardware must prevent brute force
- * attempts against the user's lock screen by limiting the number of allowed guesses (to, e.g., 10).
- * After  that number of incorrect guesses, the trusted hardware no longer allows access to the
- * key chain.
- *
- * <p>For now only the recovery agent itself is able to create keys, so it is expected that the
- * recovery agent is itself the system app.
- *
- * <p>A recovery agent requires the privileged permission
- * {@code android.Manifest.permission#RECOVER_KEYSTORE}.
- *
+ * @deprecated Use {@link android.security.keystore.recovery.RecoveryController}.
  * @hide
  */
 public class RecoveryController {
@@ -259,7 +244,9 @@
             @NonNull String packageName, @Nullable String[] aliases, int status)
             throws NameNotFoundException, InternalRecoveryServiceException {
         try {
-            mBinder.setRecoveryStatus(packageName, aliases, status);
+            for (String alias : aliases) {
+                mBinder.setRecoveryStatus(alias, status);
+            }
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         } catch (ServiceSpecificException e) {
@@ -288,7 +275,7 @@
             // IPC doesn't support generic Maps.
             @SuppressWarnings("unchecked")
             Map<String, Integer> result =
-                    (Map<String, Integer>) mBinder.getRecoveryStatus(/*packageName=*/ null);
+                    (Map<String, Integer>) mBinder.getRecoveryStatus();
             return result;
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
diff --git a/core/java/android/security/keystore/RecoveryControllerException.java b/core/java/android/security/keystore/RecoveryControllerException.java
index 5b806b7..f990c23 100644
--- a/core/java/android/security/keystore/RecoveryControllerException.java
+++ b/core/java/android/security/keystore/RecoveryControllerException.java
@@ -19,8 +19,7 @@
 import java.security.GeneralSecurityException;
 
 /**
- * Base exception for errors thrown by {@link RecoveryController}.
- *
+ * @deprecated Use {@link android.security.keystore.recovery.RecoveryController}.
  * @hide
  */
 public abstract class RecoveryControllerException extends GeneralSecurityException {
diff --git a/core/java/android/security/keystore/RecoverySession.java b/core/java/android/security/keystore/RecoverySession.java
index ae8d91a..8a3e06b 100644
--- a/core/java/android/security/keystore/RecoverySession.java
+++ b/core/java/android/security/keystore/RecoverySession.java
@@ -19,9 +19,7 @@
 import java.security.SecureRandom;
 
 /**
- * Session to recover a {@link KeychainSnapshot} from the remote trusted hardware, initiated by a
- * recovery agent.
- *
+ * @deprecated Use {@link android.security.keystore.recovery.RecoverySession}.
  * @hide
  */
 public class RecoverySession implements AutoCloseable {
diff --git a/core/java/android/security/keystore/SessionExpiredException.java b/core/java/android/security/keystore/SessionExpiredException.java
index f13e206..7c8d5e4 100644
--- a/core/java/android/security/keystore/SessionExpiredException.java
+++ b/core/java/android/security/keystore/SessionExpiredException.java
@@ -17,8 +17,7 @@
 package android.security.keystore;
 
 /**
- * Error thrown when attempting to use a {@link RecoverySession} that has since expired.
- *
+ * @deprecated Use {@link android.security.keystore.recovery.SessionExpiredException}.
  * @hide
  */
 public class SessionExpiredException extends RecoveryControllerException {
diff --git a/core/java/android/security/keystore/WrappedApplicationKey.java b/core/java/android/security/keystore/WrappedApplicationKey.java
index 522bb95..2ce8c7d 100644
--- a/core/java/android/security/keystore/WrappedApplicationKey.java
+++ b/core/java/android/security/keystore/WrappedApplicationKey.java
@@ -23,16 +23,7 @@
 import com.android.internal.util.Preconditions;
 
 /**
- * Helper class with data necessary recover a single application key, given a recovery key.
- *
- * <ul>
- *   <li>Alias - Keystore alias of the key.
- *   <li>Encrypted key material.
- * </ul>
- *
- * Note that Application info is not included. Recovery Agent can only make its own keys
- * recoverable.
- *
+ * @deprecated Use {@link android.security.keystore.recovery.WrappedApplicationKey}.
  * @hide
  */
 public final class WrappedApplicationKey implements Parcelable {
diff --git a/core/java/android/security/keystore/recovery/BadCertificateFormatException.java b/core/java/android/security/keystore/recovery/BadCertificateFormatException.java
index e0781a5..4275c29 100644
--- a/core/java/android/security/keystore/recovery/BadCertificateFormatException.java
+++ b/core/java/android/security/keystore/recovery/BadCertificateFormatException.java
@@ -17,10 +17,8 @@
 package android.security.keystore.recovery;
 
 /**
- * Error thrown when the recovery agent supplies an invalid X509 certificate.
- *
+ * @deprecated Not used.
  * @hide
- * Deprecated
  */
 public class BadCertificateFormatException extends RecoveryControllerException {
     public BadCertificateFormatException(String msg) {
diff --git a/core/java/android/security/keystore/recovery/InternalRecoveryServiceException.java b/core/java/android/security/keystore/recovery/InternalRecoveryServiceException.java
index 218d26e..e62bfb1 100644
--- a/core/java/android/security/keystore/recovery/InternalRecoveryServiceException.java
+++ b/core/java/android/security/keystore/recovery/InternalRecoveryServiceException.java
@@ -19,6 +19,7 @@
 import android.annotation.SystemApi;
 
 import java.security.GeneralSecurityException;
+
 /**
  * An error thrown when something went wrong internally in the recovery service.
  *
diff --git a/core/java/android/security/keystore/recovery/KeyChainSnapshot.java b/core/java/android/security/keystore/recovery/KeyChainSnapshot.java
index df535ed..4580c47 100644
--- a/core/java/android/security/keystore/recovery/KeyChainSnapshot.java
+++ b/core/java/android/security/keystore/recovery/KeyChainSnapshot.java
@@ -23,6 +23,7 @@
 
 import com.android.internal.util.Preconditions;
 
+import java.security.cert.CertPath;
 import java.util.List;
 
 /**
@@ -52,7 +53,8 @@
     private int mMaxAttempts = DEFAULT_MAX_ATTEMPTS;
     private long mCounterId = DEFAULT_COUNTER_ID;
     private byte[] mServerParams;
-    private byte[] mPublicKey;
+    private byte[] mPublicKey;  // The raw public key bytes used
+    private CertPath mCertPath;  // The certificate path including the intermediate certificates
     private List<KeyChainProtectionParams> mKeyChainProtectionParams;
     private List<WrappedApplicationKey> mEntryRecoveryData;
     private byte[] mEncryptedRecoveryKeyBlob;
@@ -111,14 +113,24 @@
     /**
      * Public key used to encrypt {@code encryptedRecoveryKeyBlob}.
      *
-     * See implementation for binary key format
+     * See implementation for binary key format.
+     *
+     * @deprecated Use {@link #getTrustedHardwareCertPath} instead.
      */
-    // TODO: document key format.
+    @Deprecated
     public @NonNull byte[] getTrustedHardwarePublicKey() {
         return mPublicKey;
     }
 
     /**
+     * CertPath containing the public key used to encrypt {@code encryptedRecoveryKeyBlob}.
+     */
+    // TODO: Change to @NonNull
+    public CertPath getTrustedHardwareCertPath() {
+        return mCertPath;
+    }
+
+    /**
      * UI and key derivation parameters. Note that combination of secrets may be used.
      */
     public @NonNull List<KeyChainProtectionParams> getKeyChainProtectionParams() {
@@ -207,13 +219,28 @@
          *
          * @param publicKey The public key
          * @return This builder.
+         * @deprecated Use {@link #setTrustedHardwareCertPath} instead.
          */
+        @Deprecated
         public Builder setTrustedHardwarePublicKey(byte[] publicKey) {
             mInstance.mPublicKey = publicKey;
             return this;
         }
 
         /**
+         * Sets CertPath used to validate the trusted hardware public key. The CertPath should
+         * contain a certificate of the trusted hardware public key and any necessary intermediate
+         * certificates.
+         *
+         * @param certPath The public key
+         * @return This builder.
+         */
+        public Builder setTrustedHardwareCertPath(CertPath certPath) {
+            mInstance.mCertPath = certPath;
+            return this;
+        }
+
+        /**
          * Sets UI and key derivation parameters
          *
          * @param recoveryMetadata The UI and key derivation parameters
@@ -261,7 +288,6 @@
                     "entryRecoveryData");
             Preconditions.checkNotNull(mInstance.mEncryptedRecoveryKeyBlob);
             Preconditions.checkNotNull(mInstance.mServerParams);
-            Preconditions.checkNotNull(mInstance.mPublicKey);
             return mInstance;
         }
     }
diff --git a/core/java/android/security/keystore/recovery/RecoveryCertPath.aidl b/core/java/android/security/keystore/recovery/RecoveryCertPath.aidl
new file mode 100644
index 0000000..c171a92
--- /dev/null
+++ b/core/java/android/security/keystore/recovery/RecoveryCertPath.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore.recovery;
+
+/* @hide */
+parcelable RecoveryCertPath;
diff --git a/core/java/android/security/keystore/recovery/RecoveryCertPath.java b/core/java/android/security/keystore/recovery/RecoveryCertPath.java
new file mode 100644
index 0000000..1950947
--- /dev/null
+++ b/core/java/android/security/keystore/recovery/RecoveryCertPath.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore.recovery;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.io.ByteArrayInputStream;
+import java.security.cert.CertPath;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+
+/**
+ * The certificate path of the recovery service.
+ *
+ * @hide
+ */
+public final class RecoveryCertPath implements Parcelable {
+
+    private static final String CERT_PATH_ENCODING = "PkiPath";
+
+    private final byte[] mEncodedCertPath;
+
+    /**
+     * Wraps a {@code CertPath} to create a {@code Parcelable} for Binder calls.
+     *
+     * @param certPath The certificate path to be wrapped.
+     * @throws CertificateException if the given certificate path cannot be encoded properly.
+     */
+    public static RecoveryCertPath createRecoveryCertPath(@NonNull CertPath certPath)
+            throws CertificateException {
+        // Perform the encoding here to avoid throwing exceptions in writeToParcel
+        try {
+            return new RecoveryCertPath(encodeCertPath(certPath));
+        } catch (CertificateEncodingException e) {
+            throw new CertificateException("Failed to encode the given CertPath", e);
+        }
+    }
+
+    /**
+     * Obtains the {@code CertPath} wrapped in the Parcelable.
+     *
+     * @return the wrapped certificate path.
+     * @throws CertificateException if the wrapped certificate path cannot be decoded properly.
+     */
+    public CertPath getCertPath() throws CertificateException {
+        // Perform the decoding here to avoid throwing exceptions in createFromParcel
+        return decodeCertPath(mEncodedCertPath);
+    }
+
+    private RecoveryCertPath(@NonNull byte[] encodedCertPath) {
+        mEncodedCertPath = Preconditions.checkNotNull(encodedCertPath);
+    }
+
+    private RecoveryCertPath(Parcel in) {
+        mEncodedCertPath = in.createByteArray();
+    }
+
+    public static final Parcelable.Creator<RecoveryCertPath> CREATOR =
+            new Parcelable.Creator<RecoveryCertPath>() {
+        public RecoveryCertPath createFromParcel(Parcel in) {
+            return new RecoveryCertPath(in);
+        }
+
+        public RecoveryCertPath[] newArray(int length) {
+            return new RecoveryCertPath[length];
+        }
+    };
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeByteArray(mEncodedCertPath);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @NonNull
+    private static byte[] encodeCertPath(@NonNull CertPath certPath)
+            throws CertificateEncodingException {
+        Preconditions.checkNotNull(certPath);
+        return certPath.getEncoded(CERT_PATH_ENCODING);
+    }
+
+    @NonNull
+    private static CertPath decodeCertPath(@NonNull byte[] bytes) throws CertificateException {
+        Preconditions.checkNotNull(bytes);
+        CertificateFactory certFactory;
+        try {
+            certFactory = CertificateFactory.getInstance("X.509");
+        } catch (CertificateException e) {
+            // Should not happen, as X.509 is mandatory for all providers.
+            throw new RuntimeException(e);
+        }
+        return certFactory.generateCertPath(new ByteArrayInputStream(bytes), CERT_PATH_ENCODING);
+    }
+}
diff --git a/core/java/android/security/keystore/recovery/RecoveryClaim.java b/core/java/android/security/keystore/recovery/RecoveryClaim.java
deleted file mode 100644
index 45c6b4ff..0000000
--- a/core/java/android/security/keystore/recovery/RecoveryClaim.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.security.keystore.recovery;
-
-/**
- * An attempt to recover a keychain protected by remote secure hardware.
- *
- * @hide
- * Deprecated
- */
-public class RecoveryClaim {
-
-    private final RecoverySession mRecoverySession;
-    private final byte[] mClaimBytes;
-
-    RecoveryClaim(RecoverySession recoverySession, byte[] claimBytes) {
-        mRecoverySession = recoverySession;
-        mClaimBytes = claimBytes;
-    }
-
-    /**
-     * Returns the session associated with the recovery attempt. This is used to match the symmetric
-     * key, which remains internal to the framework, for decrypting the claim response.
-     *
-     * @return The session data.
-     */
-    public RecoverySession getRecoverySession() {
-        return mRecoverySession;
-    }
-
-    /**
-     * Returns the encrypted claim's bytes.
-     *
-     * <p>This should be sent by the recovery agent to the remote secure hardware, which will use
-     * it to decrypt the keychain, before sending it re-encrypted with the session's symmetric key
-     * to the device.
-     */
-    public byte[] getClaimBytes() {
-        return mClaimBytes;
-    }
-}
diff --git a/core/java/android/security/keystore/recovery/RecoveryController.java b/core/java/android/security/keystore/recovery/RecoveryController.java
index 7cd08f7..6c882e1 100644
--- a/core/java/android/security/keystore/recovery/RecoveryController.java
+++ b/core/java/android/security/keystore/recovery/RecoveryController.java
@@ -46,11 +46,11 @@
  * <p>The RecoveryController must be paired with a recovery agent. The recovery agent is responsible
  * for transporting the keychain to remote trusted hardware. This hardware must prevent brute force
  * attempts against the user's lock screen by limiting the number of allowed guesses (to, e.g., 10).
- * After  that number of incorrect guesses, the trusted hardware no longer allows access to the
+ * After that number of incorrect guesses, the trusted hardware no longer allows access to the
  * key chain.
  *
- * <p>For now only the recovery agent itself is able to create keys, so it is expected that the
- * recovery agent is itself the system app.
+ * <p>Only the recovery agent itself is able to create keys, so it is expected that the recovery
+ * agent is itself the system app.
  *
  * <p>A recovery agent requires the privileged permission
  * {@code android.Manifest.permission#RECOVER_KEYSTORE}.
@@ -65,8 +65,6 @@
     public static final int RECOVERY_STATUS_SYNCED = 0;
     /** Waiting for recovery agent to sync the key. */
     public static final int RECOVERY_STATUS_SYNC_IN_PROGRESS = 1;
-    /** Recovery account is not available. */
-    public static final int RECOVERY_STATUS_MISSING_ACCOUNT = 2;
     /** Key cannot be synced. */
     public static final int RECOVERY_STATUS_PERMANENT_FAILURE = 3;
 
@@ -115,6 +113,14 @@
      */
     public static final int ERROR_DECRYPTION_FAILED = 26;
 
+    /**
+     * Error thrown if the format of a given key is invalid. This might be because the key has a
+     * wrong length, invalid content, etc.
+     *
+     * @hide
+     */
+    public static final int ERROR_INVALID_KEY_FORMAT = 27;
+
 
     private final ILockSettings mBinder;
     private final KeyStore mKeyStore;
@@ -177,28 +183,12 @@
     }
 
     /**
-     * Deprecated - use getKeyChainSnapshot.
-     *
-     * Returns data necessary to store all recoverable keys. Key material is
-     * encrypted with user secret and recovery public key.
-     *
-     * @return Data necessary to recover keystore.
-     * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
-     *     service.
+     * @deprecated Use {@link #getKeyChainSnapshot()}
      */
+    @Deprecated
     @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE)
-    public @Nullable KeyChainSnapshot getRecoveryData()
-            throws InternalRecoveryServiceException {
-        try {
-            return mBinder.getKeyChainSnapshot();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        } catch (ServiceSpecificException e) {
-            if (e.errorCode == ERROR_NO_SNAPSHOT_PENDING) {
-                return null;
-            }
-            throw wrapUnexpectedServiceSpecificException(e);
-        }
+    public @Nullable KeyChainSnapshot getRecoveryData() throws InternalRecoveryServiceException {
+        return getKeyChainSnapshot();
     }
 
     /**
@@ -270,17 +260,20 @@
     }
 
     /**
-     * Gets aliases of recoverable keys for the application.
-     *
-     * @param packageName which recoverable keys' aliases will be returned.
-     *
-     * @return {@code List} of all aliases.
+     * @deprecated Use {@link #getAliases()}.
      */
+    @Deprecated
     public List<String> getAliases(@Nullable String packageName)
             throws InternalRecoveryServiceException {
+        return getAliases();
+    }
+
+    /**
+     * Returns a list of aliases of keys belonging to the application.
+     */
+    public List<String> getAliases() throws InternalRecoveryServiceException {
         try {
-            // TODO: update aidl
-            Map<String, Integer> allStatuses = mBinder.getRecoveryStatus(packageName);
+            Map<String, Integer> allStatuses = mBinder.getRecoveryStatus();
             return new ArrayList<>(allStatuses.keySet());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -290,24 +283,32 @@
     }
 
     /**
-     * Updates recovery status for given key. It is used to notify keystore that key was
-     * successfully stored on the server or there were an error. Application can check this value
-     * using {@code getRecoveyStatus}.
-     *
-     * @param packageName Application whose recoverable key's status are to be updated.
-     * @param alias Application-specific key alias.
-     * @param status Status specific to recovery agent.
-     * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
-     *     service.
+     * @deprecated Use {@link #setRecoveryStatus(String, int)}
      */
+    @Deprecated
     @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE)
     public void setRecoveryStatus(
             @NonNull String packageName, String alias, int status)
             throws NameNotFoundException, InternalRecoveryServiceException {
+        setRecoveryStatus(alias, status);
+    }
+
+    /**
+     * Sets the recovery status for given key. It is used to notify the keystore that the key was
+     * successfully stored on the server or that there was an error. An application can check this
+     * value using {@link #getRecoveryStatus(String, String)}.
+     *
+     * @param alias The alias of the key whose status to set.
+     * @param status The status of the key. One of {@link #RECOVERY_STATUS_SYNCED},
+     *     {@link #RECOVERY_STATUS_SYNC_IN_PROGRESS} or {@link #RECOVERY_STATUS_PERMANENT_FAILURE}.
+     * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
+     *     service.
+     */
+    @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE)
+    public void setRecoveryStatus(String alias, int status)
+            throws InternalRecoveryServiceException {
         try {
-            // TODO: update aidl
-            String[] aliases = alias == null ? null : new String[]{alias};
-            mBinder.setRecoveryStatus(packageName, aliases, status);
+            mBinder.setRecoveryStatus(alias, status);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         } catch (ServiceSpecificException e) {
@@ -316,28 +317,30 @@
     }
 
     /**
-     * Returns recovery status for Application's KeyStore key.
-     * Negative status values are reserved for recovery agent specific codes. List of common codes:
+     * @deprecated Use {@link #getRecoveryStatus(String)}.
+     */
+    @Deprecated
+    public int getRecoveryStatus(String packageName, String alias)
+            throws InternalRecoveryServiceException {
+        return getRecoveryStatus(alias);
+    }
+
+    /**
+     * Returns the recovery status for the key with the given {@code alias}.
      *
      * <ul>
      *   <li>{@link #RECOVERY_STATUS_SYNCED}
      *   <li>{@link #RECOVERY_STATUS_SYNC_IN_PROGRESS}
-     *   <li>{@link #RECOVERY_STATUS_MISSING_ACCOUNT}
      *   <li>{@link #RECOVERY_STATUS_PERMANENT_FAILURE}
      * </ul>
      *
-     * @param packageName Application whose recoverable key status is returned.
-     * @param alias Application-specific key alias.
-     * @return Recovery status.
-     * @see #setRecoveryStatus
+     * @see #setRecoveryStatus(String, int)
      * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
      *     service.
      */
-    public int getRecoveryStatus(String packageName, String alias)
-            throws InternalRecoveryServiceException {
+    public int getRecoveryStatus(String alias) throws InternalRecoveryServiceException {
         try {
-            // TODO: update aidl
-            Map<String, Integer> allStatuses = mBinder.getRecoveryStatus(packageName);
+            Map<String, Integer> allStatuses = mBinder.getRecoveryStatus();
             Integer status = allStatuses.get(alias);
             if (status == null) {
                 return RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE;
@@ -462,36 +465,73 @@
         }
     }
 
+    // TODO: Unhide the following APIs, generateKey(), importKey(), and getKey()
     /**
-     * Generates a AES256/GCM/NoPADDING key called {@code alias} and loads it into the recoverable
-     * key store. Returns {@link javax.crypto.SecretKey}.
-     *
-     * @param alias The key alias.
-     * @param account The account associated with the key.
-     * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
-     *     service.
-     * @throws LockScreenRequiredException if the user has not set a lock screen. This is required
-     *     to generate recoverable keys, as the snapshots are encrypted using a key derived from the
-     *     lock screen.
-     * @hide
+     * @deprecated Use {@link #generateKey(String)}.
      */
+    @Deprecated
     public Key generateKey(@NonNull String alias, byte[] account)
             throws InternalRecoveryServiceException, LockScreenRequiredException {
-        // TODO: update RecoverySession.recoverKeys
+        return generateKey(alias);
+    }
+
+    /**
+     * Generates a recoverable key with the given {@code alias}.
+     *
+     * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
+     *     service.
+     * @throws LockScreenRequiredException if the user does not have a lock screen set. A lock
+     *     screen is required to generate recoverable keys.
+     */
+    public Key generateKey(@NonNull String alias) throws InternalRecoveryServiceException,
+            LockScreenRequiredException {
         try {
-            String grantAlias = mBinder.generateKey(alias, account);
+            String grantAlias = mBinder.generateKey(alias);
             if (grantAlias == null) {
-                return null;
+                throw new InternalRecoveryServiceException("null grant alias");
             }
-            Key result = AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore(
+            return AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore(
                     mKeyStore,
                     grantAlias,
                     KeyStore.UID_SELF);
-            return result;
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         } catch (UnrecoverableKeyException e) {
-            throw new InternalRecoveryServiceException("Access to newly generated key failed for");
+            throw new InternalRecoveryServiceException("Failed to get key from keystore", e);
+        } catch (ServiceSpecificException e) {
+            if (e.errorCode == ERROR_INSECURE_USER) {
+                throw new LockScreenRequiredException(e.getMessage());
+            }
+            throw wrapUnexpectedServiceSpecificException(e);
+        }
+    }
+
+    /**
+     * Imports a 256-bit recoverable AES key with the given {@code alias} and the raw bytes {@code
+     * keyBytes}.
+     *
+     * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
+     *     service.
+     * @throws LockScreenRequiredException if the user does not have a lock screen set. A lock
+     *     screen is required to generate recoverable keys.
+     *
+     * @hide
+     */
+    public Key importKey(@NonNull String alias, byte[] keyBytes)
+            throws InternalRecoveryServiceException, LockScreenRequiredException {
+        try {
+            String grantAlias = mBinder.importKey(alias, keyBytes);
+            if (grantAlias == null) {
+                throw new InternalRecoveryServiceException("Null grant alias");
+            }
+            return AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore(
+                    mKeyStore,
+                    grantAlias,
+                    KeyStore.UID_SELF);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        } catch (UnrecoverableKeyException e) {
+            throw new InternalRecoveryServiceException("Failed to get key from keystore", e);
         } catch (ServiceSpecificException e) {
             if (e.errorCode == ERROR_INSECURE_USER) {
                 throw new LockScreenRequiredException(e.getMessage());
@@ -545,6 +585,15 @@
         }
     }
 
+    /**
+     * Returns a new {@link RecoverySession}.
+     *
+     * <p>A recovery session is required to restore keys from a remote store.
+     */
+    public RecoverySession createRecoverySession() {
+        return RecoverySession.newInstance(this);
+    }
+
     InternalRecoveryServiceException wrapUnexpectedServiceSpecificException(
             ServiceSpecificException e) {
         if (e.errorCode == ERROR_SERVICE_INTERNAL_ERROR) {
diff --git a/core/java/android/security/keystore/recovery/RecoveryControllerException.java b/core/java/android/security/keystore/recovery/RecoveryControllerException.java
index 2733aca..1af61ce 100644
--- a/core/java/android/security/keystore/recovery/RecoveryControllerException.java
+++ b/core/java/android/security/keystore/recovery/RecoveryControllerException.java
@@ -19,10 +19,8 @@
 import java.security.GeneralSecurityException;
 
 /**
- * Base exception for errors thrown by {@link RecoveryController}.
- *
+ * @deprecated Not used.
  * @hide
- * Deprecated
  */
 public abstract class RecoveryControllerException extends GeneralSecurityException {
     RecoveryControllerException() { }
diff --git a/core/java/android/security/keystore/recovery/RecoverySession.java b/core/java/android/security/keystore/recovery/RecoverySession.java
index 4db5d6e..2b627b4 100644
--- a/core/java/android/security/keystore/recovery/RecoverySession.java
+++ b/core/java/android/security/keystore/recovery/RecoverySession.java
@@ -24,6 +24,7 @@
 import android.util.Log;
 
 import java.security.SecureRandom;
+import java.security.cert.CertPath;
 import java.security.cert.CertificateException;
 import java.util.List;
 import java.util.Map;
@@ -49,7 +50,7 @@
     }
 
     /**
-     * A new session, started by {@code recoveryManager}.
+     * A new session, started by the {@link RecoveryController}.
      */
     @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE)
     static RecoverySession newInstance(RecoveryController recoveryController) {
@@ -71,27 +72,9 @@
     }
 
     /**
-     * Starts a recovery session and returns a blob with proof of recovery secret possession.
-     * The method generates a symmetric key for a session, which trusted remote device can use to
-     * return recovery key.
-     *
-     * @param verifierPublicKey Encoded {@code java.security.cert.X509Certificate} with Public key
-     *     used to create the recovery blob on the source device.
-     *     Keystore will verify the certificate using root of trust.
-     * @param vaultParams Must match the parameters in the corresponding field in the recovery blob.
-     *     Used to limit number of guesses.
-     * @param vaultChallenge Data passed from server for this recovery session and used to prevent
-     *     replay attacks
-     * @param secrets Secrets provided by user, the method only uses type and secret fields.
-     * @return The recovery claim. Claim provides a b binary blob with recovery claim. It is
-     *     encrypted with verifierPublicKey and contains a proof of user secrets, session symmetric
-     *     key and parameters necessary to identify the counter with the number of failed recovery
-     *     attempts.
-     * @throws CertificateException if the {@code verifierPublicKey} is in an incorrect
-     *     format.
-     * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
-     *     service.
+     * @deprecated Use {@link #start(CertPath, byte[], byte[], List)} instead.
      */
+    @Deprecated
     @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE)
     @NonNull public byte[] start(
             @NonNull byte[] verifierPublicKey,
@@ -119,6 +102,55 @@
     }
 
     /**
+     * Starts a recovery session and returns a blob with proof of recovery secret possession.
+     * The method generates a symmetric key for a session, which trusted remote device can use to
+     * return recovery key.
+     *
+     * @param verifierCertPath The certificate path used to create the recovery blob on the source
+     *     device. Keystore will verify the certificate path by using the root of trust.
+     * @param vaultParams Must match the parameters in the corresponding field in the recovery blob.
+     *     Used to limit number of guesses.
+     * @param vaultChallenge Data passed from server for this recovery session and used to prevent
+     *     replay attacks.
+     * @param secrets Secrets provided by user, the method only uses type and secret fields.
+     * @return The recovery claim. Claim provides a b binary blob with recovery claim. It is
+     *     encrypted with verifierPublicKey and contains a proof of user secrets, session symmetric
+     *     key and parameters necessary to identify the counter with the number of failed recovery
+     *     attempts.
+     * @throws CertificateException if the {@code verifierCertPath} is invalid.
+     * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
+     *     service.
+     */
+    @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE)
+    @NonNull public byte[] start(
+            @NonNull CertPath verifierCertPath,
+            @NonNull byte[] vaultParams,
+            @NonNull byte[] vaultChallenge,
+            @NonNull List<KeyChainProtectionParams> secrets)
+            throws CertificateException, InternalRecoveryServiceException {
+        // Wrap the CertPath in a Parcelable so it can be passed via Binder calls.
+        RecoveryCertPath recoveryCertPath =
+                RecoveryCertPath.createRecoveryCertPath(verifierCertPath);
+        try {
+            byte[] recoveryClaim =
+                    mRecoveryController.getBinder().startRecoverySessionWithCertPath(
+                            mSessionId,
+                            recoveryCertPath,
+                            vaultParams,
+                            vaultChallenge,
+                            secrets);
+            return recoveryClaim;
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        } catch (ServiceSpecificException e) {
+            if (e.errorCode == RecoveryController.ERROR_BAD_CERTIFICATE_FORMAT) {
+                throw new CertificateException(e.getMessage());
+            }
+            throw mRecoveryController.wrapUnexpectedServiceSpecificException(e);
+        }
+    }
+
+    /**
      * Imports keys.
      *
      * @param recoveryKeyBlob Recovery blob encrypted by symmetric key generated for this session.
diff --git a/core/java/android/security/keystore/recovery/WrappedApplicationKey.java b/core/java/android/security/keystore/recovery/WrappedApplicationKey.java
index f360bbe9..714e35a 100644
--- a/core/java/android/security/keystore/recovery/WrappedApplicationKey.java
+++ b/core/java/android/security/keystore/recovery/WrappedApplicationKey.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@
 
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
-
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -29,7 +28,6 @@
  *
  * <ul>
  *   <li>Alias - Keystore alias of the key.
- *   <li>Account Recovery Agent specific account associated with the key.
  *   <li>Encrypted key material.
  * </ul>
  *
@@ -43,7 +41,6 @@
     private String mAlias;
     // The only supported format is AES-256 symmetric key.
     private byte[] mEncryptedKeyMaterial;
-    private byte[] mAccount;
 
     /**
      * Builder for creating {@link WrappedApplicationKey}.
@@ -63,13 +60,10 @@
         }
 
         /**
-         * Sets Recovery agent specific account.
-         *
-         * @param account The account.
-         * @return This builder.
+         * @deprecated AOSP does not associate keys with accounts. This may be done by system app.
          */
+        @Deprecated
         public Builder setAccount(@NonNull byte[] account) {
-            mInstance.mAccount = account;
             return this;
         }
 
@@ -94,15 +88,11 @@
         @NonNull public WrappedApplicationKey build() {
             Preconditions.checkNotNull(mInstance.mAlias);
             Preconditions.checkNotNull(mInstance.mEncryptedKeyMaterial);
-            if (mInstance.mAccount == null) {
-                mInstance.mAccount = new byte[]{};
-            }
             return mInstance;
         }
     }
 
-    private WrappedApplicationKey() {
-    }
+    private WrappedApplicationKey() { }
 
     /**
      * Deprecated - consider using Builder.
@@ -127,12 +117,12 @@
         return mEncryptedKeyMaterial;
     }
 
-    /** Account, default value is empty array */
+    /**
+     * @deprecated AOSP does not associate keys with accounts. This may be done by system app.
+     */
+    @Deprecated
     public @NonNull byte[] getAccount() {
-        if (mAccount == null) {
-            return new byte[]{};
-        }
-        return mAccount;
+        return new byte[0];
     }
 
     public static final Parcelable.Creator<WrappedApplicationKey> CREATOR =
@@ -150,7 +140,6 @@
     public void writeToParcel(Parcel out, int flags) {
         out.writeString(mAlias);
         out.writeByteArray(mEncryptedKeyMaterial);
-        out.writeByteArray(mAccount);
     }
 
     /**
@@ -159,7 +148,6 @@
     protected WrappedApplicationKey(Parcel in) {
         mAlias = in.readString();
         mEncryptedKeyMaterial = in.createByteArray();
-        mAccount = in.createByteArray();
     }
 
     @Override
diff --git a/core/java/android/service/autofill/AutofillFieldClassificationService.java b/core/java/android/service/autofill/AutofillFieldClassificationService.java
index 1ef6100..cf16749 100644
--- a/core/java/android/service/autofill/AutofillFieldClassificationService.java
+++ b/core/java/android/service/autofill/AutofillFieldClassificationService.java
@@ -15,12 +15,15 @@
  */
 package android.service.autofill;
 
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.app.Service;
 import android.content.Intent;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Parcel;
@@ -30,9 +33,6 @@
 import android.util.Log;
 import android.view.autofill.AutofillValue;
 
-import com.android.internal.os.HandlerCaller;
-import com.android.internal.os.SomeArgs;
-
 import java.util.Arrays;
 import java.util.List;
 
@@ -55,8 +55,6 @@
 
     private static final String TAG = "AutofillFieldClassificationService";
 
-    private static final int MSG_GET_SCORES = 1;
-
     /**
      * The {@link Intent} action that must be declared as handled by a service
      * in its manifest for the system to recognize it as a quota providing service.
@@ -83,35 +81,18 @@
 
     private AutofillFieldClassificationServiceWrapper mWrapper;
 
-    private final HandlerCaller.Callback mHandlerCallback = (msg) -> {
-        final int action = msg.what;
+    private void getScores(RemoteCallback callback, String algorithmName, Bundle algorithmArgs,
+            List<AutofillValue> actualValues, String[] userDataValues) {
         final Bundle data = new Bundle();
-        final RemoteCallback callback;
-        switch (action) {
-            case MSG_GET_SCORES:
-                final SomeArgs args = (SomeArgs) msg.obj;
-                callback = (RemoteCallback) args.arg1;
-                final String algorithmName = (String) args.arg2;
-                final Bundle algorithmArgs = (Bundle) args.arg3;
-                @SuppressWarnings("unchecked")
-                final List<AutofillValue> actualValues = ((List<AutofillValue>) args.arg4);
-                @SuppressWarnings("unchecked")
-                final String[] userDataValues = (String[]) args.arg5;
-                final float[][] scores = onGetScores(algorithmName, algorithmArgs, actualValues,
-                        Arrays.asList(userDataValues));
-                if (scores != null) {
-                    data.putParcelable(EXTRA_SCORES, new Scores(scores));
-                }
-                break;
-            default:
-                Log.w(TAG, "Handling unknown message: " + action);
-                return;
+        final float[][] scores = onGetScores(algorithmName, algorithmArgs, actualValues,
+                Arrays.asList(userDataValues));
+        if (scores != null) {
+            data.putParcelable(EXTRA_SCORES, new Scores(scores));
         }
         callback.sendResult(data);
-    };
+    }
 
-    private final HandlerCaller mHandlerCaller = new HandlerCaller(null, Looper.getMainLooper(),
-            mHandlerCallback, true);
+    private final Handler mHandler = new Handler(Looper.getMainLooper(), null, true);
 
     /** @hide */
     public AutofillFieldClassificationService() {
@@ -160,9 +141,10 @@
         public void getScores(RemoteCallback callback, String algorithmName, Bundle algorithmArgs,
                 List<AutofillValue> actualValues, String[] userDataValues)
                         throws RemoteException {
-            // TODO(b/70939974): refactor to use PooledLambda
-            mHandlerCaller.obtainMessageOOOOO(MSG_GET_SCORES, callback, algorithmName,
-                    algorithmArgs, actualValues, userDataValues).sendToTarget();
+            mHandler.sendMessage(obtainMessage(
+                    AutofillFieldClassificationService::getScores,
+                    AutofillFieldClassificationService.this,
+                    callback, algorithmName, algorithmArgs, actualValues, userDataValues));
         }
     }
 
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
index 7a304c7..0c5d8bd 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -15,6 +15,8 @@
  */
 package android.service.autofill;
 
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
 import android.annotation.CallSuper;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -22,6 +24,7 @@
 import android.app.Service;
 import android.content.Intent;
 import android.os.CancellationSignal;
+import android.os.Handler;
 import android.os.IBinder;
 import android.os.ICancellationSignal;
 import android.os.Looper;
@@ -34,9 +37,6 @@
 import android.view.autofill.AutofillManager;
 import android.view.autofill.AutofillValue;
 
-import com.android.internal.os.HandlerCaller;
-import com.android.internal.os.SomeArgs;
-
 /**
  * An {@code AutofillService} is a service used to automatically fill the contents of the screen
  * on behalf of a given user - for more information about autofill, read
@@ -554,20 +554,12 @@
      */
     public static final String SERVICE_META_DATA = "android.autofill";
 
-    // Handler messages.
-    private static final int MSG_CONNECT = 1;
-    private static final int MSG_DISCONNECT = 2;
-    private static final int MSG_ON_FILL_REQUEST = 3;
-    private static final int MSG_ON_SAVE_REQUEST = 4;
-
     private final IAutoFillService mInterface = new IAutoFillService.Stub() {
         @Override
         public void onConnectedStateChanged(boolean connected) {
-            if (connected) {
-                mHandlerCaller.obtainMessage(MSG_CONNECT).sendToTarget();
-            } else {
-                mHandlerCaller.obtainMessage(MSG_DISCONNECT).sendToTarget();
-            }
+            mHandler.sendMessage(obtainMessage(
+                    connected ? AutofillService::onConnected : AutofillService::onDisconnected,
+                    AutofillService.this));
         }
 
         @Override
@@ -578,56 +570,27 @@
             } catch (RemoteException e) {
                 e.rethrowFromSystemServer();
             }
-            mHandlerCaller.obtainMessageOOO(MSG_ON_FILL_REQUEST, request,
-                    CancellationSignal.fromTransport(transport), callback)
-                    .sendToTarget();
+            mHandler.sendMessage(obtainMessage(
+                    AutofillService::onFillRequest,
+                    AutofillService.this, request, CancellationSignal.fromTransport(transport),
+                    new FillCallback(callback, request.getId())));
         }
 
         @Override
         public void onSaveRequest(SaveRequest request, ISaveCallback callback) {
-            mHandlerCaller.obtainMessageOO(MSG_ON_SAVE_REQUEST, request,
-                    callback).sendToTarget();
+            mHandler.sendMessage(obtainMessage(
+                    AutofillService::onSaveRequest,
+                    AutofillService.this, request, new SaveCallback(callback)));
         }
     };
 
-    private final HandlerCaller.Callback mHandlerCallback = (msg) -> {
-        switch (msg.what) {
-            case MSG_CONNECT: {
-                onConnected();
-                break;
-            } case MSG_ON_FILL_REQUEST: {
-                final SomeArgs args = (SomeArgs) msg.obj;
-                final FillRequest request = (FillRequest) args.arg1;
-                final CancellationSignal cancellation = (CancellationSignal) args.arg2;
-                final IFillCallback callback = (IFillCallback) args.arg3;
-                final FillCallback fillCallback = new FillCallback(callback, request.getId());
-                args.recycle();
-                onFillRequest(request, cancellation, fillCallback);
-                break;
-            } case MSG_ON_SAVE_REQUEST: {
-                final SomeArgs args = (SomeArgs) msg.obj;
-                final SaveRequest request = (SaveRequest) args.arg1;
-                final ISaveCallback callback = (ISaveCallback) args.arg2;
-                final SaveCallback saveCallback = new SaveCallback(callback);
-                args.recycle();
-                onSaveRequest(request, saveCallback);
-                break;
-            } case MSG_DISCONNECT: {
-                onDisconnected();
-                break;
-            } default: {
-                Log.w(TAG, "MyCallbacks received invalid message type: " + msg);
-            }
-        }
-    };
-
-    private HandlerCaller mHandlerCaller;
+    private Handler mHandler;
 
     @CallSuper
     @Override
     public void onCreate() {
         super.onCreate();
-        mHandlerCaller = new HandlerCaller(null, Looper.getMainLooper(), mHandlerCallback, true);
+        mHandler = new Handler(Looper.getMainLooper(), null, true);
     }
 
     @Override
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 99e2c62..2b114d5 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -665,6 +665,11 @@
     }
 
     private void updateDoze() {
+        if (mWindowToken == null) {
+            Slog.w(TAG, "Updating doze without a window token.");
+            return;
+        }
+
         if (mDozing) {
             try {
                 mSandman.startDozing(mWindowToken, mDozeScreenState, mDozeScreenBrightness);
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 422e36b..eebd22a 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -85,7 +85,10 @@
  * or after {@link #onListenerDisconnected()}.
  * </p>
  * <p> Notification listeners cannot get notification access or be bound by the system on
- * {@link ActivityManager#isLowRamDevice() low ram} devices</p>
+ * {@linkplain ActivityManager#isLowRamDevice() low-RAM} devices. The system also ignores
+ * notification listeners running in a work profile. A
+ * {@link android.app.admin.DevicePolicyManager} might block notifications originating from a work
+ * profile.</p>
  */
 public abstract class NotificationListenerService extends Service {
 
@@ -1217,6 +1220,7 @@
                 // convert icon metadata to legacy format for older clients
                 createLegacyIconExtras(sbn.getNotification());
                 maybePopulateRemoteViews(sbn.getNotification());
+                maybePopulatePeople(sbn.getNotification());
             } catch (IllegalArgumentException e) {
                 // warn and drop corrupt notification
                 Log.w(TAG, "onNotificationPosted: can't rebuild notification from " +
diff --git a/core/java/android/service/textclassifier/TextClassifierService.java b/core/java/android/service/textclassifier/TextClassifierService.java
index 6c8c8bc..2c8c4ec 100644
--- a/core/java/android/service/textclassifier/TextClassifierService.java
+++ b/core/java/android/service/textclassifier/TextClassifierService.java
@@ -26,6 +26,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.os.CancellationSignal;
 import android.os.IBinder;
@@ -37,8 +38,6 @@
 import android.view.textclassifier.TextLinks;
 import android.view.textclassifier.TextSelection;
 
-import com.android.internal.R;
-
 /**
  * Abstract base class for the TextClassifier service.
  *
@@ -263,28 +262,33 @@
      */
     @Nullable
     public static ComponentName getServiceComponentName(Context context) {
-        final String str = context.getString(R.string.config_defaultTextClassifierService);
-        if (!TextUtils.isEmpty(str)) {
-            try {
-                final ComponentName componentName = ComponentName.unflattenFromString(str);
-                final Intent intent = new Intent(SERVICE_INTERFACE).setComponent(componentName);
-                final ServiceInfo si = context.getPackageManager()
-                        .getServiceInfo(intent.getComponent(), 0);
-                final String permission = si == null ? null : si.permission;
-                if (Manifest.permission.BIND_TEXTCLASSIFIER_SERVICE.equals(permission)) {
-                    return componentName;
-                }
-                Slog.w(LOG_TAG, String.format(
-                        "Service %s should require %s permission. Found %s permission",
-                        intent.getComponent().flattenToString(),
-                        Manifest.permission.BIND_TEXTCLASSIFIER_SERVICE,
-                        si.permission));
-            } catch (PackageManager.NameNotFoundException e) {
-                Slog.w(LOG_TAG, String.format("Service %s not found", str));
-            }
-        } else {
+        final String packageName = context.getPackageManager().getSystemTextClassifierPackageName();
+        if (TextUtils.isEmpty(packageName)) {
             Slog.d(LOG_TAG, "No configured system TextClassifierService");
+            return null;
         }
+
+        final Intent intent = new Intent(SERVICE_INTERFACE).setPackage(packageName);
+
+        final ResolveInfo ri = context.getPackageManager().resolveService(intent,
+                PackageManager.MATCH_SYSTEM_ONLY);
+
+        if ((ri == null) || (ri.serviceInfo == null)) {
+            Slog.w(LOG_TAG, String.format("Package or service not found in package %s",
+                    packageName));
+            return null;
+        }
+        final ServiceInfo si = ri.serviceInfo;
+
+        final String permission = si.permission;
+        if (Manifest.permission.BIND_TEXTCLASSIFIER_SERVICE.equals(permission)) {
+            return si.getComponentName();
+        }
+        Slog.w(LOG_TAG, String.format(
+                "Service %s should require %s permission. Found %s permission",
+                si.getComponentName(),
+                Manifest.permission.BIND_TEXTCLASSIFIER_SERVICE,
+                si.permission));
         return null;
     }
 }
diff --git a/core/java/android/text/format/DateFormat.java b/core/java/android/text/format/DateFormat.java
index eba9129..94025ef 100755
--- a/core/java/android/text/format/DateFormat.java
+++ b/core/java/android/text/format/DateFormat.java
@@ -159,9 +159,9 @@
     private static Locale sIs24HourLocale;
     private static boolean sIs24Hour;
 
-
     /**
-     * Returns true if user preference is set to 24-hour format.
+     * Returns true if times should be formatted as 24 hour times, false if times should be
+     * formatted as 12 hour (AM/PM) times. Based on the user's chosen locale and other preferences.
      * @param context the context to use for the content resolver
      * @return true if 24 hour time format is selected, false otherwise.
      */
@@ -170,7 +170,8 @@
     }
 
     /**
-     * Returns true if user preference with the given user handle is set to 24-hour format.
+     * Returns true if times should be formatted as 24 hour times, false if times should be
+     * formatted as 12 hour (AM/PM) times. Based on the user's chosen locale and other preferences.
      * @param context the context to use for the content resolver
      * @param userHandle the user handle of the user to query.
      * @return true if 24 hour time format is selected, false otherwise.
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 1ead0b4..a5a7cbc 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -37,7 +37,6 @@
     private static final Map<String, String> DEFAULT_FLAGS;
     static {
         DEFAULT_FLAGS = new HashMap<>();
-        DEFAULT_FLAGS.put("settings_connected_device_v2", "true");
         DEFAULT_FLAGS.put("settings_battery_v2", "true");
         DEFAULT_FLAGS.put("settings_battery_display_app_list", "false");
         DEFAULT_FLAGS.put("settings_zone_picker_v2", "true");
diff --git a/core/java/android/util/LauncherIcons.java b/core/java/android/util/LauncherIcons.java
index 402bef9..cc9991a 100644
--- a/core/java/android/util/LauncherIcons.java
+++ b/core/java/android/util/LauncherIcons.java
@@ -110,9 +110,9 @@
         Drawable badgeColor = sysRes.getDrawable(
                 com.android.internal.R.drawable.ic_corp_icon_badge_color)
                 .getConstantState().newDrawable().mutate();
-        badgeColor.setTint(backgroundColor);
 
         Drawable badgeForeground = sysRes.getDrawable(foregroundRes);
+        badgeForeground.setTint(backgroundColor);
 
         Drawable[] drawables = base == null
                 ? new Drawable[] {badgeShadow, badgeColor, badgeForeground }
diff --git a/core/java/android/util/LongArray.java b/core/java/android/util/LongArray.java
index 9b0489c..fa98096 100644
--- a/core/java/android/util/LongArray.java
+++ b/core/java/android/util/LongArray.java
@@ -16,11 +16,15 @@
 
 package android.util;
 
+import android.annotation.Nullable;
+
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.Preconditions;
-import java.util.Arrays;
+
 import libcore.util.EmptyArray;
 
+import java.util.Arrays;
+
 /**
  * Implements a growing array of long primitives.
  *
@@ -216,4 +220,18 @@
             throw new ArrayIndexOutOfBoundsException(mSize, index);
         }
     }
+
+    /**
+     * Test if each element of {@code a} equals corresponding element from {@code b}
+     */
+    public static boolean elementsEqual(@Nullable LongArray a, @Nullable LongArray b) {
+        if (a == null || b == null) return a == b;
+        if (a.mSize != b.mSize) return false;
+        for (int i = 0; i < a.mSize; i++) {
+            if (a.get(i) != b.get(i)) {
+                return false;
+            }
+        }
+        return true;
+    }
 }
diff --git a/core/java/android/util/apk/ApkVerityBuilder.java b/core/java/android/util/apk/ApkVerityBuilder.java
index 7b89967..3b8fc5c 100644
--- a/core/java/android/util/apk/ApkVerityBuilder.java
+++ b/core/java/android/util/apk/ApkVerityBuilder.java
@@ -331,7 +331,7 @@
         buffer.putShort((short) 1);         // meta algorithm, SHA256_MODE == 1
         buffer.putShort((short) 1);         // data algorithm, SHA256_MODE == 1
 
-        buffer.putInt(0x1);                 // flags, 0x1: has extension
+        buffer.putInt(0x0);                 // flags
         buffer.putInt(0);                   // reserved
 
         buffer.putLong(fileSize);           // original file size
diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java
index 2723030..f5b7068 100644
--- a/core/java/android/view/DisplayCutout.java
+++ b/core/java/android/view/DisplayCutout.java
@@ -23,6 +23,8 @@
 import static android.view.Surface.ROTATION_270;
 import static android.view.Surface.ROTATION_90;
 
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
+
 import android.content.res.Resources;
 import android.graphics.Matrix;
 import android.graphics.Path;
@@ -38,6 +40,7 @@
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.Objects;
@@ -73,6 +76,17 @@
     public static final DisplayCutout NO_CUTOUT = new DisplayCutout(ZERO_RECT, EMPTY_REGION,
             new Size(0, 0));
 
+
+    private static final Object CACHE_LOCK = new Object();
+    @GuardedBy("CACHE_LOCK")
+    private static String sCachedSpec;
+    @GuardedBy("CACHE_LOCK")
+    private static int sCachedDisplayWidth;
+    @GuardedBy("CACHE_LOCK")
+    private static float sCachedDensity;
+    @GuardedBy("CACHE_LOCK")
+    private static DisplayCutout sCachedCutout;
+
     private final Rect mSafeInsets;
     private final Region mBounds;
     private final Size mFrameSize;
@@ -350,10 +364,26 @@
      * @hide
      */
     public static DisplayCutout fromResources(Resources res, int displayWidth) {
-        String spec = res.getString(R.string.config_mainBuiltInDisplayCutout);
+        return fromSpec(res.getString(R.string.config_mainBuiltInDisplayCutout),
+                displayWidth, res.getDisplayMetrics().density);
+    }
+
+    /**
+     * Creates an instance according to the supplied {@link android.util.PathParser.PathData} spec.
+     *
+     * @hide
+     */
+    @VisibleForTesting(visibility = PRIVATE)
+    public static DisplayCutout fromSpec(String spec, int displayWidth, float density) {
         if (TextUtils.isEmpty(spec)) {
             return null;
         }
+        synchronized (CACHE_LOCK) {
+            if (spec.equals(sCachedSpec) && sCachedDisplayWidth == displayWidth
+                    && sCachedDensity == density) {
+                return sCachedCutout;
+            }
+        }
         spec = spec.trim();
         final boolean inDp = spec.endsWith(DP_MARKER);
         if (inDp) {
@@ -370,12 +400,19 @@
 
         final Matrix m = new Matrix();
         if (inDp) {
-            final float dpToPx = res.getDisplayMetrics().density;
-            m.postScale(dpToPx, dpToPx);
+            m.postScale(density, density);
         }
         m.postTranslate(displayWidth / 2f, 0);
         p.transform(m);
-        return fromBounds(p);
+
+        final DisplayCutout result = fromBounds(p);
+        synchronized (CACHE_LOCK) {
+            sCachedSpec = spec;
+            sCachedDisplayWidth = displayWidth;
+            sCachedDensity = density;
+            sCachedCutout = result;
+        }
+        return result;
     }
 
     /**
diff --git a/core/java/android/view/DisplayListCanvas.java b/core/java/android/view/DisplayListCanvas.java
index 8f9ae0e..671532c 100644
--- a/core/java/android/view/DisplayListCanvas.java
+++ b/core/java/android/view/DisplayListCanvas.java
@@ -198,8 +198,8 @@
      *
      * @param layer The layer to composite on this canvas
      */
-    void drawHardwareLayer(HardwareLayer layer) {
-        nDrawLayer(mNativeCanvasWrapper, layer.getLayerHandle());
+    void drawTextureLayer(TextureLayer layer) {
+        nDrawTextureLayer(mNativeCanvasWrapper, layer.getLayerHandle());
     }
 
     ///////////////////////////////////////////////////////////////////////////
@@ -257,7 +257,7 @@
     @CriticalNative
     private static native void nDrawRenderNode(long renderer, long renderNode);
     @CriticalNative
-    private static native void nDrawLayer(long renderer, long layer);
+    private static native void nDrawTextureLayer(long renderer, long layer);
     @CriticalNative
     private static native void nDrawCircle(long renderer, long propCx,
             long propCy, long propRadius, long propPaint);
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 4adcb8f..914ba0c 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -185,13 +185,6 @@
      */
     void setScreenCaptureDisabled(int userId, boolean disabled);
 
-    /**
-     * Testing and debugging infrastructure for writing surface events
-     * to given FD. See RemoteSurfaceTrace.java or Wm.java for format.
-     */
-    void enableSurfaceTrace(in ParcelFileDescriptor fd);
-    void disableSurfaceTrace();
-
     // These can only be called with the SET_ORIENTATION permission.
     /**
      * Update the current screen rotation based on the current state of
diff --git a/core/java/android/view/NotificationHeaderView.java b/core/java/android/view/NotificationHeaderView.java
index fbba8ab..137e820 100644
--- a/core/java/android/view/NotificationHeaderView.java
+++ b/core/java/android/view/NotificationHeaderView.java
@@ -17,6 +17,7 @@
 package android.view;
 
 import android.annotation.Nullable;
+import android.app.AppOpsManager;
 import android.app.Notification;
 import android.content.Context;
 import android.content.res.Resources;
@@ -25,6 +26,7 @@
 import android.graphics.Outline;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.util.ArraySet;
 import android.util.AttributeSet;
 import android.widget.ImageView;
 import android.widget.RemoteViews;
@@ -53,6 +55,10 @@
     private ImageView mExpandButton;
     private CachingIconView mIcon;
     private View mProfileBadge;
+    private View mOverlayIcon;
+    private View mCameraIcon;
+    private View mMicIcon;
+    private View mAppOps;
     private int mIconColor;
     private int mOriginalNotificationColor;
     private boolean mExpanded;
@@ -108,6 +114,10 @@
         mExpandButton = findViewById(com.android.internal.R.id.expand_button);
         mIcon = findViewById(com.android.internal.R.id.icon);
         mProfileBadge = findViewById(com.android.internal.R.id.profile_badge);
+        mCameraIcon = findViewById(com.android.internal.R.id.camera);
+        mMicIcon = findViewById(com.android.internal.R.id.mic);
+        mOverlayIcon = findViewById(com.android.internal.R.id.overlay);
+        mAppOps = findViewById(com.android.internal.R.id.app_ops);
     }
 
     @Override
@@ -198,6 +208,11 @@
                 layoutRight = end - paddingEnd;
                 end = layoutLeft = layoutRight - child.getMeasuredWidth();
             }
+            if (child == mAppOps) {
+                int paddingEnd = mContentEndMargin;
+                layoutRight = end - paddingEnd;
+                end = layoutLeft = layoutRight - child.getMeasuredWidth();
+            }
             if (getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
                 int ltrLeft = layoutLeft;
                 layoutLeft = getWidth() - layoutRight;
@@ -289,6 +304,22 @@
         updateExpandButton();
     }
 
+    /**
+     * Shows or hides 'app op in use' icons based on app usage.
+     */
+    public void showAppOpsIcons(ArraySet<Integer> appOps) {
+        if (mOverlayIcon == null || mCameraIcon == null || mMicIcon == null) {
+            return;
+        }
+
+        mOverlayIcon.setVisibility(appOps.contains(AppOpsManager.OP_SYSTEM_ALERT_WINDOW)
+                ? View.VISIBLE : View.GONE);
+        mCameraIcon.setVisibility(appOps.contains(AppOpsManager.OP_CAMERA)
+                ? View.VISIBLE : View.GONE);
+        mMicIcon.setVisibility(appOps.contains(AppOpsManager.OP_RECORD_AUDIO)
+                ? View.VISIBLE : View.GONE);
+    }
+
     private void updateExpandButton() {
         int drawableId;
         int contentDescriptionId;
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index bd7f8e5..b7524fb 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -152,6 +152,7 @@
     private static native void nativeSeverChildren(long transactionObj, long nativeObject);
     private static native void nativeSetOverrideScalingMode(long transactionObj, long nativeObject,
             int scalingMode);
+    private static native void nativeDestroy(long transactionObj, long nativeObject);
     private static native IBinder nativeGetHandle(long nativeObject);
     private static native boolean nativeGetTransformToDisplayInverse(long nativeObject);
 
@@ -763,18 +764,14 @@
     }
 
     public void deferTransactionUntil(IBinder handle, long frame) {
-        if (frame > 0) {
-            synchronized(SurfaceControl.class) {
-                sGlobalTransaction.deferTransactionUntil(this, handle, frame);
-            }
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.deferTransactionUntil(this, handle, frame);
         }
     }
 
     public void deferTransactionUntil(Surface barrier, long frame) {
-        if (frame > 0) {
-            synchronized(SurfaceControl.class) {
-                sGlobalTransaction.deferTransactionUntilSurface(this, barrier, frame);
-            }
+        synchronized(SurfaceControl.class) {
+            sGlobalTransaction.deferTransactionUntilSurface(this, barrier, frame);
         }
     }
 
@@ -1479,6 +1476,9 @@
 
         public Transaction deferTransactionUntil(SurfaceControl sc, IBinder handle,
                 long frameNumber) {
+            if (frameNumber < 0) {
+                return this;
+            }
             sc.checkNotReleased();
             nativeDeferTransactionUntil(mNativeObject, sc.mNativeObject, handle, frameNumber);
             return this;
@@ -1486,6 +1486,9 @@
 
         public Transaction deferTransactionUntilSurface(SurfaceControl sc, Surface barrierSurface,
                 long frameNumber) {
+            if (frameNumber < 0) {
+                return this;
+            }
             sc.checkNotReleased();
             nativeDeferTransactionUntilSurface(mNativeObject, sc.mNativeObject,
                     barrierSurface.mNativeObject, frameNumber);
@@ -1570,6 +1573,16 @@
             return this;
         }
 
+        /**
+         * Same as {@link #destroy()} except this is invoked in a transaction instead of
+         * immediately.
+         */
+        public Transaction destroy(SurfaceControl sc) {
+            sc.checkNotReleased();
+            nativeDestroy(mNativeObject, sc.mNativeObject);
+            return this;
+        }
+
         public Transaction setDisplaySurface(IBinder displayToken, Surface surface) {
             if (displayToken == null) {
                 throw new IllegalArgumentException("displayToken must not be null");
diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/TextureLayer.java
similarity index 88%
rename from core/java/android/view/HardwareLayer.java
rename to core/java/android/view/TextureLayer.java
index 7af1020..35a886f 100644
--- a/core/java/android/view/HardwareLayer.java
+++ b/core/java/android/view/TextureLayer.java
@@ -25,19 +25,17 @@
 import com.android.internal.util.VirtualRefBasePtr;
 
 /**
- * A hardware layer can be used to render graphics operations into a hardware
- * friendly buffer. For instance, with an OpenGL backend a hardware layer
- * would use a Frame Buffer Object (FBO.) The hardware layer can be used as
- * a drawing cache when a complex set of graphics operations needs to be
- * drawn several times.
+ * TextureLayer represents a SurfaceTexture that will be composited by RenderThread into the
+ * frame when drawn in a HW accelerated Canvas. This is backed by a DeferredLayerUpdater on
+ * the native side.
  *
  * @hide
  */
-final class HardwareLayer {
+final class TextureLayer {
     private ThreadedRenderer mRenderer;
     private VirtualRefBasePtr mFinalizer;
 
-    private HardwareLayer(ThreadedRenderer renderer, long deferredUpdater) {
+    private TextureLayer(ThreadedRenderer renderer, long deferredUpdater) {
         if (renderer == null || deferredUpdater == 0) {
             throw new IllegalArgumentException("Either hardware renderer: " + renderer
                     + " or deferredUpdater: " + deferredUpdater + " is invalid");
@@ -141,11 +139,12 @@
         mRenderer.pushLayerUpdate(this);
     }
 
-    static HardwareLayer adoptTextureLayer(ThreadedRenderer renderer, long layer) {
-        return new HardwareLayer(renderer, layer);
+    static TextureLayer adoptTextureLayer(ThreadedRenderer renderer, long layer) {
+        return new TextureLayer(renderer, layer);
     }
 
-    private static native boolean nPrepare(long layerUpdater, int width, int height, boolean isOpaque);
+    private static native boolean nPrepare(long layerUpdater, int width, int height,
+            boolean isOpaque);
     private static native void nSetLayerPaint(long layerUpdater, long paint);
     private static native void nSetTransform(long layerUpdater, long matrix);
     private static native void nSetSurfaceTexture(long layerUpdater, SurfaceTexture surface);
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index 25dce99..371794045 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -106,7 +106,7 @@
 public class TextureView extends View {
     private static final String LOG_TAG = "TextureView";
 
-    private HardwareLayer mLayer;
+    private TextureLayer mLayer;
     private SurfaceTexture mSurface;
     private SurfaceTextureListener mListener;
     private boolean mHadSurface;
@@ -336,13 +336,13 @@
         if (canvas.isHardwareAccelerated()) {
             DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas;
 
-            HardwareLayer layer = getHardwareLayer();
+            TextureLayer layer = getTextureLayer();
             if (layer != null) {
                 applyUpdate();
                 applyTransformMatrix();
 
                 mLayer.setLayerPaint(mLayerPaint); // ensure layer paint is up to date
-                displayListCanvas.drawHardwareLayer(layer);
+                displayListCanvas.drawTextureLayer(layer);
             }
         }
     }
@@ -369,7 +369,7 @@
         }
     }
 
-    HardwareLayer getHardwareLayer() {
+    TextureLayer getTextureLayer() {
         if (mLayer == null) {
             if (mAttachInfo == null || mAttachInfo.mThreadedRenderer == null) {
                 return null;
@@ -602,7 +602,7 @@
             // the layer here thanks to the validate() call at the beginning of
             // this method
             if (mLayer == null && mUpdateSurface) {
-                getHardwareLayer();
+                getTextureLayer();
             }
 
             if (mLayer != null) {
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index e50d40e..db19681 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -34,6 +34,7 @@
 import android.util.Log;
 import android.view.Surface.OutOfResourcesException;
 import android.view.View.AttachInfo;
+import android.view.animation.AnimationUtils;
 
 import com.android.internal.R;
 import com.android.internal.util.VirtualRefBasePtr;
@@ -833,9 +834,9 @@
      *
      * @return A hardware layer
      */
-    HardwareLayer createTextureLayer() {
+    TextureLayer createTextureLayer() {
         long layer = nCreateTextureLayer(mNativeProxy);
-        return HardwareLayer.adoptTextureLayer(this, layer);
+        return TextureLayer.adoptTextureLayer(this, layer);
     }
 
 
@@ -844,7 +845,7 @@
     }
 
 
-    boolean copyLayerInto(final HardwareLayer layer, final Bitmap bitmap) {
+    boolean copyLayerInto(final TextureLayer layer, final Bitmap bitmap) {
         return nCopyLayerInto(mNativeProxy,
                 layer.getDeferredLayerUpdater(), bitmap);
     }
@@ -855,7 +856,7 @@
      *
      * @param layer The hardware layer that needs an update
      */
-    void pushLayerUpdate(HardwareLayer layer) {
+    void pushLayerUpdate(TextureLayer layer) {
         nPushLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
     }
 
@@ -863,7 +864,7 @@
      * Tells the HardwareRenderer that the layer is destroyed. The renderer
      * should remove the layer from any update queues.
      */
-    void onLayerDestroyed(HardwareLayer layer) {
+    void onLayerDestroyed(TextureLayer layer) {
         nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
     }
 
@@ -943,6 +944,107 @@
         }
     }
 
+    /**
+     * Basic synchronous renderer. Currently only used to render the Magnifier, so use with care.
+     * TODO: deduplicate against ThreadedRenderer.
+     *
+     * @hide
+     */
+    public static class SimpleRenderer {
+        private final RenderNode mRootNode;
+        private long mNativeProxy;
+        private final float mLightY, mLightZ;
+        private Surface mSurface;
+        private final FrameInfo mFrameInfo = new FrameInfo();
+
+        public SimpleRenderer(final Context context, final String name, final Surface surface) {
+            final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
+            mLightY = a.getDimension(R.styleable.Lighting_lightY, 0);
+            mLightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
+            final float lightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
+            final int ambientShadowAlpha =
+                    (int) (255 * a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0) + 0.5f);
+            final int spotShadowAlpha =
+                    (int) (255 * a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0) + 0.5f);
+            a.recycle();
+
+            final long rootNodePtr = nCreateRootRenderNode();
+            mRootNode = RenderNode.adopt(rootNodePtr);
+            mRootNode.setClipToBounds(false);
+            mNativeProxy = nCreateProxy(true /* translucent */, rootNodePtr);
+            nSetName(mNativeProxy, name);
+
+            ProcessInitializer.sInstance.init(context, mNativeProxy);
+            nLoadSystemProperties(mNativeProxy);
+
+            nSetup(mNativeProxy, lightRadius, ambientShadowAlpha, spotShadowAlpha);
+
+            mSurface = surface;
+            nUpdateSurface(mNativeProxy, surface);
+        }
+
+        /**
+         * Set the light center.
+         */
+        public void setLightCenter(final Display display,
+                final int windowLeft, final int windowTop) {
+            // Adjust light position for window offsets.
+            final Point displaySize = new Point();
+            display.getRealSize(displaySize);
+            final float lightX = displaySize.x / 2f - windowLeft;
+            final float lightY = mLightY - windowTop;
+
+            nSetLightCenter(mNativeProxy, lightX, lightY, mLightZ);
+        }
+
+        public RenderNode getRootNode() {
+            return mRootNode;
+        }
+
+        /**
+         * Draw the surface.
+         */
+        public void draw(final FrameDrawingCallback callback) {
+            final long vsync = AnimationUtils.currentAnimationTimeMillis() * 1000000L;
+            mFrameInfo.setVsync(vsync, vsync);
+            mFrameInfo.addFlags(1 << 2 /* VSYNC */);
+            if (callback != null) {
+                nSetFrameCallback(mNativeProxy, callback);
+            }
+            nSyncAndDrawFrame(mNativeProxy, mFrameInfo.mFrameInfo, mFrameInfo.mFrameInfo.length);
+        }
+
+        /**
+         * Destroy the renderer.
+         */
+        public void destroy() {
+            mSurface = null;
+            nDestroy(mNativeProxy, mRootNode.mNativeRenderNode);
+        }
+
+        @Override
+        protected void finalize() throws Throwable {
+            try {
+                nDeleteProxy(mNativeProxy);
+                mNativeProxy = 0;
+            } finally {
+                super.finalize();
+            }
+        }
+    }
+
+    /**
+     * Interface used to receive callbacks when a frame is being drawn.
+     */
+    public interface FrameDrawingCallback {
+        /**
+         * Invoked during a frame drawing.
+         *
+         * @param frame The id of the frame being drawn.
+         */
+        void onFrameDraw(long frame);
+    }
+
     private static class ProcessInitializer {
         static ProcessInitializer sInstance = new ProcessInitializer();
 
@@ -1080,6 +1182,7 @@
     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 void nSetFrameCallback(long nativeProxy, FrameDrawingCallback callback);
 
     private static native long nAddFrameMetricsObserver(long nativeProxy, FrameMetricsObserver observer);
     private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver);
diff --git a/core/java/android/view/TouchDelegate.java b/core/java/android/view/TouchDelegate.java
index dc50fa1..d6c43e8 100644
--- a/core/java/android/view/TouchDelegate.java
+++ b/core/java/android/view/TouchDelegate.java
@@ -105,11 +105,13 @@
         boolean hit = true;
         boolean handled = false;
 
-        switch (event.getAction()) {
+        switch (event.getActionMasked()) {
             case MotionEvent.ACTION_DOWN:
                 mDelegateTargeted = mBounds.contains(x, y);
                 sendToDelegate = mDelegateTargeted;
                 break;
+            case MotionEvent.ACTION_POINTER_DOWN:
+            case MotionEvent.ACTION_POINTER_UP:
             case MotionEvent.ACTION_UP:
             case MotionEvent.ACTION_MOVE:
                 sendToDelegate = mDelegateTargeted;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 3ff3c97..e285222 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2953,6 +2953,9 @@
      *       1                           PFLAG3_NO_REVEAL_ON_FOCUS
      *      1                            PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT
      *     1                             PFLAG3_SCREEN_READER_FOCUSABLE
+     *    1                              PFLAG3_AGGREGATED_VISIBLE
+     *   1                               PFLAG3_AUTOFILLID_EXPLICITLY_SET
+     *  1                                available
      * |-------|-------|-------|-------|
      */
 
@@ -3243,6 +3246,12 @@
      */
     private static final int PFLAG3_AGGREGATED_VISIBLE = 0x20000000;
 
+    /**
+     * Used to indicate that {@link #mAutofillId} was explicitly set through
+     * {@link #setAutofillId(AutofillId)}.
+     */
+    private static final int PFLAG3_AUTOFILLID_EXPLICITLY_SET = 0x40000000;
+
     /* End of masks for mPrivateFlags3 */
 
     /**
@@ -7309,7 +7318,7 @@
     }
 
     private boolean isAccessibilityPane() {
-        return !TextUtils.isEmpty(mAccessibilityPaneTitle);
+        return mAccessibilityPaneTitle != null;
     }
 
     /**
@@ -8144,7 +8153,12 @@
     }
 
     /**
-     * Gets the unique identifier of this view in the screen, for autofill purposes.
+     * Gets the unique, logical identifier of this view in the activity, for autofill purposes.
+     *
+     * <p>The autofill id is created on demand, unless it is explicitly set by
+     * {@link #setAutofillId(AutofillId)}.
+     *
+     * <p>See {@link #setAutofillId(AutofillId)} for more info.
      *
      * @return The View's autofill id.
      */
@@ -8158,6 +8172,73 @@
     }
 
     /**
+     * Sets the unique, logical identifier of this view in the activity, for autofill purposes.
+     *
+     * <p>The autofill id is created on demand, and this method should only be called when a view is
+     * reused after {@link #dispatchProvideAutofillStructure(ViewStructure, int)} is called, as
+     * that method creates a snapshot of the view that is passed along to the autofill service.
+     *
+     * <p>This method is typically used when view subtrees are recycled to represent different
+     * content* &mdash;in this case, the autofill id can be saved before the view content is swapped
+     * out, and restored later when it's swapped back in. For example:
+     *
+     * <pre>
+     * EditText reusableView = ...;
+     * ViewGroup parentView = ...;
+     * AutofillManager afm = ...;
+     *
+     * // Swap out the view and change its contents
+     * AutofillId oldId = reusableView.getAutofillId();
+     * CharSequence oldText = reusableView.getText();
+     * parentView.removeView(reusableView);
+     * AutofillId newId = afm.getNextAutofillId();
+     * reusableView.setText("New I am");
+     * reusableView.setAutofillId(newId);
+     * parentView.addView(reusableView);
+     *
+     * // Later, swap the old content back in
+     * parentView.removeView(reusableView);
+     * reusableView.setAutofillId(oldId);
+     * reusableView.setText(oldText);
+     * parentView.addView(reusableView);
+     * </pre>
+     *
+     * @param id an autofill ID that is unique in the {@link android.app.Activity} hosting the view,
+     * or {@code null} to reset it. Usually it's an id previously allocated to another view (and
+     * obtained through {@link #getAutofillId()}), or a new value obtained through
+     * {@link AutofillManager#getNextAutofillId()}.
+     *
+     * @throws IllegalStateException if the view is already {@link #isAttachedToWindow() attached to
+     * a window}.
+     *
+     * @throws IllegalArgumentException if the id is an autofill id associated with a virtual view.
+     */
+    public void setAutofillId(@Nullable AutofillId id) {
+        // TODO(b/37566627): add unit / CTS test for all possible combinations below
+        if (android.view.autofill.Helper.sVerbose) {
+            Log.v(VIEW_LOG_TAG, "setAutofill(): from " + mAutofillId + " to " + id);
+        }
+        if (isAttachedToWindow()) {
+            throw new IllegalStateException("Cannot set autofill id when view is attached");
+        }
+        if (id != null && id.isVirtual()) {
+            throw new IllegalStateException("Cannot set autofill id assigned to virtual views");
+        }
+        if (id == null && (mPrivateFlags3 & PFLAG3_AUTOFILLID_EXPLICITLY_SET) == 0) {
+            // Ignore reset because it was never explicitly set before.
+            return;
+        }
+        mAutofillId = id;
+        if (id != null) {
+            mAutofillViewId = id.getViewId();
+            mPrivateFlags3 |= PFLAG3_AUTOFILLID_EXPLICITLY_SET;
+        } else {
+            mAutofillViewId = NO_ID;
+            mPrivateFlags3 &= ~PFLAG3_AUTOFILLID_EXPLICITLY_SET;
+        }
+    }
+
+    /**
      * Describes the autofill type of this view, so an
      * {@link android.service.autofill.AutofillService} can create the proper {@link AutofillValue}
      * when autofilling the view.
@@ -18055,19 +18136,20 @@
      * currently attached to.
      */
     public WindowId getWindowId() {
-        if (mAttachInfo == null) {
+        AttachInfo ai = mAttachInfo;
+        if (ai == null) {
             return null;
         }
-        if (mAttachInfo.mWindowId == null) {
+        if (ai.mWindowId == null) {
             try {
-                mAttachInfo.mIWindowId = mAttachInfo.mSession.getWindowId(
-                        mAttachInfo.mWindowToken);
-                mAttachInfo.mWindowId = new WindowId(
-                        mAttachInfo.mIWindowId);
+                ai.mIWindowId = ai.mSession.getWindowId(ai.mWindowToken);
+                if (ai.mIWindowId != null) {
+                    ai.mWindowId = new WindowId(ai.mIWindowId);
+                }
             } catch (RemoteException e) {
             }
         }
-        return mAttachInfo.mWindowId;
+        return ai.mWindowId;
     }
 
     /**
@@ -18463,7 +18545,17 @@
                 // Hence prevent the same autofill view id from being restored multiple times.
                 ((BaseSavedState) state).mSavedData &= ~BaseSavedState.AUTOFILL_ID;
 
-                mAutofillViewId = baseState.mAutofillViewId;
+                if ((mPrivateFlags3 & PFLAG3_AUTOFILLID_EXPLICITLY_SET) != 0) {
+                    // Ignore when view already set it through setAutofillId();
+                    if (android.view.autofill.Helper.sDebug) {
+                        Log.d(VIEW_LOG_TAG, "onRestoreInstanceState(): not setting autofillId to "
+                                + baseState.mAutofillViewId + " because view explicitly set it to "
+                                + mAutofillId);
+                    }
+                } else {
+                    mAutofillViewId = baseState.mAutofillViewId;
+                    mAutofillId = null; // will be set on demand by getAutofillId()
+                }
             }
         }
     }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 810864e..95e4abb 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -95,6 +95,7 @@
 import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
 import android.view.animation.AccelerateDecelerateInterpolator;
 import android.view.animation.Interpolator;
+import android.view.autofill.AutofillManager;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.Scroller;
 
@@ -3925,6 +3926,7 @@
     private final static int MSG_DISPATCH_APP_VISIBILITY = 8;
     private final static int MSG_DISPATCH_GET_NEW_SURFACE = 9;
     private final static int MSG_DISPATCH_KEY_FROM_IME = 11;
+    private final static int MSG_DISPATCH_KEY_FROM_AUTOFILL = 12;
     private final static int MSG_CHECK_FOCUS = 13;
     private final static int MSG_CLOSE_SYSTEM_DIALOGS = 14;
     private final static int MSG_DISPATCH_DRAG_EVENT = 15;
@@ -3966,6 +3968,8 @@
                     return "MSG_DISPATCH_GET_NEW_SURFACE";
                 case MSG_DISPATCH_KEY_FROM_IME:
                     return "MSG_DISPATCH_KEY_FROM_IME";
+                case MSG_DISPATCH_KEY_FROM_AUTOFILL:
+                    return "MSG_DISPATCH_KEY_FROM_AUTOFILL";
                 case MSG_CHECK_FOCUS:
                     return "MSG_CHECK_FOCUS";
                 case MSG_CLOSE_SYSTEM_DIALOGS:
@@ -4143,6 +4147,15 @@
                     }
                     enqueueInputEvent(event, null, QueuedInputEvent.FLAG_DELIVER_POST_IME, true);
                 } break;
+                case MSG_DISPATCH_KEY_FROM_AUTOFILL: {
+                    if (LOCAL_LOGV) {
+                        Log.v(TAG, "Dispatching key " + msg.obj + " from Autofill to " + mView);
+                    }
+                    KeyEvent event = (KeyEvent) msg.obj;
+                    // send InputEvent to pre IME, set FLAG_FROM_AUTOFILL so the InputEvent
+                    // wont be dropped as app window is not focus.
+                    enqueueInputEvent(event, null, QueuedInputEvent.FLAG_FROM_AUTOFILL, true);
+                } break;
                 case MSG_CHECK_FOCUS: {
                     InputMethodManager imm = InputMethodManager.peekInstance();
                     if (imm != null) {
@@ -4433,7 +4446,8 @@
                 Slog.w(mTag, "Dropping event due to root view being removed: " + q.mEvent);
                 return true;
             } else if ((!mAttachInfo.mHasWindowFocus
-                    && !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) || mStopped
+                    && !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)
+                    && (q.mFlags & QueuedInputEvent.FLAG_FROM_AUTOFILL) == 0) || mStopped
                     || (mIsAmbientMode && !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_BUTTON))
                     || (mPausedForTransition && !isBack(q.mEvent))) {
                 // This is a focus event and the window doesn't currently have input focus or
@@ -4768,6 +4782,21 @@
                 ensureTouchMode(event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN));
             }
 
+            if (action == MotionEvent.ACTION_DOWN && mView instanceof ViewGroup) {
+                // Upon motion event within app window, close autofill ui.
+                ViewGroup decorView = (ViewGroup) mView;
+                if (decorView.getChildCount() > 0) {
+                    // We cannot use decorView's Context for querying AutofillManager: DecorView's
+                    // context is based on Application Context, it would allocate a different
+                    // AutofillManager instance.
+                    AutofillManager afm = (AutofillManager) decorView.getChildAt(0).getContext()
+                            .getSystemService(Context.AUTOFILL_MANAGER_SERVICE);
+                    if (afm != null) {
+                        afm.requestHideFillUi();
+                    }
+                }
+            }
+
             if (action == MotionEvent.ACTION_DOWN && mAttachInfo.mTooltipHost != null) {
                 mAttachInfo.mTooltipHost.hideTooltip();
             }
@@ -6427,18 +6456,24 @@
             params.backup();
             mTranslator.translateWindowLayout(params);
         }
+
         if (params != null) {
             if (DBG) Log.d(mTag, "WindowLayout in layoutWindow:" + params);
-        }
 
-        if (params != null && mOrigWindowType != params.type) {
-            // For compatibility with old apps, don't crash here.
-            if (mTargetSdkVersion < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
-                Slog.w(mTag, "Window type can not be changed after "
-                        + "the window is added; ignoring change of " + mView);
-                params.type = mOrigWindowType;
+            if (mOrigWindowType != params.type) {
+                // For compatibility with old apps, don't crash here.
+                if (mTargetSdkVersion < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+                    Slog.w(mTag, "Window type can not be changed after "
+                            + "the window is added; ignoring change of " + mView);
+                    params.type = mOrigWindowType;
+                }
+            }
+
+            if (mSurface.isValid()) {
+                params.frameNumber = mSurface.getNextFrameNumber();
             }
         }
+
         int relayoutResult = mWindowSession.relayout(
                 mWindow, mSeq, params,
                 (int) (mView.getMeasuredWidth() * appScale + 0.5f),
@@ -6805,6 +6840,7 @@
         public static final int FLAG_FINISHED_HANDLED = 1 << 3;
         public static final int FLAG_RESYNTHESIZED = 1 << 4;
         public static final int FLAG_UNHANDLED = 1 << 5;
+        public static final int FLAG_FROM_AUTOFILL = 1 << 6;
 
         public QueuedInputEvent mNext;
 
@@ -7262,6 +7298,12 @@
         mHandler.sendMessage(msg);
     }
 
+    public void dispatchKeyFromAutofill(KeyEvent event) {
+        Message msg = mHandler.obtainMessage(MSG_DISPATCH_KEY_FROM_AUTOFILL, event);
+        msg.setAsynchronous(true);
+        mHandler.sendMessage(msg);
+    }
+
     /**
      * Reinject unhandled {@link InputEvent}s in order to synthesize fallbacks events.
      *
diff --git a/core/java/android/view/WindowId.java b/core/java/android/view/WindowId.java
index c4cda2c7..12e58f1 100644
--- a/core/java/android/view/WindowId.java
+++ b/core/java/android/view/WindowId.java
@@ -16,6 +16,8 @@
 
 package android.view;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
@@ -35,6 +37,7 @@
  * that doesn't allow the other process to negatively harm your window.
  */
 public class WindowId implements Parcelable {
+    @NonNull
     private final IWindowId mToken;
 
     /**
@@ -74,8 +77,7 @@
             }
         };
 
-        final HashMap<IBinder, WindowId> mRegistrations
-                = new HashMap<IBinder, WindowId>();
+        final HashMap<IBinder, WindowId> mRegistrations = new HashMap<>();
 
         class H extends Handler {
             @Override
@@ -163,10 +165,9 @@
      * same package.
      */
     @Override
-    public boolean equals(Object otherObj) {
+    public boolean equals(@Nullable Object otherObj) {
         if (otherObj instanceof WindowId) {
-            return mToken.asBinder().equals(((WindowId) otherObj)
-                    .mToken.asBinder());
+            return mToken.asBinder().equals(((WindowId) otherObj).mToken.asBinder());
         }
         return false;
     }
@@ -182,7 +183,7 @@
         sb.append("IntentSender{");
         sb.append(Integer.toHexString(System.identityHashCode(this)));
         sb.append(": ");
-        sb.append(mToken != null ? mToken.asBinder() : null);
+        sb.append(mToken.asBinder());
         sb.append('}');
         return sb.toString();
     }
@@ -195,30 +196,32 @@
         out.writeStrongBinder(mToken.asBinder());
     }
 
-    public static final Parcelable.Creator<WindowId> CREATOR
-            = new Parcelable.Creator<WindowId>() {
+    public static final Parcelable.Creator<WindowId> CREATOR = new Parcelable.Creator<WindowId>() {
+        @Override
         public WindowId createFromParcel(Parcel in) {
             IBinder target = in.readStrongBinder();
             return target != null ? new WindowId(target) : null;
         }
 
+        @Override
         public WindowId[] newArray(int size) {
             return new WindowId[size];
         }
     };
 
     /** @hide */
+    @NonNull
     public IWindowId getTarget() {
         return mToken;
     }
 
     /** @hide */
-    public WindowId(IWindowId target) {
+    public WindowId(@NonNull IWindowId target) {
         mToken = target;
     }
 
     /** @hide */
-    public WindowId(IBinder target) {
+    public WindowId(@NonNull IBinder target) {
         mToken = IWindowId.Stub.asInterface(target);
     }
 }
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index c0a9666..2354f25 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -2234,6 +2234,7 @@
          * @see #LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
          * @see #LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
          * @see DisplayCutout
+         * @see android.R.attr#layoutInDisplayCutoutMode
          */
         @LayoutInDisplayCutoutMode
         public int layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
@@ -2371,6 +2372,13 @@
         public long hideTimeoutMilliseconds = -1;
 
         /**
+         * A frame number in which changes requested in this layout will be rendered.
+         *
+         * @hide
+         */
+        public long frameNumber = -1;
+
+        /**
          * The color mode requested by this window. The target display may
          * not be able to honor the request. When the color mode is not set
          * to {@link ActivityInfo#COLOR_MODE_DEFAULT}, it might override the
@@ -2543,6 +2551,7 @@
             TextUtils.writeToParcel(accessibilityTitle, out, parcelableFlags);
             out.writeInt(mColorMode);
             out.writeLong(hideTimeoutMilliseconds);
+            out.writeLong(frameNumber);
         }
 
         public static final Parcelable.Creator<LayoutParams> CREATOR
@@ -2599,6 +2608,7 @@
             accessibilityTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
             mColorMode = in.readInt();
             hideTimeoutMilliseconds = in.readLong();
+            frameNumber = in.readLong();
         }
 
         @SuppressWarnings({"PointlessBitwiseExpression"})
@@ -2799,6 +2809,10 @@
                 changes |= SURFACE_INSETS_CHANGED;
             }
 
+            // The frame number changing is only relevant in the context of other
+            // changes, and so we don't need to track it with a flag.
+            frameNumber = o.frameNumber;
+
             if (hasManualSurfaceInsets != o.hasManualSurfaceInsets) {
                 hasManualSurfaceInsets = o.hasManualSurfaceInsets;
                 changes |= SURFACE_INSETS_CHANGED;
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 417a725..5b1dd5c 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -3203,7 +3203,7 @@
         fieldIndex++;
         if (mConnectionId != DEFAULT.mConnectionId) nonDefaultFields |= bitAt(fieldIndex);
         fieldIndex++;
-        if (!Objects.equals(mChildNodeIds, DEFAULT.mChildNodeIds)) {
+        if (!LongArray.elementsEqual(mChildNodeIds, DEFAULT.mChildNodeIds)) {
             nonDefaultFields |= bitAt(fieldIndex);
         }
         fieldIndex++;
diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java
index 474db12..64686dd 100644
--- a/core/java/android/view/animation/Animation.java
+++ b/core/java/android/view/animation/Animation.java
@@ -206,6 +206,8 @@
      */
     private boolean mDetachWallpaper = false;
 
+    private boolean mShowWallpaper;
+
     private boolean mMore = true;
     private boolean mOneMoreTime = true;
 
@@ -253,7 +255,10 @@
 
         setBackgroundColor(a.getInt(com.android.internal.R.styleable.Animation_background, 0));
 
-        setDetachWallpaper(a.getBoolean(com.android.internal.R.styleable.Animation_detachWallpaper, false));
+        setDetachWallpaper(
+                a.getBoolean(com.android.internal.R.styleable.Animation_detachWallpaper, false));
+        setShowWallpaper(
+                a.getBoolean(com.android.internal.R.styleable.Animation_showWallpaper, false));
 
         final int resID = a.getResourceId(com.android.internal.R.styleable.Animation_interpolator, 0);
 
@@ -661,6 +666,18 @@
     }
 
     /**
+     * If this animation is run as a window animation, this will make the wallpaper visible behind
+     * the animation.
+     *
+     * @param showWallpaper Whether the wallpaper should be shown during the animation.
+     * @attr ref android.R.styleable#Animation_detachWallpaper
+     * @hide
+     */
+    public void setShowWallpaper(boolean showWallpaper) {
+        mShowWallpaper = showWallpaper;
+    }
+
+    /**
      * Gets the acceleration curve type for this animation.
      *
      * @return the {@link Interpolator} associated to this animation
@@ -775,6 +792,16 @@
     }
 
     /**
+     * @return If run as a window animation, returns whether the wallpaper will be shown behind
+     *         during the animation.
+     * @attr ref android.R.styleable#Animation_showWallpaper
+     * @hide
+     */
+    public boolean getShowWallpaper() {
+        return mShowWallpaper;
+    }
+
+    /**
      * <p>Indicates whether or not this animation will affect the transformation
      * matrix. For instance, a fade animation will not affect the matrix whereas
      * a scale animation will.</p>
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 7792fa6..1e562ea 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -46,6 +46,7 @@
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.Choreographer;
+import android.view.KeyEvent;
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
@@ -357,6 +358,9 @@
     @GuardedBy("mLock")
     @Nullable private ArraySet<AutofillId> mFillableIds;
 
+    /** id of last requested autofill ui */
+    @Nullable private AutofillId mIdShownFillUi;
+
     /**
      * Views that were already "entered" - if they're entered again when the session is not active,
      * they're ignored
@@ -411,6 +415,13 @@
                 @Nullable Rect virtualBounds, IAutofillWindowPresenter presenter);
 
         /**
+         * Dispatch unhandled keyevent from Autofill window
+         * @param anchor The real view the UI needs to anchor to.
+         * @param keyEvent Unhandled KeyEvent from autofill window.
+         */
+        void autofillClientDispatchUnhandledKey(@NonNull View anchor, @NonNull KeyEvent keyEvent);
+
+        /**
          * Request hiding the autofill UI.
          *
          * @return Whether the UI was hidden.
@@ -490,7 +501,17 @@
         /**
           * @return Whether compatibility mode is enabled.
           */
-        boolean autofillIsCompatibilityModeEnabled();
+        boolean autofillClientIsCompatibilityModeEnabled();
+
+        /**
+         * Gets the next unique autofill ID.
+         *
+         * <p>Typically used to manage views whose content is recycled - see
+         * {@link View#setAutofillId(AutofillId)} for more info.
+         *
+         * @return An ID that is unique in the activity.
+         */
+        @Nullable AutofillId autofillClientGetNextAutofillId();
     }
 
     /**
@@ -773,7 +794,7 @@
     /** Returns AutofillCallback if need fire EVENT_INPUT_UNAVAILABLE */
     @GuardedBy("mLock")
     private AutofillCallback notifyViewEnteredLocked(@NonNull View view, int flags) {
-        final AutofillId id = getAutofillId(view);
+        final AutofillId id = view.getAutofillId();
         if (shouldIgnoreViewEnteredLocked(id, flags)) return null;
 
         AutofillCallback callback = null;
@@ -823,7 +844,7 @@
         if (mEnabled && isActiveLocked()) {
             // dont notify exited when Activity is already in background
             if (!isClientDisablingEnterExitEvent()) {
-                final AutofillId id = getAutofillId(view);
+                final AutofillId id = view.getAutofillId();
 
                 // Update focus on existing session.
                 updateSessionLocked(id, null, null, ACTION_VIEW_EXITED, 0);
@@ -866,6 +887,7 @@
             if (mEnabled && isActiveLocked()) {
                 final AutofillId id = virtual ? getAutofillId(view, virtualId)
                         : view.getAutofillId();
+                if (sVerbose) Log.v(TAG, "visibility changed for " + id + ": " + isVisible);
                 if (!isVisible && mFillableIds != null) {
                     if (mFillableIds.contains(id)) {
                         if (sDebug) Log.d(TAG, "Hidding UI when view " + id + " became invisible");
@@ -874,6 +896,8 @@
                 }
                 if (mTrackedViews != null) {
                     mTrackedViews.notifyViewVisibilityChangedLocked(id, isVisible);
+                } else if (sVerbose) {
+                    Log.v(TAG, "Ignoring visibility change on " + id + ": no tracked views");
                 }
             }
         }
@@ -1004,7 +1028,7 @@
             if (mLastAutofilledData == null) {
                 view.setAutofilled(false);
             } else {
-                id = getAutofillId(view);
+                id = view.getAutofillId();
                 if (mLastAutofilledData.containsKey(id)) {
                     value = view.getAutofillValue();
                     valueWasRead = true;
@@ -1029,7 +1053,7 @@
             }
 
             if (id == null) {
-                id = getAutofillId(view);
+                id = view.getAutofillId();
             }
 
             if (!valueWasRead) {
@@ -1429,8 +1453,27 @@
         }
     }
 
-    private static AutofillId getAutofillId(View view) {
-        return new AutofillId(view.getAutofillViewId());
+    /**
+     * Gets the next unique autofill ID for the activity context.
+     *
+     * <p>Typically used to manage views whose content is recycled - see
+     * {@link View#setAutofillId(AutofillId)} for more info.
+     *
+     * @return An ID that is unique in the activity, or {@code null} if autofill is not supported in
+     * the {@link Context} associated with this {@link AutofillManager}.
+     */
+    @Nullable
+    public AutofillId getNextAutofillId() {
+        final AutofillClient client = getClient();
+        if (client == null) return null;
+
+        final AutofillId id = client.autofillClientGetNextAutofillId();
+
+        if (id == null && sDebug) {
+            Log.d(TAG, "getNextAutofillId(): client " + client + " returned null");
+        }
+
+        return id;
     }
 
     private static AutofillId getAutofillId(View parent, int virtualId) {
@@ -1507,6 +1550,7 @@
         mTrackedViews = null;
         mFillableIds = null;
         mSaveTriggerId = null;
+        mIdShownFillUi = null;
         if (resetEnteredIds) {
             mEnteredIds = null;
         }
@@ -1636,8 +1680,9 @@
 
                 if (client != null) {
                     if (client.autofillClientRequestShowFillUi(anchor, width, height,
-                            anchorBounds, presenter) && mCallback != null) {
+                            anchorBounds, presenter)) {
                         callback = mCallback;
+                        mIdShownFillUi = id;
                     }
                 }
             }
@@ -1668,6 +1713,24 @@
         }
     }
 
+    private void dispatchUnhandledKey(int sessionId, AutofillId id, KeyEvent keyEvent) {
+        final View anchor = findView(id);
+        if (anchor == null) {
+            return;
+        }
+
+        AutofillCallback callback = null;
+        synchronized (mLock) {
+            if (mSessionId == sessionId) {
+                AutofillClient client = getClient();
+
+                if (client != null) {
+                    client.autofillClientDispatchUnhandledKey(anchor, keyEvent);
+                }
+            }
+        }
+    }
+
     /** @hide */
     public static final int SET_STATE_FLAG_ENABLED = 0x01;
     /** @hide */
@@ -1713,7 +1776,7 @@
                 if (mLastAutofilledData == null) {
                     mLastAutofilledData = new ParcelableMap(1);
                 }
-                mLastAutofilledData.put(getAutofillId(view), targetValue);
+                mLastAutofilledData.put(view.getAutofillId(), targetValue);
             }
             view.setAutofilled(true);
         }
@@ -1886,10 +1949,23 @@
         }
     }
 
-    private void requestHideFillUi(AutofillId id) {
-        final View anchor = findView(id);
+    /** @hide */
+    public void requestHideFillUi() {
+        requestHideFillUi(mIdShownFillUi, true);
+    }
+
+    private void requestHideFillUi(AutofillId id, boolean force) {
+        final View anchor = id == null ? null : findView(id);
         if (sVerbose) Log.v(TAG, "requestHideFillUi(" + id + "): anchor = " + anchor);
         if (anchor == null) {
+            if (force) {
+                // When user taps outside autofill window, force to close fill ui even id does
+                // not match.
+                AutofillClient client = getClient();
+                if (client != null) {
+                    client.autofillClientRequestHideFillUi();
+                }
+            }
             return;
         }
         requestHideFillUi(id, anchor);
@@ -1905,7 +1981,8 @@
             //    service being uninstalled and the UI being dismissed.
             AutofillClient client = getClient();
             if (client != null) {
-                if (client.autofillClientRequestHideFillUi() && mCallback != null) {
+                if (client.autofillClientRequestHideFillUi()) {
+                    mIdShownFillUi = null;
                     callback = mCallback;
                 }
             }
@@ -2597,7 +2674,7 @@
         public void requestHideFillUi(int sessionId, AutofillId id) {
             final AutofillManager afm = mAfm.get();
             if (afm != null) {
-                afm.post(() -> afm.requestHideFillUi(id));
+                afm.post(() -> afm.requestHideFillUi(id, false));
             }
         }
 
@@ -2610,6 +2687,14 @@
         }
 
         @Override
+        public void dispatchUnhandledKey(int sessionId, AutofillId id, KeyEvent fullScreen) {
+            final AutofillManager afm = mAfm.get();
+            if (afm != null) {
+                afm.post(() -> afm.dispatchUnhandledKey(sessionId, id, fullScreen));
+            }
+        }
+
+        @Override
         public void startIntentSender(IntentSender intentSender, Intent intent) {
             final AutofillManager afm = mAfm.get();
             if (afm != null) {
diff --git a/core/java/android/view/autofill/IAutoFillManagerClient.aidl b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
index 254c8a5..0ff7a0b 100644
--- a/core/java/android/view/autofill/IAutoFillManagerClient.aidl
+++ b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
@@ -25,6 +25,7 @@
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillValue;
 import android.view.autofill.IAutofillWindowPresenter;
+import android.view.KeyEvent;
 
 /**
  * Object running in the application process and responsible for autofilling it.
@@ -74,6 +75,13 @@
     void notifyNoFillUi(int sessionId, in AutofillId id, int sessionFinishedState);
 
     /**
+     * Dispatches unhandled keyevent from autofill ui. Autofill ui handles DPAD and ENTER events,
+     * other unhandled keyevents are dispatched to app's window to filter autofill result.
+     * Note this method is not called when autofill ui is in fullscreen mode (TV only).
+     */
+    void dispatchUnhandledKey(int sessionId, in AutofillId id, in KeyEvent keyEvent);
+
+    /**
      * Starts the provided intent sender.
      */
     void startIntentSender(in IntentSender intentSender, in Intent intent);
diff --git a/core/java/android/view/textclassifier/SmartSelection.java b/core/java/android/view/textclassifier/SmartSelection.java
deleted file mode 100644
index 69c38ee..0000000
--- a/core/java/android/view/textclassifier/SmartSelection.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.textclassifier;
-
-import android.annotation.Nullable;
-import android.content.res.AssetFileDescriptor;
-
-/**
- *  Java wrapper for SmartSelection native library interface.
- *  This library is used for detecting entities in text.
- */
-final class SmartSelection {
-
-    static {
-        System.loadLibrary("textclassifier");
-    }
-
-    /** Hints the classifier that this may be a url. */
-    static final int HINT_FLAG_URL = 0x01;
-    /** Hints the classifier that this may be an email. */
-    static final int HINT_FLAG_EMAIL = 0x02;
-
-    private final long mCtx;
-
-    /**
-     * Creates a new instance of SmartSelect predictor, using the provided model image,
-     * given as a file descriptor.
-     */
-    SmartSelection(int fd) {
-        mCtx = nativeNew(fd);
-    }
-
-    /**
-     * Creates a new instance of SmartSelect predictor, using the provided model image, given as a
-     * file path.
-     */
-    SmartSelection(String path) {
-        mCtx = nativeNewFromPath(path);
-    }
-
-    /**
-     * Creates a new instance of SmartSelect predictor, using the provided model image, given as an
-     * AssetFileDescriptor.
-     */
-    SmartSelection(AssetFileDescriptor afd) {
-        mCtx = nativeNewFromAssetFileDescriptor(afd, afd.getStartOffset(), afd.getLength());
-        if (mCtx == 0L) {
-            throw new IllegalArgumentException(
-                "Couldn't initialize TC from given AssetFileDescriptor");
-        }
-    }
-
-    /**
-     * Given a string context and current selection, computes the SmartSelection suggestion.
-     *
-     * The begin and end are character indices into the context UTF8 string. selectionBegin is the
-     * character index where the selection begins, and selectionEnd is the index of one character
-     * past the selection span.
-     *
-     * The return value is an array of two ints: suggested selection beginning and end, with the
-     * same semantics as the input selectionBeginning and selectionEnd.
-     */
-    public int[] suggest(String context, int selectionBegin, int selectionEnd) {
-        return nativeSuggest(mCtx, context, selectionBegin, selectionEnd);
-    }
-
-    /**
-     * Given a string context and current selection, classifies the type of the selected text.
-     *
-     * The begin and end params are character indices in the context string.
-     *
-     * Returns an array of ClassificationResult objects with the probability
-     * scores for different collections.
-     */
-    public ClassificationResult[] classifyText(
-            String context, int selectionBegin, int selectionEnd, int hintFlags) {
-        return nativeClassifyText(mCtx, context, selectionBegin, selectionEnd, hintFlags);
-    }
-
-    /**
-     * Annotates given input text. Every word of the input is a part of some annotation.
-     * The annotations are sorted by their position in the context string.
-     * The annotations do not overlap.
-     */
-    public AnnotatedSpan[] annotate(String text) {
-        return nativeAnnotate(mCtx, text);
-    }
-
-    /**
-     * Frees up the allocated memory.
-     */
-    public void close() {
-        nativeClose(mCtx);
-    }
-
-    /**
-     * Returns a comma separated list of locales supported by the model as BCP 47 tags.
-     */
-    public static String getLanguages(int fd) {
-        return nativeGetLanguage(fd);
-    }
-
-    /**
-     * Returns the version of the model.
-     */
-    public static int getVersion(int fd) {
-        return nativeGetVersion(fd);
-    }
-
-    private static native long nativeNew(int fd);
-
-    private static native long nativeNewFromPath(String path);
-
-    private static native long nativeNewFromAssetFileDescriptor(AssetFileDescriptor afd,
-                                                                long offset, long size);
-
-    private static native int[] nativeSuggest(
-            long context, String text, int selectionBegin, int selectionEnd);
-
-    private static native ClassificationResult[] nativeClassifyText(
-            long context, String text, int selectionBegin, int selectionEnd, int hintFlags);
-
-    private static native AnnotatedSpan[] nativeAnnotate(long context, String text);
-
-    private static native void nativeClose(long context);
-
-    private static native String nativeGetLanguage(int fd);
-
-    private static native int nativeGetVersion(int fd);
-
-    /** Classification result for classifyText method. */
-    static final class ClassificationResult {
-        final String mCollection;
-        /** float range: 0 - 1 */
-        final float mScore;
-        @Nullable final DatetimeParseResult mDatetime;
-
-        ClassificationResult(String collection, float score) {
-            mCollection = collection;
-            mScore = score;
-            mDatetime = null;
-        }
-
-        ClassificationResult(String collection, float score, DatetimeParseResult datetime) {
-            mCollection = collection;
-            mScore = score;
-            mDatetime = datetime;
-        }
-    }
-
-    /** Parsed date information for the classification result. */
-    static final class DatetimeParseResult {
-        long mMsSinceEpoch;
-    }
-
-    /** Represents a result of Annotate call. */
-    public static final class AnnotatedSpan {
-        final int mStartIndex;
-        final int mEndIndex;
-        final ClassificationResult[] mClassification;
-
-        AnnotatedSpan(int startIndex, int endIndex, ClassificationResult[] classification) {
-            mStartIndex = startIndex;
-            mEndIndex = endIndex;
-            mClassification = classification;
-        }
-
-        public int getStartIndex() {
-            return mStartIndex;
-        }
-
-        public int getEndIndex() {
-            return mEndIndex;
-        }
-
-        public ClassificationResult[] getClassification() {
-            return mClassification;
-        }
-    }
-}
diff --git a/core/java/android/view/textclassifier/SystemTextClassifier.java b/core/java/android/view/textclassifier/SystemTextClassifier.java
index cbc3828..2b335fb 100644
--- a/core/java/android/view/textclassifier/SystemTextClassifier.java
+++ b/core/java/android/view/textclassifier/SystemTextClassifier.java
@@ -29,6 +29,8 @@
 import android.service.textclassifier.ITextLinksCallback;
 import android.service.textclassifier.ITextSelectionCallback;
 
+import com.android.internal.util.Preconditions;
+
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
@@ -40,12 +42,17 @@
     private static final String LOG_TAG = "SystemTextClassifier";
 
     private final ITextClassifierService mManagerService;
+    private final TextClassificationConstants mSettings;
     private final TextClassifier mFallback;
+    private final String mPackageName;
 
-    SystemTextClassifier(Context context) throws ServiceManager.ServiceNotFoundException {
+    SystemTextClassifier(Context context, TextClassificationConstants settings)
+                throws ServiceManager.ServiceNotFoundException {
         mManagerService = ITextClassifierService.Stub.asInterface(
                 ServiceManager.getServiceOrThrow(Context.TEXT_CLASSIFICATION_SERVICE));
-        mFallback = new TextClassifierImpl(context);
+        mSettings = Preconditions.checkNotNull(settings);
+        mFallback = new TextClassifierImpl(context, settings);
+        mPackageName = context.getPackageName();
     }
 
     /**
@@ -106,7 +113,17 @@
     public TextLinks generateLinks(
             @NonNull CharSequence text, @Nullable TextLinks.Options options) {
         Utils.validate(text, false /* allowInMainThread */);
+
+        if (!mSettings.isSmartLinkifyEnabled()) {
+            return TextClassifier.NO_OP.generateLinks(text, options);
+        }
+
         try {
+            if (options == null) {
+                options = new TextLinks.Options().setCallingPackageName(mPackageName);
+            } else if (!mPackageName.equals(options.getCallingPackageName())) {
+                options.setCallingPackageName(mPackageName);
+            }
             final TextLinksCallback callback = new TextLinksCallback();
             mManagerService.onGenerateLinks(text, options, callback);
             final TextLinks links = callback.mReceiver.get();
diff --git a/core/java/android/view/textclassifier/TextClassificationConstants.java b/core/java/android/view/textclassifier/TextClassificationConstants.java
new file mode 100644
index 0000000..21b5603
--- /dev/null
+++ b/core/java/android/view/textclassifier/TextClassificationConstants.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.textclassifier;
+
+import android.annotation.Nullable;
+import android.util.KeyValueListParser;
+import android.util.Slog;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.StringJoiner;
+
+/**
+ * TextClassifier specific settings.
+ * This is encoded as a key=value list, separated by commas. Ex:
+ *
+ * <pre>
+ * smart_linkify_enabled                    (boolean)
+ * system_textclassifier_enabled            (boolean)
+ * model_dark_launch_enabled                (boolean)
+ * smart_selection_enabled                  (boolean)
+ * smart_text_share_enabled                 (boolean)
+ * smart_linkify_enabled                    (boolean)
+ * smart_select_animation_enabled           (boolean)
+ * suggest_selection_max_range_length       (int)
+ * classify_text_max_range_length           (int)
+ * generate_links_max_text_length           (int)
+ * generate_links_log_sample_rate           (int)
+ * entity_list_default                      (String[])
+ * entity_list_not_editable                 (String[])
+ * entity_list_editable                     (String[])
+ * </pre>
+ *
+ * <p>
+ * Type: string
+ * see also android.provider.Settings.Global.TEXT_CLASSIFIER_CONSTANTS
+ *
+ * Example of setting the values for testing.
+ * adb shell settings put global text_classifier_constants \
+ *      model_dark_launch_enabled=true,smart_selection_enabled=true,\
+ *      entity_list_default=phone:address
+ * @hide
+ */
+public final class TextClassificationConstants {
+
+    private static final String LOG_TAG = "TextClassificationConstants";
+
+    private static final String LOCAL_TEXT_CLASSIFIER_ENABLED =
+            "local_textclassifier_enabled";
+    private static final String SYSTEM_TEXT_CLASSIFIER_ENABLED =
+            "system_textclassifier_enabled";
+    private static final String MODEL_DARK_LAUNCH_ENABLED =
+            "model_dark_launch_enabled";
+    private static final String SMART_SELECTION_ENABLED =
+            "smart_selection_enabled";
+    private static final String SMART_TEXT_SHARE_ENABLED =
+            "smart_text_share_enabled";
+    private static final String SMART_LINKIFY_ENABLED =
+            "smart_linkify_enabled";
+    private static final String SMART_SELECT_ANIMATION_ENABLED =
+            "smart_select_animation_enabled";
+    private static final String SUGGEST_SELECTION_MAX_RANGE_LENGTH =
+            "suggest_selection_max_range_length";
+    private static final String CLASSIFY_TEXT_MAX_RANGE_LENGTH =
+            "classify_text_max_range_length";
+    private static final String GENERATE_LINKS_MAX_TEXT_LENGTH =
+            "generate_links_max_text_length";
+    private static final String GENERATE_LINKS_LOG_SAMPLE_RATE =
+            "generate_links_log_sample_rate";
+    private static final String ENTITY_LIST_DEFAULT =
+            "entity_list_default";
+    private static final String ENTITY_LIST_NOT_EDITABLE =
+            "entity_list_not_editable";
+    private static final String ENTITY_LIST_EDITABLE =
+            "entity_list_editable";
+
+    private static final boolean LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT = true;
+    private static final boolean SYSTEM_TEXT_CLASSIFIER_ENABLED_DEFAULT = true;
+    private static final boolean MODEL_DARK_LAUNCH_ENABLED_DEFAULT = false;
+    private static final boolean SMART_SELECTION_ENABLED_DEFAULT = true;
+    private static final boolean SMART_TEXT_SHARE_ENABLED_DEFAULT = true;
+    private static final boolean SMART_LINKIFY_ENABLED_DEFAULT = true;
+    private static final boolean SMART_SELECT_ANIMATION_ENABLED_DEFAULT = true;
+    private static final int SUGGEST_SELECTION_MAX_RANGE_LENGTH_DEFAULT = 10 * 1000;
+    private static final int CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT = 10 * 1000;
+    private static final int GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT = 100 * 1000;
+    private static final int GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT = 100;
+    private static final String ENTITY_LIST_DELIMITER = ":";
+    private static final String ENTITY_LIST_DEFAULT_VALUE = new StringJoiner(ENTITY_LIST_DELIMITER)
+            .add(TextClassifier.TYPE_ADDRESS)
+            .add(TextClassifier.TYPE_EMAIL)
+            .add(TextClassifier.TYPE_PHONE)
+            .add(TextClassifier.TYPE_URL)
+            .add(TextClassifier.TYPE_DATE)
+            .add(TextClassifier.TYPE_DATE_TIME)
+            .add(TextClassifier.TYPE_FLIGHT_NUMBER).toString();
+
+    private final boolean mSystemTextClassifierEnabled;
+    private final boolean mLocalTextClassifierEnabled;
+    private final boolean mModelDarkLaunchEnabled;
+    private final boolean mSmartSelectionEnabled;
+    private final boolean mSmartTextShareEnabled;
+    private final boolean mSmartLinkifyEnabled;
+    private final boolean mSmartSelectionAnimationEnabled;
+    private final int mSuggestSelectionMaxRangeLength;
+    private final int mClassifyTextMaxRangeLength;
+    private final int mGenerateLinksMaxTextLength;
+    private final int mGenerateLinksLogSampleRate;
+    private final List<String> mEntityListDefault;
+    private final List<String> mEntityListNotEditable;
+    private final List<String> mEntityListEditable;
+
+    private TextClassificationConstants(@Nullable String settings) {
+        final KeyValueListParser parser = new KeyValueListParser(',');
+        try {
+            parser.setString(settings);
+        } catch (IllegalArgumentException e) {
+            // Failed to parse the settings string, log this and move on with defaults.
+            Slog.e(LOG_TAG, "Bad TextClassifier settings: " + settings);
+        }
+        mSystemTextClassifierEnabled = parser.getBoolean(
+                SYSTEM_TEXT_CLASSIFIER_ENABLED,
+                SYSTEM_TEXT_CLASSIFIER_ENABLED_DEFAULT);
+        mLocalTextClassifierEnabled = parser.getBoolean(
+                LOCAL_TEXT_CLASSIFIER_ENABLED,
+                LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT);
+        mModelDarkLaunchEnabled = parser.getBoolean(
+                MODEL_DARK_LAUNCH_ENABLED,
+                MODEL_DARK_LAUNCH_ENABLED_DEFAULT);
+        mSmartSelectionEnabled = parser.getBoolean(
+                SMART_SELECTION_ENABLED,
+                SMART_SELECTION_ENABLED_DEFAULT);
+        mSmartTextShareEnabled = parser.getBoolean(
+                SMART_TEXT_SHARE_ENABLED,
+                SMART_TEXT_SHARE_ENABLED_DEFAULT);
+        mSmartLinkifyEnabled = parser.getBoolean(
+                SMART_LINKIFY_ENABLED,
+                SMART_LINKIFY_ENABLED_DEFAULT);
+        mSmartSelectionAnimationEnabled = parser.getBoolean(
+                SMART_SELECT_ANIMATION_ENABLED,
+                SMART_SELECT_ANIMATION_ENABLED_DEFAULT);
+        mSuggestSelectionMaxRangeLength = parser.getInt(
+                SUGGEST_SELECTION_MAX_RANGE_LENGTH,
+                SUGGEST_SELECTION_MAX_RANGE_LENGTH_DEFAULT);
+        mClassifyTextMaxRangeLength = parser.getInt(
+                CLASSIFY_TEXT_MAX_RANGE_LENGTH,
+                CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT);
+        mGenerateLinksMaxTextLength = parser.getInt(
+                GENERATE_LINKS_MAX_TEXT_LENGTH,
+                GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT);
+        mGenerateLinksLogSampleRate = parser.getInt(
+                GENERATE_LINKS_LOG_SAMPLE_RATE,
+                GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT);
+        mEntityListDefault = parseEntityList(parser.getString(
+                ENTITY_LIST_DEFAULT,
+                ENTITY_LIST_DEFAULT_VALUE));
+        mEntityListNotEditable = parseEntityList(parser.getString(
+                ENTITY_LIST_NOT_EDITABLE,
+                ENTITY_LIST_DEFAULT_VALUE));
+        mEntityListEditable = parseEntityList(parser.getString(
+                ENTITY_LIST_EDITABLE,
+                ENTITY_LIST_DEFAULT_VALUE));
+    }
+
+    /** Load from a settings string. */
+    public static TextClassificationConstants loadFromString(String settings) {
+        return new TextClassificationConstants(settings);
+    }
+
+    public boolean isLocalTextClassifierEnabled() {
+        return mLocalTextClassifierEnabled;
+    }
+
+    public boolean isSystemTextClassifierEnabled() {
+        return mSystemTextClassifierEnabled;
+    }
+
+    public boolean isModelDarkLaunchEnabled() {
+        return mModelDarkLaunchEnabled;
+    }
+
+    public boolean isSmartSelectionEnabled() {
+        return mSmartSelectionEnabled;
+    }
+
+    public boolean isSmartTextShareEnabled() {
+        return mSmartTextShareEnabled;
+    }
+
+    public boolean isSmartLinkifyEnabled() {
+        return mSmartLinkifyEnabled;
+    }
+
+    public boolean isSmartSelectionAnimationEnabled() {
+        return mSmartSelectionAnimationEnabled;
+    }
+
+    public int getSuggestSelectionMaxRangeLength() {
+        return mSuggestSelectionMaxRangeLength;
+    }
+
+    public int getClassifyTextMaxRangeLength() {
+        return mClassifyTextMaxRangeLength;
+    }
+
+    public int getGenerateLinksMaxTextLength() {
+        return mGenerateLinksMaxTextLength;
+    }
+
+    public int getGenerateLinksLogSampleRate() {
+        return mGenerateLinksLogSampleRate;
+    }
+
+    public List<String> getEntityListDefault() {
+        return mEntityListDefault;
+    }
+
+    public List<String> getEntityListNotEditable() {
+        return mEntityListNotEditable;
+    }
+
+    public List<String> getEntityListEditable() {
+        return mEntityListEditable;
+    }
+
+    private static List<String> parseEntityList(String listStr) {
+        return Collections.unmodifiableList(Arrays.asList(listStr.split(ENTITY_LIST_DELIMITER)));
+    }
+}
diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java
index 300aef2..a7f1ca1 100644
--- a/core/java/android/view/textclassifier/TextClassificationManager.java
+++ b/core/java/android/view/textclassifier/TextClassificationManager.java
@@ -20,8 +20,11 @@
 import android.annotation.SystemService;
 import android.content.Context;
 import android.os.ServiceManager;
+import android.provider.Settings;
 import android.service.textclassifier.TextClassifierService;
+import android.view.textclassifier.TextClassifier.TextClassifierType;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.Preconditions;
 
 /**
@@ -30,55 +33,41 @@
 @SystemService(Context.TEXT_CLASSIFICATION_SERVICE)
 public final class TextClassificationManager {
 
-    // TODO: Make this a configurable flag.
-    private static final boolean SYSTEM_TEXT_CLASSIFIER_ENABLED = true;
-
     private static final String LOG_TAG = "TextClassificationManager";
 
     private final Object mLock = new Object();
 
     private final Context mContext;
+    private final TextClassificationConstants mSettings;
+
+    @GuardedBy("mLock")
     private TextClassifier mTextClassifier;
+    @GuardedBy("mLock")
+    private TextClassifier mLocalTextClassifier;
+    @GuardedBy("mLock")
     private TextClassifier mSystemTextClassifier;
 
     /** @hide */
     public TextClassificationManager(Context context) {
         mContext = Preconditions.checkNotNull(context);
+        mSettings = TextClassificationConstants.loadFromString(Settings.Global.getString(
+                context.getContentResolver(), Settings.Global.TEXT_CLASSIFIER_CONSTANTS));
     }
 
     /**
-     * Returns the system's default TextClassifier.
-     * @hide
-     */
-    // TODO: Unhide when this is ready.
-    public TextClassifier getSystemDefaultTextClassifier() {
-        synchronized (mLock) {
-            if (mSystemTextClassifier == null && isSystemTextClassifierEnabled()) {
-                try {
-                    Log.d(LOG_TAG, "Initialized SystemTextClassifier");
-                    mSystemTextClassifier = new SystemTextClassifier(mContext);
-                } catch (ServiceManager.ServiceNotFoundException e) {
-                    Log.e(LOG_TAG, "Could not initialize SystemTextClassifier", e);
-                }
-            }
-            if (mSystemTextClassifier == null) {
-                Log.d(LOG_TAG, "Using an in-process TextClassifier as the system default");
-                mSystemTextClassifier = new TextClassifierImpl(mContext);
-            }
-        }
-        return mSystemTextClassifier;
-    }
-
-    /**
-     * Returns the text classifier.
+     * Returns the text classifier that was set via {@link #setTextClassifier(TextClassifier)}.
+     * If this is null, this method returns a default text classifier (i.e. either the system text
+     * classifier if one exists, or a local text classifier running in this app.)
+     *
+     * @see #setTextClassifier(TextClassifier)
      */
     public TextClassifier getTextClassifier() {
         synchronized (mLock) {
             if (mTextClassifier == null) {
                 if (isSystemTextClassifierEnabled()) {
-                    mTextClassifier = getSystemDefaultTextClassifier();
+                    mTextClassifier = getSystemTextClassifier();
                 } else {
-                    mTextClassifier = new TextClassifierImpl(mContext);
+                    mTextClassifier = getLocalTextClassifier();
                 }
             }
             return mTextClassifier;
@@ -96,8 +85,75 @@
         }
     }
 
+    /**
+     * Returns a specific type of text classifier.
+     * If the specified text classifier cannot be found, this returns {@link TextClassifier#NO_OP}.
+     *
+     * @see TextClassifier#LOCAL
+     * @see TextClassifier#SYSTEM
+     * @hide
+     */
+    // TODO: Expose as system API.
+    public TextClassifier getTextClassifier(@TextClassifierType int type) {
+        switch (type) {
+            case TextClassifier.LOCAL:
+                return getLocalTextClassifier();
+            default:
+                return getSystemTextClassifier();
+        }
+    }
+
+    /** @hide */
+    public TextClassificationConstants getSettings() {
+        return mSettings;
+    }
+
+    private TextClassifier getSystemTextClassifier() {
+        synchronized (mLock) {
+            if (mSystemTextClassifier == null && isSystemTextClassifierEnabled()) {
+                try {
+                    mSystemTextClassifier = new SystemTextClassifier(mContext, mSettings);
+                    Log.d(LOG_TAG, "Initialized SystemTextClassifier");
+                } catch (ServiceManager.ServiceNotFoundException e) {
+                    Log.e(LOG_TAG, "Could not initialize SystemTextClassifier", e);
+                }
+            }
+        }
+        if (mSystemTextClassifier != null) {
+            return mSystemTextClassifier;
+        }
+        return TextClassifier.NO_OP;
+    }
+
+    private TextClassifier getLocalTextClassifier() {
+        synchronized (mLock) {
+            if (mLocalTextClassifier == null) {
+                if (mSettings.isLocalTextClassifierEnabled()) {
+                    mLocalTextClassifier = new TextClassifierImpl(mContext, mSettings);
+                } else {
+                    Log.d(LOG_TAG, "Local TextClassifier disabled");
+                    mLocalTextClassifier = TextClassifierImpl.NO_OP;
+                }
+            }
+            return mLocalTextClassifier;
+        }
+    }
+
     private boolean isSystemTextClassifierEnabled() {
-        return SYSTEM_TEXT_CLASSIFIER_ENABLED
+        return mSettings.isSystemTextClassifierEnabled()
                 && TextClassifierService.getServiceComponentName(mContext) != null;
     }
+
+    /** @hide */
+    public static TextClassificationConstants getSettings(Context context) {
+        Preconditions.checkNotNull(context);
+        final TextClassificationManager tcm =
+                context.getSystemService(TextClassificationManager.class);
+        if (tcm != null) {
+            return tcm.mSettings;
+        } else {
+            return TextClassificationConstants.loadFromString(Settings.Global.getString(
+                    context.getContentResolver(), Settings.Global.TEXT_CLASSIFIER_CONSTANTS));
+        }
+    }
 }
diff --git a/core/java/android/view/textclassifier/TextClassifier.java b/core/java/android/view/textclassifier/TextClassifier.java
index d52a30b..ec40fdd 100644
--- a/core/java/android/view/textclassifier/TextClassifier.java
+++ b/core/java/android/view/textclassifier/TextClassifier.java
@@ -16,6 +16,7 @@
 
 package android.view.textclassifier;
 
+import android.annotation.IntDef;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -49,6 +50,16 @@
     /** @hide */
     String DEFAULT_LOG_TAG = "androidtc";
 
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {LOCAL, SYSTEM})
+    @interface TextClassifierType {}  // TODO: Expose as system APIs.
+    /** Specifies a TextClassifier that runs locally in the app's process. @hide */
+    int LOCAL = 0;
+    /** Specifies a TextClassifier that runs in the system process and serves all apps. @hide */
+    int SYSTEM = 1;
+
     /** The TextClassifier failed to run. */
     String TYPE_UNKNOWN = "";
     /** The classifier ran, but didn't recognize a known entity. */
@@ -329,14 +340,6 @@
     }
 
     /**
-     * Returns this TextClassifier's settings.
-     * @hide
-     */
-    default TextClassifierConstants getSettings() {
-        return TextClassifierConstants.DEFAULT;
-    }
-
-    /**
      * Configuration object for specifying what entities to identify.
      *
      * Configs are initially based on a predefined preset, and can be modified from there.
diff --git a/core/java/android/view/textclassifier/TextClassifierConstants.java b/core/java/android/view/textclassifier/TextClassifierConstants.java
deleted file mode 100644
index efa6948..0000000
--- a/core/java/android/view/textclassifier/TextClassifierConstants.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.textclassifier;
-
-import android.annotation.Nullable;
-import android.util.KeyValueListParser;
-import android.util.Slog;
-
-/**
- * TextClassifier specific settings.
- * This is encoded as a key=value list, separated by commas. Ex:
- *
- * <pre>
- * smart_selection_dark_launch              (boolean)
- * smart_selection_enabled_for_edit_text    (boolean)
- * </pre>
- *
- * <p>
- * Type: string
- * see also android.provider.Settings.Global.TEXT_CLASSIFIER_CONSTANTS
- *
- * Example of setting the values for testing.
- * adb shell settings put global text_classifier_constants smart_selection_dark_launch=true,smart_selection_enabled_for_edit_text=true
- * @hide
- */
-public final class TextClassifierConstants {
-
-    private static final String LOG_TAG = "TextClassifierConstants";
-
-    private static final String SMART_SELECTION_DARK_LAUNCH =
-            "smart_selection_dark_launch";
-    private static final String SMART_SELECTION_ENABLED_FOR_EDIT_TEXT =
-            "smart_selection_enabled_for_edit_text";
-    private static final String SMART_LINKIFY_ENABLED =
-            "smart_linkify_enabled";
-    private static final String SUGGEST_SELECTION_MAX_RANGE_LENGTH =
-            "suggest_selection_max_range_length";
-    private static final String CLASSIFY_TEXT_MAX_RANGE_LENGTH =
-            "classify_text_max_range_length";
-    private static final String GENERATE_LINKS_MAX_TEXT_LENGTH =
-            "generate_links_max_text_length";
-
-    private static final boolean SMART_SELECTION_DARK_LAUNCH_DEFAULT = false;
-    private static final boolean SMART_SELECTION_ENABLED_FOR_EDIT_TEXT_DEFAULT = true;
-    private static final boolean SMART_LINKIFY_ENABLED_DEFAULT = true;
-    private static final int SUGGEST_SELECTION_MAX_RANGE_LENGTH_DEFAULT = 10 * 1000;
-    private static final int CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT = 10 * 1000;
-    private static final int GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT = 100 * 1000;
-
-    /** Default settings. */
-    static final TextClassifierConstants DEFAULT = new TextClassifierConstants();
-
-    private final boolean mDarkLaunch;
-    private final boolean mSuggestSelectionEnabledForEditableText;
-    private final boolean mSmartLinkifyEnabled;
-    private final int mSuggestSelectionMaxRangeLength;
-    private final int mClassifyTextMaxRangeLength;
-    private final int mGenerateLinksMaxTextLength;
-
-    private TextClassifierConstants() {
-        mDarkLaunch = SMART_SELECTION_DARK_LAUNCH_DEFAULT;
-        mSuggestSelectionEnabledForEditableText = SMART_SELECTION_ENABLED_FOR_EDIT_TEXT_DEFAULT;
-        mSmartLinkifyEnabled = SMART_LINKIFY_ENABLED_DEFAULT;
-        mSuggestSelectionMaxRangeLength = SUGGEST_SELECTION_MAX_RANGE_LENGTH_DEFAULT;
-        mClassifyTextMaxRangeLength = CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT;
-        mGenerateLinksMaxTextLength = GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT;
-    }
-
-    private TextClassifierConstants(@Nullable String settings) {
-        final KeyValueListParser parser = new KeyValueListParser(',');
-        try {
-            parser.setString(settings);
-        } catch (IllegalArgumentException e) {
-            // Failed to parse the settings string, log this and move on with defaults.
-            Slog.e(LOG_TAG, "Bad TextClassifier settings: " + settings);
-        }
-        mDarkLaunch = parser.getBoolean(
-                SMART_SELECTION_DARK_LAUNCH,
-                SMART_SELECTION_DARK_LAUNCH_DEFAULT);
-        mSuggestSelectionEnabledForEditableText = parser.getBoolean(
-                SMART_SELECTION_ENABLED_FOR_EDIT_TEXT,
-                SMART_SELECTION_ENABLED_FOR_EDIT_TEXT_DEFAULT);
-        mSmartLinkifyEnabled = parser.getBoolean(
-                SMART_LINKIFY_ENABLED,
-                SMART_LINKIFY_ENABLED_DEFAULT);
-        mSuggestSelectionMaxRangeLength = parser.getInt(
-                SUGGEST_SELECTION_MAX_RANGE_LENGTH,
-                SUGGEST_SELECTION_MAX_RANGE_LENGTH_DEFAULT);
-        mClassifyTextMaxRangeLength = parser.getInt(
-                CLASSIFY_TEXT_MAX_RANGE_LENGTH,
-                CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT);
-        mGenerateLinksMaxTextLength = parser.getInt(
-                GENERATE_LINKS_MAX_TEXT_LENGTH,
-                GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT);
-    }
-
-    static TextClassifierConstants loadFromString(String settings) {
-        return new TextClassifierConstants(settings);
-    }
-
-    public boolean isDarkLaunch() {
-        return mDarkLaunch;
-    }
-
-    public boolean isSuggestSelectionEnabledForEditableText() {
-        return mSuggestSelectionEnabledForEditableText;
-    }
-
-    public boolean isSmartLinkifyEnabled() {
-        return mSmartLinkifyEnabled;
-    }
-
-    public int getSuggestSelectionMaxRangeLength() {
-        return mSuggestSelectionMaxRangeLength;
-    }
-
-    public int getClassifyTextMaxRangeLength() {
-        return mClassifyTextMaxRangeLength;
-    }
-
-    public int getGenerateLinksMaxTextLength() {
-        return mGenerateLinksMaxTextLength;
-    }
-}
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index 20467ac..41f1c69 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -34,14 +34,11 @@
 import android.provider.Browser;
 import android.provider.CalendarContract;
 import android.provider.ContactsContract;
-import android.provider.Settings;
-import android.text.util.Linkify;
-import android.util.Patterns;
 import android.view.textclassifier.logging.DefaultLogger;
+import android.view.textclassifier.logging.GenerateLinksLogger;
 import android.view.textclassifier.logging.Logger;
 
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.logging.MetricsLogger;
 import com.android.internal.util.Preconditions;
 
 import java.io.File;
@@ -81,20 +78,11 @@
     private static final String MODEL_FILE_REGEX = "textclassifier\\.(.*)\\.model";
     private static final String UPDATED_MODEL_FILE_PATH =
             "/data/misc/textclassifier/textclassifier.model";
-    private static final List<String> ENTITY_TYPES_ALL =
-            Collections.unmodifiableList(Arrays.asList(
-                    TextClassifier.TYPE_ADDRESS,
-                    TextClassifier.TYPE_EMAIL,
-                    TextClassifier.TYPE_PHONE,
-                    TextClassifier.TYPE_URL,
-                    TextClassifier.TYPE_DATE,
-                    TextClassifier.TYPE_DATE_TIME,
-                    TextClassifier.TYPE_FLIGHT_NUMBER));
 
     private final Context mContext;
     private final TextClassifier mFallback;
 
-    private final MetricsLogger mMetricsLogger = new MetricsLogger();
+    private final GenerateLinksLogger mGenerateLinksLogger;
 
     private final Object mLock = new Object();
     @GuardedBy("mLock") // Do not access outside this lock.
@@ -102,7 +90,7 @@
     @GuardedBy("mLock") // Do not access outside this lock.
     private ModelFile mModel;
     @GuardedBy("mLock") // Do not access outside this lock.
-    private SmartSelection mSmartSelection;
+    private TextClassifierImplNative mNative;
 
     private final Object mLoggerLock = new Object();
     @GuardedBy("mLoggerLock") // Do not access outside this lock.
@@ -110,11 +98,13 @@
     @GuardedBy("mLoggerLock") // Do not access outside this lock.
     private Logger mLogger;  // Should never be null if mLoggerConfig.get() is not null.
 
-    private TextClassifierConstants mSettings;
+    private final TextClassificationConstants mSettings;
 
-    public TextClassifierImpl(Context context) {
+    public TextClassifierImpl(Context context, TextClassificationConstants settings) {
         mContext = Preconditions.checkNotNull(context);
         mFallback = TextClassifier.NO_OP;
+        mSettings = Preconditions.checkNotNull(settings);
+        mGenerateLinksLogger = new GenerateLinksLogger(mSettings.getGenerateLinksLogSampleRate());
     }
 
     /** @inheritDoc */
@@ -126,19 +116,22 @@
         try {
             final int rangeLength = selectionEndIndex - selectionStartIndex;
             if (text.length() > 0
-                    && rangeLength <= getSettings().getSuggestSelectionMaxRangeLength()) {
+                    && rangeLength <= mSettings.getSuggestSelectionMaxRangeLength()) {
                 final LocaleList locales = (options == null) ? null : options.getDefaultLocales();
+                final String localesString = concatenateLocales(locales);
+                final Calendar refTime = Calendar.getInstance();
                 final boolean darkLaunchAllowed = options != null && options.isDarkLaunchAllowed();
-                final SmartSelection smartSelection = getSmartSelection(locales);
+                final TextClassifierImplNative nativeImpl = getNative(locales);
                 final String string = text.toString();
                 final int start;
                 final int end;
-                if (getSettings().isDarkLaunch() && !darkLaunchAllowed) {
+                if (mSettings.isModelDarkLaunchEnabled() && !darkLaunchAllowed) {
                     start = selectionStartIndex;
                     end = selectionEndIndex;
                 } else {
-                    final int[] startEnd = smartSelection.suggest(
-                            string, selectionStartIndex, selectionEndIndex);
+                    final int[] startEnd = nativeImpl.suggestSelection(
+                            string, selectionStartIndex, selectionEndIndex,
+                            new TextClassifierImplNative.SelectionOptions(localesString));
                     start = startEnd[0];
                     end = startEnd[1];
                 }
@@ -146,13 +139,16 @@
                         && start >= 0 && end <= string.length()
                         && start <= selectionStartIndex && end >= selectionEndIndex) {
                     final TextSelection.Builder tsBuilder = new TextSelection.Builder(start, end);
-                    final SmartSelection.ClassificationResult[] results =
-                            smartSelection.classifyText(
+                    final TextClassifierImplNative.ClassificationResult[] results =
+                            nativeImpl.classifyText(
                                     string, start, end,
-                                    getHintFlags(string, start, end));
+                                    new TextClassifierImplNative.ClassificationOptions(
+                                            refTime.getTimeInMillis(),
+                                            refTime.getTimeZone().getID(),
+                                            localesString));
                     final int size = results.length;
                     for (int i = 0; i < size; i++) {
-                        tsBuilder.setEntityType(results[i].mCollection, results[i].mScore);
+                        tsBuilder.setEntityType(results[i].getCollection(), results[i].getScore());
                     }
                     return tsBuilder
                             .setSignature(
@@ -182,13 +178,20 @@
         Utils.validate(text, startIndex, endIndex, false /* allowInMainThread */);
         try {
             final int rangeLength = endIndex - startIndex;
-            if (text.length() > 0 && rangeLength <= getSettings().getClassifyTextMaxRangeLength()) {
+            if (text.length() > 0 && rangeLength <= mSettings.getClassifyTextMaxRangeLength()) {
                 final String string = text.toString();
                 final LocaleList locales = (options == null) ? null : options.getDefaultLocales();
-                final Calendar refTime = (options == null) ? null : options.getReferenceTime();
-                final SmartSelection.ClassificationResult[] results = getSmartSelection(locales)
-                        .classifyText(string, startIndex, endIndex,
-                                getHintFlags(string, startIndex, endIndex));
+                final String localesString = concatenateLocales(locales);
+                final Calendar refTime = (options != null && options.getReferenceTime() != null)
+                        ? options.getReferenceTime() : Calendar.getInstance();
+
+                final TextClassifierImplNative.ClassificationResult[] results =
+                        getNative(locales)
+                                .classifyText(string, startIndex, endIndex,
+                                        new TextClassifierImplNative.ClassificationOptions(
+                                                refTime.getTimeInMillis(),
+                                                refTime.getTimeZone().getID(),
+                                                localesString));
                 if (results.length > 0) {
                     return createClassificationResult(
                             results, string, startIndex, endIndex, refTime);
@@ -210,31 +213,50 @@
         final String textString = text.toString();
         final TextLinks.Builder builder = new TextLinks.Builder(textString);
 
-        if (!getSettings().isSmartLinkifyEnabled()) {
+        if (!mSettings.isSmartLinkifyEnabled()) {
             return builder.build();
         }
 
         try {
+            final long startTimeMs = System.currentTimeMillis();
             final LocaleList defaultLocales = options != null ? options.getDefaultLocales() : null;
+            final Calendar refTime = Calendar.getInstance();
             final Collection<String> entitiesToIdentify =
                     options != null && options.getEntityConfig() != null
                             ? options.getEntityConfig().resolveEntityListModifications(
                                     getEntitiesForHints(options.getEntityConfig().getHints()))
-                            : ENTITY_TYPES_ALL;
-            final SmartSelection smartSelection = getSmartSelection(defaultLocales);
-            final SmartSelection.AnnotatedSpan[] annotations = smartSelection.annotate(textString);
-            for (SmartSelection.AnnotatedSpan span : annotations) {
-                final SmartSelection.ClassificationResult[] results = span.getClassification();
-                if (results.length == 0 || !entitiesToIdentify.contains(results[0].mCollection)) {
+                            : mSettings.getEntityListDefault();
+            final TextClassifierImplNative nativeImpl =
+                    getNative(defaultLocales);
+            final TextClassifierImplNative.AnnotatedSpan[] annotations =
+                    nativeImpl.annotate(
+                        textString,
+                        new TextClassifierImplNative.AnnotationOptions(
+                                refTime.getTimeInMillis(),
+                                refTime.getTimeZone().getID(),
+                                concatenateLocales(defaultLocales)));
+            for (TextClassifierImplNative.AnnotatedSpan span : annotations) {
+                final TextClassifierImplNative.ClassificationResult[] results =
+                        span.getClassification();
+                if (results.length == 0
+                        || !entitiesToIdentify.contains(results[0].getCollection())) {
                     continue;
                 }
                 final Map<String, Float> entityScores = new HashMap<>();
                 for (int i = 0; i < results.length; i++) {
-                    entityScores.put(results[i].mCollection, results[i].mScore);
+                    entityScores.put(results[i].getCollection(), results[i].getScore());
                 }
                 builder.addLink(span.getStartIndex(), span.getEndIndex(), entityScores);
             }
-            return builder.build();
+            final TextLinks links = builder.build();
+            final long endTimeMs = System.currentTimeMillis();
+            final String callingPackageName =
+                    options == null || options.getCallingPackageName() == null
+                            ? mContext.getPackageName()  // local (in process) TC.
+                            : options.getCallingPackageName();
+            mGenerateLinksLogger.logGenerateLinks(
+                    text, links, callingPackageName, endTimeMs - startTimeMs);
+            return links;
         } catch (Throwable t) {
             // Avoid throwing from this method. Log the error.
             Log.e(LOG_TAG, "Error getting links info.", t);
@@ -245,11 +267,22 @@
     /** @inheritDoc */
     @Override
     public int getMaxGenerateLinksTextLength() {
-        return getSettings().getGenerateLinksMaxTextLength();
+        return mSettings.getGenerateLinksMaxTextLength();
     }
 
     private Collection<String> getEntitiesForHints(Collection<String> hints) {
-        return ENTITY_TYPES_ALL;
+        final boolean editable = hints.contains(HINT_TEXT_IS_EDITABLE);
+        final boolean notEditable = hints.contains(HINT_TEXT_IS_NOT_EDITABLE);
+
+        // Use the default if there is no hint, or conflicting ones.
+        final boolean useDefault = editable == notEditable;
+        if (useDefault) {
+            return mSettings.getEntityListDefault();
+        } else if (editable) {
+            return mSettings.getEntityListEditable();
+        } else {  // notEditable
+            return mSettings.getEntityListNotEditable();
+        }
     }
 
     @Override
@@ -264,33 +297,24 @@
         }
     }
 
-    /** @hide */
-    @Override
-    public TextClassifierConstants getSettings() {
-        if (mSettings == null) {
-            mSettings = TextClassifierConstants.loadFromString(Settings.Global.getString(
-                    mContext.getContentResolver(), Settings.Global.TEXT_CLASSIFIER_CONSTANTS));
-        }
-        return mSettings;
-    }
-
-    private SmartSelection getSmartSelection(LocaleList localeList) throws FileNotFoundException {
+    private TextClassifierImplNative getNative(LocaleList localeList)
+            throws FileNotFoundException {
         synchronized (mLock) {
             localeList = localeList == null ? LocaleList.getEmptyLocaleList() : localeList;
             final ModelFile bestModel = findBestModelLocked(localeList);
             if (bestModel == null) {
                 throw new FileNotFoundException("No model for " + localeList.toLanguageTags());
             }
-            if (mSmartSelection == null || !Objects.equals(mModel, bestModel)) {
+            if (mNative == null || !Objects.equals(mModel, bestModel)) {
                 Log.d(DEFAULT_LOG_TAG, "Loading " + bestModel);
-                destroySmartSelectionIfExistsLocked();
+                destroyNativeIfExistsLocked();
                 final ParcelFileDescriptor fd = ParcelFileDescriptor.open(
                         new File(bestModel.getPath()), ParcelFileDescriptor.MODE_READ_ONLY);
-                mSmartSelection = new SmartSelection(fd.getFd());
+                mNative = new TextClassifierImplNative(fd.getFd());
                 closeAndLogError(fd);
                 mModel = bestModel;
             }
-            return mSmartSelection;
+            return mNative;
         }
     }
 
@@ -302,13 +326,17 @@
     }
 
     @GuardedBy("mLock") // Do not call outside this lock.
-    private void destroySmartSelectionIfExistsLocked() {
-        if (mSmartSelection != null) {
-            mSmartSelection.close();
-            mSmartSelection = null;
+    private void destroyNativeIfExistsLocked() {
+        if (mNative != null) {
+            mNative.close();
+            mNative = null;
         }
     }
 
+    private static String concatenateLocales(@Nullable LocaleList locales) {
+        return (locales == null) ? "" : locales.toLanguageTags();
+    }
+
     /**
      * Finds the most appropriate model to use for the given target locale list.
      *
@@ -372,20 +400,21 @@
     }
 
     private TextClassification createClassificationResult(
-            SmartSelection.ClassificationResult[] classifications,
+            TextClassifierImplNative.ClassificationResult[] classifications,
             String text, int start, int end, @Nullable Calendar referenceTime) {
         final String classifiedText = text.substring(start, end);
         final TextClassification.Builder builder = new TextClassification.Builder()
                 .setText(classifiedText);
 
         final int size = classifications.length;
-        SmartSelection.ClassificationResult highestScoringResult = null;
+        TextClassifierImplNative.ClassificationResult highestScoringResult = null;
         float highestScore = Float.MIN_VALUE;
         for (int i = 0; i < size; i++) {
-            builder.setEntityType(classifications[i].mCollection, classifications[i].mScore);
-            if (classifications[i].mScore > highestScore) {
+            builder.setEntityType(classifications[i].getCollection(),
+                                  classifications[i].getScore());
+            if (classifications[i].getScore() > highestScore) {
                 highestScoringResult = classifications[i];
-                highestScore = classifications[i].mScore;
+                highestScore = classifications[i].getScore();
             }
         }
 
@@ -433,19 +462,6 @@
         }
     }
 
-    private static int getHintFlags(CharSequence text, int start, int end) {
-        int flag = 0;
-        final CharSequence subText = text.subSequence(start, end);
-        if (Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(subText).matches()) {
-            flag |= SmartSelection.HINT_FLAG_EMAIL;
-        }
-        if (Patterns.AUTOLINK_WEB_URL.matcher(subText).matches()
-                && Linkify.sUrlMatchFilter.acceptMatch(text, start, end)) {
-            flag |= SmartSelection.HINT_FLAG_URL;
-        }
-        return flag;
-    }
-
     /**
      * Closes the ParcelFileDescriptor and logs any errors that occur.
      */
@@ -473,8 +489,9 @@
             try {
                 final ParcelFileDescriptor modelFd = ParcelFileDescriptor.open(
                         file, ParcelFileDescriptor.MODE_READ_ONLY);
-                final int version = SmartSelection.getVersion(modelFd.getFd());
-                final String supportedLocalesStr = SmartSelection.getLanguages(modelFd.getFd());
+                final int version = TextClassifierImplNative.getVersion(modelFd.getFd());
+                final String supportedLocalesStr =
+                        TextClassifierImplNative.getLocales(modelFd.getFd());
                 if (supportedLocalesStr.isEmpty()) {
                     Log.d(DEFAULT_LOG_TAG, "Ignoring " + file.getAbsolutePath());
                     return null;
@@ -560,9 +577,9 @@
         public static List<Intent> create(
                 Context context,
                 @Nullable Calendar referenceTime,
-                SmartSelection.ClassificationResult classification,
+                TextClassifierImplNative.ClassificationResult classification,
                 String text) {
-            final String type = classification.mCollection.trim().toLowerCase(Locale.ENGLISH);
+            final String type = classification.getCollection().trim().toLowerCase(Locale.ENGLISH);
             text = text.trim();
             switch (type) {
                 case TextClassifier.TYPE_EMAIL:
@@ -575,9 +592,10 @@
                     return createForUrl(context, text);
                 case TextClassifier.TYPE_DATE:
                 case TextClassifier.TYPE_DATE_TIME:
-                    if (classification.mDatetime != null) {
+                    if (classification.getDatetimeResult() != null) {
                         Calendar eventTime = Calendar.getInstance();
-                        eventTime.setTimeInMillis(classification.mDatetime.mMsSinceEpoch);
+                        eventTime.setTimeInMillis(
+                                classification.getDatetimeResult().getTimeMsUtc());
                         return createForDatetime(type, referenceTime, eventTime);
                     } else {
                         return new ArrayList<>();
diff --git a/core/java/android/view/textclassifier/TextClassifierImplNative.java b/core/java/android/view/textclassifier/TextClassifierImplNative.java
new file mode 100644
index 0000000..3d4c8f2
--- /dev/null
+++ b/core/java/android/view/textclassifier/TextClassifierImplNative.java
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.textclassifier;
+
+import android.content.res.AssetFileDescriptor;
+
+/**
+ * Java wrapper for TextClassifier native library interface. This library is used for detecting
+ * entities in text.
+ */
+final class TextClassifierImplNative {
+
+    static {
+        System.loadLibrary("textclassifier");
+    }
+
+    private final long mModelPtr;
+
+    /**
+     * Creates a new instance of TextClassifierImplNative, using the provided model image, given as
+     * a file descriptor.
+     */
+    TextClassifierImplNative(int fd) {
+        mModelPtr = nativeNew(fd);
+        if (mModelPtr == 0L) {
+            throw new IllegalArgumentException("Couldn't initialize TC from file descriptor.");
+        }
+    }
+
+    /**
+     * Creates a new instance of TextClassifierImplNative, using the provided model image, given as
+     * a file path.
+     */
+    TextClassifierImplNative(String path) {
+        mModelPtr = nativeNewFromPath(path);
+        if (mModelPtr == 0L) {
+            throw new IllegalArgumentException("Couldn't initialize TC from given file.");
+        }
+    }
+
+    /**
+     * Creates a new instance of TextClassifierImplNative, using the provided model image, given as
+     * an AssetFileDescriptor.
+     */
+    TextClassifierImplNative(AssetFileDescriptor afd) {
+        mModelPtr = nativeNewFromAssetFileDescriptor(afd, afd.getStartOffset(), afd.getLength());
+        if (mModelPtr == 0L) {
+            throw new IllegalArgumentException(
+                    "Couldn't initialize TC from given AssetFileDescriptor");
+        }
+    }
+
+    /**
+     * Given a string context and current selection, computes the SmartSelection suggestion.
+     *
+     * <p>The begin and end are character indices into the context UTF8 string. selectionBegin is
+     * the character index where the selection begins, and selectionEnd is the index of one
+     * character past the selection span.
+     *
+     * <p>The return value is an array of two ints: suggested selection beginning and end, with the
+     * same semantics as the input selectionBeginning and selectionEnd.
+     */
+    public int[] suggestSelection(
+            String context, int selectionBegin, int selectionEnd, SelectionOptions options) {
+        return nativeSuggestSelection(mModelPtr, context, selectionBegin, selectionEnd, options);
+    }
+
+    /**
+     * Given a string context and current selection, classifies the type of the selected text.
+     *
+     * <p>The begin and end params are character indices in the context string.
+     *
+     * <p>Returns an array of ClassificationResult objects with the probability scores for different
+     * collections.
+     */
+    public ClassificationResult[] classifyText(
+            String context, int selectionBegin, int selectionEnd, ClassificationOptions options) {
+        return nativeClassifyText(mModelPtr, context, selectionBegin, selectionEnd, options);
+    }
+
+    /**
+     * Annotates given input text. The annotations should cover the whole input context except for
+     * whitespaces, and are sorted by their position in the context string.
+     */
+    public AnnotatedSpan[] annotate(String text, AnnotationOptions options) {
+        return nativeAnnotate(mModelPtr, text, options);
+    }
+
+    /** Frees up the allocated memory. */
+    public void close() {
+        nativeClose(mModelPtr);
+    }
+
+    /** Returns a comma separated list of locales supported by the model as BCP 47 tags. */
+    public static String getLocales(int fd) {
+        return nativeGetLocales(fd);
+    }
+
+    /** Returns the version of the model. */
+    public static int getVersion(int fd) {
+        return nativeGetVersion(fd);
+    }
+
+    /** Represents a datetime parsing result from classifyText calls. */
+    public static final class DatetimeResult {
+        static final int GRANULARITY_YEAR = 0;
+        static final int GRANULARITY_MONTH = 1;
+        static final int GRANULARITY_WEEK = 2;
+        static final int GRANULARITY_DAY = 3;
+        static final int GRANULARITY_HOUR = 4;
+        static final int GRANULARITY_MINUTE = 5;
+        static final int GRANULARITY_SECOND = 6;
+
+        private final long mTimeMsUtc;
+        private final int mGranularity;
+
+        DatetimeResult(long timeMsUtc, int granularity) {
+            mGranularity = granularity;
+            mTimeMsUtc = timeMsUtc;
+        }
+
+        public long getTimeMsUtc() {
+            return mTimeMsUtc;
+        }
+
+        public int getGranularity() {
+            return mGranularity;
+        }
+    }
+
+    /** Represents a result of classifyText method call. */
+    public static final class ClassificationResult {
+        private final String mCollection;
+        private final float mScore;
+        private final DatetimeResult mDatetimeResult;
+
+        ClassificationResult(
+                String collection, float score, DatetimeResult datetimeResult) {
+            mCollection = collection;
+            mScore = score;
+            mDatetimeResult = datetimeResult;
+        }
+
+        public String getCollection() {
+            if (mCollection.equals(TextClassifier.TYPE_DATE) && mDatetimeResult != null) {
+                switch (mDatetimeResult.getGranularity()) {
+                    case DatetimeResult.GRANULARITY_HOUR:
+                        // fall through
+                    case DatetimeResult.GRANULARITY_MINUTE:
+                        // fall through
+                    case DatetimeResult.GRANULARITY_SECOND:
+                        return TextClassifier.TYPE_DATE_TIME;
+                    default:
+                        return TextClassifier.TYPE_DATE;
+                }
+            }
+            return mCollection;
+        }
+
+        public float getScore() {
+            return mScore;
+        }
+
+        public DatetimeResult getDatetimeResult() {
+            return mDatetimeResult;
+        }
+    }
+
+    /** Represents a result of Annotate call. */
+    public static final class AnnotatedSpan {
+        private final int mStartIndex;
+        private final int mEndIndex;
+        private final ClassificationResult[] mClassification;
+
+        AnnotatedSpan(
+                int startIndex, int endIndex, ClassificationResult[] classification) {
+            mStartIndex = startIndex;
+            mEndIndex = endIndex;
+            mClassification = classification;
+        }
+
+        public int getStartIndex() {
+            return mStartIndex;
+        }
+
+        public int getEndIndex() {
+            return mEndIndex;
+        }
+
+        public ClassificationResult[] getClassification() {
+            return mClassification;
+        }
+    }
+
+    /** Represents options for the suggestSelection call. */
+    public static final class SelectionOptions {
+        private final String mLocales;
+
+        SelectionOptions(String locales) {
+            mLocales = locales;
+        }
+
+        public String getLocales() {
+            return mLocales;
+        }
+    }
+
+    /** Represents options for the classifyText call. */
+    public static final class ClassificationOptions {
+        private final long mReferenceTimeMsUtc;
+        private final String mReferenceTimezone;
+        private final String mLocales;
+
+        ClassificationOptions(long referenceTimeMsUtc, String referenceTimezone, String locale) {
+            mReferenceTimeMsUtc = referenceTimeMsUtc;
+            mReferenceTimezone = referenceTimezone;
+            mLocales = locale;
+        }
+
+        public long getReferenceTimeMsUtc() {
+            return mReferenceTimeMsUtc;
+        }
+
+        public String getReferenceTimezone() {
+            return mReferenceTimezone;
+        }
+
+        public String getLocale() {
+            return mLocales;
+        }
+    }
+
+    /** Represents options for the Annotate call. */
+    public static final class AnnotationOptions {
+        private final long mReferenceTimeMsUtc;
+        private final String mReferenceTimezone;
+        private final String mLocales;
+
+        AnnotationOptions(long referenceTimeMsUtc, String referenceTimezone, String locale) {
+            mReferenceTimeMsUtc = referenceTimeMsUtc;
+            mReferenceTimezone = referenceTimezone;
+            mLocales = locale;
+        }
+
+        public long getReferenceTimeMsUtc() {
+            return mReferenceTimeMsUtc;
+        }
+
+        public String getReferenceTimezone() {
+            return mReferenceTimezone;
+        }
+
+        public String getLocale() {
+            return mLocales;
+        }
+    }
+
+    private static native long nativeNew(int fd);
+
+    private static native long nativeNewFromPath(String path);
+
+    private static native long nativeNewFromAssetFileDescriptor(
+            AssetFileDescriptor afd, long offset, long size);
+
+    private static native int[] nativeSuggestSelection(
+            long context,
+            String text,
+            int selectionBegin,
+            int selectionEnd,
+            SelectionOptions options);
+
+    private static native ClassificationResult[] nativeClassifyText(
+            long context,
+            String text,
+            int selectionBegin,
+            int selectionEnd,
+            ClassificationOptions options);
+
+    private static native AnnotatedSpan[] nativeAnnotate(
+            long context, String text, AnnotationOptions options);
+
+    private static native void nativeClose(long context);
+
+    private static native String nativeGetLocales(int fd);
+
+    private static native int nativeGetVersion(int fd);
+}
diff --git a/core/java/android/view/textclassifier/TextLinks.java b/core/java/android/view/textclassifier/TextLinks.java
index dc24d0c..884cbe8 100644
--- a/core/java/android/view/textclassifier/TextLinks.java
+++ b/core/java/android/view/textclassifier/TextLinks.java
@@ -305,6 +305,8 @@
         private @ApplyStrategy int mApplyStrategy;
         private Function<TextLink, TextLinkSpan> mSpanFactory;
 
+        private String mCallingPackageName;
+
         /**
          * Returns a new options object based on the specified link mask.
          */
@@ -377,6 +379,15 @@
         }
 
         /**
+         * Sets the name of the package that requested the links to get generated.
+         * @hide
+         */
+        public Options setCallingPackageName(@Nullable String callingPackageName) {
+            mCallingPackageName = callingPackageName;
+            return this;
+        }
+
+        /**
          * @return ordered list of locale preferences that can be used to disambiguate
          *      the provided text
          */
@@ -417,6 +428,16 @@
             return mSpanFactory;
         }
 
+        /**
+         * @return the name of the package that requested the links to get generated.
+         * TODO: make available as system API
+         * @hide
+         */
+        @Nullable
+        public String getCallingPackageName() {
+            return mCallingPackageName;
+        }
+
         @Override
         public int describeContents() {
             return 0;
@@ -433,6 +454,7 @@
                 mEntityConfig.writeToParcel(dest, flags);
             }
             dest.writeInt(mApplyStrategy);
+            dest.writeString(mCallingPackageName);
         }
 
         public static final Parcelable.Creator<Options> CREATOR =
@@ -456,6 +478,7 @@
                 mEntityConfig = TextClassifier.EntityConfig.CREATOR.createFromParcel(in);
             }
             mApplyStrategy = in.readInt();
+            mCallingPackageName = in.readString();
         }
     }
 
diff --git a/core/java/android/view/textclassifier/logging/GenerateLinksLogger.java b/core/java/android/view/textclassifier/logging/GenerateLinksLogger.java
new file mode 100644
index 0000000..fb6f205
--- /dev/null
+++ b/core/java/android/view/textclassifier/logging/GenerateLinksLogger.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.textclassifier.logging;
+
+import android.annotation.Nullable;
+import android.metrics.LogMaker;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.view.textclassifier.TextClassifier;
+import android.view.textclassifier.TextLinks;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.util.Preconditions;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.Random;
+import java.util.UUID;
+
+/**
+ * A helper for logging calls to generateLinks.
+ * @hide
+ */
+@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+public final class GenerateLinksLogger {
+
+    private static final String LOG_TAG = "GenerateLinksLogger";
+    private static final String ZERO = "0";
+
+    private final MetricsLogger mMetricsLogger;
+    private final Random mRng;
+    private final int mSampleRate;
+
+    /**
+     * @param sampleRate the rate at which log events are written. (e.g. 100 means there is a 0.01
+     *                   chance that a call to logGenerateLinks results in an event being written).
+     *                   To write all events, pass 1.
+     */
+    public GenerateLinksLogger(int sampleRate) {
+        mSampleRate = sampleRate;
+        mRng = new Random(System.nanoTime());
+        mMetricsLogger = new MetricsLogger();
+    }
+
+    @VisibleForTesting
+    public GenerateLinksLogger(int sampleRate, MetricsLogger metricsLogger) {
+        mSampleRate = sampleRate;
+        mRng = new Random(System.nanoTime());
+        mMetricsLogger = metricsLogger;
+    }
+
+    /** Logs statistics about a call to generateLinks. */
+    public void logGenerateLinks(CharSequence text, TextLinks links, String callingPackageName,
+            long latencyMs) {
+        Preconditions.checkNotNull(text);
+        Preconditions.checkNotNull(links);
+        Preconditions.checkNotNull(callingPackageName);
+        if (!shouldLog()) {
+            return;
+        }
+
+        // Always populate the total stats, and per-entity stats for each entity type detected.
+        final LinkifyStats totalStats = new LinkifyStats();
+        final Map<String, LinkifyStats> perEntityTypeStats = new ArrayMap<>();
+        for (TextLinks.TextLink link : links.getLinks()) {
+            if (link.getEntityCount() == 0) continue;
+            final String entityType = link.getEntity(0);
+            if (entityType == null
+                    || TextClassifier.TYPE_OTHER.equals(entityType)
+                    || TextClassifier.TYPE_UNKNOWN.equals(entityType)) {
+                continue;
+            }
+            totalStats.countLink(link);
+            perEntityTypeStats.computeIfAbsent(entityType, k -> new LinkifyStats()).countLink(link);
+        }
+
+        final String callId = UUID.randomUUID().toString();
+        writeStats(callId, callingPackageName, null, totalStats, text, latencyMs);
+        for (Map.Entry<String, LinkifyStats> entry : perEntityTypeStats.entrySet()) {
+            writeStats(callId, callingPackageName, entry.getKey(), entry.getValue(), text,
+                       latencyMs);
+        }
+    }
+
+    /**
+     * Returns whether this particular event should be logged.
+     *
+     * Sampling is used to reduce the amount of logging data generated.
+     **/
+    private boolean shouldLog() {
+        if (mSampleRate <= 1) {
+            return true;
+        } else {
+            return mRng.nextInt(mSampleRate) == 0;
+        }
+    }
+
+    /** Writes a log event for the given stats. */
+    private void writeStats(String callId, String callingPackageName, @Nullable String entityType,
+                            LinkifyStats stats, CharSequence text, long latencyMs) {
+        final LogMaker log = new LogMaker(MetricsEvent.TEXT_CLASSIFIER_GENERATE_LINKS)
+                .setPackageName(callingPackageName)
+                .addTaggedData(MetricsEvent.FIELD_LINKIFY_CALL_ID, callId)
+                .addTaggedData(MetricsEvent.FIELD_LINKIFY_NUM_LINKS, stats.mNumLinks)
+                .addTaggedData(MetricsEvent.FIELD_LINKIFY_LINK_LENGTH, stats.mNumLinksTextLength)
+                .addTaggedData(MetricsEvent.FIELD_LINKIFY_TEXT_LENGTH, text.length())
+                .addTaggedData(MetricsEvent.FIELD_LINKIFY_LATENCY, latencyMs);
+        if (entityType != null) {
+            log.addTaggedData(MetricsEvent.FIELD_LINKIFY_ENTITY_TYPE, entityType);
+        }
+        mMetricsLogger.write(log);
+        debugLog(log);
+    }
+
+    private static void debugLog(LogMaker log) {
+        if (!Logger.DEBUG_LOG_ENABLED) return;
+
+        final String callId = Objects.toString(
+                log.getTaggedData(MetricsEvent.FIELD_LINKIFY_CALL_ID), "");
+        final String entityType = Objects.toString(
+                log.getTaggedData(MetricsEvent.FIELD_LINKIFY_ENTITY_TYPE), "ANY_ENTITY");
+        final int numLinks = Integer.parseInt(
+                Objects.toString(log.getTaggedData(MetricsEvent.FIELD_LINKIFY_NUM_LINKS), ZERO));
+        final int linkLength = Integer.parseInt(
+                Objects.toString(log.getTaggedData(MetricsEvent.FIELD_LINKIFY_LINK_LENGTH), ZERO));
+        final int textLength = Integer.parseInt(
+                Objects.toString(log.getTaggedData(MetricsEvent.FIELD_LINKIFY_TEXT_LENGTH), ZERO));
+        final int latencyMs = Integer.parseInt(
+                Objects.toString(log.getTaggedData(MetricsEvent.FIELD_LINKIFY_LATENCY), ZERO));
+
+        Log.d(LOG_TAG, String.format("%s:%s %d links (%d/%d chars) %dms %s", callId, entityType,
+                numLinks, linkLength, textLength, latencyMs, log.getPackageName()));
+    }
+
+    /** Helper class for storing per-entity type statistics. */
+    private static final class LinkifyStats {
+        int mNumLinks;
+        int mNumLinksTextLength;
+
+        void countLink(TextLinks.TextLink link) {
+            mNumLinks += 1;
+            mNumLinksTextLength += link.getEnd() - link.getStart();
+        }
+    }
+}
diff --git a/core/java/android/webkit/URLUtil.java b/core/java/android/webkit/URLUtil.java
index 84c000a..ed122a6 100644
--- a/core/java/android/webkit/URLUtil.java
+++ b/core/java/android/webkit/URLUtil.java
@@ -39,7 +39,7 @@
     // "file:///android_res/drawable/bar.png". Use "drawable" to refer to
     // "drawable-hdpi" directory as well.
     static final String RESOURCE_BASE = "file:///android_res/";
-    static final String FILE_BASE = "file://";
+    static final String FILE_BASE = "file:";
     static final String PROXY_BASE = "file:///cookieless_proxy/";
     static final String CONTENT_BASE = "content:";
 
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 65deb3b..a8f6b03 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1689,8 +1689,8 @@
     }
 
     /**
-     * Sets the list of domains that are exempt from SafeBrowsing checks. The list is
-     * global for all the WebViews.
+     * Sets the list of hosts (domain names/IP addresses) that are exempt from SafeBrowsing checks.
+     * The list is global for all the WebViews.
      * <p>
      * Each rule should take one of these:
      * <table>
@@ -1702,15 +1702,18 @@
      * </table>
      * <p>
      * All other rules, including wildcards, are invalid.
+     * <p>
+     * The correct syntax for hosts is defined by <a
+     * href="https://tools.ietf.org/html/rfc3986#section-3.2.2">RFC 3986</a>.
      *
-     * @param urls the list of URLs
-     * @param callback will be called with {@code true} if URLs are successfully added to the
-     * whitelist. It will be called with {@code false} if any URLs are malformed. The callback will
-     * be run on the UI thread
+     * @param hosts the list of hosts
+     * @param callback will be called with {@code true} if hosts are successfully added to the
+     * whitelist. It will be called with {@code false} if any hosts are malformed. The callback
+     * will be run on the UI thread
      */
-    public static void setSafeBrowsingWhitelist(@NonNull List<String> urls,
+    public static void setSafeBrowsingWhitelist(@NonNull List<String> hosts,
             @Nullable ValueCallback<Boolean> callback) {
-        getFactory().getStatics().setSafeBrowsingWhitelist(urls, callback);
+        getFactory().getStatics().setSafeBrowsingWhitelist(hosts, callback);
     }
 
     /**
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index e9fe481..e0ccda9 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -205,25 +205,21 @@
         }
 
         PackageManager packageManager = AppGlobals.getInitialApplication().getPackageManager();
-        PackageInfo packageInfo;
+        String libraryFileName;
         try {
-            packageInfo = packageManager.getPackageInfo(packageName,
+            PackageInfo packageInfo = packageManager.getPackageInfo(packageName,
                     PackageManager.GET_META_DATA | PackageManager.MATCH_DEBUG_TRIAGED_MISSING);
+            libraryFileName = getWebViewLibrary(packageInfo.applicationInfo);
         } catch (PackageManager.NameNotFoundException e) {
             Log.e(LOGTAG, "Couldn't find package " + packageName);
             return LIBLOAD_WRONG_PACKAGE_NAME;
         }
 
-        try {
-            int loadNativeRet = WebViewLibraryLoader.loadNativeLibrary(clazzLoader, packageInfo);
-            // If we failed waiting for relro we want to return that fact even if we successfully
-            // load the relro file.
-            if (loadNativeRet == LIBLOAD_SUCCESS) return response.status;
-            return loadNativeRet;
-        } catch (MissingWebViewPackageException e) {
-            Log.e(LOGTAG, "Couldn't load native library: " + e);
-            return LIBLOAD_FAILED_TO_LOAD_LIBRARY;
-        }
+        int loadNativeRet = WebViewLibraryLoader.loadNativeLibrary(clazzLoader, libraryFileName);
+        // If we failed waiting for relro we want to return that fact even if we successfully
+        // load the relro file.
+        if (loadNativeRet == LIBLOAD_SUCCESS) return response.status;
+        return loadNativeRet;
     }
 
     static WebViewFactoryProvider getProvider() {
@@ -454,7 +450,8 @@
                 ClassLoader clazzLoader = webViewContext.getClassLoader();
 
                 Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.loadNativeLibrary()");
-                WebViewLibraryLoader.loadNativeLibrary(clazzLoader, sPackageInfo);
+                WebViewLibraryLoader.loadNativeLibrary(clazzLoader,
+                        getWebViewLibrary(sPackageInfo.applicationInfo));
                 Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW);
 
                 Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "Class.forName()");
diff --git a/core/java/android/webkit/WebViewFactoryProvider.java b/core/java/android/webkit/WebViewFactoryProvider.java
index 4f7cdab..4ff49ea 100644
--- a/core/java/android/webkit/WebViewFactoryProvider.java
+++ b/core/java/android/webkit/WebViewFactoryProvider.java
@@ -89,7 +89,7 @@
         * {@link android.webkit.WebView#setSafeBrowsingWhitelist(List<String>,
         * ValueCallback<Boolean>)}
         */
-        void setSafeBrowsingWhitelist(List<String> urls, ValueCallback<Boolean> callback);
+        void setSafeBrowsingWhitelist(List<String> hosts, ValueCallback<Boolean> callback);
 
         /**
          * Implement the API method
diff --git a/core/java/android/webkit/WebViewLibraryLoader.java b/core/java/android/webkit/WebViewLibraryLoader.java
index eb2b6bc..cabba06 100644
--- a/core/java/android/webkit/WebViewLibraryLoader.java
+++ b/core/java/android/webkit/WebViewLibraryLoader.java
@@ -234,17 +234,14 @@
      * <p class="note"><b>Note:</b> Assumes that we have waited for relro creation.
      *
      * @param clazzLoader class loader used to find the linker namespace to load the library into.
-     * @param packageInfo the package from which WebView is loaded.
+     * @param libraryFileName the filename of the library to load.
      */
-    static int loadNativeLibrary(ClassLoader clazzLoader, PackageInfo packageInfo)
-            throws WebViewFactory.MissingWebViewPackageException {
+    public static int loadNativeLibrary(ClassLoader clazzLoader, String libraryFileName) {
         if (!sAddressSpaceReserved) {
             Log.e(LOGTAG, "can't load with relro file; address space not reserved");
             return WebViewFactory.LIBLOAD_ADDRESS_SPACE_NOT_RESERVED;
         }
 
-        final String libraryFileName =
-                WebViewFactory.getWebViewLibrary(packageInfo.applicationInfo);
         String relroPath = VMRuntime.getRuntime().is64Bit() ? CHROMIUM_WEBVIEW_NATIVE_RELRO_64 :
                                                               CHROMIUM_WEBVIEW_NATIVE_RELRO_32;
         int result = nativeLoadWithRelroFile(libraryFileName, relroPath, clazzLoader);
diff --git a/core/java/android/webkit/WebViewZygote.java b/core/java/android/webkit/WebViewZygote.java
index 63fbef3..07593a5 100644
--- a/core/java/android/webkit/WebViewZygote.java
+++ b/core/java/android/webkit/WebViewZygote.java
@@ -93,13 +93,11 @@
         synchronized (sLock) {
             sMultiprocessEnabled = enabled;
 
-            // When toggling between multi-process being on/off, start or stop the
-            // zygote. If it is enabled and the zygote is not yet started, launch it.
-            // Otherwise, kill it. The name may be null if the package information has
-            // not yet been resolved.
-            if (enabled) {
-                connectToZygoteIfNeededLocked();
-            } else {
+            // When multi-process is disabled, kill the zygote. When it is enabled,
+            // the zygote is not explicitly started here to avoid waiting on the
+            // zygote launch at boot. Instead, the zygote will be started when it is
+            // first needed in getProcess().
+            if (!enabled) {
                 stopZygoteLocked();
             }
         }
@@ -169,6 +167,8 @@
             final String zip = (zipPaths.size() == 1) ? zipPaths.get(0) :
                     TextUtils.join(File.pathSeparator, zipPaths);
 
+            String libFileName = WebViewFactory.getWebViewLibrary(sPackage.applicationInfo);
+
             // In the case where the ApplicationInfo has been modified by the stub WebView,
             // we need to use the original ApplicationInfo to determine what the original classpath
             // would have been to use as a cache key.
@@ -179,7 +179,7 @@
             ZygoteProcess.waitForConnectionToZygote(sZygote.getPrimarySocketAddress());
 
             Log.d(LOGTAG, "Preloading package " + zip + " " + librarySearchPath);
-            sZygote.preloadPackageForAbi(zip, librarySearchPath, cacheKey,
+            sZygote.preloadPackageForAbi(zip, librarySearchPath, libFileName, cacheKey,
                                          Build.SUPPORTED_ABIS[0]);
         } catch (Exception e) {
             Log.e(LOGTAG, "Error connecting to webview zygote", e);
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 2e7b2fd..02f35ca 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -107,6 +107,7 @@
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
 import android.view.textclassifier.TextClassification;
+import android.view.textclassifier.TextClassificationManager;
 import android.view.textclassifier.TextLinks;
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.TextView.Drawables;
@@ -4024,7 +4025,7 @@
 
         private void updateAssistMenuItems(Menu menu) {
             clearAssistMenuItems(menu);
-            if (!mTextView.isDeviceProvisioned()) {
+            if (!shouldEnableAssistMenuItems()) {
                 return;
             }
             final TextClassification textClassification =
@@ -4097,7 +4098,7 @@
 
             final TextClassification textClassification =
                     getSelectionActionModeHelper().getTextClassification();
-            if (!mTextView.isDeviceProvisioned() || textClassification == null) {
+            if (!shouldEnableAssistMenuItems() || textClassification == null) {
                 // No textClassification result to handle the click. Eat the click.
                 return true;
             }
@@ -4118,6 +4119,12 @@
             return true;
         }
 
+        private boolean shouldEnableAssistMenuItems() {
+            return mTextView.isDeviceProvisioned()
+                && TextClassificationManager.getSettings(mTextView.getContext())
+                        .isSmartTextShareEnabled();
+        }
+
         @Override
         public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
             getSelectionActionModeHelper().onSelectionAction(item.getItemId());
diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java
index 8836561..85f68d7 100644
--- a/core/java/android/widget/Magnifier.java
+++ b/core/java/android/widget/Magnifier.java
@@ -18,21 +18,33 @@
 
 import android.annotation.FloatRange;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.TestApi;
 import android.annotation.UiThread;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.Outline;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
 import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.os.Handler;
-import android.view.Gravity;
+import android.os.HandlerThread;
+import android.os.Message;
+import android.view.Display;
+import android.view.DisplayListCanvas;
 import android.view.LayoutInflater;
 import android.view.PixelCopy;
+import android.view.RenderNode;
 import android.view.Surface;
+import android.view.SurfaceControl;
 import android.view.SurfaceHolder;
+import android.view.SurfaceSession;
 import android.view.SurfaceView;
+import android.view.ThreadedRenderer;
 import android.view.View;
 import android.view.ViewParent;
 import android.view.ViewRootImpl;
@@ -46,33 +58,41 @@
 public final class Magnifier {
     // Use this to specify that a previous configuration value does not exist.
     private static final int NONEXISTENT_PREVIOUS_CONFIG_VALUE = -1;
+    // The callbacks of the pixel copy requests will be invoked on
+    // the Handler of this Thread when the copy is finished.
+    private static final HandlerThread sPixelCopyHandlerThread =
+            new HandlerThread("magnifier pixel copy result handler");
+
     // The view to which this magnifier is attached.
     private final View mView;
     // The coordinates of the view in the surface.
     private final int[] mViewCoordinatesInSurface;
     // The window containing the magnifier.
-    private final PopupWindow mWindow;
+    private InternalPopupWindow mWindow;
     // The center coordinates of the window containing the magnifier.
     private final Point mWindowCoords = new Point();
     // The width of the window containing the magnifier.
     private final int mWindowWidth;
     // The height of the window containing the magnifier.
     private final int mWindowHeight;
-    // The bitmap used to display the contents of the magnifier.
-    private final Bitmap mBitmap;
+    // The width of the bitmaps where the magnifier content is copied.
+    private final int mBitmapWidth;
+    // The height of the bitmaps where the magnifier content is copied.
+    private final int mBitmapHeight;
+    // The elevation of the window containing the magnifier.
+    private final float mWindowElevation;
     // The center coordinates of the content that is to be magnified.
     private final Point mCenterZoomCoords = new Point();
-    // The callback of the pixel copy request will be invoked on this Handler when
-    // the copy is finished.
-    private final Handler mPixelCopyHandler = Handler.getMain();
-    // Current magnification scale.
-    private final float mZoomScale;
     // Variables holding previous states, used for detecting redundant calls and invalidation.
     private final Point mPrevStartCoordsInSurface = new Point(
             NONEXISTENT_PREVIOUS_CONFIG_VALUE, NONEXISTENT_PREVIOUS_CONFIG_VALUE);
     private final PointF mPrevPosInView = new PointF(
             NONEXISTENT_PREVIOUS_CONFIG_VALUE, NONEXISTENT_PREVIOUS_CONFIG_VALUE);
+    // Rectangle defining the view surface area we pixel copy content from.
     private final Rect mPixelCopyRequestRect = new Rect();
+    // Lock to synchronize between the UI thread and the thread that handles pixel copy results.
+    // Only sync mWindow writes from UI thread with mWindow reads from sPixelCopyHandlerThread.
+    private final Object mLock = new Object();
 
     /**
      * Initializes a magnifier.
@@ -82,8 +102,6 @@
     public Magnifier(@NonNull View view) {
         mView = Preconditions.checkNotNull(view);
         final Context context = mView.getContext();
-        final float elevation = context.getResources().getDimension(
-                com.android.internal.R.dimen.magnifier_elevation);
         final View content = LayoutInflater.from(context).inflate(
                 com.android.internal.R.layout.magnifier, null);
         content.findViewById(com.android.internal.R.id.magnifier_inner).setClipToOutline(true);
@@ -91,23 +109,18 @@
                 com.android.internal.R.dimen.magnifier_width);
         mWindowHeight = context.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.magnifier_height);
-        mZoomScale = context.getResources().getFloat(
+        mWindowElevation = context.getResources().getDimension(
+                com.android.internal.R.dimen.magnifier_elevation);
+        final float zoomScale = context.getResources().getFloat(
                 com.android.internal.R.dimen.magnifier_zoom_scale);
+        mBitmapWidth = Math.round(mWindowWidth / zoomScale);
+        mBitmapHeight = Math.round(mWindowHeight / zoomScale);
         // The view's surface coordinates will not be updated until the magnifier is first shown.
         mViewCoordinatesInSurface = new int[2];
+    }
 
-        mWindow = new PopupWindow(context);
-        mWindow.setContentView(content);
-        mWindow.setWidth(mWindowWidth);
-        mWindow.setHeight(mWindowHeight);
-        mWindow.setElevation(elevation);
-        mWindow.setTouchable(false);
-        mWindow.setBackgroundDrawable(null);
-
-        final int bitmapWidth = Math.round(mWindowWidth / mZoomScale);
-        final int bitmapHeight = Math.round(mWindowHeight / mZoomScale);
-        mBitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888);
-        getImageView().setImageBitmap(mBitmap);
+    static {
+        sPixelCopyHandlerThread.start();
     }
 
     /**
@@ -155,30 +168,50 @@
         }
 
         final int startX = Math.max(zeroScrollXInSurface, Math.min(
-                mCenterZoomCoords.x - mBitmap.getWidth() / 2,
-                zeroScrollXInSurface + actualWidth - mBitmap.getWidth()));
-        final int startY = mCenterZoomCoords.y - mBitmap.getHeight() / 2;
+                mCenterZoomCoords.x - mBitmapWidth / 2,
+                zeroScrollXInSurface + actualWidth - mBitmapWidth));
+        final int startY = mCenterZoomCoords.y - mBitmapHeight / 2;
 
         if (xPosInView != mPrevPosInView.x || yPosInView != mPrevPosInView.y) {
-            performPixelCopy(startX, startY);
-
+            if (mWindow == null) {
+                synchronized (mLock) {
+                    mWindow = new InternalPopupWindow(mView.getContext(), mView.getDisplay(),
+                            getValidViewSurface(), mWindowWidth, mWindowHeight, mWindowElevation,
+                            Handler.getMain() /* draw the magnifier on the UI thread */, mLock,
+                            mCallback);
+                }
+            }
+            performPixelCopy(startX, startY, true /* update window position */);
             mPrevPosInView.x = xPosInView;
             mPrevPosInView.y = yPosInView;
-
-            if (mWindow.isShowing()) {
-                mWindow.update(mWindowCoords.x, mWindowCoords.y, mWindow.getWidth(),
-                        mWindow.getHeight());
-            } else {
-                mWindow.showAtLocation(mView, Gravity.NO_GRAVITY, mWindowCoords.x, mWindowCoords.y);
-            }
         }
     }
 
+    @Nullable
+    private Surface getValidViewSurface() {
+        // TODO: deduplicate this against the first part of #performPixelCopy
+        final Surface surface;
+        if (mView instanceof SurfaceView) {
+            surface = ((SurfaceView) mView).getHolder().getSurface();
+        } else if (mView.getViewRootImpl() != null) {
+            surface = mView.getViewRootImpl().mSurface;
+        } else {
+            surface = null;
+        }
+
+        return (surface != null && surface.isValid()) ? surface : null;
+    }
+
     /**
      * Dismisses the magnifier from the screen. Calling this on a dismissed magnifier is a no-op.
      */
     public void dismiss() {
-        mWindow.dismiss();
+        if (mWindow != null) {
+            synchronized (mLock) {
+                mWindow.destroy();
+                mWindow = null;
+            }
+        }
     }
 
     /**
@@ -186,43 +219,40 @@
      * {@link #show(float, float)}. This only happens if the magnifier is currently showing.
      */
     public void update() {
-        if (mWindow.isShowing()) {
-            // Update the contents shown in the magnifier.
-            performPixelCopy(mPrevStartCoordsInSurface.x, mPrevStartCoordsInSurface.y);
+        if (mWindow != null) {
+            // Update the content shown in the magnifier.
+            performPixelCopy(mPrevStartCoordsInSurface.x, mPrevStartCoordsInSurface.y,
+                    false /* update window position */);
         }
     }
 
     private void configureCoordinates(final float xPosInView, final float yPosInView) {
         // Compute the coordinates of the center of the content going to be displayed in the
         // magnifier. These are relative to the surface the content is copied from.
-        final float contentPosX;
-        final float contentPosY;
+        final float posX;
+        final float posY;
         if (mView instanceof SurfaceView) {
             // No offset required if the backing Surface matches the size of the SurfaceView.
-            contentPosX = xPosInView;
-            contentPosY = yPosInView;
+            posX = xPosInView;
+            posY = yPosInView;
         } else {
             mView.getLocationInSurface(mViewCoordinatesInSurface);
-            contentPosX = xPosInView + mViewCoordinatesInSurface[0];
-            contentPosY = yPosInView + mViewCoordinatesInSurface[1];
+            posX = xPosInView + mViewCoordinatesInSurface[0];
+            posY = yPosInView + mViewCoordinatesInSurface[1];
         }
-        mCenterZoomCoords.x = Math.round(contentPosX);
-        mCenterZoomCoords.y = Math.round(contentPosY);
+        mCenterZoomCoords.x = Math.round(posX);
+        mCenterZoomCoords.y = Math.round(posY);
 
-        // Compute the position of the magnifier window. These have to be relative to the window
-        // of the view the magnifier is attached to, as the magnifier popup is a panel window
-        // attached to that window.
-        final int[] viewCoordinatesInWindow = new int[2];
-        mView.getLocationInWindow(viewCoordinatesInWindow);
+        // Compute the position of the magnifier window. Again, this has to be relative to the
+        // surface of the magnified view, as this surface is the parent of the magnifier surface.
         final int verticalOffset = mView.getContext().getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.magnifier_offset);
-        final float magnifierPosX = xPosInView + viewCoordinatesInWindow[0];
-        final float magnifierPosY = yPosInView + viewCoordinatesInWindow[1] - verticalOffset;
-        mWindowCoords.x = Math.round(magnifierPosX - mWindowWidth / 2);
-        mWindowCoords.y = Math.round(magnifierPosY - mWindowHeight / 2);
+        mWindowCoords.x = mCenterZoomCoords.x - mWindowWidth / 2;
+        mWindowCoords.y = mCenterZoomCoords.y - mWindowHeight / 2 - verticalOffset;
     }
 
-    private void performPixelCopy(final int startXInSurface, final int startYInSurface) {
+    private void performPixelCopy(final int startXInSurface, final int startYInSurface,
+            final boolean updateWindowPosition) {
         // Get the view surface where the content will be copied from.
         final Surface surface;
         final int surfaceWidth;
@@ -256,20 +286,309 @@
         // Perform the pixel copy.
         mPixelCopyRequestRect.set(clampedStartXInSurface,
                 clampedStartYInSurface,
-                clampedStartXInSurface + mBitmap.getWidth(),
-                clampedStartYInSurface + mBitmap.getHeight());
-        PixelCopy.request(surface, mPixelCopyRequestRect, mBitmap,
+                clampedStartXInSurface + mBitmapWidth,
+                clampedStartYInSurface + mBitmapHeight);
+        final int windowCoordsX = mWindowCoords.x;
+        final int windowCoordsY = mWindowCoords.y;
+        final InternalPopupWindow currentWindowInstance = mWindow;
+
+        final Bitmap bitmap =
+                Bitmap.createBitmap(mBitmapWidth, mBitmapHeight, Bitmap.Config.ARGB_8888);
+        PixelCopy.request(surface, mPixelCopyRequestRect, bitmap,
                 result -> {
-                    getImageView().invalidate();
-                    mPrevStartCoordsInSurface.x = startXInSurface;
-                    mPrevStartCoordsInSurface.y = startYInSurface;
+                    synchronized (mLock) {
+                        if (mWindow != currentWindowInstance) {
+                            // The magnifier was dismissed (and maybe shown again) in the meantime.
+                            return;
+                        }
+                        if (updateWindowPosition) {
+                            // TODO: pull the position update outside #performPixelCopy
+                            mWindow.setContentPositionForNextDraw(windowCoordsX, windowCoordsY);
+                        }
+                        mWindow.updateContent(bitmap);
+                    }
                 },
-                mPixelCopyHandler);
+                sPixelCopyHandlerThread.getThreadHandler());
+        mPrevStartCoordsInSurface.x = startXInSurface;
+        mPrevStartCoordsInSurface.y = startYInSurface;
     }
 
-    private ImageView getImageView() {
-        return mWindow.getContentView().findViewById(
-                com.android.internal.R.id.magnifier_image);
+    /**
+     * Magnifier's own implementation of PopupWindow-similar floating window.
+     * This exists to ensure frame-synchronization between window position updates and window
+     * content updates. By using a PopupWindow, these events would happen in different frames,
+     * producing a shakiness effect for the magnifier content.
+     */
+    private static class InternalPopupWindow {
+        // The alpha set on the magnifier's content, which defines how
+        // prominent the white background is.
+        private static final int CONTENT_BITMAP_ALPHA = 242;
+
+        // Display associated to the view the magnifier is attached to.
+        private final Display mDisplay;
+        // The size of the content of the magnifier.
+        private final int mContentWidth;
+        private final int mContentHeight;
+        // The size of the allocated surface.
+        private final int mSurfaceWidth;
+        private final int mSurfaceHeight;
+        // The insets of the content inside the allocated surface.
+        private final int mOffsetX;
+        private final int mOffsetY;
+        // The surface we allocate for the magnifier content + shadow.
+        private final SurfaceSession mSurfaceSession;
+        private final SurfaceControl mSurfaceControl;
+        private final Surface mSurface;
+        // The renderer used for the allocated surface.
+        private final ThreadedRenderer.SimpleRenderer mRenderer;
+        // The RenderNode used to draw the magnifier content in the surface.
+        private final RenderNode mBitmapRenderNode;
+        // The job that will be post'd to apply the pending magnifier updates to the surface.
+        private final Runnable mMagnifierUpdater;
+        // The handler where the magnifier updater jobs will be post'd.
+        private final Handler mHandler;
+        // The callback to be run after the next draw. Only used for testing.
+        private Callback mCallback;
+
+        // Members below describe the state of the magnifier. Reads/writes to them
+        // have to be synchronized between the UI thread and the thread that handles
+        // the pixel copy results. This is the purpose of mLock.
+        private final Object mLock;
+        // Whether a magnifier frame draw is currently pending in the UI thread queue.
+        private boolean mFrameDrawScheduled;
+        // The content bitmap.
+        private Bitmap mBitmap;
+        // Whether the next draw will be the first one for the current instance.
+        private boolean mFirstDraw = true;
+        // The window position in the parent surface. Might be applied during the next draw,
+        // when mPendingWindowPositionUpdate is true.
+        private int mWindowPositionX;
+        private int mWindowPositionY;
+        private boolean mPendingWindowPositionUpdate;
+
+        InternalPopupWindow(final Context context, final Display display,
+                final Surface parentSurface,
+                final int width, final int height, final float elevation,
+                final Handler handler, final Object lock, final Callback callback) {
+            mDisplay = display;
+            mLock = lock;
+            mCallback = callback;
+
+            mContentWidth = width;
+            mContentHeight = height;
+            mOffsetX = (int) (0.1f * width);
+            mOffsetY = (int) (0.1f * height);
+            // Setup the surface we will use for drawing the content and shadow.
+            mSurfaceWidth = mContentWidth + 2 * mOffsetX;
+            mSurfaceHeight = mContentHeight + 2 * mOffsetY;
+            mSurfaceSession = new SurfaceSession(parentSurface);
+            mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession)
+                    .setFormat(PixelFormat.TRANSLUCENT)
+                    .setSize(mSurfaceWidth, mSurfaceHeight)
+                    .setName("magnifier surface")
+                    .setFlags(SurfaceControl.HIDDEN)
+                    .build();
+            mSurface = new Surface();
+            mSurface.copyFrom(mSurfaceControl);
+
+            // Setup the RenderNode tree. The root has only one child, which contains the bitmap.
+            mRenderer = new ThreadedRenderer.SimpleRenderer(
+                    context,
+                    "magnifier renderer",
+                    mSurface
+            );
+            mBitmapRenderNode = createRenderNodeForBitmap(
+                    "magnifier content",
+                    elevation
+            );
+
+            final DisplayListCanvas canvas = mRenderer.getRootNode().start(width, height);
+            try {
+                canvas.insertReorderBarrier();
+                canvas.drawRenderNode(mBitmapRenderNode);
+                canvas.insertInorderBarrier();
+            } finally {
+                mRenderer.getRootNode().end(canvas);
+            }
+
+            // Initialize the update job and the handler where this will be post'd.
+            mHandler = handler;
+            mMagnifierUpdater = this::doDraw;
+            mFrameDrawScheduled = false;
+        }
+
+        private RenderNode createRenderNodeForBitmap(final String name, final float elevation) {
+            final RenderNode bitmapRenderNode = RenderNode.create(name, null);
+
+            // Define the position of the bitmap in the parent render node. The surface regions
+            // outside the bitmap are used to draw elevation.
+            bitmapRenderNode.setLeftTopRightBottom(mOffsetX, mOffsetY,
+                    mOffsetX + mContentWidth, mOffsetY + mContentHeight);
+            bitmapRenderNode.setElevation(elevation);
+
+            final Outline outline = new Outline();
+            outline.setRoundRect(0, 0, mContentWidth, mContentHeight, 3);
+            outline.setAlpha(1.0f);
+            bitmapRenderNode.setOutline(outline);
+            bitmapRenderNode.setClipToOutline(true);
+
+            // Create a dummy draw, which will be replaced later with real drawing.
+            final DisplayListCanvas canvas = bitmapRenderNode.start(mContentWidth, mContentHeight);
+            try {
+                canvas.drawColor(0xFF00FF00);
+            } finally {
+                bitmapRenderNode.end(canvas);
+            }
+
+            return bitmapRenderNode;
+        }
+
+        /**
+         * Sets the position of the magnifier content relative to the parent surface.
+         * The position update will happen in the same frame with the next draw.
+         * The method has to be called in a context that holds {@link #mLock}.
+         *
+         * @param contentX the x coordinate of the content
+         * @param contentY the y coordinate of the content
+         */
+        public void setContentPositionForNextDraw(final int contentX, final int contentY) {
+            mWindowPositionX = contentX - mOffsetX;
+            mWindowPositionY = contentY - mOffsetY;
+            mPendingWindowPositionUpdate = true;
+            requestUpdate();
+        }
+
+        /**
+         * Sets the content that should be displayed in the magnifier.
+         * The update happens immediately, and possibly triggers a pending window movement set
+         * by {@link #setContentPositionForNextDraw(int, int)}.
+         * The method has to be called in a context that holds {@link #mLock}.
+         *
+         * @param bitmap the content bitmap
+         */
+        public void updateContent(final @NonNull Bitmap bitmap) {
+            if (mBitmap != null) {
+                mBitmap.recycle();
+            }
+            mBitmap = bitmap;
+            requestUpdate();
+        }
+
+        private void requestUpdate() {
+            if (mFrameDrawScheduled) {
+                return;
+            }
+            final Message request = Message.obtain(mHandler, mMagnifierUpdater);
+            request.setAsynchronous(true);
+            request.sendToTarget();
+            mFrameDrawScheduled = true;
+        }
+
+        /**
+         * Destroys this instance.
+         */
+        public void destroy() {
+            synchronized (mLock) {
+                mRenderer.destroy();
+                mSurface.destroy();
+                mSurfaceControl.destroy();
+                mSurfaceSession.kill();
+                mBitmapRenderNode.destroy();
+                mHandler.removeCallbacks(mMagnifierUpdater);
+                if (mBitmap != null) {
+                    mBitmap.recycle();
+                }
+            }
+        }
+
+        private void doDraw() {
+            final ThreadedRenderer.FrameDrawingCallback callback;
+
+            // Draw the current bitmap to the surface, and prepare the callback which updates the
+            // surface position. These have to be in the same synchronized block, in order to
+            // guarantee the consistency between the bitmap content and the surface position.
+            synchronized (mLock) {
+                if (!mSurface.isValid()) {
+                    // Probably #destroy() was called for the current instance, so we skip the draw.
+                    return;
+                }
+
+                final DisplayListCanvas canvas =
+                        mBitmapRenderNode.start(mContentWidth, mContentHeight);
+                try {
+                    canvas.drawColor(Color.WHITE);
+
+                    final Rect srcRect = new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
+                    final Rect dstRect = new Rect(0, 0, mContentWidth, mContentHeight);
+                    final Paint paint = new Paint();
+                    paint.setFilterBitmap(true);
+                    paint.setAlpha(CONTENT_BITMAP_ALPHA);
+                    canvas.drawBitmap(mBitmap, srcRect, dstRect, paint);
+                } finally {
+                    mBitmapRenderNode.end(canvas);
+                }
+
+                if (mPendingWindowPositionUpdate || mFirstDraw) {
+                    // If the window has to be shown or moved, defer this until the next draw.
+                    final boolean firstDraw = mFirstDraw;
+                    mFirstDraw = false;
+                    final boolean updateWindowPosition = mPendingWindowPositionUpdate;
+                    mPendingWindowPositionUpdate = false;
+                    final int pendingX = mWindowPositionX;
+                    final int pendingY = mWindowPositionY;
+
+                    callback = frame -> {
+                        synchronized (mLock) {
+                            if (!mSurface.isValid()) {
+                                return;
+                            }
+                            mRenderer.setLightCenter(mDisplay, pendingX, pendingY);
+                            // Show or move the window at the content draw frame.
+                            SurfaceControl.openTransaction();
+                            mSurfaceControl.deferTransactionUntil(mSurface, frame);
+                            if (updateWindowPosition) {
+                                mSurfaceControl.setPosition(pendingX, pendingY);
+                            }
+                            if (firstDraw) {
+                                mSurfaceControl.show();
+                            }
+                            SurfaceControl.closeTransaction();
+                        }
+                    };
+                } else {
+                    callback = null;
+                }
+
+                mFrameDrawScheduled = false;
+            }
+
+            mRenderer.draw(callback);
+            if (mCallback != null) {
+                mCallback.onOperationComplete();
+            }
+        }
+    }
+
+    // The rest of the file consists of test APIs.
+
+    /**
+     * See {@link #setOnOperationCompleteCallback(Callback)}.
+     */
+    @TestApi
+    private Callback mCallback;
+
+    /**
+     * Sets a callback which will be invoked at the end of the next
+     * {@link #show(float, float)} or {@link #update()} operation.
+     *
+     * @hide
+     */
+    @TestApi
+    public void setOnOperationCompleteCallback(final Callback callback) {
+        mCallback = callback;
+        if (mWindow != null) {
+            mWindow.mCallback = callback;
+        }
     }
 
     /**
@@ -278,8 +597,13 @@
      * @hide
      */
     @TestApi
-    public Bitmap getContent() {
-        return mBitmap;
+    public @Nullable Bitmap getContent() {
+        if (mWindow == null) {
+            return null;
+        }
+        synchronized (mWindow.mLock) {
+            return mWindow.mBitmap;
+        }
     }
 
     /**
@@ -296,7 +620,7 @@
 
         final int left = mWindowCoords.x + viewLocationOnScreen[0] - viewLocationInSurface[0];
         final int top = mWindowCoords.y + viewLocationOnScreen[1] - viewLocationInSurface[1];
-        return new Rect(left, top, left + mWindow.getWidth(), top + mWindow.getHeight());
+        return new Rect(left, top, left + mWindowWidth, top + mWindowHeight);
     }
 
     /**
@@ -313,4 +637,15 @@
         size.y = resources.getDimension(com.android.internal.R.dimen.magnifier_height) / density;
         return size;
     }
+
+    /**
+     * @hide
+     */
+    @TestApi
+    public interface Callback {
+        /**
+         * Callback called after the drawing for a magnifier update has happened.
+         */
+        void onOperationComplete();
+    }
 }
diff --git a/core/java/android/widget/MediaControlView2.java b/core/java/android/widget/MediaControlView2.java
index 7d556bf..4fb303e 100644
--- a/core/java/android/widget/MediaControlView2.java
+++ b/core/java/android/widget/MediaControlView2.java
@@ -20,15 +20,18 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.media.SessionToken2;
 import android.media.session.MediaController;
 import android.media.update.ApiLoader;
 import android.media.update.MediaControlView2Provider;
 import android.media.update.ViewGroupHelper;
 import android.util.AttributeSet;
+import android.view.View;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
+// TODO: Use link annotation to refer VideoView2 once VideoView2 became unhidden.
 /**
  * A View that contains the controls for MediaPlayer2.
  * It provides a wide range of UI including buttons such as "Play/Pause", "Rewind", "Fast Forward",
@@ -55,10 +58,7 @@
  * <p>
  * It is also possible to add custom buttons with custom icons and actions inside MediaControlView2.
  * Those buttons will be shown when the overflow button is clicked.
- * See {@link VideoView2#setCustomActions} for more details on how to add.
- *
- * TODO PUBLIC API
- * @hide
+ * See VideoView2#setCustomActions for more details on how to add.
  */
 public class MediaControlView2 extends ViewGroupHelper<MediaControlView2Provider> {
     /** @hide */
@@ -80,62 +80,75 @@
 
     /**
      * MediaControlView2 button value for playing and pausing media.
+     * @hide
      */
     public static final int BUTTON_PLAY_PAUSE = 1;
     /**
      * MediaControlView2 button value for jumping 30 seconds forward.
+     * @hide
      */
     public static final int BUTTON_FFWD = 2;
     /**
      * MediaControlView2 button value for jumping 10 seconds backward.
+     * @hide
      */
     public static final int BUTTON_REW = 3;
     /**
      * MediaControlView2 button value for jumping to next media.
+     * @hide
      */
     public static final int BUTTON_NEXT = 4;
     /**
      * MediaControlView2 button value for jumping to previous media.
+     * @hide
      */
     public static final int BUTTON_PREV = 5;
     /**
      * MediaControlView2 button value for showing/hiding subtitle track.
+     * @hide
      */
     public static final int BUTTON_SUBTITLE = 6;
     /**
      * MediaControlView2 button value for toggling full screen.
+     * @hide
      */
     public static final int BUTTON_FULL_SCREEN = 7;
     /**
      * MediaControlView2 button value for showing/hiding overflow buttons.
+     * @hide
      */
     public static final int BUTTON_OVERFLOW = 8;
     /**
      * MediaControlView2 button value for muting audio.
+     * @hide
      */
     public static final int BUTTON_MUTE = 9;
     /**
      * MediaControlView2 button value for adjusting aspect ratio of view.
+     * @hide
      */
     public static final int BUTTON_ASPECT_RATIO = 10;
     /**
      * MediaControlView2 button value for showing/hiding settings page.
+     * @hide
      */
     public static final int BUTTON_SETTINGS = 11;
 
     /**
      * String for receiving command to show subtitle from MediaSession. Can be checked by
      * implementing {@link android.media.session.MediaSession.Callback#onCommand}
+     * @hide
      */
     public static final String COMMAND_SHOW_SUBTITLE = "showSubtitle";
     /**
      * String for receiving command to hide subtitle from MediaSession. Can be checked by
      * implementing {@link android.media.session.MediaSession.Callback#onCommand}
+     * @hide
      */
     public static final String COMMAND_HIDE_SUBTITLE = "hideSubtitle";
+
     /**
-     * String for receiving command to set fullscreen from MediaSession. Can be checked by
-     * implementing {@link android.media.session.MediaSession.Callback#onCommand}
+     * @hide TODO: remove once the implementation is revised
      */
     public static final String COMMAND_SET_FULLSCREEN = "setFullscreen";
 
@@ -163,10 +176,24 @@
     }
 
     /**
-     * Sets MediaController instance to control corresponding MediaSession.
+     * Sets MediaSession2 token to control corresponding MediaSession2.
+     */
+    public void setMediaSessionToken(SessionToken2 token) {
+        mProvider.setMediaSessionToken_impl(token);
+    }
+
+    /**
+     * Registers a callback to be invoked when the fullscreen mode should be changed.
+     * @param l The callback that will be run
+     */
+    public void setOnFullScreenListener(OnFullScreenListener l) {
+        mProvider.setOnFullScreenListener_impl(l);
+    }
+
+    /**
+     * @hide TODO: remove once the implementation is revised
      */
     public void setController(MediaController controller) {
-        mProvider.setController_impl(controller);
     }
 
     /**
@@ -187,6 +214,7 @@
      * <li>{@link #BUTTON_SETTINGS}
      * </ul>
      * @param visibility One of {@link #VISIBLE}, {@link #INVISIBLE}, or {@link #GONE}.
+     * @hide
      */
     public void setButtonVisibility(@Button int button, @Visibility int visibility) {
         mProvider.setButtonVisibility_impl(button, visibility);
@@ -203,4 +231,15 @@
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         mProvider.onLayout_impl(changed, l, t, r, b);
     }
+
+    /**
+     * Interface definition of a callback to be invoked to inform the fullscreen mode is changed.
+     * Application should handle the fullscreen mode accordingly.
+     */
+    public interface OnFullScreenListener {
+        /**
+         * Called to indicate a fullscreen mode change.
+         */
+        void onFullScreen(View view, boolean fullScreen);
+    }
 }
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 7217def..9553cf5 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -2563,7 +2563,9 @@
                     public void onViewDetachedFromWindow(View v) {
                         v.removeOnAttachStateChangeListener(this);
 
-                        TransitionManager.endTransitions(PopupDecorView.this);
+                        if (isAttachedToWindow()) {
+                            TransitionManager.endTransitions(PopupDecorView.this);
+                        }
                     }
                 };
 
diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java
index 6ab09d6..12ab0ee 100644
--- a/core/java/android/widget/SelectionActionModeHelper.java
+++ b/core/java/android/widget/SelectionActionModeHelper.java
@@ -34,6 +34,8 @@
 import android.util.Log;
 import android.view.ActionMode;
 import android.view.textclassifier.TextClassification;
+import android.view.textclassifier.TextClassificationConstants;
+import android.view.textclassifier.TextClassificationManager;
 import android.view.textclassifier.TextClassifier;
 import android.view.textclassifier.TextLinks;
 import android.view.textclassifier.TextSelection;
@@ -65,12 +67,10 @@
 
     private static final String LOG_TAG = "SelectActionModeHelper";
 
-    // TODO: Make this a configurable flag.
-    private static final boolean SMART_SELECT_ANIMATION_ENABLED = true;
-
     private final Editor mEditor;
     private final TextView mTextView;
     private final TextClassificationHelper mTextClassificationHelper;
+    private final TextClassificationConstants mTextClassificationSettings;
 
     private TextClassification mTextClassification;
     private AsyncTask mTextClassificationAsyncTask;
@@ -84,6 +84,7 @@
     SelectionActionModeHelper(@NonNull Editor editor) {
         mEditor = Preconditions.checkNotNull(editor);
         mTextView = mEditor.getTextView();
+        mTextClassificationSettings = TextClassificationManager.getSettings(mTextView.getContext());
         mTextClassificationHelper = new TextClassificationHelper(
                 mTextView.getContext(),
                 mTextView.getTextClassifier(),
@@ -91,7 +92,7 @@
                 0, 1, mTextView.getTextLocales());
         mSelectionTracker = new SelectionTracker(mTextView);
 
-        if (SMART_SELECT_ANIMATION_ENABLED) {
+        if (mTextClassificationSettings.isSmartSelectionAnimationEnabled()) {
             mSmartSelectSprite = new SmartSelectSprite(mTextView.getContext(),
                     editor.getTextView().mHighlightColor, mTextView::invalidate);
         } else {
@@ -104,9 +105,7 @@
      */
     public void startSelectionActionModeAsync(boolean adjustSelection) {
         // Check if the smart selection should run for editable text.
-        adjustSelection &= !mTextView.isTextEditable()
-                || mTextView.getTextClassifier().getSettings()
-                        .isSuggestSelectionEnabledForEditableText();
+        adjustSelection &= mTextClassificationSettings.isSmartSelectionEnabled();
 
         mSelectionTracker.onOriginalSelection(
                 getText(mTextView),
@@ -249,7 +248,7 @@
                     || mTextView.isTextEditable()
                     || actionMode == Editor.TextActionMode.TEXT_LINK)) {
             // Do not change the selection if TextClassifier should be dark launched.
-            if (!mTextView.getTextClassifier().getSettings().isDarkLaunch()) {
+            if (!mTextClassificationSettings.isModelDarkLaunchEnabled()) {
                 Selection.setSelection((Spannable) text, result.mStart, result.mEnd);
                 mTextView.invalidate();
             }
@@ -450,7 +449,6 @@
             selectionEnd = mTextView.getSelectionEnd();
         }
         mTextClassificationHelper.init(
-                mTextView.getContext(),
                 mTextView.getTextClassifier(),
                 getText(mTextView),
                 selectionStart, selectionEnd,
@@ -882,7 +880,8 @@
 
         private static final int TRIM_DELTA = 120;  // characters
 
-        private Context mContext;
+        private final Context mContext;
+        private final boolean mDarkLaunchEnabled;
         private TextClassifier mTextClassifier;
 
         /** The original TextView text. **/
@@ -917,13 +916,15 @@
 
         TextClassificationHelper(Context context, TextClassifier textClassifier,
                 CharSequence text, int selectionStart, int selectionEnd, LocaleList locales) {
-            init(context, textClassifier, text, selectionStart, selectionEnd, locales);
+            init(textClassifier, text, selectionStart, selectionEnd, locales);
+            mContext = Preconditions.checkNotNull(context);
+            mDarkLaunchEnabled = TextClassificationManager.getSettings(mContext)
+                    .isModelDarkLaunchEnabled();
         }
 
         @UiThread
-        public void init(Context context, TextClassifier textClassifier,
-                CharSequence text, int selectionStart, int selectionEnd, LocaleList locales) {
-            mContext = Preconditions.checkNotNull(context);
+        public void init(TextClassifier textClassifier, CharSequence text,
+                int selectionStart, int selectionEnd, LocaleList locales) {
             mTextClassifier = Preconditions.checkNotNull(textClassifier);
             mText = Preconditions.checkNotNull(text).toString();
             mLastClassificationText = null; // invalidate.
@@ -956,7 +957,7 @@
                         mSelectionOptions.getDefaultLocales());
             }
             // Do not classify new selection boundaries if TextClassifier should be dark launched.
-            if (!mTextClassifier.getSettings().isDarkLaunch()) {
+            if (!mDarkLaunchEnabled) {
                 mSelectionStart = Math.max(0, selection.getSelectionStartIndex() + mTrimStart);
                 mSelectionEnd = Math.min(
                         mText.length(), selection.getSelectionEndIndex() + mTrimStart);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 2cfdb76..50e6393 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -319,6 +319,11 @@
 
     // Enum for the "typeface" XML parameter.
     // TODO: How can we get this from the XML instead of hardcoding it here?
+    /** @hide */
+    @IntDef(value = {DEFAULT_TYPEFACE, SANS, SERIF, MONOSPACE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface XMLTypefaceAttr{}
+    private static final int DEFAULT_TYPEFACE = -1;
     private static final int SANS = 1;
     private static final int SERIF = 2;
     private static final int MONOSPACE = 3;
@@ -1976,33 +1981,52 @@
         }
     }
 
-    private void setTypefaceFromAttrs(Typeface fontTypeface, String familyName, int typefaceIndex,
-            int styleIndex) {
-        Typeface tf = fontTypeface;
-        if (tf == null && familyName != null) {
-            tf = Typeface.create(familyName, styleIndex);
-        } else if (tf != null && tf.getStyle() != styleIndex) {
-            tf = Typeface.create(tf, styleIndex);
+    /**
+     * Sets the Typeface taking into account the given attributes.
+     *
+     * @param typeface a typeface
+     * @param familyName family name string, e.g. "serif"
+     * @param typefaceIndex an index of the typeface enum, e.g. SANS, SERIF.
+     * @param style a typeface style
+     * @param weight a weight value for the Typeface or -1 if not specified.
+     */
+    private void setTypefaceFromAttrs(@Nullable Typeface typeface, @Nullable String familyName,
+            @XMLTypefaceAttr int typefaceIndex, @Typeface.Style int style,
+            @IntRange(from = -1, to = Typeface.MAX_WEIGHT) int weight) {
+        if (typeface == null && familyName != null) {
+            // Lookup normal Typeface from system font map.
+            final Typeface normalTypeface = Typeface.create(familyName, Typeface.NORMAL);
+            resolveStyleAndSetTypeface(normalTypeface, style, weight);
+        } else if (typeface != null) {
+            resolveStyleAndSetTypeface(typeface, style, weight);
+        } else {  // both typeface and familyName is null.
+            switch (typefaceIndex) {
+                case SANS:
+                    resolveStyleAndSetTypeface(Typeface.SANS_SERIF, style, weight);
+                    break;
+                case SERIF:
+                    resolveStyleAndSetTypeface(Typeface.SERIF, style, weight);
+                    break;
+                case MONOSPACE:
+                    resolveStyleAndSetTypeface(Typeface.MONOSPACE, style, weight);
+                    break;
+                case DEFAULT_TYPEFACE:
+                default:
+                    resolveStyleAndSetTypeface(null, style, weight);
+                    break;
+            }
         }
-        if (tf != null) {
-            setTypeface(tf);
-            return;
+    }
+
+    private void resolveStyleAndSetTypeface(@NonNull Typeface typeface, @Typeface.Style int style,
+            @IntRange(from = -1, to = Typeface.MAX_WEIGHT) int weight) {
+        if (weight >= 0) {
+            weight = Math.min(Typeface.MAX_WEIGHT, weight);
+            final boolean italic = (style & Typeface.ITALIC) != 0;
+            setTypeface(Typeface.create(typeface, weight, italic));
+        } else {
+            setTypeface(Typeface.create(typeface, style));
         }
-        switch (typefaceIndex) {
-            case SANS:
-                tf = Typeface.SANS_SERIF;
-                break;
-
-            case SERIF:
-                tf = Typeface.SERIF;
-                break;
-
-            case MONOSPACE:
-                tf = Typeface.MONOSPACE;
-                break;
-        }
-
-        setTypeface(tf, styleIndex);
     }
 
     private void setRelativeDrawablesIfNeeded(Drawable start, Drawable end) {
@@ -3392,6 +3416,7 @@
         boolean mFontFamilyExplicit = false;
         int mTypefaceIndex = -1;
         int mStyleIndex = -1;
+        int mFontWeight = -1;
         boolean mAllCaps = false;
         int mShadowColor = 0;
         float mShadowDx = 0, mShadowDy = 0, mShadowRadius = 0;
@@ -3416,6 +3441,7 @@
                     + "    mFontFamilyExplicit:" + mFontFamilyExplicit + "\n"
                     + "    mTypefaceIndex:" + mTypefaceIndex + "\n"
                     + "    mStyleIndex:" + mStyleIndex + "\n"
+                    + "    mFontWeight:" + mFontWeight + "\n"
                     + "    mAllCaps:" + mAllCaps + "\n"
                     + "    mShadowColor:" + mShadowColor + "\n"
                     + "    mShadowDx:" + mShadowDx + "\n"
@@ -3451,6 +3477,8 @@
                 com.android.internal.R.styleable.TextAppearance_fontFamily);
         sAppearanceValues.put(com.android.internal.R.styleable.TextView_textStyle,
                 com.android.internal.R.styleable.TextAppearance_textStyle);
+        sAppearanceValues.put(com.android.internal.R.styleable.TextView_textFontWeight,
+                com.android.internal.R.styleable.TextAppearance_textFontWeight);
         sAppearanceValues.put(com.android.internal.R.styleable.TextView_textAllCaps,
                 com.android.internal.R.styleable.TextAppearance_textAllCaps);
         sAppearanceValues.put(com.android.internal.R.styleable.TextView_shadowColor,
@@ -3536,6 +3564,9 @@
                 case com.android.internal.R.styleable.TextAppearance_textStyle:
                     attributes.mStyleIndex = appearance.getInt(attr, attributes.mStyleIndex);
                     break;
+                case com.android.internal.R.styleable.TextAppearance_textFontWeight:
+                    attributes.mFontWeight = appearance.getInt(attr, attributes.mFontWeight);
+                    break;
                 case com.android.internal.R.styleable.TextAppearance_textAllCaps:
                     attributes.mAllCaps = appearance.getBoolean(attr, attributes.mAllCaps);
                     break;
@@ -3598,7 +3629,7 @@
             attributes.mFontFamily = null;
         }
         setTypefaceFromAttrs(attributes.mFontTypeface, attributes.mFontFamily,
-                attributes.mTypefaceIndex, attributes.mStyleIndex);
+                attributes.mTypefaceIndex, attributes.mStyleIndex, attributes.mFontWeight);
 
         if (attributes.mShadowColor != 0) {
             setShadowLayer(attributes.mShadowRadius, attributes.mShadowDx, attributes.mShadowDy,
@@ -5938,15 +5969,19 @@
         boolean forceUpdate = false;
         if (isPassword) {
             setTransformationMethod(PasswordTransformationMethod.getInstance());
-            setTypefaceFromAttrs(null/* fontTypeface */, null /* fontFamily */, MONOSPACE, 0);
+            setTypefaceFromAttrs(null/* fontTypeface */, null /* fontFamily */, MONOSPACE,
+                    Typeface.NORMAL, -1 /* weight, not specifeid */);
         } else if (isVisiblePassword) {
             if (mTransformation == PasswordTransformationMethod.getInstance()) {
                 forceUpdate = true;
             }
-            setTypefaceFromAttrs(null/* fontTypeface */, null /* fontFamily */, MONOSPACE, 0);
+            setTypefaceFromAttrs(null/* fontTypeface */, null /* fontFamily */, MONOSPACE,
+                    Typeface.NORMAL, -1 /* weight, not specified */);
         } else if (wasPassword || wasVisiblePassword) {
             // not in password mode, clean up typeface and transformation
-            setTypefaceFromAttrs(null/* fontTypeface */, null /* fontFamily */, -1, -1);
+            setTypefaceFromAttrs(null/* fontTypeface */, null /* fontFamily */,
+                    DEFAULT_TYPEFACE /* typeface index */, Typeface.NORMAL,
+                    -1 /* weight, not specified */);
             if (mTransformation == PasswordTransformationMethod.getInstance()) {
                 forceUpdate = true;
             }
diff --git a/core/java/android/widget/VideoView2.java b/core/java/android/widget/VideoView2.java
index 69c1fb6..09ff337 100644
--- a/core/java/android/widget/VideoView2.java
+++ b/core/java/android/widget/VideoView2.java
@@ -22,7 +22,12 @@
 import android.content.Context;
 import android.media.AudioAttributes;
 import android.media.AudioManager;
-import android.media.MediaPlayerInterface;
+import android.media.DataSourceDesc;
+import android.media.MediaItem2;
+import android.media.MediaMetadata2;
+import android.media.MediaPlayer2;
+import android.media.MediaPlayerBase;
+import android.media.SessionToken2;
 import android.media.session.MediaController;
 import android.media.session.MediaSession;
 import android.media.session.PlaybackState;
@@ -44,14 +49,14 @@
 
 // TODO: Replace MediaSession wtih MediaSession2 once MediaSession2 is submitted.
 /**
- * Displays a video file.  VideoView2 class is a View class which is wrapping MediaPlayer2 so that
- * developers can easily implement a video rendering application.
+ * Displays a video file.  VideoView2 class is a View class which is wrapping {@link MediaPlayer2}
+ * so that developers can easily implement a video rendering application.
  *
  * <p>
  * <em> Data sources that VideoView2 supports : </em>
  * VideoView2 can play video files and audio-only files as
  * well. It can load from various sources such as resources or content providers. The supported
- * media file formats are the same as MediaPlayer2.
+ * media file formats are the same as {@link MediaPlayer2}.
  *
  * <p>
  * <em> View type can be selected : </em>
@@ -100,8 +105,6 @@
  * does not restore the current play state, play position, selected tracks. Applications should save
  * and restore these on their own in {@link android.app.Activity#onSaveInstanceState} and
  * {@link android.app.Activity#onRestoreInstanceState}.
- *
- * @hide
  */
 public class VideoView2 extends ViewGroupHelper<VideoView2Provider> {
     /** @hide */
@@ -168,6 +171,27 @@
         return mProvider.getMediaControlView2_impl();
     }
 
+    /**
+     * Sets MediaMetadata2 instance. It will replace the previously assigned MediaMetadata2 instance
+     * if any.
+     *
+     * @param metadata a MediaMetadata2 instance.
+     * @hide
+     */
+    public void setMediaMetadata(MediaMetadata2 metadata) {
+        mProvider.setMediaMetadata_impl(metadata);
+    }
+
+    /**
+     * Returns MediaMetadata2 instance which is retrieved from MediaPlayer2 inside VideoView2 by
+     * default or by {@link #setMediaMetadata} method.
+     * @hide
+     */
+    public MediaMetadata2 getMediaMetadata() {
+        // TODO: add to Javadoc whether this value can be null or not when integrating with
+        // MediaSession2.
+        return mProvider.getMediaMetadata_impl();
+    }
 
     /**
      * Returns MediaController instance which is connected with MediaSession that VideoView2 is
@@ -177,12 +201,24 @@
      * before calling this method.
      *
      * @throws IllegalStateException if interal MediaSession is not created yet.
+     * @hide  TODO: remove
      */
     public MediaController getMediaController() {
         return mProvider.getMediaController_impl();
     }
 
     /**
+     * Returns {@link android.media.SessionToken2} so that developers create their own
+     * {@link android.media.MediaController2} instance. This method should be called when VideoView2
+     * is attached to window, or it throws IllegalStateException.
+     *
+     * @throws IllegalStateException if interal MediaSession is not created yet.
+     */
+    public SessionToken2 getMediaSessionToken() {
+        return mProvider.getMediaSessionToken_impl();
+    }
+
+    /**
      * Shows or hides closed caption or subtitles if there is any.
      * The first subtitle track will be chosen if there multiple subtitle tracks exist.
      * Default behavior of VideoView2 is not showing subtitle.
@@ -243,6 +279,7 @@
         mProvider.setAudioAttributes_impl(attributes);
     }
 
+    // TODO: unhide this method when MediaPlayerInterface became unhidden.
     /**
      * Sets a remote player for handling playback of the selected route from MediaControlView2.
      * If this is not called, MediaCotrolView2 will not show the route button.
@@ -255,7 +292,7 @@
      * @hide
      */
     public void setRouteAttributes(@NonNull List<String> routeCategories,
-            @Nullable MediaPlayerInterface player) {
+            @Nullable MediaPlayerBase player) {
         mProvider.setRouteAttributes_impl(routeCategories, player);
     }
 
@@ -280,6 +317,8 @@
      * Sets video path.
      *
      * @param path the path of the video.
+     *
+     * @hide TODO remove
      */
     public void setVideoPath(String path) {
         mProvider.setVideoPath_impl(path);
@@ -289,6 +328,8 @@
      * Sets video URI.
      *
      * @param uri the URI of the video.
+     *
+     * @hide TODO remove
      */
     public void setVideoUri(Uri uri) {
         mProvider.setVideoUri_impl(uri);
@@ -303,12 +344,33 @@
      *                changed with key/value pairs through the headers parameter with
      *                "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value
      *                to disallow or allow cross domain redirection.
+     *
+     * @hide TODO remove
      */
     public void setVideoUri(Uri uri, Map<String, String> headers) {
         mProvider.setVideoUri_impl(uri, headers);
     }
 
     /**
+     * Sets {@link MediaItem2} object to render using VideoView2. Alternative way to set media
+     * object to VideoView2 is {@link #setDataSource}.
+     * @param mediaItem the MediaItem2 to play
+     * @see #setDataSource
+     */
+    public void setMediaItem(@NonNull MediaItem2 mediaItem) {
+        mProvider.setMediaItem_impl(mediaItem);
+    }
+
+    /**
+     * Sets {@link DataSourceDesc} object to render using VideoView2.
+     * @param dataSource the {@link DataSourceDesc} object to play.
+     * @see #setMediaItem
+     */
+    public void setDataSource(@NonNull DataSourceDesc dataSource) {
+        mProvider.setDataSource_impl(dataSource);
+    }
+
+    /**
      * Selects which view will be used to render video between SurfacView and TextureView.
      *
      * @param viewType the view type to render video
@@ -339,6 +401,7 @@
      *                   in {@link MediaControlView2}.
      * @param executor executor to run callbacks on.
      * @param listener A listener to be called when a custom button is clicked.
+     * @hide  TODO remove
      */
     public void setCustomActions(List<PlaybackState.CustomAction> actionList,
             Executor executor, OnCustomActionListener listener) {
@@ -349,7 +412,6 @@
      * Registers a callback to be invoked when a view type change is done.
      * {@see #setViewType(int)}
      * @param l The callback that will be run
-     *
      * @hide
      */
     @VisibleForTesting
@@ -360,6 +422,7 @@
     /**
      * Registers a callback to be invoked when the fullscreen mode should be changed.
      * @param l The callback that will be run
+     * @hide  TODO remove
      */
     public void setFullScreenRequestListener(OnFullScreenRequestListener l) {
         mProvider.setFullScreenRequestListener_impl(l);
@@ -388,6 +451,7 @@
     /**
      * Interface definition of a callback to be invoked to inform the fullscreen mode is changed.
      * Application should handle the fullscreen mode accordingly.
+     * @hide  TODO remove
      */
     public interface OnFullScreenRequestListener {
         /**
@@ -398,8 +462,8 @@
 
     /**
      * Interface definition of a callback to be invoked to inform that a custom action is performed.
+     * @hide  TODO remove
      */
-    // TODO: When MediaSession2 is ready, modify the method to match the signature.
     public interface OnCustomActionListener {
         /**
          * Called to indicate that a custom action is performed.
diff --git a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
index 293471c..ffc21d5 100644
--- a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
+++ b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
@@ -319,7 +319,7 @@
         }
         final PackageManager pm = mContext.getPackageManager();
         String label = serviceInfo.getResolveInfo().loadLabel(pm).toString();
-        String summary = serviceInfo.loadSummary(pm).toString();
+        CharSequence summary = serviceInfo.loadSummary(pm);
         if (!includeSummary || TextUtils.isEmpty(summary)) {
             return label;
         }
diff --git a/core/java/com/android/internal/app/ColorDisplayController.java b/core/java/com/android/internal/app/ColorDisplayController.java
index b8682a8..278d31a 100644
--- a/core/java/com/android/internal/app/ColorDisplayController.java
+++ b/core/java/com/android/internal/app/ColorDisplayController.java
@@ -22,6 +22,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.database.ContentObserver;
+import android.metrics.LogMaker;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Looper;
@@ -31,6 +32,8 @@
 import android.util.Slog;
 
 import com.android.internal.R;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -109,10 +112,10 @@
 
     private final Context mContext;
     private final int mUserId;
-
     private final ContentObserver mContentObserver;
 
     private Callback mCallback;
+    private MetricsLogger mMetricsLogger;
 
     public ColorDisplayController(@NonNull Context context) {
         this(context, ActivityManager.getCurrentUser());
@@ -209,6 +212,15 @@
     }
 
     /**
+     * Returns the current auto mode value, without validation, or {@code 1} if the auto mode has
+     * never been set.
+     */
+    public int getAutoModeRaw() {
+        return Secure.getIntForUser(mContext.getContentResolver(), Secure.NIGHT_DISPLAY_AUTO_MODE,
+                -1, mUserId);
+    }
+
+    /**
      * Sets the current auto mode value controlling when Night display will be automatically
      * activated. One of {@link #AUTO_MODE_DISABLED}, {@link #AUTO_MODE_CUSTOM}, or
      * {@link #AUTO_MODE_TWILIGHT}.
@@ -228,7 +240,12 @@
                     Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
                     null,
                     mUserId);
+            getMetricsLogger().write(new LogMaker(
+                    MetricsEvent.ACTION_NIGHT_DISPLAY_AUTO_MODE_CHANGED)
+                    .setType(MetricsEvent.TYPE_ACTION)
+                    .setSubtype(autoMode));
         }
+
         return Secure.putIntForUser(mContext.getContentResolver(),
                 Secure.NIGHT_DISPLAY_AUTO_MODE, autoMode, mUserId);
     }
@@ -263,6 +280,10 @@
         if (startTime == null) {
             throw new IllegalArgumentException("startTime cannot be null");
         }
+        getMetricsLogger().write(new LogMaker(
+                MetricsEvent.ACTION_NIGHT_DISPLAY_AUTO_MODE_CUSTOM_TIME_CHANGED)
+                .setType(MetricsEvent.TYPE_ACTION)
+                .setSubtype(0));
         return Secure.putIntForUser(mContext.getContentResolver(),
                 Secure.NIGHT_DISPLAY_CUSTOM_START_TIME, startTime.toSecondOfDay() * 1000, mUserId);
     }
@@ -297,6 +318,10 @@
         if (endTime == null) {
             throw new IllegalArgumentException("endTime cannot be null");
         }
+        getMetricsLogger().write(new LogMaker(
+                MetricsEvent.ACTION_NIGHT_DISPLAY_AUTO_MODE_CUSTOM_TIME_CHANGED)
+                .setType(MetricsEvent.TYPE_ACTION)
+                .setSubtype(1));
         return Secure.putIntForUser(mContext.getContentResolver(),
                 Secure.NIGHT_DISPLAY_CUSTOM_END_TIME, endTime.toSecondOfDay() * 1000, mUserId);
     }
@@ -450,6 +475,13 @@
         }
     }
 
+    private MetricsLogger getMetricsLogger() {
+        if (mMetricsLogger == null) {
+            mMetricsLogger = new MetricsLogger();
+        }
+        return mMetricsLogger;
+    }
+
     /**
      * Returns {@code true} if Night display is supported by the device.
      */
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index fabda4a..2505ea5 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -26,7 +26,8 @@
     // be kept in sync with frameworks/native/libs/binder/include/binder/IAppOpsService.h
     int checkOperation(int code, int uid, String packageName);
     int noteOperation(int code, int uid, String packageName);
-    int startOperation(IBinder token, int code, int uid, String packageName);
+    int startOperation(IBinder token, int code, int uid, String packageName,
+            boolean startIfModeDefault);
     void finishOperation(IBinder token, int code, int uid, String packageName);
     void startWatchingMode(int op, String packageName, IAppOpsCallback callback);
     void stopWatchingMode(IAppOpsCallback callback);
diff --git a/core/java/com/android/internal/app/procstats/SparseMappingTable.java b/core/java/com/android/internal/app/procstats/SparseMappingTable.java
index 956ce99..91b2054 100644
--- a/core/java/com/android/internal/app/procstats/SparseMappingTable.java
+++ b/core/java/com/android/internal/app/procstats/SparseMappingTable.java
@@ -18,6 +18,7 @@
 
 import android.os.Build;
 import android.os.Parcel;
+import android.util.EventLog;
 import android.util.Slog;
 import libcore.util.EmptyArray;
 
@@ -529,6 +530,12 @@
             readCompactedLongArray(in, array, size);
             mLongs.add(array);
         }
+        // Verify that last array's length is consistent with writeToParcel
+        if (N > 0 && mLongs.get(N - 1).length != mNextIndex) {
+            EventLog.writeEvent(0x534e4554, "73252178", -1, "");
+            throw new IllegalStateException("Expected array of length " + mNextIndex + " but was "
+                    + mLongs.get(N - 1).length);
+        }
     }
 
     /**
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index d1932cf..242f422 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -110,7 +110,10 @@
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
+import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.locks.ReentrantLock;
 
@@ -134,7 +137,7 @@
     private static final int MAGIC = 0xBA757475; // 'BATSTATS'
 
     // Current on-disk Parcel version
-    private static final int VERSION = 175 + (USE_OLD_HISTORY ? 1000 : 0);
+    private static final int VERSION = 176 + (USE_OLD_HISTORY ? 1000 : 0);
 
     // Maximum number of items we will record in the history.
     private static final int MAX_HISTORY_ITEMS;
@@ -2820,6 +2823,7 @@
             implements Parcelable {
         private final LongSamplingCounter mIdleTimeMillis;
         private final LongSamplingCounter mScanTimeMillis;
+        private final LongSamplingCounter mSleepTimeMillis;
         private final LongSamplingCounter mRxTimeMillis;
         private final LongSamplingCounter[] mTxTimeMillis;
         private final LongSamplingCounter mPowerDrainMaMs;
@@ -2827,6 +2831,7 @@
         public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates) {
             mIdleTimeMillis = new LongSamplingCounter(timeBase);
             mScanTimeMillis = new LongSamplingCounter(timeBase);
+            mSleepTimeMillis = new LongSamplingCounter(timeBase);
             mRxTimeMillis = new LongSamplingCounter(timeBase);
             mTxTimeMillis = new LongSamplingCounter[numTxStates];
             for (int i = 0; i < numTxStates; i++) {
@@ -2838,6 +2843,7 @@
         public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates, Parcel in) {
             mIdleTimeMillis = new LongSamplingCounter(timeBase, in);
             mScanTimeMillis = new LongSamplingCounter(timeBase, in);
+            mSleepTimeMillis = new LongSamplingCounter(timeBase, in);
             mRxTimeMillis = new LongSamplingCounter(timeBase, in);
             final int recordedTxStates = in.readInt();
             if (recordedTxStates != numTxStates) {
@@ -2854,6 +2860,7 @@
         public void readSummaryFromParcel(Parcel in) {
             mIdleTimeMillis.readSummaryFromParcelLocked(in);
             mScanTimeMillis.readSummaryFromParcelLocked(in);
+            mSleepTimeMillis.readSummaryFromParcelLocked(in);
             mRxTimeMillis.readSummaryFromParcelLocked(in);
             final int recordedTxStates = in.readInt();
             if (recordedTxStates != mTxTimeMillis.length) {
@@ -2873,6 +2880,7 @@
         public void writeSummaryToParcel(Parcel dest) {
             mIdleTimeMillis.writeSummaryFromParcelLocked(dest);
             mScanTimeMillis.writeSummaryFromParcelLocked(dest);
+            mSleepTimeMillis.writeSummaryFromParcelLocked(dest);
             mRxTimeMillis.writeSummaryFromParcelLocked(dest);
             dest.writeInt(mTxTimeMillis.length);
             for (LongSamplingCounter counter : mTxTimeMillis) {
@@ -2885,6 +2893,7 @@
         public void writeToParcel(Parcel dest, int flags) {
             mIdleTimeMillis.writeToParcel(dest);
             mScanTimeMillis.writeToParcel(dest);
+            mSleepTimeMillis.writeToParcel(dest);
             mRxTimeMillis.writeToParcel(dest);
             dest.writeInt(mTxTimeMillis.length);
             for (LongSamplingCounter counter : mTxTimeMillis) {
@@ -2896,6 +2905,7 @@
         public void reset(boolean detachIfReset) {
             mIdleTimeMillis.reset(detachIfReset);
             mScanTimeMillis.reset(detachIfReset);
+            mSleepTimeMillis.reset(detachIfReset);
             mRxTimeMillis.reset(detachIfReset);
             for (LongSamplingCounter counter : mTxTimeMillis) {
                 counter.reset(detachIfReset);
@@ -2906,6 +2916,7 @@
         public void detach() {
             mIdleTimeMillis.detach();
             mScanTimeMillis.detach();
+            mSleepTimeMillis.detach();
             mRxTimeMillis.detach();
             for (LongSamplingCounter counter : mTxTimeMillis) {
                 counter.detach();
@@ -2932,6 +2943,15 @@
         }
 
         /**
+         * @return a LongSamplingCounter, measuring time spent in the sleep state in
+         * milliseconds.
+         */
+        @Override
+        public LongSamplingCounter getSleepTimeCounter() {
+            return mSleepTimeMillis;
+        }
+
+        /**
          * @return a LongSamplingCounter, measuring time spent in the receive state in
          * milliseconds.
          */
@@ -11435,6 +11455,8 @@
                 mHasModemReporting = true;
                 mModemActivity.getIdleTimeCounter().addCountLocked(
                         deltaInfo.getIdleTimeMillis());
+                mModemActivity.getSleepTimeCounter().addCountLocked(
+                        deltaInfo.getSleepTimeMillis());
                 mModemActivity.getRxTimeCounter().addCountLocked(deltaInfo.getRxTimeMillis());
                 for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) {
                     mModemActivity.getTxTimeCounters()[lvl]
@@ -11575,7 +11597,7 @@
      * time at the highest power level.
      * @param activityInfo
      */
-    private void addModemTxPowerToHistory(final ModemActivityInfo activityInfo) {
+    private synchronized void addModemTxPowerToHistory(final ModemActivityInfo activityInfo) {
         if (activityInfo == null) {
             return;
         }
@@ -12334,7 +12356,7 @@
     @VisibleForTesting
     public void readKernelUidCpuActiveTimesLocked(boolean onBattery) {
         final long startTimeMs = mClocks.uptimeMillis();
-        mKernelUidCpuActiveTimeReader.readDelta((uid, cpuActiveTimesUs) -> {
+        mKernelUidCpuActiveTimeReader.readDelta((uid, cpuActiveTimesMs) -> {
             uid = mapUid(uid);
             if (Process.isIsolated(uid)) {
                 mKernelUidCpuActiveTimeReader.removeUid(uid);
@@ -12347,7 +12369,7 @@
                 return;
             }
             final Uid u = getUidStatsLocked(uid);
-            u.mCpuActiveTimeMs.addCountLocked(cpuActiveTimesUs, onBattery);
+            u.mCpuActiveTimeMs.addCountLocked(cpuActiveTimesMs, onBattery);
         });
 
         final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs;
@@ -12363,7 +12385,7 @@
     @VisibleForTesting
     public void readKernelUidCpuClusterTimesLocked(boolean onBattery) {
         final long startTimeMs = mClocks.uptimeMillis();
-        mKernelUidCpuClusterTimeReader.readDelta((uid, cpuClusterTimesUs) -> {
+        mKernelUidCpuClusterTimeReader.readDelta((uid, cpuClusterTimesMs) -> {
             uid = mapUid(uid);
             if (Process.isIsolated(uid)) {
                 mKernelUidCpuClusterTimeReader.removeUid(uid);
@@ -12376,7 +12398,7 @@
                 return;
             }
             final Uid u = getUidStatsLocked(uid);
-            u.mCpuClusterTimesMs.addCountLocked(cpuClusterTimesUs, onBattery);
+            u.mCpuClusterTimesMs.addCountLocked(cpuClusterTimesMs, onBattery);
         });
 
         final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs;
@@ -12584,7 +12606,7 @@
         temp = Math.max(0, temp);
 
         reportChangesToStatsLog(mHaveBatteryLevel ? mHistoryCur : null,
-                status, plugType, level, temp);
+                status, plugType, level);
 
         final boolean onBattery = isOnBattery(plugType, status);
         final long uptime = mClocks.uptimeMillis();
@@ -12783,7 +12805,7 @@
     // Inform StatsLog of setBatteryState changes.
     // If this is the first reporting, pass in recentPast == null.
     private void reportChangesToStatsLog(HistoryItem recentPast,
-            final int status, final int plugType, final int level, final int temp) {
+            final int status, final int plugType, final int level) {
 
         if (recentPast == null || recentPast.batteryStatus != status) {
             StatsLog.write(StatsLog.CHARGING_STATE_CHANGED, status);
@@ -12794,8 +12816,6 @@
         if (recentPast == null || recentPast.batteryLevel != level) {
             StatsLog.write(StatsLog.BATTERY_LEVEL_CHANGED, level);
         }
-        // Let's just always print the temperature, regardless of whether it changed.
-        StatsLog.write(StatsLog.DEVICE_TEMPERATURE_REPORTED, temp);
     }
 
     public long getAwakeTimeBattery() {
@@ -12957,6 +12977,7 @@
         final int which = STATS_SINCE_CHARGED;
         final long rawRealTime = SystemClock.elapsedRealtime() * 1000;
         final ControllerActivityCounter counter = getModemControllerActivity();
+        final long sleepTimeMs = counter.getSleepTimeCounter().getCountLocked(which);
         final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which);
         final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which);
         final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which);
@@ -12976,10 +12997,6 @@
             txTimeMs[i] = counter.getTxTimeCounters()[i].getCountLocked(which);
             totalTxTimeMs += txTimeMs[i];
         }
-        final long totalControllerActivityTimeMs
-            = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which) / 1000;
-        final long sleepTimeMs
-            = totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + totalTxTimeMs);
         s.setLoggingDurationMs(computeBatteryRealtime(rawRealTime, which) / 1000);
         s.setKernelActiveTimeMs(getMobileRadioActiveTime(rawRealTime, which) / 1000);
         s.setNumPacketsTx(getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which));
@@ -13326,17 +13343,20 @@
                 = "read_binary_cpu_time";
         public static final String KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS
                 = "proc_state_cpu_times_read_delay_ms";
+        public static final String KEY_KERNEL_UID_READERS_THROTTLE_TIME
+                = "kernel_uid_readers_throttle_time";
 
         private static final boolean DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE = true;
         private static final boolean DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME = true;
-        private static final boolean DEFAULT_READ_BINARY_CPU_TIME = false;
+        private static final boolean DEFAULT_READ_BINARY_CPU_TIME = true;
         private static final long DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS = 5_000;
+        private static final long DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME = 10_000;
 
         public boolean TRACK_CPU_TIMES_BY_PROC_STATE = DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE;
         public boolean TRACK_CPU_ACTIVE_CLUSTER_TIME = DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME;
-        // Not used right now.
         public boolean READ_BINARY_CPU_TIME = DEFAULT_READ_BINARY_CPU_TIME;
         public long PROC_STATE_CPU_TIMES_READ_DELAY_MS = DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS;
+        public long KERNEL_UID_READERS_THROTTLE_TIME = DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME;
 
         private ContentResolver mResolver;
         private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -13374,11 +13394,14 @@
                                 DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE));
                 TRACK_CPU_ACTIVE_CLUSTER_TIME = mParser.getBoolean(
                         KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME, DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME);
-                READ_BINARY_CPU_TIME = mParser.getBoolean(
-                        KEY_READ_BINARY_CPU_TIME, DEFAULT_READ_BINARY_CPU_TIME);
+                updateReadBinaryCpuTime(READ_BINARY_CPU_TIME,
+                        mParser.getBoolean(KEY_READ_BINARY_CPU_TIME, DEFAULT_READ_BINARY_CPU_TIME));
                 updateProcStateCpuTimesReadDelayMs(PROC_STATE_CPU_TIMES_READ_DELAY_MS,
                         mParser.getLong(KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS,
-                        DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS));
+                                DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS));
+                updateKernelUidReadersThrottleTime(KERNEL_UID_READERS_THROTTLE_TIME,
+                        mParser.getLong(KEY_KERNEL_UID_READERS_THROTTLE_TIME,
+                                DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME));
             }
         }
 
@@ -13394,6 +13417,13 @@
             }
         }
 
+        private void updateReadBinaryCpuTime(boolean oldEnabled, boolean isEnabled) {
+            READ_BINARY_CPU_TIME = isEnabled;
+            if (oldEnabled != isEnabled) {
+                mKernelUidCpuFreqTimeReader.setReadBinary(isEnabled);
+            }
+        }
+
         private void updateProcStateCpuTimesReadDelayMs(long oldDelayMillis, long newDelayMillis) {
             PROC_STATE_CPU_TIMES_READ_DELAY_MS = newDelayMillis;
             if (oldDelayMillis != newDelayMillis) {
@@ -13403,6 +13433,17 @@
             }
         }
 
+        private void updateKernelUidReadersThrottleTime(long oldTimeMs, long newTimeMs) {
+            KERNEL_UID_READERS_THROTTLE_TIME = newTimeMs;
+            if (oldTimeMs != newTimeMs) {
+                mKernelUidCpuTimeReader.setThrottleInterval(KERNEL_UID_READERS_THROTTLE_TIME);
+                mKernelUidCpuFreqTimeReader.setThrottleInterval(KERNEL_UID_READERS_THROTTLE_TIME);
+                mKernelUidCpuActiveTimeReader.setThrottleInterval(KERNEL_UID_READERS_THROTTLE_TIME);
+                mKernelUidCpuClusterTimeReader
+                        .setThrottleInterval(KERNEL_UID_READERS_THROTTLE_TIME);
+            }
+        }
+
         public void dumpLocked(PrintWriter pw) {
             pw.print(KEY_TRACK_CPU_TIMES_BY_PROC_STATE); pw.print("=");
             pw.println(TRACK_CPU_TIMES_BY_PROC_STATE);
@@ -13412,6 +13453,8 @@
             pw.println(READ_BINARY_CPU_TIME);
             pw.print(KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS); pw.print("=");
             pw.println(PROC_STATE_CPU_TIMES_READ_DELAY_MS);
+            pw.print(KEY_KERNEL_UID_READERS_THROTTLE_TIME); pw.print("=");
+            pw.println(KERNEL_UID_READERS_THROTTLE_TIME);
         }
     }
 
@@ -14574,6 +14617,7 @@
             u.mJobsFreshnessTimeMs.writeSummaryFromParcelLocked(out);
             for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) {
                 if (u.mJobsFreshnessBuckets[i] != null) {
+                    out.writeInt(1);
                     u.mJobsFreshnessBuckets[i].writeSummaryFromParcelLocked(out);
                 } else {
                     out.writeInt(0);
diff --git a/core/java/com/android/internal/os/CpuPowerCalculator.java b/core/java/com/android/internal/os/CpuPowerCalculator.java
index a34e7f5..101c321 100644
--- a/core/java/com/android/internal/os/CpuPowerCalculator.java
+++ b/core/java/com/android/internal/os/CpuPowerCalculator.java
@@ -50,13 +50,14 @@
                 cpuPowerMaUs += cpuSpeedStepPower;
             }
         }
-        cpuPowerMaUs += u.getCpuActiveTime() * mProfile.getAveragePower(
+        cpuPowerMaUs += u.getCpuActiveTime() * 1000 * mProfile.getAveragePower(
                 PowerProfile.POWER_CPU_ACTIVE);
         long[] cpuClusterTimes = u.getCpuClusterTimes();
         if (cpuClusterTimes != null) {
             if (cpuClusterTimes.length == numClusters) {
                 for (int i = 0; i < numClusters; i++) {
-                    double power = cpuClusterTimes[i] * mProfile.getAveragePowerForCpuCluster(i);
+                    double power =
+                            cpuClusterTimes[i] * 1000 * mProfile.getAveragePowerForCpuCluster(i);
                     cpuPowerMaUs += power;
                     if (DEBUG) {
                         Log.d(TAG, "UID " + u.getUid() + ": CPU cluster #" + i + " clusterTimeUs="
diff --git a/core/java/com/android/internal/os/KernelCpuProcReader.java b/core/java/com/android/internal/os/KernelCpuProcReader.java
new file mode 100644
index 0000000..4d56905
--- /dev/null
+++ b/core/java/com/android/internal/os/KernelCpuProcReader.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.os;
+
+import android.os.StrictMode;
+import android.os.SystemClock;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.FileChannel;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+
+/**
+ * Reads cpu time proc files with throttling (adjustable interval).
+ *
+ * KernelCpuProcReader is implemented as singletons for built-in kernel proc files. Get___Instance()
+ * method will return corresponding reader instance. In order to prevent frequent GC,
+ * KernelCpuProcReader reuses a {@link ByteBuffer} to store data read from proc files.
+ *
+ * A KernelCpuProcReader instance keeps an error counter. When the number of read errors within that
+ * instance accumulates to 5, this instance will reject all further read requests.
+ *
+ * Each KernelCpuProcReader instance also has a throttler. Throttle interval can be adjusted via
+ * {@link #setThrottleInterval(long)} method. Default throttle interval is 3000ms. If current
+ * timestamp based on {@link SystemClock#elapsedRealtime()} is less than throttle interval from
+ * the last read timestamp, {@link #readBytes()} will return previous result.
+ *
+ * A KernelCpuProcReader instance is thread-unsafe. Caller needs to hold a lock on this object while
+ * accessing its instance methods or digesting the return values.
+ */
+public class KernelCpuProcReader {
+    private static final String TAG = "KernelCpuProcReader";
+    private static final int ERROR_THRESHOLD = 5;
+    // Throttle interval in milliseconds
+    private static final long DEFAULT_THROTTLE_INTERVAL = 3000L;
+    private static final int INITIAL_BUFFER_SIZE = 8 * 1024;
+    private static final int MAX_BUFFER_SIZE = 1024 * 1024;
+    private static final String PROC_UID_FREQ_TIME = "/proc/uid_cpupower/time_in_state";
+    private static final String PROC_UID_ACTIVE_TIME = "/proc/uid_cpupower/concurrent_active_time";
+    private static final String PROC_UID_CLUSTER_TIME = "/proc/uid_cpupower/concurrent_policy_time";
+
+    private static final KernelCpuProcReader mFreqTimeReader = new KernelCpuProcReader(
+            PROC_UID_FREQ_TIME);
+    private static final KernelCpuProcReader mActiveTimeReader = new KernelCpuProcReader(
+            PROC_UID_ACTIVE_TIME);
+    private static final KernelCpuProcReader mClusterTimeReader = new KernelCpuProcReader(
+            PROC_UID_CLUSTER_TIME);
+
+    public static KernelCpuProcReader getFreqTimeReaderInstance() {
+        return mFreqTimeReader;
+    }
+
+    public static KernelCpuProcReader getActiveTimeReaderInstance() {
+        return mActiveTimeReader;
+    }
+
+    public static KernelCpuProcReader getClusterTimeReaderInstance() {
+        return mClusterTimeReader;
+    }
+
+    private int mErrors;
+    private long mThrottleInterval = DEFAULT_THROTTLE_INTERVAL;
+    private long mLastReadTime = Long.MIN_VALUE;
+    private final Path mProc;
+    private ByteBuffer mBuffer;
+
+    @VisibleForTesting
+    public KernelCpuProcReader(String procFile) {
+        mProc = Paths.get(procFile);
+        mBuffer = ByteBuffer.allocateDirect(INITIAL_BUFFER_SIZE);
+        mBuffer.clear();
+    }
+
+    /**
+     * Reads all bytes from the corresponding proc file.
+     *
+     * If elapsed time since last call to this method is less than the throttle interval, it will
+     * return previous result. When IOException accumulates to 5, it will always return null. This
+     * method is thread-unsafe, so is the return value. Caller needs to hold a lock on this
+     * object while calling this method and digesting its return value.
+     *
+     * @return a {@link ByteBuffer} containing all bytes from the proc file.
+     */
+    public ByteBuffer readBytes() {
+        if (mErrors >= ERROR_THRESHOLD) {
+            return null;
+        }
+        if (SystemClock.elapsedRealtime() < mLastReadTime + mThrottleInterval) {
+            if (mBuffer.limit() > 0 && mBuffer.limit() < mBuffer.capacity()) {
+                // mBuffer has data.
+                return mBuffer.asReadOnlyBuffer().order(ByteOrder.nativeOrder());
+            }
+            return null;
+        }
+        mLastReadTime = SystemClock.elapsedRealtime();
+        mBuffer.clear();
+        final int oldMask = StrictMode.allowThreadDiskReadsMask();
+        try (FileChannel fc = FileChannel.open(mProc, StandardOpenOption.READ)) {
+            while (fc.read(mBuffer) == mBuffer.capacity()) {
+                if (!resize()) {
+                    mErrors++;
+                    Slog.e(TAG, "Proc file is too large: " + mProc);
+                    return null;
+                }
+                fc.position(0);
+            }
+        } catch (IOException e) {
+            mErrors++;
+            Slog.e(TAG, "Error reading: " + mProc, e);
+            return null;
+        } finally {
+            StrictMode.setThreadPolicyMask(oldMask);
+        }
+        mBuffer.flip();
+        return mBuffer.asReadOnlyBuffer().order(ByteOrder.nativeOrder());
+    }
+
+    /**
+     * Sets the throttle interval. Set to 0 will disable throttling. Thread-unsafe, holding a lock
+     * on this object is recommended.
+     *
+     * @param throttleInterval throttle interval in milliseconds
+     */
+    public void setThrottleInterval(long throttleInterval) {
+        if (throttleInterval >= 0) {
+            mThrottleInterval = throttleInterval;
+        }
+    }
+
+    private boolean resize() {
+        if (mBuffer.capacity() >= MAX_BUFFER_SIZE) {
+            return false;
+        }
+        int newSize = Math.min(mBuffer.capacity() << 1, MAX_BUFFER_SIZE);
+        // Slog.i(TAG, "Resize buffer " + mBuffer.capacity() + " => " + newSize);
+        mBuffer = ByteBuffer.allocateDirect(newSize);
+        return true;
+    }
+}
diff --git a/core/java/com/android/internal/os/KernelUidCpuActiveTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuActiveTimeReader.java
index cb96c5c..ce45f3c 100644
--- a/core/java/com/android/internal/os/KernelUidCpuActiveTimeReader.java
+++ b/core/java/com/android/internal/os/KernelUidCpuActiveTimeReader.java
@@ -17,53 +17,109 @@
 package com.android.internal.os;
 
 import android.annotation.Nullable;
-import android.os.StrictMode;
-import android.os.SystemClock;
 import android.util.Slog;
 import android.util.SparseArray;
-import android.util.TimeUtils;
 
 import com.android.internal.annotations.VisibleForTesting;
 
-import java.io.BufferedReader;
-import java.io.FileReader;
-import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
 
 /**
- * Reads /proc/uid_concurrent_active_time which has the format:
- * active: X (X is # cores)
- * [uid0]: [time-0] [time-1] [time-2] ... (# entries = # cores)
- * [uid1]: [time-0] [time-1] [time-2] ... ...
+ * Reads binary proc file /proc/uid_cpupower/concurrent_active_time and reports CPU active time to
+ * BatteryStats to compute {@link PowerProfile#POWER_CPU_ACTIVE}.
+ *
+ * concurrent_active_time is an array of u32's in the following format:
+ * [n, uid0, time0a, time0b, ..., time0n,
+ * uid1, time1a, time1b, ..., time1n,
+ * uid2, time2a, time2b, ..., time2n, etc.]
+ * where n is the total number of cpus (num_possible_cpus)
  * ...
- * Time-N means the CPU time a UID spent running concurrently with N other processes.
+ * timeXn means the CPU time that a UID X spent running concurrently with n other processes.
  * The file contains a monotonically increasing count of time for a single boot. This class
  * maintains the previous results of a call to {@link #readDelta} in order to provide a
  * proper delta.
+ *
+ * This class uses a throttler to reject any {@link #readDelta} call within
+ * {@link #mThrottleInterval}. This is different from the throttler in {@link KernelCpuProcReader},
+ * which has a shorter throttle interval and returns cached result from last read when the request
+ * is throttled.
+ *
+ * This class is NOT thread-safe and NOT designed to be accessed by more than one caller since each
+ * caller has its own view of delta.
  */
-public class KernelUidCpuActiveTimeReader {
-    private static final boolean DEBUG = false;
-    private static final String TAG = "KernelUidCpuActiveTimeReader";
-    private static final String UID_TIMES_PROC_FILE = "/proc/uid_concurrent_active_time";
+public class KernelUidCpuActiveTimeReader extends
+        KernelUidCpuTimeReaderBase<KernelUidCpuActiveTimeReader.Callback> {
+    private static final String TAG = KernelUidCpuActiveTimeReader.class.getSimpleName();
 
-    private int mCoreCount;
-    private long mLastTimeReadMs;
-    private long mNowTimeMs;
-    private SparseArray<long[]> mLastUidCpuActiveTimeMs = new SparseArray<>();
+    private final KernelCpuProcReader mProcReader;
+    private SparseArray<Double> mLastUidCpuActiveTimeMs = new SparseArray<>();
 
-    public interface Callback {
+    public interface Callback extends KernelUidCpuTimeReaderBase.Callback {
+        /**
+         * Notifies when new data is available.
+         *
+         * @param uid             uid int
+         * @param cpuActiveTimeMs cpu active time spent by this uid in milliseconds
+         */
         void onUidCpuActiveTime(int uid, long cpuActiveTimeMs);
     }
 
-    public void readDelta(@Nullable Callback cb) {
-        final int oldMask = StrictMode.allowThreadDiskReadsMask();
-        try (BufferedReader reader = new BufferedReader(new FileReader(UID_TIMES_PROC_FILE))) {
-            mNowTimeMs = SystemClock.elapsedRealtime();
-            readDeltaInternal(reader, cb);
-            mLastTimeReadMs = mNowTimeMs;
-        } catch (IOException e) {
-            Slog.e(TAG, "Failed to read " + UID_TIMES_PROC_FILE + ": " + e);
-        } finally {
-            StrictMode.setThreadPolicyMask(oldMask);
+    public KernelUidCpuActiveTimeReader() {
+        mProcReader = KernelCpuProcReader.getActiveTimeReaderInstance();
+    }
+
+    @VisibleForTesting
+    public KernelUidCpuActiveTimeReader(KernelCpuProcReader procReader) {
+        mProcReader = procReader;
+    }
+
+    @Override
+    protected void readDeltaImpl(@Nullable Callback cb) {
+        synchronized (mProcReader) {
+            final ByteBuffer bytes = mProcReader.readBytes();
+            if (bytes == null || bytes.remaining() <= 4) {
+                // Error already logged in mProcReader.
+                return;
+            }
+            if ((bytes.remaining() & 3) != 0) {
+                Slog.wtf(TAG,
+                        "Cannot parse active time proc bytes to int: " + bytes.remaining());
+                return;
+            }
+            final IntBuffer buf = bytes.asIntBuffer();
+            final int cores = buf.get();
+            if (cores <= 0 || buf.remaining() % (cores + 1) != 0) {
+                Slog.wtf(TAG,
+                        "Cpu active time format error: " + buf.remaining() + " / " + (cores
+                                + 1));
+                return;
+            }
+            int numUids = buf.remaining() / (cores + 1);
+            for (int i = 0; i < numUids; i++) {
+                int uid = buf.get();
+                boolean corrupted = false;
+                double curTime = 0;
+                for (int j = 1; j <= cores; j++) {
+                    int time = buf.get();
+                    if (time < 0) {
+                        Slog.e(TAG, "Corrupted data from active time proc: " + time);
+                        corrupted = true;
+                    } else {
+                        curTime += (double) time * 10 / j; // Unit is 10ms.
+                    }
+                }
+                double delta = curTime - mLastUidCpuActiveTimeMs.get(uid, 0.0);
+                if (delta > 0 && !corrupted) {
+                    mLastUidCpuActiveTimeMs.put(uid, curTime);
+                    if (cb != null) {
+                        cb.onUidCpuActiveTime(uid, (long) delta);
+                    }
+                }
+            }
+            if (DEBUG) {
+                Slog.d(TAG, "Read uids: " + numUids);
+            }
         }
     }
 
@@ -82,65 +138,4 @@
         final int lastIndex = mLastUidCpuActiveTimeMs.indexOfKey(endUid);
         mLastUidCpuActiveTimeMs.removeAtRange(firstIndex, lastIndex - firstIndex + 1);
     }
-
-    @VisibleForTesting
-    public void readDeltaInternal(BufferedReader reader, @Nullable Callback cb) throws IOException {
-        String line = reader.readLine();
-        if (line == null || !line.startsWith("active:")) {
-            Slog.e(TAG, String.format("Malformed proc file: %s ", UID_TIMES_PROC_FILE));
-            return;
-        }
-        if (mCoreCount == 0) {
-            mCoreCount = Integer.parseInt(line.substring(line.indexOf(' ')+1));
-        }
-        while ((line = reader.readLine()) != null) {
-            final int index = line.indexOf(' ');
-            final int uid = Integer.parseInt(line.substring(0, index - 1), 10);
-            readTimesForUid(uid, line.substring(index + 1), cb);
-        }
-    }
-
-    private void readTimesForUid(int uid, String line, @Nullable Callback cb) {
-        long[] lastActiveTime = mLastUidCpuActiveTimeMs.get(uid);
-        if (lastActiveTime == null) {
-            lastActiveTime = new long[mCoreCount];
-            mLastUidCpuActiveTimeMs.put(uid, lastActiveTime);
-        }
-        final String[] timesStr = line.split(" ");
-        if (timesStr.length != mCoreCount) {
-            Slog.e(TAG, String.format("# readings don't match # cores, readings: %d, CPU cores: %d",
-                    timesStr.length, mCoreCount));
-            return;
-        }
-        long sumDeltas = 0;
-        final long[] curActiveTime = new long[mCoreCount];
-        boolean notify = false;
-        for (int i = 0; i < mCoreCount; i++) {
-            // Times read will be in units of 10ms
-            curActiveTime[i] = Long.parseLong(timesStr[i], 10) * 10;
-            long delta = curActiveTime[i] - lastActiveTime[i];
-            if (delta < 0 || curActiveTime[i] < 0) {
-                if (DEBUG) {
-                    final StringBuilder sb = new StringBuilder();
-                    sb.append(String.format("Malformed cpu active time for UID=%d\n", uid));
-                    sb.append(String.format("data=(%d,%d)\n", lastActiveTime[i], curActiveTime[i]));
-                    sb.append("times=(");
-                    TimeUtils.formatDuration(mLastTimeReadMs, sb);
-                    sb.append(",");
-                    TimeUtils.formatDuration(mNowTimeMs, sb);
-                    sb.append(")");
-                    Slog.e(TAG, sb.toString());
-                }
-                return;
-            }
-            notify |= delta > 0;
-            sumDeltas += delta / (i + 1);
-        }
-        if (notify) {
-            System.arraycopy(curActiveTime, 0, lastActiveTime, 0, mCoreCount);
-            if (cb != null) {
-                cb.onUidCpuActiveTime(uid, sumDeltas);
-            }
-        }
-    }
 }
diff --git a/core/java/com/android/internal/os/KernelUidCpuClusterTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuClusterTimeReader.java
index 85153bc..c21b766 100644
--- a/core/java/com/android/internal/os/KernelUidCpuClusterTimeReader.java
+++ b/core/java/com/android/internal/os/KernelUidCpuClusterTimeReader.java
@@ -17,66 +17,181 @@
 package com.android.internal.os;
 
 import android.annotation.Nullable;
-import android.os.StrictMode;
-import android.os.SystemClock;
 import android.util.Slog;
 import android.util.SparseArray;
-import android.util.TimeUtils;
 
 import com.android.internal.annotations.VisibleForTesting;
 
-import java.io.BufferedReader;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
 
 /**
- * Reads /proc/uid_concurrent_policy_time which has the format:
- * policy0: X policy4: Y (there are X cores on policy0, Y cores on policy4)
- * [uid0]: [time-0-0] [time-0-1] ... [time-1-0] [time-1-1] ...
- * [uid1]: [time-0-0] [time-0-1] ... [time-1-0] [time-1-1] ...
- * ...
- * Time-X-Y means the time a UID spent on clusterX running concurrently with Y other processes.
+ * Reads binary proc file /proc/uid_cpupower/concurrent_policy_time and reports CPU cluster times
+ * to BatteryStats to compute cluster power. See
+ * {@link PowerProfile#getAveragePowerForCpuCluster(int)}.
+ *
+ * concurrent_policy_time is an array of u32's in the following format:
+ * [n, x0, ..., xn, uid0, time0a, time0b, ..., time0n,
+ * uid1, time1a, time1b, ..., time1n,
+ * uid2, time2a, time2b, ..., time2n, etc.]
+ * where n is the number of policies
+ * xi is the number cpus on a particular policy
+ * Each uidX is followed by x0 time entries corresponding to the time UID X spent on cluster0
+ * running concurrently with 0, 1, 2, ..., x0 - 1 other processes, then followed by x1, ..., xn
+ * time entries.
+ *
  * The file contains a monotonically increasing count of time for a single boot. This class
- * maintains the previous results of a call to {@link #readDelta} in order to provide a proper
- * delta.
+ * maintains the previous results of a call to {@link #readDelta} in order to provide a
+ * proper delta.
+ *
+ * This class uses a throttler to reject any {@link #readDelta} call within
+ * {@link #mThrottleInterval}. This is different from the throttler in {@link KernelCpuProcReader},
+ * which has a shorter throttle interval and returns cached result from last read when the request
+ * is throttled.
+ *
+ * This class is NOT thread-safe and NOT designed to be accessed by more than one caller since each
+ * caller has its own view of delta.
  */
-public class KernelUidCpuClusterTimeReader {
+public class KernelUidCpuClusterTimeReader extends
+        KernelUidCpuTimeReaderBase<KernelUidCpuClusterTimeReader.Callback> {
+    private static final String TAG = KernelUidCpuClusterTimeReader.class.getSimpleName();
 
-    private static final boolean DEBUG = false;
-    private static final String TAG = "KernelUidCpuClusterTimeReader";
-    private static final String UID_TIMES_PROC_FILE = "/proc/uid_concurrent_policy_time";
+    private final KernelCpuProcReader mProcReader;
+    private SparseArray<double[]> mLastUidPolicyTimeMs = new SparseArray<>();
 
-    // mCoreOnCluster[i] is the # of cores on cluster i
-    private int[] mCoreOnCluster;
-    private int mCores;
-    private long mLastTimeReadMs;
-    private long mNowTimeMs;
-    private SparseArray<long[]> mLastUidPolicyTimeMs = new SparseArray<>();
+    private int mNumClusters = -1;
+    private int mNumCores;
+    private int[] mNumCoresOnCluster;
 
-    public interface Callback {
+    private double[] mCurTime; // Reuse to avoid GC.
+    private long[] mDeltaTime; // Reuse to avoid GC.
+
+    public interface Callback extends KernelUidCpuTimeReaderBase.Callback {
         /**
-         * @param uid
-         * @param cpuActiveTimeMs the first dimension is cluster, the second dimension is the # of
-         *                        processes running concurrently with this uid.
+         * Notifies when new data is available.
+         *
+         * @param uid              uid int
+         * @param cpuClusterTimeMs an array of times spent by this uid on corresponding clusters.
+         *                         The array index is the cluster index.
          */
-        void onUidCpuPolicyTime(int uid, long[] cpuActiveTimeMs);
+        void onUidCpuPolicyTime(int uid, long[] cpuClusterTimeMs);
     }
 
-    public void readDelta(@Nullable Callback cb) {
-        final int oldMask = StrictMode.allowThreadDiskReadsMask();
-        try (BufferedReader reader = new BufferedReader(new FileReader(UID_TIMES_PROC_FILE))) {
-            mNowTimeMs = SystemClock.elapsedRealtime();
-            readDeltaInternal(reader, cb);
-            mLastTimeReadMs = mNowTimeMs;
-        } catch (IOException e) {
-            Slog.e(TAG, "Failed to read " + UID_TIMES_PROC_FILE + ": " + e);
-        } finally {
-            StrictMode.setThreadPolicyMask(oldMask);
+    public KernelUidCpuClusterTimeReader() {
+        mProcReader = KernelCpuProcReader.getClusterTimeReaderInstance();
+    }
+
+    @VisibleForTesting
+    public KernelUidCpuClusterTimeReader(KernelCpuProcReader procReader) {
+        mProcReader = procReader;
+    }
+
+    @Override
+    protected void readDeltaImpl(@Nullable Callback cb) {
+        synchronized (mProcReader) {
+            ByteBuffer bytes = mProcReader.readBytes();
+            if (bytes == null || bytes.remaining() <= 4) {
+                // Error already logged in mProcReader.
+                return;
+            }
+            if ((bytes.remaining() & 3) != 0) {
+                Slog.wtf(TAG,
+                        "Cannot parse cluster time proc bytes to int: " + bytes.remaining());
+                return;
+            }
+            IntBuffer buf = bytes.asIntBuffer();
+            final int numClusters = buf.get();
+            if (numClusters <= 0) {
+                Slog.wtf(TAG, "Cluster time format error: " + numClusters);
+                return;
+            }
+            if (mNumClusters == -1) {
+                mNumClusters = numClusters;
+            }
+            if (buf.remaining() < numClusters) {
+                Slog.wtf(TAG, "Too few data left in the buffer: " + buf.remaining());
+                return;
+            }
+            if (mNumCores <= 0) {
+                if (!readCoreInfo(buf, numClusters)) {
+                    return;
+                }
+            } else {
+                buf.position(buf.position() + numClusters);
+            }
+
+            if (buf.remaining() % (mNumCores + 1) != 0) {
+                Slog.wtf(TAG,
+                        "Cluster time format error: " + buf.remaining() + " / " + (mNumCores
+                                + 1));
+                return;
+            }
+            int numUids = buf.remaining() / (mNumCores + 1);
+
+            for (int i = 0; i < numUids; i++) {
+                processUid(buf, cb);
+            }
+            if (DEBUG) {
+                Slog.d(TAG, "Read uids: " + numUids);
+            }
         }
     }
 
+    private void processUid(IntBuffer buf, @Nullable Callback cb) {
+        int uid = buf.get();
+        double[] lastTimes = mLastUidPolicyTimeMs.get(uid);
+        if (lastTimes == null) {
+            lastTimes = new double[mNumClusters];
+            mLastUidPolicyTimeMs.put(uid, lastTimes);
+        }
+
+        boolean notify = false;
+        boolean corrupted = false;
+
+        for (int j = 0; j < mNumClusters; j++) {
+            mCurTime[j] = 0;
+            for (int k = 1; k <= mNumCoresOnCluster[j]; k++) {
+                int time = buf.get();
+                if (time < 0) {
+                    Slog.e(TAG, "Corrupted data from cluster time proc uid: " + uid);
+                    corrupted = true;
+                }
+                mCurTime[j] += (double) time * 10 / k; // Unit is 10ms.
+            }
+            mDeltaTime[j] = (long) (mCurTime[j] - lastTimes[j]);
+            if (mDeltaTime[j] < 0) {
+                Slog.e(TAG, "Unexpected delta from cluster time proc uid: " + uid);
+                corrupted = true;
+            }
+            notify |= mDeltaTime[j] > 0;
+        }
+        if (notify && !corrupted) {
+            System.arraycopy(mCurTime, 0, lastTimes, 0, mNumClusters);
+            if (cb != null) {
+                cb.onUidCpuPolicyTime(uid, mDeltaTime);
+            }
+        }
+    }
+
+    // Returns if it has read valid info.
+    private boolean readCoreInfo(IntBuffer buf, int numClusters) {
+        int numCores = 0;
+        int[] numCoresOnCluster = new int[numClusters];
+        for (int i = 0; i < numClusters; i++) {
+            numCoresOnCluster[i] = buf.get();
+            numCores += numCoresOnCluster[i];
+        }
+        if (numCores <= 0) {
+            Slog.e(TAG, "Invalid # cores from cluster time proc file: " + numCores);
+            return false;
+        }
+        mNumCores = numCores;
+        mNumCoresOnCluster = numCoresOnCluster;
+        mCurTime = new double[numClusters];
+        mDeltaTime = new long[numClusters];
+        return true;
+    }
+
     public void removeUid(int uid) {
         mLastUidPolicyTimeMs.delete(uid);
     }
@@ -92,87 +207,4 @@
         final int lastIndex = mLastUidPolicyTimeMs.indexOfKey(endUid);
         mLastUidPolicyTimeMs.removeAtRange(firstIndex, lastIndex - firstIndex + 1);
     }
-
-    @VisibleForTesting
-    public void readDeltaInternal(BufferedReader reader, @Nullable Callback cb) throws IOException {
-        String line = reader.readLine();
-        if (line == null || !line.startsWith("policy")) {
-            Slog.e(TAG, String.format("Malformed proc file: %s ", UID_TIMES_PROC_FILE));
-            return;
-        }
-        if (mCoreOnCluster == null) {
-            List<Integer> list = new ArrayList<>();
-            String[] policies = line.split(" ");
-
-            if (policies.length == 0 || policies.length % 2 != 0) {
-                Slog.e(TAG, String.format("Malformed proc file: %s ", UID_TIMES_PROC_FILE));
-                return;
-            }
-
-            for (int i = 0; i < policies.length; i+=2) {
-                list.add(Integer.parseInt(policies[i+1]));
-            }
-
-            mCoreOnCluster = new int[list.size()];
-            for(int i=0;i<list.size();i++){
-                mCoreOnCluster[i] = list.get(i);
-                mCores += mCoreOnCluster[i];
-            }
-        }
-        while ((line = reader.readLine()) != null) {
-            final int index = line.indexOf(' ');
-            final int uid = Integer.parseInt(line.substring(0, index - 1), 10);
-            readTimesForUid(uid, line.substring(index + 1), cb);
-        }
-    }
-
-    private void readTimesForUid(int uid, String line, @Nullable Callback cb) {
-        long[] lastPolicyTime = mLastUidPolicyTimeMs.get(uid);
-        if (lastPolicyTime == null) {
-            lastPolicyTime = new long[mCores];
-            mLastUidPolicyTimeMs.put(uid, lastPolicyTime);
-        }
-        final String[] timeStr = line.split(" ");
-        if (timeStr.length != mCores) {
-            Slog.e(TAG, String.format("# readings don't match # cores, readings: %d, # CPU cores: %d",
-                    timeStr.length, mCores));
-            return;
-        }
-        final long[] deltaPolicyTime = new long[mCores];
-        final long[] currPolicyTime = new long[mCores];
-        boolean notify = false;
-        for (int i = 0; i < mCores; i++) {
-            // Times read will be in units of 10ms
-            currPolicyTime[i] = Long.parseLong(timeStr[i], 10) * 10;
-            deltaPolicyTime[i] = currPolicyTime[i] - lastPolicyTime[i];
-            if (deltaPolicyTime[i] < 0 || currPolicyTime[i] < 0) {
-                if (DEBUG) {
-                    final StringBuilder sb = new StringBuilder();
-                    sb.append(String.format("Malformed cpu policy time for UID=%d\n", uid));
-                    sb.append(String.format("data=(%d,%d)\n", lastPolicyTime[i], currPolicyTime[i]));
-                    sb.append("times=(");
-                    TimeUtils.formatDuration(mLastTimeReadMs, sb);
-                    sb.append(",");
-                    TimeUtils.formatDuration(mNowTimeMs, sb);
-                    sb.append(")");
-                    Slog.e(TAG, sb.toString());
-                }
-                return;
-            }
-            notify |= deltaPolicyTime[i] > 0;
-        }
-        if (notify) {
-            System.arraycopy(currPolicyTime, 0, lastPolicyTime, 0, mCores);
-            if (cb != null) {
-                final long[] times = new long[mCoreOnCluster.length];
-                int core = 0;
-                for (int i = 0; i < mCoreOnCluster.length; i++) {
-                    for (int j = 0; j < mCoreOnCluster[i]; j++) {
-                        times[i] += deltaPolicyTime[core++] / (j+1);
-                    }
-                }
-                cb.onUidCpuPolicyTime(uid, times);
-            }
-        }
-    }
 }
diff --git a/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java
index d97538c..a0787a0 100644
--- a/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java
+++ b/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java
@@ -32,6 +32,8 @@
 import java.io.BufferedReader;
 import java.io.FileReader;
 import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
 
 /**
  * Reads /proc/uid_time_in_state which has the format:
@@ -41,24 +43,42 @@
  * [uid2]: [time in freq1] [time in freq2] [time in freq3] ...
  * ...
  *
+ * Binary variation reads /proc/uid_cpupower/time_in_state in the following format:
+ * [n, uid0, time0a, time0b, ..., time0n,
+ * uid1, time1a, time1b, ..., time1n,
+ * uid2, time2a, time2b, ..., time2n, etc.]
+ * where n is the total number of frequencies.
+ *
  * This provides the times a UID's processes spent executing at each different cpu frequency.
  * The file contains a monotonically increasing count of time for a single boot. This class
  * maintains the previous results of a call to {@link #readDelta} in order to provide a proper
  * delta.
+ *
+ * This class uses a throttler to reject any {@link #readDelta} call within
+ * {@link #mThrottleInterval}. This is different from the throttler in {@link KernelCpuProcReader},
+ * which has a shorter throttle interval and returns cached result from last read when the request
+ * is throttled.
+ *
+ * This class is NOT thread-safe and NOT designed to be accessed by more than one caller since each
+ * caller has its own view of delta.
  */
-public class KernelUidCpuFreqTimeReader {
-    private static final boolean DEBUG = false;
-    private static final String TAG = "KernelUidCpuFreqTimeReader";
+public class KernelUidCpuFreqTimeReader extends
+        KernelUidCpuTimeReaderBase<KernelUidCpuFreqTimeReader.Callback> {
+    private static final String TAG = KernelUidCpuFreqTimeReader.class.getSimpleName();
     static final String UID_TIMES_PROC_FILE = "/proc/uid_time_in_state";
 
-    public interface Callback {
+    public interface Callback extends KernelUidCpuTimeReaderBase.Callback {
         void onUidCpuFreqTime(int uid, long[] cpuFreqTimeMs);
     }
 
     private long[] mCpuFreqs;
+    private long[] mCurTimes; // Reuse to prevent GC.
+    private long[] mDeltaTimes; // Reuse to prevent GC.
     private int mCpuFreqsCount;
-    private long mLastTimeReadMs;
+    private long mLastTimeReadMs = Long.MIN_VALUE;
     private long mNowTimeMs;
+    private boolean mReadBinary = true;
+    private final KernelCpuProcReader mProcReader;
 
     private SparseArray<long[]> mLastUidCpuFreqTimeMs = new SparseArray<>();
 
@@ -69,6 +89,15 @@
     private boolean mPerClusterTimesAvailable;
     private boolean mAllUidTimesAvailable = true;
 
+    public KernelUidCpuFreqTimeReader() {
+        mProcReader = KernelCpuProcReader.getFreqTimeReaderInstance();
+    }
+
+    @VisibleForTesting
+    public KernelUidCpuFreqTimeReader(KernelCpuProcReader procReader) {
+        mProcReader = procReader;
+    }
+
     public boolean perClusterTimesAvailable() {
         return mPerClusterTimesAvailable;
     }
@@ -83,7 +112,6 @@
 
     public long[] readFreqs(@NonNull PowerProfile powerProfile) {
         checkNotNull(powerProfile);
-
         if (mCpuFreqs != null) {
             // No need to read cpu freqs more than once.
             return mCpuFreqs;
@@ -115,20 +143,87 @@
         return readCpuFreqs(line, powerProfile);
     }
 
-    public void readDelta(@Nullable Callback callback) {
+    public void setReadBinary(boolean readBinary) {
+        mReadBinary = readBinary;
+    }
+
+    @Override
+    protected void readDeltaImpl(@Nullable Callback callback) {
         if (mCpuFreqs == null) {
             return;
         }
+        if (mReadBinary) {
+            readDeltaBinary(callback);
+        } else {
+            readDeltaString(callback);
+        }
+    }
+
+    private void readDeltaString(@Nullable Callback callback) {
+        mNowTimeMs = SystemClock.elapsedRealtime();
         final int oldMask = StrictMode.allowThreadDiskReadsMask();
         try (BufferedReader reader = new BufferedReader(new FileReader(UID_TIMES_PROC_FILE))) {
-            mNowTimeMs = SystemClock.elapsedRealtime();
             readDelta(reader, callback);
-            mLastTimeReadMs = mNowTimeMs;
         } catch (IOException e) {
             Slog.e(TAG, "Failed to read " + UID_TIMES_PROC_FILE + ": " + e);
         } finally {
             StrictMode.setThreadPolicyMask(oldMask);
         }
+        mLastTimeReadMs = mNowTimeMs;
+    }
+
+    @VisibleForTesting
+    public void readDeltaBinary(@Nullable Callback callback) {
+        synchronized (mProcReader) {
+            ByteBuffer bytes = mProcReader.readBytes();
+            if (bytes == null || bytes.remaining() <= 4) {
+                // Error already logged in mProcReader.
+                return;
+            }
+            if ((bytes.remaining() & 3) != 0) {
+                Slog.wtf(TAG, "Cannot parse cluster time proc bytes to int: " + bytes.remaining());
+                return;
+            }
+            IntBuffer buf = bytes.asIntBuffer();
+            final int freqs = buf.get();
+            if (freqs != mCpuFreqsCount) {
+                Slog.wtf(TAG, "Cpu freqs expect " + mCpuFreqsCount + " , got " + freqs);
+                return;
+            }
+            if (buf.remaining() % (freqs + 1) != 0) {
+                Slog.wtf(TAG, "Freq time format error: " + buf.remaining() + " / " + (freqs + 1));
+                return;
+            }
+            int numUids = buf.remaining() / (freqs + 1);
+            for (int i = 0; i < numUids; i++) {
+                int uid = buf.get();
+                long[] lastTimes = mLastUidCpuFreqTimeMs.get(uid);
+                if (lastTimes == null) {
+                    lastTimes = new long[mCpuFreqsCount];
+                    mLastUidCpuFreqTimeMs.put(uid, lastTimes);
+                }
+                boolean notify = false;
+                boolean corrupted = false;
+                for (int j = 0; j < freqs; j++) {
+                    mCurTimes[j] = (long) buf.get() * 10; // Unit is 10ms.
+                    mDeltaTimes[j] = mCurTimes[j] - lastTimes[j];
+                    if (mCurTimes[j] < 0 || mDeltaTimes[j] < 0) {
+                        Slog.e(TAG, "Unexpected data from freq time proc: " + mCurTimes[j]);
+                        corrupted = true;
+                    }
+                    notify |= mDeltaTimes[j] > 0;
+                }
+                if (notify && !corrupted) {
+                    System.arraycopy(mCurTimes, 0, lastTimes, 0, freqs);
+                    if (callback != null) {
+                        callback.onUidCpuFreqTime(uid, mDeltaTimes);
+                    }
+                }
+            }
+            if (DEBUG) {
+                Slog.d(TAG, "Read uids: " + numUids);
+            }
+        }
     }
 
     public void removeUid(int uid) {
@@ -212,6 +307,8 @@
         // First item would be "uid: " which needs to be ignored.
         mCpuFreqsCount = freqStr.length - 1;
         mCpuFreqs = new long[mCpuFreqsCount];
+        mCurTimes = new long[mCpuFreqsCount];
+        mDeltaTimes = new long[mCpuFreqsCount];
         for (int i = 0; i < mCpuFreqsCount; ++i) {
             mCpuFreqs[i] = Long.parseLong(freqStr[i + 1], 10);
         }
diff --git a/core/java/com/android/internal/os/KernelUidCpuTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
index 444049e..4263b83 100644
--- a/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
+++ b/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
@@ -38,18 +38,19 @@
  * maintains the previous results of a call to {@link #readDelta} in order to provide a proper
  * delta.
  */
-public class KernelUidCpuTimeReader {
-    private static final String TAG = "KernelUidCpuTimeReader";
+public class KernelUidCpuTimeReader extends
+        KernelUidCpuTimeReaderBase<KernelUidCpuTimeReader.Callback> {
+    private static final String TAG = KernelUidCpuTimeReader.class.getSimpleName();
     private static final String sProcFile = "/proc/uid_cputime/show_uid_stat";
     private static final String sRemoveUidProcFile = "/proc/uid_cputime/remove_uid_range";
 
     /**
      * Callback interface for processing each line of the proc file.
      */
-    public interface Callback {
+    public interface Callback extends KernelUidCpuTimeReaderBase.Callback {
         /**
-         * @param uid UID of the app
-         * @param userTimeUs time spent executing in user space in microseconds
+         * @param uid          UID of the app
+         * @param userTimeUs   time spent executing in user space in microseconds
          * @param systemTimeUs time spent executing in kernel space in microseconds
          */
         void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs);
@@ -61,11 +62,13 @@
 
     /**
      * Reads the proc file, calling into the callback with a delta of time for each UID.
+     *
      * @param callback The callback to invoke for each line of the proc file. If null,
      *                 the data is consumed and subsequent calls to readDelta will provide
      *                 a fresh delta.
      */
-    public void readDelta(@Nullable Callback callback) {
+    @Override
+    protected void readDeltaImpl(@Nullable Callback callback) {
         final int oldMask = StrictMode.allowThreadDiskReadsMask();
         long nowUs = SystemClock.elapsedRealtime() * 1000;
         try (BufferedReader reader = new BufferedReader(new FileReader(sProcFile))) {
@@ -132,7 +135,10 @@
     }
 
     /**
-     * Removes the UID from the kernel module and from internal accounting data.
+     * Removes the UID from the kernel module and from internal accounting data. Only
+     * {@link BatteryStatsImpl} and its child processes should call this, as the change on Kernel is
+     * visible system wide.
+     *
      * @param uid The UID to remove.
      */
     public void removeUid(int uid) {
@@ -145,9 +151,12 @@
     }
 
     /**
-     * Removes UIDs in a given range from the kernel module and internal accounting data.
+     * Removes UIDs in a given range from the kernel module and internal accounting data. Only
+     * {@link BatteryStatsImpl} and its child processes should call this, as the change on Kernel is
+     * visible system wide.
+     *
      * @param startUid the first uid to remove
-     * @param endUid the last uid to remove
+     * @param endUid   the last uid to remove
      */
     public void removeUidsInRange(int startUid, int endUid) {
         if (endUid < startUid) {
diff --git a/core/java/com/android/internal/os/KernelUidCpuTimeReaderBase.java b/core/java/com/android/internal/os/KernelUidCpuTimeReaderBase.java
new file mode 100644
index 0000000..11e50e1
--- /dev/null
+++ b/core/java/com/android/internal/os/KernelUidCpuTimeReaderBase.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.os;
+
+import android.annotation.Nullable;
+import android.os.SystemClock;
+import android.util.Slog;
+
+/**
+ * The base class of all KernelUidCpuTimeReaders.
+ *
+ * This class is NOT designed to be thread-safe or accessed by more than one caller (due to
+ * the nature of {@link #readDelta(Callback)}).
+ */
+public abstract class KernelUidCpuTimeReaderBase<T extends KernelUidCpuTimeReaderBase.Callback> {
+    protected static final boolean DEBUG = false;
+    // Throttle interval in milliseconds
+    private static final long DEFAULT_THROTTLE_INTERVAL = 10_000L;
+
+    private final String TAG = this.getClass().getSimpleName();
+    private long mLastTimeReadMs = Long.MIN_VALUE;
+    private long mThrottleInterval = DEFAULT_THROTTLE_INTERVAL;
+
+    // A generic Callback interface (used by readDelta) to be extended by subclasses.
+    public interface Callback {
+    }
+
+    public void readDelta(@Nullable T cb) {
+        if (SystemClock.elapsedRealtime() < mLastTimeReadMs + mThrottleInterval) {
+            if (DEBUG) {
+                Slog.d(TAG, "Throttle");
+            }
+            return;
+        }
+        readDeltaImpl(cb);
+        mLastTimeReadMs = SystemClock.elapsedRealtime();
+    }
+
+    protected abstract void readDeltaImpl(@Nullable T cb);
+
+    public void setThrottleInterval(long throttleInterval) {
+        if (throttleInterval >= 0) {
+            mThrottleInterval = throttleInterval;
+        }
+    }
+}
diff --git a/core/java/com/android/internal/os/KernelWakelockReader.java b/core/java/com/android/internal/os/KernelWakelockReader.java
index 7178ec7..46667d1 100644
--- a/core/java/com/android/internal/os/KernelWakelockReader.java
+++ b/core/java/com/android/internal/os/KernelWakelockReader.java
@@ -16,6 +16,7 @@
 package com.android.internal.os;
 
 import android.os.Process;
+import android.os.StrictMode;
 import android.os.SystemClock;
 import android.util.Slog;
 
@@ -69,6 +70,7 @@
         boolean wakeup_sources;
         final long startTime = SystemClock.uptimeMillis();
 
+        final int oldMask = StrictMode.allowThreadDiskReadsMask();
         try {
             FileInputStream is;
             try {
@@ -90,6 +92,8 @@
         } catch (java.io.IOException e) {
             Slog.wtf(TAG, "failed to read kernel wakelocks", e);
             return null;
+        } finally {
+            StrictMode.setThreadPolicyMask(oldMask);
         }
 
         final long readTime = SystemClock.uptimeMillis() - startTime;
diff --git a/core/java/com/android/internal/os/WebViewZygoteInit.java b/core/java/com/android/internal/os/WebViewZygoteInit.java
index 32b580c..9f2434e 100644
--- a/core/java/com/android/internal/os/WebViewZygoteInit.java
+++ b/core/java/com/android/internal/os/WebViewZygoteInit.java
@@ -27,6 +27,7 @@
 import android.util.Log;
 import android.webkit.WebViewFactory;
 import android.webkit.WebViewFactoryProvider;
+import android.webkit.WebViewLibraryLoader;
 
 import java.io.DataOutputStream;
 import java.io.File;
@@ -71,7 +72,8 @@
         }
 
         @Override
-        protected void handlePreloadPackage(String packagePath, String libsPath, String cacheKey) {
+        protected void handlePreloadPackage(String packagePath, String libsPath, String libFileName,
+                String cacheKey) {
             Log.i(TAG, "Beginning package preload");
             // Ask ApplicationLoaders to create and cache a classloader for the WebView APK so that
             // our children will reuse the same classloader instead of creating their own.
@@ -80,6 +82,10 @@
             ClassLoader loader = ApplicationLoaders.getDefault().createAndCacheWebViewClassLoader(
                     packagePath, libsPath, cacheKey);
 
+            // Load the native library using WebViewLibraryLoader to share the RELRO data with other
+            // processes.
+            WebViewLibraryLoader.loadNativeLibrary(loader, libFileName);
+
             // Add the APK to the Zygote's list of allowed files for children.
             String[] packageList = TextUtils.split(packagePath, File.pathSeparator);
             for (String packageEntry : packageList) {
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index a32fb43..cd83c57 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -155,7 +155,7 @@
 
         if (parsedArgs.preloadPackage != null) {
             handlePreloadPackage(parsedArgs.preloadPackage, parsedArgs.preloadPackageLibs,
-                    parsedArgs.preloadPackageCacheKey);
+                    parsedArgs.preloadPackageLibFileName, parsedArgs.preloadPackageCacheKey);
             return null;
         }
 
@@ -290,7 +290,8 @@
         return mSocketOutStream;
     }
 
-    protected void handlePreloadPackage(String packagePath, String libsPath, String cacheKey) {
+    protected void handlePreloadPackage(String packagePath, String libsPath, String libFileName,
+            String cacheKey) {
         throw new RuntimeException("Zyogte does not support package preloading");
     }
 
@@ -402,10 +403,24 @@
         String appDataDir;
 
         /**
-         * Whether to preload a package, with the package path in the remainingArgs.
+         * The APK path of the package to preload, when using --preload-package.
          */
         String preloadPackage;
+
+        /**
+         * The native library path of the package to preload, when using --preload-package.
+         */
         String preloadPackageLibs;
+
+        /**
+         * The filename of the native library to preload, when using --preload-package.
+         */
+        String preloadPackageLibFileName;
+
+        /**
+         * The cache key under which to enter the preloaded package into the classloader cache,
+         * when using --preload-package.
+         */
         String preloadPackageCacheKey;
 
         /**
@@ -571,6 +586,7 @@
                 } else if (arg.equals("--preload-package")) {
                     preloadPackage = args[++curArg];
                     preloadPackageLibs = args[++curArg];
+                    preloadPackageLibFileName = args[++curArg];
                     preloadPackageCacheKey = args[++curArg];
                 } else if (arg.equals("--preload-default")) {
                     preloadDefault = true;
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 03a7cd2..528888f 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -2040,6 +2040,10 @@
                 if (getKeyguardManager().inKeyguardRestrictedInputMode()) {
                     break;
                 }
+                if ((getContext().getResources().getConfiguration().uiMode
+                        & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_WATCH) {
+                    break;
+                }
                 if (event.isTracking() && !event.isCanceled()) {
                     launchDefaultSearch(event);
                 }
@@ -2460,6 +2464,15 @@
             decor.setSystemUiVisibility(
                     decor.getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
         }
+        if (a.hasValue(R.styleable.Window_windowLayoutInDisplayCutoutMode)) {
+            int mode = a.getInt(R.styleable.Window_windowLayoutInDisplayCutoutMode, -1);
+            if (mode < LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
+                    || mode > LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER) {
+                throw new UnsupportedOperationException("Unknown windowLayoutInDisplayCutoutMode: "
+                        + a.getString(R.styleable.Window_windowLayoutInDisplayCutoutMode));
+            }
+            params.layoutInDisplayCutoutMode = mode;
+        }
 
         if (mAlwaysReadCloseOnTouchAttr || getContext().getApplicationInfo().targetSdkVersion
                 >= android.os.Build.VERSION_CODES.HONEYCOMB) {
diff --git a/core/java/com/android/internal/util/IndentingPrintWriter.java b/core/java/com/android/internal/util/IndentingPrintWriter.java
index 696667c..e453866 100644
--- a/core/java/com/android/internal/util/IndentingPrintWriter.java
+++ b/core/java/com/android/internal/util/IndentingPrintWriter.java
@@ -57,26 +57,46 @@
         mWrapLength = wrapLength;
     }
 
-    public void increaseIndent() {
+    public IndentingPrintWriter setIndent(String indent) {
+        mIndentBuilder.setLength(0);
+        mIndentBuilder.append(indent);
+        mCurrentIndent = null;
+        return this;
+    }
+
+    public IndentingPrintWriter setIndent(int indent) {
+        mIndentBuilder.setLength(0);
+        for (int i = 0; i < indent; i++) {
+            increaseIndent();
+        }
+        return this;
+    }
+
+    public IndentingPrintWriter increaseIndent() {
         mIndentBuilder.append(mSingleIndent);
         mCurrentIndent = null;
+        return this;
     }
 
-    public void decreaseIndent() {
+    public IndentingPrintWriter decreaseIndent() {
         mIndentBuilder.delete(0, mSingleIndent.length());
         mCurrentIndent = null;
+        return this;
     }
 
-    public void printPair(String key, Object value) {
+    public IndentingPrintWriter printPair(String key, Object value) {
         print(key + "=" + String.valueOf(value) + " ");
+        return this;
     }
 
-    public void printPair(String key, Object[] value) {
+    public IndentingPrintWriter printPair(String key, Object[] value) {
         print(key + "=" + Arrays.toString(value) + " ");
+        return this;
     }
 
-    public void printHexPair(String key, int value) {
+    public IndentingPrintWriter printHexPair(String key, int value) {
         print(key + "=0x" + Integer.toHexString(value) + " ");
+        return this;
     }
 
     @Override
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index 732534c..7c9cf7a 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -22,6 +22,7 @@
 import android.security.keystore.recovery.WrappedApplicationKey;
 import android.security.keystore.recovery.KeyChainSnapshot;
 import android.security.keystore.recovery.KeyChainProtectionParams;
+import android.security.keystore.recovery.RecoveryCertPath;
 import com.android.internal.widget.ICheckCredentialProgressCallback;
 import com.android.internal.widget.VerifyCredentialResponse;
 
@@ -66,14 +67,15 @@
     void initRecoveryService(in String rootCertificateAlias, in byte[] signedPublicKeyList);
     KeyChainSnapshot getKeyChainSnapshot();
     byte[] generateAndStoreKey(String alias);
-    String generateKey(String alias, in byte[] account);
+    String generateKey(String alias);
+    String importKey(String alias, in byte[] keyBytes);
     String getKey(String alias);
     void removeKey(String alias);
     void setSnapshotCreatedPendingIntent(in PendingIntent intent);
     Map getRecoverySnapshotVersions();
     void setServerParams(in byte[] serverParams);
-    void setRecoveryStatus(in String packageName, in String[] aliases, int status);
-    Map getRecoveryStatus(in String packageName);
+    void setRecoveryStatus(in String alias, int status);
+    Map getRecoveryStatus();
     void setRecoverySecretTypes(in int[] secretTypes);
     int[] getRecoverySecretTypes();
     int[] getPendingRecoverySecretTypes();
@@ -81,6 +83,9 @@
     byte[] startRecoverySession(in String sessionId,
             in byte[] verifierPublicKey, in byte[] vaultParams, in byte[] vaultChallenge,
             in List<KeyChainProtectionParams> secrets);
+    byte[] startRecoverySessionWithCertPath(in String sessionId,
+            in RecoveryCertPath verifierCertPath, in byte[] vaultParams, in byte[] vaultChallenge,
+            in List<KeyChainProtectionParams> secrets);
     Map/*<String, byte[]>*/ recoverKeys(in String sessionId, in byte[] recoveryKeyBlob,
             in List<WrappedApplicationKey> applicationKeys);
     void closeSession(in String sessionId);
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 7a248f2..51dd929 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -125,6 +125,7 @@
     private boolean mInStealthMode = false;
     private boolean mEnableHapticFeedback = true;
     private boolean mPatternInProgress = false;
+    private boolean mFadePattern = true;
 
     private float mHitFactor = 0.6f;
 
@@ -376,6 +377,14 @@
     }
 
     /**
+     * Set whether the pattern should fade as it's being drawn. If
+     * true, each segment of the pattern fades over time.
+     */
+    public void setFadePattern(boolean fadePattern) {
+        mFadePattern = fadePattern;
+    }
+
+    /**
      * Set whether the view will use tactile feedback.  If true, there will be
      * tactile feedback as the user enters the pattern.
      *
@@ -1167,10 +1176,18 @@
                     currentPath.moveTo(lastX, lastY);
                     if (state.lineEndX != Float.MIN_VALUE && state.lineEndY != Float.MIN_VALUE) {
                         currentPath.lineTo(state.lineEndX, state.lineEndY);
-                        mPathPaint.setAlpha((int) 255 - lineFadeVal );
+                        if (mFadePattern) {
+                            mPathPaint.setAlpha((int) 255 - lineFadeVal );
+                        } else {
+                            mPathPaint.setAlpha(255);
+                        }
                     } else {
                         currentPath.lineTo(centerX, centerY);
-                        mPathPaint.setAlpha((int) 255 - lineFadeVal );
+                        if (mFadePattern) {
+                            mPathPaint.setAlpha((int) 255 - lineFadeVal );
+                        } else {
+                            mPathPaint.setAlpha(255);
+                        }
                     }
                     canvas.drawPath(currentPath, mPathPaint);
                 }
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index 111934f..8b1de2f 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -63,6 +63,7 @@
     private static final int ALLOW_APP_CONFIGS = 0x08;
     private static final int ALLOW_PRIVAPP_PERMISSIONS = 0x10;
     private static final int ALLOW_OEM_PERMISSIONS = 0x20;
+    private static final int ALLOW_HIDDENAPI_WHITELISTING = 0x40;
     private static final int ALLOW_ALL = ~0;
 
     // Group-ids that are given to all packages as read from etc/permissions/*.xml.
@@ -137,6 +138,9 @@
     // These are the permitted backup transport service components
     final ArraySet<ComponentName> mBackupTransportWhitelist = new ArraySet<>();
 
+    // Package names that are exempted from private API blacklisting
+    final ArraySet<String> mHiddenApiPackageWhitelist = new ArraySet<>();
+
     // These are the packages of carrier-associated apps which should be disabled until used until
     // a SIM is inserted which grants carrier privileges to that carrier app.
     final ArrayMap<String, List<String>> mDisabledUntilUsedPreinstalledCarrierAssociatedApps =
@@ -215,6 +219,10 @@
         return mSystemUserBlacklistedApps;
     }
 
+    public ArraySet<String> getHiddenApiWhitelistedApps() {
+        return mHiddenApiPackageWhitelist;
+    }
+
     public ArraySet<ComponentName> getDefaultVrComponents() {
         return mDefaultVrComponents;
     }
@@ -376,6 +384,7 @@
             boolean allowAppConfigs = (permissionFlag & ALLOW_APP_CONFIGS) != 0;
             boolean allowPrivappPermissions = (permissionFlag & ALLOW_PRIVAPP_PERMISSIONS) != 0;
             boolean allowOemPermissions = (permissionFlag & ALLOW_OEM_PERMISSIONS) != 0;
+            boolean allowApiWhitelisting = (permissionFlag & ALLOW_HIDDENAPI_WHITELISTING) != 0;
             while (true) {
                 XmlUtils.nextElement(parser);
                 if (parser.getEventType() == XmlPullParser.END_DOCUMENT) {
@@ -637,6 +646,15 @@
                     }
                 } else if ("oem-permissions".equals(name) && allowOemPermissions) {
                     readOemPermissions(parser);
+                } else if ("hidden-api-whitelisted-app".equals(name) && allowApiWhitelisting) {
+                    String pkgname = parser.getAttributeValue(null, "package");
+                    if (pkgname == null) {
+                        Slog.w(TAG, "<hidden-api-whitelisted-app> without package in " + permFile
+                                + " at " + parser.getPositionDescription());
+                    } else {
+                        mHiddenApiPackageWhitelist.add(pkgname);
+                    }
+                    XmlUtils.skipCurrentTag(parser);
                 } else {
                     XmlUtils.skipCurrentTag(parser);
                     continue;
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 33f80ce..b048977 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -64,7 +64,7 @@
         "android_graphics_drawable_VectorDrawable.cpp",
         "android_view_DisplayEventReceiver.cpp",
         "android_view_DisplayListCanvas.cpp",
-        "android_view_HardwareLayer.cpp",
+        "android_view_TextureLayer.cpp",
         "android_view_InputChannel.cpp",
         "android_view_InputDevice.cpp",
         "android_view_InputEventReceiver.cpp",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index d202173..f280c7a 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -142,7 +142,7 @@
 extern int register_android_graphics_pdf_PdfRenderer(JNIEnv* env);
 extern int register_android_view_DisplayEventReceiver(JNIEnv* env);
 extern int register_android_view_DisplayListCanvas(JNIEnv* env);
-extern int register_android_view_HardwareLayer(JNIEnv* env);
+extern int register_android_view_TextureLayer(JNIEnv* env);
 extern int register_android_view_RenderNode(JNIEnv* env);
 extern int register_android_view_RenderNodeAnimator(JNIEnv* env);
 extern int register_android_view_Surface(JNIEnv* env);
@@ -1370,7 +1370,7 @@
     REG_JNI(register_android_view_RenderNode),
     REG_JNI(register_android_view_RenderNodeAnimator),
     REG_JNI(register_android_view_DisplayListCanvas),
-    REG_JNI(register_android_view_HardwareLayer),
+    REG_JNI(register_android_view_TextureLayer),
     REG_JNI(register_android_view_ThreadedRenderer),
     REG_JNI(register_android_view_Surface),
     REG_JNI(register_android_view_SurfaceControl),
diff --git a/core/jni/android/graphics/AnimatedImageDrawable.cpp b/core/jni/android/graphics/AnimatedImageDrawable.cpp
index ba56d59..6fd4abf 100644
--- a/core/jni/android/graphics/AnimatedImageDrawable.cpp
+++ b/core/jni/android/graphics/AnimatedImageDrawable.cpp
@@ -132,6 +132,11 @@
 // Java's LOOP_INFINITE relies on this being the same.
 static_assert(SkCodec::kRepetitionCountInfinite == -1);
 
+static jint AnimatedImageDrawable_nGetLoopCount(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
+    auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
+    return drawable->getRepetitionCount();
+}
+
 static void AnimatedImageDrawable_nSetLoopCount(JNIEnv* env, jobject /*clazz*/, jlong nativePtr,
                                                 jint loopCount) {
     auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
@@ -218,6 +223,7 @@
     { "nIsRunning",          "(J)Z",                                                         (void*) AnimatedImageDrawable_nIsRunning },
     { "nStart",              "(J)Z",                                                         (void*) AnimatedImageDrawable_nStart },
     { "nStop",               "(J)Z",                                                         (void*) AnimatedImageDrawable_nStop },
+    { "nGetLoopCount",       "(J)I",                                                         (void*) AnimatedImageDrawable_nGetLoopCount },
     { "nSetLoopCount",       "(JI)V",                                                        (void*) AnimatedImageDrawable_nSetLoopCount },
     { "nSetOnAnimationEndListener", "(JLandroid/graphics/drawable/AnimatedImageDrawable;)V", (void*) AnimatedImageDrawable_nSetOnAnimationEndListener },
     { "nNativeByteSize",     "(J)J",                                                         (void*) AnimatedImageDrawable_nNativeByteSize },
diff --git a/core/jni/android/graphics/YuvToJpegEncoder.cpp b/core/jni/android/graphics/YuvToJpegEncoder.cpp
index 5eecd9c..09adc82 100644
--- a/core/jni/android/graphics/YuvToJpegEncoder.cpp
+++ b/core/jni/android/graphics/YuvToJpegEncoder.cpp
@@ -23,16 +23,28 @@
 YuvToJpegEncoder::YuvToJpegEncoder(int* strides) : fStrides(strides) {
 }
 
+struct ErrorMgr {
+    struct jpeg_error_mgr pub;
+    jmp_buf jmp;
+};
+
+void error_exit(j_common_ptr cinfo) {
+    ErrorMgr* err = (ErrorMgr*) cinfo->err;
+    (*cinfo->err->output_message) (cinfo);
+    longjmp(err->jmp, 1);
+}
+
 bool YuvToJpegEncoder::encode(SkWStream* stream, void* inYuv, int width,
         int height, int* offsets, int jpegQuality) {
     jpeg_compress_struct    cinfo;
-    jpeg_error_mgr          err;
+    ErrorMgr                err;
     skjpeg_destination_mgr  sk_wstream(stream);
 
-    cinfo.err = jpeg_std_error(&err);
-    err.error_exit = skjpeg_error_exit;
-    jmp_buf jmp;
-    if (setjmp(jmp)) {
+    cinfo.err = jpeg_std_error(&err.pub);
+    err.pub.error_exit = error_exit;
+
+    if (setjmp(err.jmp)) {
+        jpeg_destroy_compress(&cinfo);
         return false;
     }
     jpeg_create_compress(&cinfo);
@@ -47,6 +59,8 @@
 
     jpeg_finish_compress(&cinfo);
 
+    jpeg_destroy_compress(&cinfo);
+
     return true;
 }
 
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index 888db32..b163597 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -622,29 +622,25 @@
 
 // ---------------------------------------------------------------------------
 
-static int checkInternalFormat(SkColorType colorType, int format, int type)
+static int checkInternalFormat(SkColorType colorType, int internalformat,
+    int type)
 {
     switch(colorType) {
         case kN32_SkColorType:
+            return (type == GL_UNSIGNED_BYTE &&
+                internalformat == GL_RGBA) ? 0 : -1;
         case kAlpha_8_SkColorType:
-            if (type == GL_UNSIGNED_BYTE)
-                return 0;
+            return (type == GL_UNSIGNED_BYTE &&
+                internalformat == GL_ALPHA) ? 0 : -1;
         case kARGB_4444_SkColorType:
+            return (type == GL_UNSIGNED_SHORT_4_4_4_4 &&
+                internalformat == GL_RGBA) ? 0 : -1;
         case kRGB_565_SkColorType:
-            switch (type) {
-                case GL_UNSIGNED_SHORT_4_4_4_4:
-                case GL_UNSIGNED_SHORT_5_6_5:
-                case GL_UNSIGNED_SHORT_5_5_5_1:
-                    return 0;
-                case GL_UNSIGNED_BYTE:
-                    if (format == GL_LUMINANCE_ALPHA)
-                        return 0;
-            }
-            break;
+            return (type == GL_UNSIGNED_SHORT_5_6_5 &&
+                internalformat == GL_RGB) ? 0 : -1;
         case kRGBA_F16_SkColorType:
-            if (type == GL_HALF_FLOAT && format == GL_RGBA16F)
-                return 0;
-            break;
+            return (type == GL_HALF_FLOAT &&
+                internalformat == GL_RGBA16F) ? 0 : -1;
         default:
             break;
     }
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 61a22c1..6456fe6 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -282,7 +282,7 @@
 
         // compute the frame count
         size_t frameCount;
-        if (audio_is_linear_pcm(format)) {
+        if (audio_has_proportional_frames(format)) {
             const size_t bytesPerSample = audio_bytes_per_sample(format);
             frameCount = buffSizeInBytes / (channelCount * bytesPerSample);
         } else {
diff --git a/core/jni/android_media_MicrophoneInfo.cpp b/core/jni/android_media_MicrophoneInfo.cpp
index 9198cbe..5bd808b 100644
--- a/core/jni/android_media_MicrophoneInfo.cpp
+++ b/core/jni/android_media_MicrophoneInfo.cpp
@@ -65,13 +65,11 @@
     }
     jGeometricLocation = env->NewObject(gMicrophoneInfoCoordinateClass,
                                         gMicrophoneInfoCoordinateCstor,
-                                        NULL,
                                         microphoneInfo->getGeometricLocation()[0],
                                         microphoneInfo->getGeometricLocation()[1],
                                         microphoneInfo->getGeometricLocation()[2]);
     jOrientation = env->NewObject(gMicrophoneInfoCoordinateClass,
                                   gMicrophoneInfoCoordinateCstor,
-                                  NULL,
                                   microphoneInfo->getOrientation()[0],
                                   microphoneInfo->getOrientation()[1],
                                   microphoneInfo->getOrientation()[2]);
@@ -177,7 +175,7 @@
             env, "android/media/MicrophoneInfo$Coordinate3F");
     gMicrophoneInfoCoordinateClass = MakeGlobalRefOrDie(env, microphoneInfoCoordinateClass);
     gMicrophoneInfoCoordinateCstor = GetMethodIDOrDie(env, microphoneInfoCoordinateClass, "<init>",
-           "(Landroid/media/MicrophoneInfo;FFF)V");
+           "(FFF)V");
 
     jclass pairClass = FindClassOrDie(env, "android/util/Pair");
     gPairClass = MakeGlobalRefOrDie(env, pairClass);
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index d18c172..5e2cd40 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -28,9 +28,9 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-#include <utils/Atomic.h>
 #include <binder/IInterface.h>
 #include <binder/IPCThreadState.h>
+#include <cutils/atomic.h>
 #include <utils/Log.h>
 #include <utils/SystemClock.h>
 #include <utils/List.h>
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index d17993a..1b206fd 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -35,8 +35,8 @@
 #include <binder/Parcel.h>
 #include <binder/BpBinder.h>
 #include <binder/ProcessState.h>
+#include <cutils/atomic.h>
 #include <log/log.h>
-#include <utils/Atomic.h>
 #include <utils/KeyedVector.h>
 #include <utils/List.h>
 #include <utils/Log.h>
diff --git a/core/jni/android_view_DisplayListCanvas.cpp b/core/jni/android_view_DisplayListCanvas.cpp
index 98f4733..7956bf4 100644
--- a/core/jni/android_view_DisplayListCanvas.cpp
+++ b/core/jni/android_view_DisplayListCanvas.cpp
@@ -159,7 +159,7 @@
     canvas->drawRenderNode(renderNode);
 }
 
-static void android_view_DisplayListCanvas_drawLayer(jlong canvasPtr, jlong layerPtr) {
+static void android_view_DisplayListCanvas_drawTextureLayer(jlong canvasPtr, jlong layerPtr) {
     Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
     DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
     canvas->drawLayer(layer);
@@ -210,7 +210,7 @@
     { "nInsertReorderBarrier",    "(JZ)V",      (void*) android_view_DisplayListCanvas_insertReorderBarrier },
     { "nFinishRecording",         "(J)J",       (void*) android_view_DisplayListCanvas_finishRecording },
     { "nDrawRenderNode",          "(JJ)V",      (void*) android_view_DisplayListCanvas_drawRenderNode },
-    { "nDrawLayer",               "(JJ)V",      (void*) android_view_DisplayListCanvas_drawLayer },
+    { "nDrawTextureLayer",        "(JJ)V",      (void*) android_view_DisplayListCanvas_drawTextureLayer },
     { "nDrawCircle",              "(JJJJJ)V",   (void*) android_view_DisplayListCanvas_drawCircleProps },
     { "nDrawRoundRect",           "(JJJJJJJJ)V",(void*) android_view_DisplayListCanvas_drawRoundRectProps },
 };
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 0ef5445..8ca5062 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -846,6 +846,14 @@
     transaction->setOverrideScalingMode(ctrl, scalingMode);
 }
 
+static void nativeDestroyInTransaction(JNIEnv* env, jclass clazz,
+                                       jlong transactionObj,
+                                       jlong nativeObject) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+    auto ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
+    transaction->destroySurface(ctrl);
+}
+
 static jobject nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) {
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
     return javaObjectForIBinder(env, ctrl->getHandle());
@@ -997,6 +1005,8 @@
             (void*)nativeSeverChildren } ,
     {"nativeSetOverrideScalingMode", "(JJI)V",
             (void*)nativeSetOverrideScalingMode },
+    {"nativeDestroy", "(JJ)V",
+            (void*)nativeDestroyInTransaction },
     {"nativeGetHandle", "(J)Landroid/os/IBinder;",
             (void*)nativeGetHandle },
     {"nativeScreenshotToBuffer",
diff --git a/core/jni/android_view_HardwareLayer.cpp b/core/jni/android_view_TextureLayer.cpp
similarity index 73%
rename from core/jni/android_view_HardwareLayer.cpp
rename to core/jni/android_view_TextureLayer.cpp
index d934870..e14c46f 100644
--- a/core/jni/android_view_HardwareLayer.cpp
+++ b/core/jni/android_view_TextureLayer.cpp
@@ -40,7 +40,7 @@
 
 using namespace uirenderer;
 
-static jboolean android_view_HardwareLayer_prepare(JNIEnv* env, jobject clazz,
+static jboolean TextureLayer_prepare(JNIEnv* env, jobject clazz,
         jlong layerUpdaterPtr, jint width, jint height, jboolean isOpaque) {
     DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
     bool changed = false;
@@ -49,7 +49,7 @@
     return changed;
 }
 
-static void android_view_HardwareLayer_setLayerPaint(JNIEnv* env, jobject clazz,
+static void TextureLayer_setLayerPaint(JNIEnv* env, jobject clazz,
         jlong layerUpdaterPtr, jlong paintPtr) {
     DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
     if (layer) {
@@ -58,21 +58,21 @@
     }
 }
 
-static void android_view_HardwareLayer_setTransform(JNIEnv* env, jobject clazz,
+static void TextureLayer_setTransform(JNIEnv* env, jobject clazz,
         jlong layerUpdaterPtr, jlong matrixPtr) {
     DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
     SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
     layer->setTransform(matrix);
 }
 
-static void android_view_HardwareLayer_setSurfaceTexture(JNIEnv* env, jobject clazz,
+static void TextureLayer_setSurfaceTexture(JNIEnv* env, jobject clazz,
         jlong layerUpdaterPtr, jobject surface) {
     DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
     sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, surface));
     layer->setSurfaceTexture(surfaceTexture);
 }
 
-static void android_view_HardwareLayer_updateSurfaceTexture(JNIEnv* env, jobject clazz,
+static void TextureLayer_updateSurfaceTexture(JNIEnv* env, jobject clazz,
         jlong layerUpdaterPtr) {
     DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
     layer->updateTexImage();
@@ -82,18 +82,18 @@
 // JNI Glue
 // ----------------------------------------------------------------------------
 
-const char* const kClassPathName = "android/view/HardwareLayer";
+const char* const kClassPathName = "android/view/TextureLayer";
 
 static const JNINativeMethod gMethods[] = {
-    { "nPrepare",                "(JIIZ)Z",    (void*) android_view_HardwareLayer_prepare },
-    { "nSetLayerPaint",          "(JJ)V",      (void*) android_view_HardwareLayer_setLayerPaint },
-    { "nSetTransform",           "(JJ)V",      (void*) android_view_HardwareLayer_setTransform },
+    { "nPrepare",                "(JIIZ)Z",    (void*) TextureLayer_prepare },
+    { "nSetLayerPaint",          "(JJ)V",      (void*) TextureLayer_setLayerPaint },
+    { "nSetTransform",           "(JJ)V",      (void*) TextureLayer_setTransform },
     { "nSetSurfaceTexture",      "(JLandroid/graphics/SurfaceTexture;)V",
-            (void*) android_view_HardwareLayer_setSurfaceTexture },
-    { "nUpdateSurfaceTexture",   "(J)V",       (void*) android_view_HardwareLayer_updateSurfaceTexture },
+            (void*) TextureLayer_setSurfaceTexture },
+    { "nUpdateSurfaceTexture",   "(J)V",       (void*) TextureLayer_updateSurfaceTexture },
 };
 
-int register_android_view_HardwareLayer(JNIEnv* env) {
+int register_android_view_TextureLayer(JNIEnv* env) {
     return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
 }
 
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 9f3475a..13e0e4a 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -68,6 +68,10 @@
     jmethodID callback;
 } gFrameMetricsObserverClassInfo;
 
+struct {
+    jmethodID onFrameDraw;
+} gFrameDrawingCallback;
+
 static JNIEnv* getenv(JavaVM* vm) {
     JNIEnv* env;
     if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
@@ -849,6 +853,44 @@
     proxy->setContentDrawBounds(left, top, right, bottom);
 }
 
+class JGlobalRefHolder {
+public:
+    JGlobalRefHolder(JavaVM* vm, jobject object) : mVm(vm), mObject(object) {}
+
+    virtual ~JGlobalRefHolder() {
+        getenv(mVm)->DeleteGlobalRef(mObject);
+        mObject = nullptr;
+    }
+
+    jobject object() { return mObject; }
+    JavaVM* vm() { return mVm; }
+
+private:
+    JGlobalRefHolder(const JGlobalRefHolder&) = delete;
+    void operator=(const JGlobalRefHolder&) = delete;
+
+    JavaVM* mVm;
+    jobject mObject;
+};
+
+static void android_view_ThreadedRenderer_setFrameCallback(JNIEnv* env,
+        jobject clazz, jlong proxyPtr, jobject frameCallback) {
+    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+    if (!frameCallback) {
+        proxy->setFrameCallback(nullptr);
+    } else {
+        JavaVM* vm = nullptr;
+        LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM");
+        auto globalCallbackRef = std::make_shared<JGlobalRefHolder>(vm,
+                env->NewGlobalRef(frameCallback));
+        proxy->setFrameCallback([globalCallbackRef](int64_t frameNr) {
+            JNIEnv* env = getenv(globalCallbackRef->vm());
+            env->CallVoidMethod(globalCallbackRef->object(), gFrameDrawingCallback.onFrameDraw,
+                    static_cast<jlong>(frameNr));
+        });
+    }
+}
+
 static jint android_view_ThreadedRenderer_copySurfaceInto(JNIEnv* env,
         jobject clazz, jobject jsurface, jint left, jint top,
         jint right, jint bottom, jobject jbitmap) {
@@ -1034,6 +1076,8 @@
     { "nRemoveRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_removeRenderNode},
     { "nDrawRenderNode", "(JJ)V", (void*) android_view_ThreadedRendererd_drawRenderNode},
     { "nSetContentDrawBounds", "(JIIII)V", (void*)android_view_ThreadedRenderer_setContentDrawBounds},
+    { "nSetFrameCallback", "(JLandroid/view/ThreadedRenderer$FrameDrawingCallback;)V",
+            (void*)android_view_ThreadedRenderer_setFrameCallback},
     { "nAddFrameMetricsObserver",
             "(JLandroid/view/FrameMetricsObserver;)J",
             (void*)android_view_ThreadedRenderer_addFrameMetricsObserver },
@@ -1078,6 +1122,11 @@
     gFrameMetricsObserverClassInfo.timingDataBuffer = GetFieldIDOrDie(
             env, metricsClass, "mTimingData", "[J");
 
+    jclass frameCallbackClass = FindClassOrDie(env,
+            "android/view/ThreadedRenderer$FrameDrawingCallback");
+    gFrameDrawingCallback.onFrameDraw = GetMethodIDOrDie(env, frameCallbackClass,
+            "onFrameDraw", "(J)V");
+
     return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
 }
 
diff --git a/core/proto/android/content/configuration.proto b/core/proto/android/content/configuration.proto
index a62d56c..74b47d2 100644
--- a/core/proto/android/content/configuration.proto
+++ b/core/proto/android/content/configuration.proto
@@ -25,7 +25,7 @@
 import "frameworks/base/libs/incident/proto/android/privacy.proto";
 
 /**
- * An android resource configuration.
+ * An android Configuration object.
  */
 message ConfigurationProto {
   option (.android.msg_privacy).dest = DEST_AUTOMATIC;
@@ -35,17 +35,65 @@
   optional uint32 mnc = 3;
   repeated LocaleProto locales = 4;
   optional uint32 screen_layout = 5;
-  optional uint32 touchscreen = 6;
-  optional uint32 keyboard_hidden = 7;
-  optional uint32 hard_keyboard_hidden = 8;
-  optional uint32 navigation = 9;
-  optional uint32 navigation_hidden = 10;
-  optional uint32 orientation = 11;
-  optional uint32 ui_mode = 12;
-  optional uint32 screen_width_dp = 13;
-  optional uint32 screen_height_dp = 14;
-  optional uint32 smallest_screen_width_dp = 15;
-  optional uint32 density_dpi = 16;
-  optional .android.app.WindowConfigurationProto window_configuration = 17;
+  optional uint32 color_mode = 6;
+  optional uint32 touchscreen = 7;
+  optional uint32 keyboard = 8;
+  optional uint32 keyboard_hidden = 9;
+  optional uint32 hard_keyboard_hidden = 10;
+  optional uint32 navigation = 11;
+  optional uint32 navigation_hidden = 12;
+  optional uint32 orientation = 13;
+  optional uint32 ui_mode = 14;
+  optional uint32 screen_width_dp = 15;
+  optional uint32 screen_height_dp = 16;
+  optional uint32 smallest_screen_width_dp = 17;
+  optional uint32 density_dpi = 18;
+  optional .android.app.WindowConfigurationProto window_configuration = 19;
 }
 
+/**
+ * All current configuration data used to select resources.
+ */
+message ResourcesConfigurationProto {
+  option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+  required ConfigurationProto configuration = 1;
+
+  optional uint32 sdk_version = 2;
+  optional uint32 screen_width_px = 3;
+  optional uint32 screen_height_px = 4;
+}
+
+/**
+ * Overall device configuration data.
+ */
+message DeviceConfigurationProto {
+  option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+  optional uint32 stable_screen_width_px = 1;
+  optional uint32 stable_screen_height_px = 2;
+  optional uint32 stable_density_dpi = 3;
+
+  optional uint64 total_ram = 4;
+  optional bool low_ram = 5;
+  optional uint32 max_cores = 6;
+  optional bool has_secure_screen_lock = 7;
+
+  optional uint32 opengl_version = 8;
+  repeated string opengl_extensions = 9;
+
+  repeated string shared_libraries = 10;
+  repeated string features = 11;
+  repeated string cpu_architectures = 12;
+}
+
+/**
+ * All current configuration data device is running with, everything used
+ * to filter and target apps.
+ */
+message GlobalConfigurationProto {
+  option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+  optional ResourcesConfigurationProto resources = 1;
+  optional DeviceConfigurationProto device = 2;
+}
diff --git a/core/proto/android/os/batterystats.proto b/core/proto/android/os/batterystats.proto
index 9f9fd05..9915174 100644
--- a/core/proto/android/os/batterystats.proto
+++ b/core/proto/android/os/batterystats.proto
@@ -226,7 +226,11 @@
       LTE = 13;
       EHRPD = 14;
       HSPAP = 15;
-      OTHER = 16;
+      GSM = 16;
+      TD_SCDMA = 17;
+      IWLAN = 18;
+      LTE_CA = 19;
+      OTHER = 20;
     };
     optional Name name = 1;
     optional TimerProto total = 2;
diff --git a/core/proto/android/os/data.proto b/core/proto/android/os/data.proto
new file mode 100644
index 0000000..c06f318
--- /dev/null
+++ b/core/proto/android/os/data.proto
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_multiple_files = true;
+
+package android.os;
+
+// This file contains protobuf definitions used in incidentd directly.
+// The top level proto message must be used as a new SectionType in
+// incidentd.
+
+// Output of SECTION_GZIP section type, which reads a file, gzip it and attached
+// in incident report as a proto field, example is LAST_KMSG.
+// NOTE the content in the file must not contain sensitive PII otherwise
+// implement it with fine-grained proto definition.
+message GZippedFileProto {
+    optional string filename = 1;
+
+    optional bytes gzipped_data = 2;
+}
diff --git a/core/proto/android/os/enums.proto b/core/proto/android/os/enums.proto
index fe9b7ac..aa99ac7 100644
--- a/core/proto/android/os/enums.proto
+++ b/core/proto/android/os/enums.proto
@@ -56,6 +56,17 @@
     BATTERY_STATUS_FULL = 5;
 }
 
+// These constants are defined in hardware/interfaces/thermal/1.0/types.hal
+// They are primarily used by android/os/HardwarePropertiesManager.java.
+// Any change to the types in the thermal hal should be made here as well.
+enum TemperatureTypeEnum {
+    TEMPERATURE_TYPE_UKNOWN = -1;
+    TEMPERATURE_TYPE_CPU = 0;
+    TEMPERATURE_TYPE_GPU = 1;
+    TEMPERATURE_TYPE_BATTERY = 2;
+    TEMPERATURE_TYPE_SKIN = 3;
+}
+
 // Wakelock types, primarily used by android/os/PowerManager.java.
 enum WakeLockLevelEnum {
     // NOTE: Wake lock levels were previously defined as a bit field, except
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 9a53b89..7326829 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -20,6 +20,7 @@
 import "frameworks/base/core/proto/android/os/batterytype.proto";
 import "frameworks/base/core/proto/android/os/cpufreq.proto";
 import "frameworks/base/core/proto/android/os/cpuinfo.proto";
+import "frameworks/base/core/proto/android/os/data.proto";
 import "frameworks/base/core/proto/android/os/kernelwake.proto";
 import "frameworks/base/core/proto/android/os/pagetypeinfo.proto";
 import "frameworks/base/core/proto/android/os/procrank.proto";
@@ -52,9 +53,8 @@
 
 package android.os;
 
-// privacy field options must not be set at this level because all
-// the sections are able to be controlled and configured by section ids.
-// Instead privacy field options need to be configured in each section proto message.
+// Privacy tag can be marked to override UNSET messages so generic
+// message type can be handled case by case, e.g. GZippedFileProto.
 message IncidentProto {
     reserved 1001;
 
@@ -151,6 +151,12 @@
         (section).args = "/sys/class/power_supply/bms/battery_type"
     ];
 
+    optional GZippedFileProto last_kmsg = 2007 [
+        (section).type = SECTION_GZIP,
+        (section).args = "/sys/fs/pstore/console-ramoops /sys/fs/pstore/console-ramoops-0 /proc/last_kmsg",
+        (privacy).dest = DEST_AUTOMATIC
+    ];
+
     // System Services
     optional com.android.server.fingerprint.FingerprintServiceDumpProto fingerprint = 3000 [
         (section).type = SECTION_DUMPSYS,
@@ -208,37 +214,37 @@
         (section).args = "procstats --proto"
     ];
 
-    optional com.android.server.am.proto.ActivityStackSupervisorProto activities = 3012 [
+    optional com.android.server.am.proto.ActivityManagerServiceDumpActivitiesProto activities = 3012 [
         (section).type = SECTION_DUMPSYS,
         (section).args = "activity --proto activities"
     ];
 
-    optional com.android.server.am.proto.BroadcastProto broadcasts = 3013 [
+    optional com.android.server.am.proto.ActivityManagerServiceDumpBroadcastsProto broadcasts = 3013 [
         (section).type = SECTION_DUMPSYS,
         (section).args = "activity --proto broadcasts"
     ];
 
-    optional com.android.server.am.proto.ActiveServicesProto amservices = 3014 [
+    optional com.android.server.am.proto.ActivityManagerServiceDumpServicesProto amservices = 3014 [
         (section).type = SECTION_DUMPSYS,
         (section).args = "activity --proto service"
     ];
 
-    optional com.android.server.am.proto.ProcessesProto amprocesses = 3015 [
+    optional com.android.server.am.proto.ActivityManagerServiceDumpProcessesProto amprocesses = 3015 [
         (section).type = SECTION_DUMPSYS,
         (section).args = "activity --proto processes"
     ];
 
-    optional com.android.server.AlarmManagerServiceProto alarm = 3016 [
+    optional com.android.server.AlarmManagerServiceDumpProto alarm = 3016 [
         (section).type = SECTION_DUMPSYS,
         (section).args = "alarm --proto"
     ];
 
-    optional com.android.server.wm.proto.WindowManagerServiceProto window = 3017 [
+    optional com.android.server.wm.proto.WindowManagerServiceDumpProto window = 3017 [
         (section).type = SECTION_DUMPSYS,
         (section).args = "window --proto"
     ];
 
-    optional com.android.server.am.proto.MemInfoProto meminfo = 3018 [
+    optional com.android.server.am.proto.MemInfoDumpProto meminfo = 3018 [
         (section).type = SECTION_DUMPSYS,
         (section).args = "meminfo -a --proto"
     ];
diff --git a/core/proto/android/os/pagetypeinfo.proto b/core/proto/android/os/pagetypeinfo.proto
index f5d77d6..0b8a5da 100644
--- a/core/proto/android/os/pagetypeinfo.proto
+++ b/core/proto/android/os/pagetypeinfo.proto
@@ -58,7 +58,7 @@
     }
     repeated MigrateType migrate_types = 3;
 
-    // Next tag: 9
+    // Next tag: 10
     message Block {
         option (android.msg_privacy).dest = DEST_AUTOMATIC;
 
@@ -77,6 +77,8 @@
         optional int32 reserve = 7;
 
         optional int32 isolate = 8;
+
+        optional int32 highatomic = 9;
     }
     repeated Block blocks = 4;
 }
diff --git a/core/proto/android/providers/settings.proto b/core/proto/android/providers/settings.proto
index c35b2ec..9752d3b 100644
--- a/core/proto/android/providers/settings.proto
+++ b/core/proto/android/providers/settings.proto
@@ -179,9 +179,11 @@
     optional SettingProto tether_dun_required = 114 [ (android.privacy).dest = DEST_AUTOMATIC ];
     optional SettingProto tether_dun_apn = 115;
     optional SettingProto tether_offload_disabled = 301 [ (android.privacy).dest = DEST_AUTOMATIC ];
-    // List of carrier apps which are whitelisted to prompt the user for install
-    // when a SIM card with marchin UICC carrier privilege rules is inserted.
+    // List of carrier app certificate mapped to carrier app package id which are whitelisted to
+    // prompt the user for install when a SIM card with matching UICC carrier privilege rules is
+    // inserted.
     optional SettingProto carrier_app_whitelist = 116 [ (android.privacy).dest = DEST_AUTOMATIC ];
+    optional SettingProto carrier_app_names = 358 [ (android.privacy).dest = DEST_AUTOMATIC ];
     optional SettingProto usb_mass_storage_enabled = 117 [ (android.privacy).dest = DEST_AUTOMATIC ];
     optional SettingProto use_google_mail = 118 [ (android.privacy).dest = DEST_AUTOMATIC ];
     optional SettingProto webview_data_reduction_proxy_key = 119;
@@ -433,7 +435,7 @@
 
     // Please insert fields in the same order as in
     // frameworks/base/core/java/android/provider/Settings.java.
-    // Next tag = 356;
+    // Next tag = 359;
 }
 
 message SecureSettingsProto {
diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto
index 788d901..3b9150f 100644
--- a/core/proto/android/server/activitymanagerservice.proto
+++ b/core/proto/android/server/activitymanagerservice.proto
@@ -40,16 +40,22 @@
 message ActivityManagerServiceProto {
   option (.android.msg_privacy).dest = DEST_AUTOMATIC;
 
-  optional ActivityStackSupervisorProto activities = 1;
+  optional ActivityManagerServiceDumpActivitiesProto activities = 1;
 
-  optional BroadcastProto broadcasts = 2;
+  optional ActivityManagerServiceDumpBroadcastsProto broadcasts = 2;
 
-  optional ActiveServicesProto services = 3;
+  optional ActivityManagerServiceDumpServicesProto services = 3;
 
-  optional ProcessesProto processes = 4;
+  optional ActivityManagerServiceDumpProcessesProto processes = 4;
 }
 
 // "dumpsys activity --proto activities"
+message ActivityManagerServiceDumpActivitiesProto {
+  option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+  optional ActivityStackSupervisorProto activity_stack_supervisor = 1;
+}
+
 message ActivityStackSupervisorProto {
   option (.android.msg_privacy).dest = DEST_AUTOMATIC;
 
@@ -58,6 +64,9 @@
   optional KeyguardControllerProto keyguard_controller = 3;
   optional int32 focused_stack_id = 4;
   optional .com.android.server.wm.proto.IdentifierProto resumed_activity = 5;
+  // Whether or not the home activity is the recents activity. This is needed for the CTS tests to
+  // know what activity types to check for when invoking splitscreen multi-window.
+  optional bool is_home_recents_component = 6;
 }
 
 /* represents ActivityStackSupervisor.ActivityDisplay */
@@ -118,7 +127,7 @@
 }
 
 // "dumpsys activity --proto broadcasts"
-message BroadcastProto {
+message ActivityManagerServiceDumpBroadcastsProto {
   option (.android.msg_privacy).dest = DEST_AUTOMATIC;
 
   repeated ReceiverListProto  receiver_list = 1;
@@ -199,7 +208,7 @@
   repeated BroadcastSummary historical_broadcasts_summary = 6;
 }
 
-message MemInfoProto {
+message MemInfoDumpProto {
   option (.android.msg_privacy).dest = DEST_AUTOMATIC;
 
   optional int64 uptime_duration_ms = 1;
@@ -403,6 +412,12 @@
 }
 
 // "dumpsys activity --proto service"
+message ActivityManagerServiceDumpServicesProto {
+  option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+  optional ActiveServicesProto active_services = 1;
+}
+
 message ActiveServicesProto {
   option (.android.msg_privacy).dest = DEST_AUTOMATIC;
 
@@ -582,7 +597,7 @@
 }
 
 // TODO: "dumpsys activity --proto processes"
-message ProcessesProto {
+message ActivityManagerServiceDumpProcessesProto {
   option (.android.msg_privacy).dest = DEST_AUTOMATIC;
 
   repeated ProcessRecordProto procs = 1;
diff --git a/core/proto/android/server/alarmmanagerservice.proto b/core/proto/android/server/alarmmanagerservice.proto
index d1c5db6..53e3ba9 100644
--- a/core/proto/android/server/alarmmanagerservice.proto
+++ b/core/proto/android/server/alarmmanagerservice.proto
@@ -28,7 +28,7 @@
 option java_multiple_files = true;
 
 // next ID: 43
-message AlarmManagerServiceProto {
+message AlarmManagerServiceDumpProto {
   option (.android.msg_privacy).dest = DEST_AUTOMATIC;
 
   optional int64 current_time = 1;
@@ -220,6 +220,8 @@
   optional int64 allow_while_idle_long_duration_ms = 5;
   // BroadcastOptions.setTemporaryAppWhitelistDuration() to use for FLAG_ALLOW_WHILE_IDLE.
   optional int64 allow_while_idle_whitelist_duration_ms = 6;
+  // Maximum alarm recurrence interval.
+  optional int64 max_interval_duration_ms = 7;
 }
 
 // A com.android.server.AlarmManagerService.FilterStats object.
diff --git a/core/proto/android/server/jobscheduler.proto b/core/proto/android/server/jobscheduler.proto
index 304e63f..69abed3 100644
--- a/core/proto/android/server/jobscheduler.proto
+++ b/core/proto/android/server/jobscheduler.proto
@@ -36,6 +36,11 @@
 
     optional ConstantsProto settings = 1;
 
+    optional int32 current_heartbeat = 14;
+    repeated int32 next_heartbeat = 15;
+    optional int64 last_heartbeat_time_millis = 16;
+    optional int64 next_heartbeat_time_millis = 17;
+
     repeated int32 started_users = 2;
 
     message RegisteredJob {
@@ -54,6 +59,8 @@
         optional bool is_job_currently_active = 6;
         optional bool is_uid_backing_up = 7;
         optional bool is_component_present = 8;
+
+        optional int64 last_run_heartbeat = 9;
     }
     repeated RegisteredJob registered_jobs = 3;
 
@@ -201,6 +208,12 @@
     // be indices into this array, rather than the raw constants used by
     // AppIdleHistory.
     repeated int32 standby_beats = 20;
+    // The fraction of a job's running window that must pass before we
+    // consider running it when the network is congested.
+    optional double conn_congestion_delay_frac = 21;
+    // The fraction of a prefetch job's running window that must pass before
+    // we consider matching it against a metered network.
+    optional double conn_prefetch_relax_frac = 22;
 }
 
 message StateControllerProto {
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index c11058a..9598f24 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -32,7 +32,7 @@
 
 option java_multiple_files = true;
 
-message WindowManagerServiceProto {
+message WindowManagerServiceDumpProto {
   option (.android.msg_privacy).dest = DEST_AUTOMATIC;
 
   optional WindowManagerPolicyProto policy = 1;
@@ -295,7 +295,6 @@
   optional bool animating_exit = 14;
   repeated WindowStateProto child_windows = 15;
   optional .android.graphics.RectProto surface_position = 16;
-  optional .android.graphics.RectProto shown_position = 17;
   optional int32 requested_width = 18;
   optional int32 requested_height = 19;
   optional int32 view_visibility = 20;
diff --git a/core/proto/android/server/windowmanagertrace.proto b/core/proto/android/server/windowmanagertrace.proto
index d96953e..96a90bf 100644
--- a/core/proto/android/server/windowmanagertrace.proto
+++ b/core/proto/android/server/windowmanagertrace.proto
@@ -48,5 +48,5 @@
     /* where the trace originated */
     optional string where = 2;
 
-    optional WindowManagerServiceProto window_manager_service = 3;
+    optional WindowManagerServiceDumpProto window_manager_service = 3;
 }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index caeca592..a7178a0 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2402,6 +2402,12 @@
     <permission android:name="android.permission.UPDATE_CONFIG"
         android:protectionLevel="signature|privileged" />
 
+    <!-- Allows an application to query the current time zone rules state
+         on device.
+         @SystemApi @hide -->
+    <permission android:name="android.permission.QUERY_TIME_ZONE_RULES"
+                android:protectionLevel="signature|privileged" />
+
     <!-- Allows a time zone rule updater application to request
          the system installs / uninstalls timezone rules.
          <p>An application requesting this permission is responsible for
@@ -3810,9 +3816,15 @@
     <permission android:name="android.permission.INSTANT_APP_FOREGROUND_SERVICE"
         android:protectionLevel="signature|development|instant|appop" />
 
-    <!-- @hide Allows system components to access all app shortcuts. -->
+    <!-- @SystemApi Allows to access all app shortcuts.
+         @hide -->
     <permission android:name="android.permission.ACCESS_SHORTCUTS"
-        android:protectionLevel="signature" />
+        android:protectionLevel="signature|textClassifier" />
+
+    <!-- @SystemApi Allows unlimited calls to shortcut mutation APIs.
+         @hide -->
+    <permission android:name="android.permission.UNLIMITED_SHORTCUTS_API_CALLS"
+        android:protectionLevel="signature|textClassifier" />
 
     <!-- @SystemApi Allows an application to read the runtime profiles of other apps.
          @hide <p>Not for use by third-party applications. -->
diff --git a/core/res/res/anim/task_close_enter.xml b/core/res/res/anim/task_close_enter.xml
index 81d1300..c298b80 100644
--- a/core/res/res/anim/task_close_enter.xml
+++ b/core/res/res/anim/task_close_enter.xml
@@ -17,7 +17,8 @@
 -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
     android:shareInterpolator="false"
-    android:zAdjustment="top">
+    android:zAdjustment="top"
+    android:showWallpaper="true">
 
     <alpha
         android:fromAlpha="1"
diff --git a/core/res/res/anim/task_close_exit.xml b/core/res/res/anim/task_close_exit.xml
index ab8b89c..9394c57 100644
--- a/core/res/res/anim/task_close_exit.xml
+++ b/core/res/res/anim/task_close_exit.xml
@@ -17,7 +17,8 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shareInterpolator="false">
+    android:shareInterpolator="false"
+    android:showWallpaper="true">
 
     <alpha
         android:fromAlpha="1.0"
diff --git a/core/res/res/anim/task_open_enter.xml b/core/res/res/anim/task_open_enter.xml
index 0e66eda..e23201f 100644
--- a/core/res/res/anim/task_open_enter.xml
+++ b/core/res/res/anim/task_open_enter.xml
@@ -19,7 +19,8 @@
 <!-- This should in sync with cross_profile_apps_thumbnail_enter.xml -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
     android:shareInterpolator="false"
-    android:zAdjustment="top">
+    android:zAdjustment="top"
+    android:showWallpaper="true">
 
     <alpha
         android:fromAlpha="1"
diff --git a/core/res/res/anim/task_open_enter_cross_profile_apps.xml b/core/res/res/anim/task_open_enter_cross_profile_apps.xml
index a92425e..defea08 100644
--- a/core/res/res/anim/task_open_enter_cross_profile_apps.xml
+++ b/core/res/res/anim/task_open_enter_cross_profile_apps.xml
@@ -19,7 +19,8 @@
 <!-- This should in sync with task_open_enter.xml -->
 <set xmlns:android="http://schemas.android.com/apk/res/android"
     android:shareInterpolator="false"
-    android:zAdjustment="top">
+    android:zAdjustment="top"
+    android:showWallpaper="true">
 
     <alpha
         android:fromAlpha="1"
diff --git a/core/res/res/anim/task_open_exit.xml b/core/res/res/anim/task_open_exit.xml
index ecb98ce..c9ade22 100644
--- a/core/res/res/anim/task_open_exit.xml
+++ b/core/res/res/anim/task_open_exit.xml
@@ -17,7 +17,8 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shareInterpolator="false">
+    android:shareInterpolator="false"
+    android:showWallpaper="true">
 
     <alpha
         android:fromAlpha="1.0"
diff --git a/core/res/res/drawable-watch/sym_def_app_icon.xml b/core/res/res/drawable-watch/sym_def_app_icon.xml
new file mode 100644
index 0000000..6945256
--- /dev/null
+++ b/core/res/res/drawable-watch/sym_def_app_icon.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/sym_def_app_icon_background" />
+    <foreground android:drawable="@mipmap/sym_def_app_icon_foreground" />
+</adaptive-icon>
diff --git a/core/res/res/drawable-watch/sym_def_app_icon_background.xml b/core/res/res/drawable-watch/sym_def_app_icon_background.xml
new file mode 100644
index 0000000..6d6352f
--- /dev/null
+++ b/core/res/res/drawable-watch/sym_def_app_icon_background.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#2374CE"/>
+</shape>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_alert_window_layer.xml b/core/res/res/drawable/ic_alert_window_layer.xml
new file mode 100644
index 0000000..15931b8
--- /dev/null
+++ b/core/res/res/drawable/ic_alert_window_layer.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2018 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT 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="16dp"
+        android:height="16dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M11.99,18.54l-7.37,-5.73L3,14.07l9,7 9,-7 -1.63,-1.27 -7.38,5.74zM12,16l7.36,-5.73L21,9l-9,-7 -9,7 1.63,1.27L12,16z"/>
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_camera.xml b/core/res/res/drawable/ic_camera.xml
new file mode 100644
index 0000000..2921a68
--- /dev/null
+++ b/core/res/res/drawable/ic_camera.xml
@@ -0,0 +1,27 @@
+<!--
+Copyright (C) 2018 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT 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="16dp"
+        android:height="16dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:pathData="M12,12m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0"
+        android:fillColor="#FFFFFF"/>
+    <path
+        android:pathData="M9,2L7.17,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2h-3.17L15,2L9,2zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z"
+        android:fillColor="#FFFFFF"/>
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_corp_badge.xml b/core/res/res/drawable/ic_corp_badge.xml
index 78cce58..915f5fb 100644
--- a/core/res/res/drawable/ic_corp_badge.xml
+++ b/core/res/res/drawable/ic_corp_badge.xml
@@ -1,12 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2018 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT 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="20dp"
         android:height="20dp"
-        android:viewportWidth="20.0"
-        android:viewportHeight="20.0">
+        android:viewportWidth="20"
+        android:viewportHeight="20">
+
     <path
-        android:pathData="M10,10m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0"
-        android:fillColor="#FF6D00"/>
+        android:fillColor="#fcfcfc"
+        android:pathData="M 10 0 C 15.5228474983 0 20 4.47715250169 20 10 C 20 15.5228474983 15.5228474983 20 10 20 C 4.47715250169 20 0 15.5228474983 0 10 C 0 4.47715250169 4.47715250169 0 10 0 Z" />
     <path
-        android:pathData="M14.67,6.5h-2.33V5.33c0,-0.65 -0.52,-1.17 -1.17,-1.17H8.83c-0.65,0 -1.17,0.52 -1.17,1.17V6.5H5.33c-0.65,0 -1.16,0.52 -1.16,1.17l-0.01,6.42c0,0.65 0.52,1.17 1.17,1.17h9.33c0.65,0 1.17,-0.52 1.17,-1.17V7.67C15.83,7.02 15.31,6.5 14.67,6.5zM10,11.75c-0.64,0 -1.17,-0.52 -1.17,-1.17c0,-0.64 0.52,-1.17 1.17,-1.17c0.64,0 1.17,0.52 1.17,1.17C11.17,11.22 10.64,11.75 10,11.75zM11.17,6.5H8.83V5.33h2.33V6.5z"
-        android:fillColor="#FFFFFF"/>
-</vector>
+        android:strokeColor="#e8eaed"
+        android:strokeWidth="0.25"
+        android:pathData="M 10 0.12 C 15.4565733283 0.12 19.88 4.54342667167 19.88 10 C 19.88 15.4565733283 15.4565733283 19.88 10 19.88 C 4.54342667167 19.88 0.12 15.4565733283 0.12 10 C 0.12 4.54342667167 4.54342667167 0.12 10 0.12 Z" />
+    <path
+        android:pathData="M 3.5 3.5 L 16.5 3.5 L 16.5 16.5 L 3.5 16.5 L 3.5 3.5 Z" />
+    <path
+        android:fillColor="#1a73e8"
+        android:pathData="M14.46,6.58H12.23V5.5a1.09,1.09,0,0,0-1.11-1.08H8.89A1.09,1.09,0,0,0,7.77,5.5V6.58H5.54A1.09,1.09,0,0,0,4.43,7.65v5.91a1.09,1.09,0,0,0,1.11,1.08h8.91a1.09,1.09,0,0,0,1.11-1.08V7.65A1.09,1.09,0,0,0,14.46,6.58ZM10,11.42a1.08,1.08,0,1,1,1.11-1.08A1.1,1.1,0,0,1,10,11.42Zm1.11-4.84H8.89V5.5h2.23Z" />
+    <path
+        android:pathData="M 0 0 H 20 V 20 H 0 V 0 Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_corp_badge_case.xml b/core/res/res/drawable/ic_corp_badge_case.xml
index 2d11ee6..1cd995e 100644
--- a/core/res/res/drawable/ic_corp_badge_case.xml
+++ b/core/res/res/drawable/ic_corp_badge_case.xml
@@ -5,5 +5,5 @@
         android:viewportHeight="20.0">
     <path
         android:pathData="M14.67,6.5h-2.33V5.33c0,-0.65 -0.52,-1.17 -1.17,-1.17H8.83c-0.65,0 -1.17,0.52 -1.17,1.17V6.5H5.33c-0.65,0 -1.16,0.52 -1.16,1.17l-0.01,6.42c0,0.65 0.52,1.17 1.17,1.17h9.33c0.65,0 1.17,-0.52 1.17,-1.17V7.67C15.83,7.02 15.31,6.5 14.67,6.5zM10,11.75c-0.64,0 -1.17,-0.52 -1.17,-1.17c0,-0.64 0.52,-1.17 1.17,-1.17c0.64,0 1.17,0.52 1.17,1.17C11.17,11.22 10.64,11.75 10,11.75zM11.17,6.5H8.83V5.33h2.33V6.5z"
-        android:fillColor="#FFFFFF"/>
+        android:fillColor="#1A73E8"/>
 </vector>
diff --git a/core/res/res/drawable/ic_corp_badge_color.xml b/core/res/res/drawable/ic_corp_badge_color.xml
index b6c7969..4aef7d0 100644
--- a/core/res/res/drawable/ic_corp_badge_color.xml
+++ b/core/res/res/drawable/ic_corp_badge_color.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
 Copyright (C) 2016 The Android Open Source Project
 
@@ -20,5 +21,5 @@
         android:viewportHeight="20.0">
     <path
         android:pathData="M10.0,10.0m-10.0,0.0a10.0,10.0 0.0,1.0 1.0,20.0 0.0a10.0,10.0 0.0,1.0 1.0,-20.0 0.0"
-        android:fillColor="#FFFFFF"/>
-</vector>
+        android:fillColor="#fcfcfc"/>
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_corp_icon_badge_case.xml b/core/res/res/drawable/ic_corp_icon_badge_case.xml
index dd653c6..50551d40 100644
--- a/core/res/res/drawable/ic_corp_icon_badge_case.xml
+++ b/core/res/res/drawable/ic_corp_icon_badge_case.xml
@@ -1,9 +1,30 @@
+<?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.
+-->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="64dp"
         android:height="64dp"
-        android:viewportWidth="64.0"
-        android:viewportHeight="64.0">
+        android:viewportWidth="64"
+        android:viewportHeight="64">
+
     <path
-        android:pathData="M55.67,44h-3.33v-1.67c0,-0.92 -0.74,-1.67 -1.67,-1.67h-3.33c-0.92,0 -1.67,0.74 -1.67,1.67V44h-3.33c-0.92,0 -1.66,0.74 -1.66,1.67l-0.01,9.17c0,0.93 0.74,1.67 1.67,1.67h13.33c0.92,0 1.67,-0.74 1.67,-1.67v-9.17C57.33,44.74 56.59,44 55.67,44zM49,51.5c-0.92,0 -1.67,-0.75 -1.67,-1.67c0,-0.92 0.75,-1.67 1.67,-1.67s1.67,0.75 1.67,1.67C50.67,50.75 49.92,51.5 49,51.5zM50.67,44h-3.33v-1.67h3.33V44z"
-        android:fillColor="#FFFFFF"/>
-</vector>
+        android:pathData="M 42 42 L 58 42 L 58 58 L 42 58 L 42 42 Z" />
+    <path
+        android:fillColor="#1A73E8"
+        android:pathData="M55.33,46H52.67V44.67a1.33,1.33,0,0,0-1.33-1.33H48.67a1.33,1.33,0,0,0-1.33,1.33V46H44.67a1.32,1.32,0,0,0-1.33,1.33v7.33A1.33,1.33,0,0,0,44.67,56H55.33a1.33,1.33,0,0,0,1.33-1.33V47.33A1.33,1.33,0,0,0,55.33,46ZM50,52a1.33,1.33,0,1,1,1.33-1.33A1.34,1.34,0,0,1,50,52Zm1.33-6H48.67V44.67h2.67Z" />
+    <path
+        android:pathData="M 0 0 H 64 V 64 H 0 V 0 Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_corp_icon_badge_color.xml b/core/res/res/drawable/ic_corp_icon_badge_color.xml
index 3bc4e67..6dba277 100644
--- a/core/res/res/drawable/ic_corp_icon_badge_color.xml
+++ b/core/res/res/drawable/ic_corp_icon_badge_color.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
 Copyright (C) 2016 The Android Open Source Project
 
@@ -14,11 +15,16 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="64.0dp"
-        android:height="64.0dp"
-        android:viewportWidth="64.0"
-        android:viewportHeight="64.0">
+        android:width="64dp"
+        android:height="64dp"
+        android:viewportWidth="64"
+        android:viewportHeight="64">
+
     <path
-        android:pathData="M49.1,48.8m-13.9,0.0a13.9,13.9 0.0,1.0 1.0,27.8 0.0a13.9,13.9 0.0,1.0 1.0,-27.8 0.0"
-        android:fillColor="#FFFFFF"/>
-</vector>
+        android:fillColor="#fcfcfc"
+        android:strokeColor="#e8eaed"
+        android:strokeWidth="0.25"
+        android:pathData="M62,50A12,12,0,1,1,50,38,12,12,0,0,1,62,50" />
+    <path
+        android:pathData="M 0 0 H 64 V 64 H 0 V 0 Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_corp_icon_badge_shadow.xml b/core/res/res/drawable/ic_corp_icon_badge_shadow.xml
index a546cdd..f33ed1f 100644
--- a/core/res/res/drawable/ic_corp_icon_badge_shadow.xml
+++ b/core/res/res/drawable/ic_corp_icon_badge_shadow.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
 Copyright (C) 2016 The Android Open Source Project
 
@@ -14,16 +15,35 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="64.0dp"
-        android:height="64.0dp"
-        android:viewportWidth="64.0"
-        android:viewportHeight="64.0">
+        android:width="64dp"
+        android:height="64dp"
+        android:viewportWidth="64"
+        android:viewportHeight="64">
+
     <path
-        android:fillColor="#FF000000"
-        android:pathData="M49.1,50.1m-13.9,0.0a13.9,13.9 0.0,1.0 1.0,27.8 0.0a13.9,13.9 0.0,1.0 1.0,-27.8 0.0"
-        android:fillAlpha="0.2"/>
+        android:fillColor="#000000"
+        android:fillAlpha="0.06"
+        android:strokeAlpha="0.06"
+        android:strokeWidth="1"
+        android:pathData="M62,51.25a12,12,0,1,1-12-12,12,12,0,0,1,12,12" />
     <path
-        android:fillColor="#FF000000"
-        android:pathData="M49.1,49.4m-13.9,0.0a13.9,13.9 0.0,1.0 1.0,27.8 0.0a13.9,13.9 0.0,1.0 1.0,-27.8 0.0"
-        android:fillAlpha="0.2"/>
-</vector>
+        android:pathData="M 0 0 H 64 V 64 H 0 V 0 Z" />
+    <path
+        android:fillColor="#000000"
+        android:fillAlpha="0.06"
+        android:strokeAlpha="0.06"
+        android:strokeWidth="1"
+        android:pathData="M62,52.28A12,12,0,1,1,50.53,39.76,12,12,0,0,1,62,52.28" />
+    <path
+        android:fillColor="#000000"
+        android:fillAlpha="0.06"
+        android:strokeAlpha="0.06"
+        android:strokeWidth="1"
+        android:pathData="M62,50.75a12,12,0,1,1-12-12,12,12,0,0,1,12,12" />
+    <path
+        android:fillColor="#000000"
+        android:fillAlpha="0.06"
+        android:strokeAlpha="0.06"
+        android:strokeWidth="1"
+        android:pathData="M62,50.25a12,12,0,1,1-12-12,12,12,0,0,1,12,12" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_mic.xml b/core/res/res/drawable/ic_mic.xml
new file mode 100644
index 0000000..3212330
--- /dev/null
+++ b/core/res/res/drawable/ic_mic.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2018 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT 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="16dp"
+        android:height="16dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:pathData="M12,14c1.66,0 2.99,-1.34 2.99,-3L15,5c0,-1.66 -1.34,-3 -3,-3S9,3.34 9,5v6c0,1.66 1.34,3 3,3zM17.3,11c0,3 -2.54,5.1 -5.3,5.1S6.7,14 6.7,11L5,11c0,3.41 2.72,6.23 6,6.72L11,21h2v-3.28c3.28,-0.48 6,-3.3 6,-6.72h-1.7z"
+        android:fillColor="#FFFFFF"/>
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/progress_horizontal_material.xml b/core/res/res/drawable/progress_horizontal_material.xml
index c1795640..2f94d0c 100644
--- a/core/res/res/drawable/progress_horizontal_material.xml
+++ b/core/res/res/drawable/progress_horizontal_material.xml
@@ -19,6 +19,7 @@
           android:gravity="center_vertical|fill_horizontal">
         <shape android:shape="rectangle"
                android:tint="?attr/colorControlNormal">
+            <corners android:radius="?attr/progressBarCornerRadius" />
             <size android:height="@dimen/progress_bar_height_material" />
             <solid android:color="@color/white_disabled_material" />
         </shape>
@@ -28,6 +29,7 @@
         <scale android:scaleWidth="100%">
             <shape android:shape="rectangle"
                    android:tint="?attr/colorControlActivated">
+                <corners android:radius="?attr/progressBarCornerRadius" />
                 <size android:height="@dimen/progress_bar_height_material" />
                 <solid android:color="@color/white_disabled_material" />
             </shape>
@@ -38,6 +40,7 @@
         <scale android:scaleWidth="100%">
             <shape android:shape="rectangle"
                    android:tint="?attr/colorControlActivated">
+                <corners android:radius="?attr/progressBarCornerRadius" />
                 <size android:height="@dimen/progress_bar_height_material" />
                 <solid android:color="@color/white" />
             </shape>
diff --git a/core/res/res/drawable/seekbar_track_material.xml b/core/res/res/drawable/seekbar_track_material.xml
index e88a73f..62ef136 100644
--- a/core/res/res/drawable/seekbar_track_material.xml
+++ b/core/res/res/drawable/seekbar_track_material.xml
@@ -19,6 +19,7 @@
           android:gravity="center_vertical|fill_horizontal">
         <shape android:shape="rectangle"
                android:tint="@color/control_nodisable_material">
+            <corners android:radius="?attr/progressBarCornerRadius" />
             <size android:height="@dimen/seekbar_track_background_height_material" />
             <solid android:color="@color/white_disabled_material" />
         </shape>
@@ -32,6 +33,7 @@
                 <item>
                     <shape android:shape="rectangle"
                            android:tint="?attr/colorControlActivated">
+                        <corners android:radius="?attr/progressBarCornerRadius" />
                         <size android:height="@dimen/seekbar_track_progress_height_material" />
                         <solid android:color="@color/white_disabled_material" />
                     </shape>
@@ -48,6 +50,7 @@
                 <item>
                     <shape android:shape="rectangle"
                            android:tint="?attr/colorControlActivated">
+                        <corners android:radius="?attr/progressBarCornerRadius" />
                         <size android:height="@dimen/seekbar_track_progress_height_material" />
                         <solid android:color="@color/white" />
                     </shape>
diff --git a/core/res/res/layout/autofill_dataset_picker.xml b/core/res/res/layout/autofill_dataset_picker.xml
index a88836e..ef19f87 100644
--- a/core/res/res/layout/autofill_dataset_picker.xml
+++ b/core/res/res/layout/autofill_dataset_picker.xml
@@ -14,7 +14,8 @@
      limitations under the License.
 -->
 
-<FrameLayout  xmlns:android="http://schemas.android.com/apk/res/android"
+<view  xmlns:android="http://schemas.android.com/apk/res/android"
+    class="com.android.server.autofill.ui.FillUi$AutofillFrameLayout"
     android:id="@+id/autofill_dataset_picker"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
@@ -30,4 +31,4 @@
         android:visibility="gone">
     </ListView>
 
-</FrameLayout>
+</view>
diff --git a/core/res/res/layout/notification_material_action_list.xml b/core/res/res/layout/notification_material_action_list.xml
index 49b0ee7..07559f4 100644
--- a/core/res/res/layout/notification_material_action_list.xml
+++ b/core/res/res/layout/notification_material_action_list.xml
@@ -24,11 +24,9 @@
             android:layout_width="match_parent"
             android:layout_height="@dimen/notification_action_list_height"
             android:paddingEnd="12dp"
-            android:paddingStart="8dp"
             android:orientation="horizontal"
             android:gravity="center_vertical"
             android:visibility="gone"
-            android:background="@color/notification_action_list"
             >
         <!-- actions will be added here -->
     </com.android.internal.widget.NotificationActionListLayout>
diff --git a/core/res/res/layout/notification_material_reply_text.xml b/core/res/res/layout/notification_material_reply_text.xml
index bc22eb4..84603b0 100644
--- a/core/res/res/layout/notification_material_reply_text.xml
+++ b/core/res/res/layout/notification_material_reply_text.xml
@@ -28,7 +28,8 @@
             android:layout_width="match_parent"
             android:layout_height="1dip"
             android:id="@+id/action_divider"
-            android:layout_marginBottom="15dp"
+            android:layout_marginTop="@dimen/notification_content_margin"
+            android:layout_marginBottom="@dimen/notification_content_margin"
             android:background="@drawable/notification_template_divider" />
 
     <TextView
@@ -53,7 +54,6 @@
             android:id="@+id/notification_material_reply_text_1"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_marginBottom="15dp"
             android:layout_marginEnd="@dimen/notification_content_margin_end"
             android:textAppearance="@style/TextAppearance.Material.Notification.Reply"
             android:singleLine="true" />
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index 20bdf3f..c03cf51 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -14,7 +14,7 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
   -->
-
+<!-- extends ViewGroup -->
 <NotificationHeaderView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:theme="@style/Theme.Material.Notification"
@@ -126,5 +126,42 @@
         android:visibility="gone"
         android:contentDescription="@string/notification_work_profile_content_description"
         />
+
+    <LinearLayout
+        android:id="@+id/app_ops"
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content"
+        android:orientation="horizontal" >
+        <ImageButton
+            android:id="@+id/camera"
+            android:layout_width="?attr/notificationHeaderIconSize"
+            android:layout_height="?attr/notificationHeaderIconSize"
+            android:src="@drawable/ic_camera"
+            android:tint="@color/notification_secondary_text_color_light"
+            android:background="?android:selectableItemBackgroundBorderless"
+            android:layout_marginStart="6dp"
+            android:visibility="gone"
+            />
+        <ImageButton
+            android:id="@+id/mic"
+            android:layout_width="?attr/notificationHeaderIconSize"
+            android:layout_height="?attr/notificationHeaderIconSize"
+            android:src="@drawable/ic_mic"
+            android:tint="@color/notification_secondary_text_color_light"
+            android:background="?android:selectableItemBackgroundBorderless"
+            android:layout_marginStart="4dp"
+            android:visibility="gone"
+            />
+        <ImageButton
+            android:id="@+id/overlay"
+            android:layout_width="?attr/notificationHeaderIconSize"
+            android:layout_height="?attr/notificationHeaderIconSize"
+            android:src="@drawable/ic_alert_window_layer"
+            android:tint="@color/notification_secondary_text_color_light"
+            android:background="?android:selectableItemBackgroundBorderless"
+            android:layout_marginStart="4dp"
+            android:visibility="gone"
+            />
+    </LinearLayout>
 </NotificationHeaderView>
 
diff --git a/core/res/res/layout/notification_template_material_ambient.xml b/core/res/res/layout/notification_template_material_ambient.xml
index 19c4d23..346aad6c 100644
--- a/core/res/res/layout/notification_template_material_ambient.xml
+++ b/core/res/res/layout/notification_template_material_ambient.xml
@@ -43,6 +43,7 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="top"
+            android:layout_weight="1"
             android:paddingStart="@dimen/notification_content_margin_start"
             android:paddingEnd="@dimen/notification_content_margin_end"
             android:clipToPadding="false"
@@ -75,20 +76,19 @@
                 android:maxLines="3"
             />
         </LinearLayout>
+        <FrameLayout android:id="@+id/actions_container"
+                     android:layout_width="match_parent"
+                     android:layout_height="wrap_content"
+                     android:layout_gravity="bottom">
+            <com.android.internal.widget.NotificationActionListLayout
+                android:id="@+id/actions"
+                android:layout_width="match_parent"
+                android:layout_height="@dimen/notification_action_list_height"
+                android:paddingEnd="4dp"
+                android:orientation="horizontal"
+                android:gravity="center"
+                android:visibility="gone"
+            />
+        </FrameLayout>
     </LinearLayout>
-    <FrameLayout android:id="@+id/actions_container"
-                 android:layout_width="match_parent"
-                 android:layout_height="wrap_content"
-                 android:layout_gravity="bottom">
-        <com.android.internal.widget.NotificationActionListLayout
-            android:id="@+id/actions"
-            android:layout_width="match_parent"
-            android:layout_height="@dimen/notification_action_list_height"
-            android:paddingEnd="4dp"
-            android:orientation="horizontal"
-            android:gravity="center"
-            android:visibility="gone"
-            android:background="@color/notification_action_list"
-        />
-    </FrameLayout>
 </FrameLayout>
diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml
index 445b19b..221bcf6 100644
--- a/core/res/res/layout/notification_template_material_base.xml
+++ b/core/res/res/layout/notification_template_material_base.xml
@@ -30,7 +30,7 @@
         android:layout_marginStart="@dimen/notification_content_margin_start"
         android:layout_marginEnd="@dimen/notification_content_margin_end"
         android:layout_marginTop="@dimen/notification_content_margin_top"
-        android:layout_marginBottom="@dimen/notification_content_margin_bottom"
+        android:layout_marginBottom="@dimen/notification_content_margin"
         android:orientation="vertical" >
         <include layout="@layout/notification_template_part_line1" />
         <include layout="@layout/notification_template_text" />
@@ -42,7 +42,7 @@
         <include layout="@layout/notification_template_smart_reply_container"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_marginTop="@dimen/notification_content_margin_bottom" />
+            android:layout_marginTop="@dimen/notification_content_margin" />
     </LinearLayout>
     <include layout="@layout/notification_template_right_icon" />
 </FrameLayout>
diff --git a/core/res/res/layout/notification_template_material_big_base.xml b/core/res/res/layout/notification_template_material_big_base.xml
index d47bff6..2106890 100644
--- a/core/res/res/layout/notification_template_material_big_base.xml
+++ b/core/res/res/layout/notification_template_material_big_base.xml
@@ -20,6 +20,7 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical"
+    android:clipChildren="false"
     android:tag="big" >
     <LinearLayout
             android:id="@+id/notification_action_list_margin_target"
@@ -30,6 +31,7 @@
         <FrameLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:layout_weight="1"
             android:layout_gravity="top" >
             <include layout="@layout/notification_template_header" />
             <LinearLayout
@@ -39,7 +41,6 @@
                 android:layout_marginStart="@dimen/notification_content_margin_start"
                 android:layout_marginEnd="@dimen/notification_content_margin_end"
                 android:layout_marginTop="@dimen/notification_content_margin_top"
-                android:layout_marginBottom="@dimen/notification_content_margin_bottom"
                 android:orientation="vertical" >
                 <include layout="@layout/notification_template_part_line1" />
                 <include layout="@layout/notification_template_text" />
@@ -61,7 +62,7 @@
             android:layout_height="wrap_content"
             android:layout_marginStart="@dimen/notification_content_margin_start"
             android:layout_marginEnd="@dimen/notification_content_margin_end"
-            android:layout_marginBottom="@dimen/notification_content_margin_bottom" />
+            android:layout_marginTop="@dimen/notification_content_margin" />
+        <include layout="@layout/notification_material_action_list" />
     </LinearLayout>
-    <include layout="@layout/notification_material_action_list" />
 </FrameLayout>
diff --git a/core/res/res/layout/notification_template_material_big_media.xml b/core/res/res/layout/notification_template_material_big_media.xml
index cc4dd387..b4e26483 100644
--- a/core/res/res/layout/notification_template_material_big_media.xml
+++ b/core/res/res/layout/notification_template_material_big_media.xml
@@ -46,7 +46,7 @@
             android:layout_height="wrap_content"
             android:layout_marginTop="@dimen/notification_content_margin_top"
             android:layout_marginStart="@dimen/notification_content_margin_start"
-            android:layout_marginBottom="@dimen/notification_content_margin_bottom"
+            android:layout_marginBottom="@dimen/notification_content_margin"
             android:layout_marginEnd="@dimen/notification_content_margin_end"
             android:minHeight="@dimen/notification_min_content_height"
             android:orientation="vertical"
diff --git a/core/res/res/layout/notification_template_material_big_picture.xml b/core/res/res/layout/notification_template_material_big_picture.xml
index 76c0a67..7a1cc1e 100644
--- a/core/res/res/layout/notification_template_material_big_picture.xml
+++ b/core/res/res/layout/notification_template_material_big_picture.xml
@@ -20,17 +20,18 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:tag="bigPicture"
+    android:clipChildren="false"
     >
     <include layout="@layout/notification_template_header" />
     <include layout="@layout/notification_template_right_icon" />
     <LinearLayout
+            android:id="@+id/notification_action_list_margin_target"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:layout_gravity="top"
             android:layout_marginTop="@dimen/notification_content_margin_top"
             android:clipToPadding="false"
             android:orientation="vertical"
-            android:id="@+id/notification_action_list_margin_target"
             >
         <LinearLayout
             android:id="@+id/notification_main_column"
@@ -53,7 +54,6 @@
                 android:adjustViewBounds="true"
                 android:layout_weight="1"
                 android:layout_marginTop="13dp"
-                android:layout_marginBottom="16dp"
                 android:layout_marginStart="@dimen/notification_content_margin_start"
                 android:layout_marginEnd="@dimen/notification_content_margin_end"
                 android:scaleType="centerCrop"
@@ -69,7 +69,7 @@
             android:layout_height="wrap_content"
             android:layout_marginStart="@dimen/notification_content_margin_start"
             android:layout_marginEnd="@dimen/notification_content_margin_end"
-            android:layout_marginBottom="@dimen/notification_content_margin_bottom" />
+            android:layout_marginTop="@dimen/notification_content_margin" />
+        <include layout="@layout/notification_material_action_list" />
     </LinearLayout>
-    <include layout="@layout/notification_material_action_list" />
 </FrameLayout>
diff --git a/core/res/res/layout/notification_template_material_big_text.xml b/core/res/res/layout/notification_template_material_big_text.xml
index ac4c052..3a6f573 100644
--- a/core/res/res/layout/notification_template_material_big_text.xml
+++ b/core/res/res/layout/notification_template_material_big_text.xml
@@ -19,6 +19,7 @@
     android:id="@+id/status_bar_latest_event_content"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:clipChildren="false"
     android:tag="bigText"
     >
     <include layout="@layout/notification_template_header" />
@@ -43,6 +44,7 @@
             android:clipToPadding="false"
             android:minHeight="@dimen/notification_min_content_height"
             android:orientation="vertical"
+            android:layout_weight="1"
             >
             <include layout="@layout/notification_template_part_line1" />
             <include layout="@layout/notification_template_progress"
@@ -54,7 +56,6 @@
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_marginTop="@dimen/notification_text_margin_top"
-                android:paddingBottom="@dimen/notification_content_margin_bottom"
                 android:textAppearance="@style/TextAppearance.Material.Notification"
                 android:singleLine="false"
                 android:gravity="top"
@@ -68,12 +69,12 @@
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content" />
         <include layout="@layout/notification_template_smart_reply_container"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="@dimen/notification_content_margin_start"
-            android:layout_marginEnd="@dimen/notification_content_margin_end"
-            android:layout_marginBottom="@dimen/notification_content_margin_bottom" />
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginStart="@dimen/notification_content_margin_start"
+                android:layout_marginEnd="@dimen/notification_content_margin_end"
+                android:layout_marginTop="@dimen/notification_content_margin" />
+        <include layout="@layout/notification_material_action_list" />
     </LinearLayout>
-    <include layout="@layout/notification_material_action_list" />
     <include layout="@layout/notification_template_right_icon" />
 </FrameLayout>
diff --git a/core/res/res/layout/notification_template_material_inbox.xml b/core/res/res/layout/notification_template_material_inbox.xml
index 718cf16..23d8799 100644
--- a/core/res/res/layout/notification_template_material_inbox.xml
+++ b/core/res/res/layout/notification_template_material_inbox.xml
@@ -20,6 +20,7 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:tag="inbox"
+    android:clipChildren="false"
     >
     <include layout="@layout/notification_template_header" />
     <LinearLayout
@@ -38,8 +39,8 @@
             android:layout_gravity="top"
             android:paddingStart="@dimen/notification_content_margin_start"
             android:paddingEnd="@dimen/notification_content_margin_end"
-            android:paddingBottom="@dimen/notification_content_margin_bottom"
             android:minHeight="@dimen/notification_min_content_height"
+            android:layout_weight="1"
             android:clipToPadding="false"
             android:orientation="vertical"
             >
@@ -124,8 +125,8 @@
             android:layout_height="wrap_content"
             android:layout_marginStart="@dimen/notification_content_margin_start"
             android:layout_marginEnd="@dimen/notification_content_margin_end"
-            android:layout_marginBottom="@dimen/notification_content_margin_bottom" />
+            android:layout_marginTop="@dimen/notification_content_margin" />
+        <include layout="@layout/notification_material_action_list" />
     </LinearLayout>
-    <include layout="@layout/notification_material_action_list" />
     <include layout="@layout/notification_template_right_icon" />
 </FrameLayout>
diff --git a/core/res/res/layout/notification_template_material_media.xml b/core/res/res/layout/notification_template_material_media.xml
index 2c69b90..3a0912b 100644
--- a/core/res/res/layout/notification_template_material_media.xml
+++ b/core/res/res/layout/notification_template_material_media.xml
@@ -49,7 +49,7 @@
             android:layout_gravity="fill_vertical"
             android:layout_weight="1"
             android:minHeight="@dimen/notification_min_content_height"
-            android:paddingBottom="@dimen/notification_content_margin_bottom"
+            android:paddingBottom="@dimen/notification_content_margin"
             android:orientation="vertical"
             >
             <include layout="@layout/notification_template_part_line1"/>
diff --git a/core/res/res/layout/notification_template_material_messaging.xml b/core/res/res/layout/notification_template_material_messaging.xml
index 34f5ae8..53514a3 100644
--- a/core/res/res/layout/notification_template_material_messaging.xml
+++ b/core/res/res/layout/notification_template_material_messaging.xml
@@ -19,10 +19,11 @@
     android:id="@+id/status_bar_latest_event_content"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:clipChildren="false"
     android:tag="messaging"
     >
     <include layout="@layout/notification_template_header"/>
-    <LinearLayout
+    <com.android.internal.widget.RemeasuringLinearLayout
             android:id="@+id/notification_action_list_margin_target"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
@@ -31,15 +32,15 @@
             android:clipToPadding="false"
             android:orientation="vertical">
 
-        <LinearLayout
+        <com.android.internal.widget.RemeasuringLinearLayout
             android:id="@+id/notification_main_column"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="top"
+            android:layout_weight="1"
             android:layout_marginStart="@dimen/notification_content_margin_start"
             android:layout_marginEnd="@dimen/notification_content_margin_end"
             android:minHeight="@dimen/notification_min_content_height"
-            android:layout_marginBottom="@dimen/notification_content_margin_bottom"
             android:orientation="vertical"
             >
             <com.android.internal.widget.MessagingLinearLayout
@@ -47,12 +48,12 @@
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:spacing="@dimen/notification_messaging_spacing" />
-            <include layout="@layout/notification_template_smart_reply_container"
+        </com.android.internal.widget.RemeasuringLinearLayout>
+        <include layout="@layout/notification_template_smart_reply_container"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="@dimen/notification_content_margin_bottom" />
-        </LinearLayout>
-    </LinearLayout>
-    <include layout="@layout/notification_material_action_list" />
+                android:layout_marginTop="@dimen/notification_content_margin" />
+        <include layout="@layout/notification_material_action_list" />
+    </com.android.internal.widget.RemeasuringLinearLayout>
     <include layout="@layout/notification_template_right_icon"/>
 </com.android.internal.widget.MessagingLayout>
diff --git a/core/res/res/mipmap-watch-anydpi/sym_def_app_icon_foreground.xml b/core/res/res/mipmap-watch-anydpi/sym_def_app_icon_foreground.xml
new file mode 100644
index 0000000..69c241c
--- /dev/null
+++ b/core/res/res/mipmap-watch-anydpi/sym_def_app_icon_foreground.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<inset
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:insetLeft="24dp"
+    android:insetRight="24dp"
+    android:insetTop="24dp"
+    android:insetBottom="24dp">
+    <vector
+        android:width="60dp"
+        android:height="60dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+        <path
+            android:fillColor="#FFFFFF"
+            android:pathData="M20,12c0,-2.6 -1.2,-4.8 -3.1,-6.3l-0.5,-2.8c-1.4,-0.7 -2.9,-1.1 -4.5,-1.1c-1.6,0 -3.1,0.4 -4.5,1.1L7,5.7C5.1,7.2 3.9,9.4 3.9,12c0,2.6 1.2,4.8 3.1,6.3l0.5,2.8c1.4,0.7 2.9,1.1 4.5,1.1c1.6,0 3.2,-0.4 4.5,-1.1l0.5,-2.8C18.8,16.8 20,14.6 20,12zM12,18c-3.3,0 -6,-2.7 -6,-6c0,-3.3 2.7,-6 6,-6s6,2.7 6,6C18,15.3 15.3,18 12,18z"/>
+        <path
+            android:fillColor="#FFFFFF"
+            android:pathData="M11.2,15.6h1.4v-4.3h-1.4V15.6zM11.2,9.8h1.4V8.4h-1.4V9.8z"/>
+    </vector>
+</inset>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 17742bf..86b9c51 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Begin programme."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Voltooi herlaai."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> loop"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Tik om na program te wissel"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Wissel programme?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"\'n Ander program loop reeds wat gestop moet word voor jy \'n nuwe een kan begin."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Keer terug na <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Moenie die nuwe program begin nie."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Begin <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Stop die ou program sonder om te stoor."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> het berginglimiet oorskry"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Hoopstorting is ingesamel; tik om te deel"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Deel hoopstorting?"</string>
@@ -1833,6 +1838,6 @@
     <string name="slices_permission_request" msgid="8484943441501672932">"<xliff:g id="APP_0">%1$s</xliff:g> wil <xliff:g id="APP_2">%2$s</xliff:g>-skyfies wys"</string>
     <string name="screenshot_edit" msgid="7867478911006447565">"Wysig"</string>
     <string name="notification_channel_system_changes" msgid="5072715579030948646">"Stelselveranderinge"</string>
-    <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"Moenie steur nie het verander"</string>
+    <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"Moenie Steur Nie het verander"</string>
     <string name="zen_upgrade_notification_content" msgid="6603123479476554768">"Tik om jou optrede-instellings vir onderbrekings na te gaan"</string>
 </resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 92783e9..58772d1 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"የኤስኤምኤስ መልዕክቶች"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"የድምጽ መልዕክቶች"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"የWi-Fi ጥሪ"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"የሲም ሁኔታ"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"ቢጤ መልዕክት መጻጻፊያ ስልክ ሁነታ FULL ጠይቋል"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"ቢጤ መልዕክት መጻጻፊያ ስልክ ሁነታ HCO ጠይቋል"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"ቢጤ መልዕክት መጻጻፊያ ስልክ ሁነታ VCO ጠይቋል"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"ቅንብሮች"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"ደግፍ"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"የድምጽ እርዳታ"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"መቆለፊያ"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"አዲስ ማሳወቂያ"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ምናባዊ የቁልፍ ሰሌዳ"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"ጠቃሚ ምክር፦ ለማጉላት እና ለማሳነስ ሁለቴ-መታ አድርግ።"</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"ራስ ሙላ"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"በራስ ሰር ሙላ አዘጋጅ"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"ራስ-ሙላ"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">"፣ "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"መተግበሪያዎችን በማስጀመር ላይ፡፡"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"አጨራረስ ማስነሻ፡፡"</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> አሂድ"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"ወደ መተግበሪያ ለመቀየር መታ ያድርጉ"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"መተግበሪያዎችን ለውጥ?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"አዲስ ከመጀመርህ በፊት መቆም ያለበት ሌላ መተግበሪያ እየሄደ ነው።"</string>
-    <string name="old_app_action" msgid="493129172238566282">"ወደ <xliff:g id="OLD_APP">%1$s</xliff:g> ተመለስ"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"አዲሱን መተግበሪያ አትጀምር።"</string>
-    <string name="new_app_action" msgid="5472756926945440706">"ጀምር <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"የድሮውን ትግበራ ሳታስቀምጥ አቁም።"</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> የማህደረ ትውስታ ገደብን አልፏል"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"የቆሻሻ ቁልል ተሰብስቧል፤ ለማጋራት መታ ያድርጉ"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"የቆሻሻ ቁልል ይጋራ?"</string>
@@ -1200,12 +1202,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"SIM ካርድ አክል"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"የተንቀሳቃሽ አውታረ መረብን ለመድረስ መሣሪያህን ድጋሚ አስነሳ።"</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"ዳግም ጀምር"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"የሞባይል አገልግሎትን አግብር"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"የእርስዎን አዲስ ሲም ለማግበር የአገልግሎት አቅራቢውን መተግበሪያ ያውርዱ"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"መተግበሪያን አውርድ"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"አዲስ ሲም ገብቷል"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"ለማዋቀር መታ ያድርጉ"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"ጊዜ አዘጋጅ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 8bbf52e..1d48e88 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1165,13 +1165,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"بدء التطبيقات."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"جارٍ إعادة التشغيل."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> يعمل"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"انقر للتبديل إلى التطبيق"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"تبديل التطبيقات؟"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"يوجد تطبيق آخر قيد التشغيل فعلاً ويجب إيقافه حتى تتمكن من بدء تطبيق جديد."</string>
-    <string name="old_app_action" msgid="493129172238566282">"عودة إلى <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"عدم بدء التطبيق الجديد."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"بدء <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"إيقاف التطبيق القديم بدون الحفظ."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"لقد تجاوزت <xliff:g id="PROC">%1$s</xliff:g> حد الذاكرة."</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"تم نسخ الذاكرة، انقر للمشاركة."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"هل تريد مشاركة نَسْخ الذاكرة؟"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 4842e7e..f0253a2 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Tətbiqlər başladılır."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Yükləmə başa çatır."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> çalışır"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Tətbiqə keçmək üçün tıklayın"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Tətbiqlərə keçilsin?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Bir tətbiq artıq işləyir. Digərini başlatmaq üçün onu dayandırmalısınız."</string>
-    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g> bölməsinə qayıdın"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Yeni tətbiqi başlatmayın."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> tətbiqini başladın"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Köhnə tətbiqi yadda saxlamadan dayandırın."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> yaddaş limitini keçdi"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Yığın toplanıb; paylaşmaq üçün tıklayın"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Yığın paylaşılsın?"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 2c81b71..6941579 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1105,13 +1105,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Pokretanje aplikacija."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Završavanje pokretanja."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> je pokrenuta"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Dodirnite da biste prešli na aplikaciju"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Želite li da pređete na drugu aplikaciju?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Već je pokrenuta druga aplikacija koja mora da bude zaustavljena da biste mogli da pokrenete novu."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Vrati se u <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Ne pokrećite novu aplikaciju."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Pokreni <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Zaustavlja staru aplikaciju bez čuvanja."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> premašuje ograničenje memorije"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Snimak dinamičkog dela memorije je napravljen; dodirnite za deljenje"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Želite li da delite snimak dinamičkog dela memorije?"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 3af78d3..082a7a6 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -95,8 +95,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS-паведамленні"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Паведамленні галасавой пошты"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi-тэлефанія"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"Статус SIM-карты"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"Аднарангавая прылада запытала рэжым TTY FULL"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"Аднарангавая прылада запытала рэжым TTY НСО"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"Аднарангавая прылада запытала рэжым TTY VCO"</string>
@@ -246,8 +245,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"Налады"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"Дапамога"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Галас. дапамога"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"Блакіроўка"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"Новае апавяшчэнне"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Віртуальная клавіятура"</string>
@@ -834,8 +832,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"Падказка: двойчы націсніце, каб павялічыць або паменшыць."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Аўтазапаўненне"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Усталяванне аўтазапаўнення"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"Аўтазапаўненне"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1128,13 +1125,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Запуск прыкладанняў."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Завяршэнне загрузкі."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"Прыкладанне \"<xliff:g id="APP">%1$s</xliff:g>\" запушчанае"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Дакраніцеся, каб пераключыцца на праграму"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Пераключыць прыкладанні?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Ужо запушчана іншае прыкладанне, якое павінна быць спынена перад запускам новага."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Вярнуцца да <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Не запускайце новыя прыкладанні."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Запусціць <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Спыніць старыя прыкладанні без захавання."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"Працэс <xliff:g id="PROC">%1$s</xliff:g> перавысіў ліміт памяці"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Быў сабраны дамп кучы; дакраніцеся, каб абагуліць"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Абагуліць дамп дынамічнай вобласці?"</string>
@@ -1244,12 +1246,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"SIM-карта дадазеная"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"Перазагрузіце прыладу, каб атрымаць доступ да мабільнай сеткі."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Перазапусціць"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"Уключыць мабільную сувязь"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Спампаваць праграму аператара для актывацыі новай SIM-карты"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"Спампаваць праграму"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"Устаўлена новая SIM-карта"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"Краніце, каб наладзіць"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Задаць час"</string>
@@ -1908,10 +1907,7 @@
     <string name="harmful_app_warning_title" msgid="8982527462829423432">"Выяўлена шкодная праграма"</string>
     <string name="slices_permission_request" msgid="8484943441501672932">"Праграма <xliff:g id="APP_0">%1$s</xliff:g> запытвае дазвол на паказ зрэзаў праграмы <xliff:g id="APP_2">%2$s</xliff:g>"</string>
     <string name="screenshot_edit" msgid="7867478911006447565">"Рэдагаваць"</string>
-    <!-- no translation found for notification_channel_system_changes (5072715579030948646) -->
-    <skip />
-    <!-- no translation found for zen_upgrade_notification_title (3799603322910377294) -->
-    <skip />
-    <!-- no translation found for zen_upgrade_notification_content (6603123479476554768) -->
-    <skip />
+    <string name="notification_channel_system_changes" msgid="5072715579030948646">"Сістэмныя змены"</string>
+    <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"Зменены налады рэжыму \"Не турбаваць\""</string>
+    <string name="zen_upgrade_notification_content" msgid="6603123479476554768">"Націсніце, каб праверыць налады апавяшчэнняў"</string>
 </resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 66fb2a8..4319081 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS съобщения"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Съобщения в гласовата поща"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"Обаждания през Wi-Fi"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"Състояние на SIM картата"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"Отсрещният потребител заяви пълен TTY режим (FULL)"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"Отсрещният потребител заяви TTY режим с пренос на слух (HCO)"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"Отсрещният потребител заяви TTY режим с пренос на глас (VCО)"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"Настройки"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"Помощ"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Гласова помощ"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"Заключване"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"Ново известие"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Виртуална клавиатура"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"Съвет: Докоснете двукратно, за да увеличите или намалите мащаба."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Автопоп."</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Автопоп.: Настройка"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"Автоматично попълване"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Приложенията се стартират."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Зареждането завършва."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> се изпълнява"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Докоснете за превключване към приложението"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Да се превключат ли приложенията?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Вече се изпълнява друго приложение, което трябва да бъде спряно, преди да можете да стартирате ново."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Назад към <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Новото приложение да не се стартира."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Стартиране на <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Спиране на старото приложение без запазване."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> надхвърли ограничението за памет"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Извлечена е моментна снимка на паметта. Докоснете, за да я споделите"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Да се сподели ли моментната снимка на паметта?"</string>
@@ -1200,12 +1202,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"SIM картата е добавена"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"Рестартирайте устройството си, за да осъществите достъп до мобилната мрежа."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Рестартиране"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"Активиране на мобилната услуга"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Изтеглете приложението на оператора, за да активирате новата си SIM карта"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"Изтегляне на приложението"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"Поставена е нова SIM карта"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"Докоснете, за да я настроите"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Задаване на часа"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index c7116c2..7052e48 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"এসএমএস মেসেজ"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"ভয়েসমেল মেসেজ"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"ওয়াই-ফাই কলিং"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"সিম কার্ডের স্টাটাস"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"পির TTY মোড FULL অনুরোধ করেছে"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"পির TTY মোড HCO অনুরোধ করেছে"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"পির TTY মোড VCO অনুরোধ করেছে"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"সেটিংস"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"সহযোগিতা"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ভয়েস সহায়তা"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"লকডাউন"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"৯৯৯+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"নতুন বিজ্ঞপ্তি"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ভার্চুয়াল কীবোর্ড"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"টিপ: জুম বাড়ানো ও কমানোর জন্য দুইবার আলতো চাপুন৷"</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"স্বতঃপূর্ণ"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"স্বতঃপূর্ণ সেট করুন"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"আপনাআপনি পূরণ করুন"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$১$২$৩"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"অ্যাপ্লিকেশানগুলি শুরু করা হচ্ছে৷"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"চালু করা সম্পূর্ণ হচ্ছে৷"</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> চলছে"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"অ্যাপ্লিকেশান পাল্টাতে আলতো চাপুন"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"একটি থেকে অন্য অ্যাপ্লিকেশানগুলিতে পরিবর্তন করবেন?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"অন্য একটি অ্যাপ্লিকেশান ইতিমধ্যেই চলছে, নতুন একটি চালু করতে আপনাকে অবশ্যই সেটি বন্ধ করতে হবে৷"</string>
-    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g> এ ফিরুন"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"নতুন অ্যাপ্লিকেশান চালু করবেন না৷"</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> শুরু করুন"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"সংরক্ষণ না করেই পুরোনো অ্যাপ্লিকেশানটি বন্ধ করুন৷"</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> মেমরি সীমা অতিক্রম করেছে"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"অনেক ডেটা সংগ্রহ করা হয়েছে; শেয়ার করার জন্য ট্যাপ করুন"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"হিপ ডাম্প শেয়ার করবেন?"</string>
@@ -1201,12 +1203,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"সিম কার্ড যোগ করা হয়েছে"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"মোবাইল নেটওয়ার্ক অ্যাক্সেস করতে আপনার ডিভাইসটি পুনর্সূচনা করুন৷"</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"রিস্টার্ট করুন"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"মোবাইল পরিষেবা চালু করুন"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"আপনার নতুন সিম কার্ড চালু করতে পরিষেবা প্রদানকারীর অ্যাপটি ডাউনলোড করুন"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"অ্যাপ ডাউনলোড করুন"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"নতুন সিম ঢোকানো হয়েছে"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"এটিকে সেট আপ করতে আলতো চাপুন"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"সময় সেট করুন"</string>
@@ -1839,10 +1838,7 @@
     <string name="harmful_app_warning_title" msgid="8982527462829423432">"ক্ষতিকর অ্যাপ শনাক্ত করা হয়েছে"</string>
     <string name="slices_permission_request" msgid="8484943441501672932">"<xliff:g id="APP_0">%1$s</xliff:g> অ্যাপটি <xliff:g id="APP_2">%2$s</xliff:g> এর অংশ দেখাতে চায়"</string>
     <string name="screenshot_edit" msgid="7867478911006447565">"এডিট করুন"</string>
-    <!-- no translation found for notification_channel_system_changes (5072715579030948646) -->
-    <skip />
-    <!-- no translation found for zen_upgrade_notification_title (3799603322910377294) -->
-    <skip />
-    <!-- no translation found for zen_upgrade_notification_content (6603123479476554768) -->
-    <skip />
+    <string name="notification_channel_system_changes" msgid="5072715579030948646">"সিস্টেমে হয়ে থাকা পরিবর্তন"</string>
+    <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"\'বিরক্ত করবেন না\' মোডের সেটিং বদলে গেছে"</string>
+    <string name="zen_upgrade_notification_content" msgid="6603123479476554768">"বিজ্ঞপ্তির উপর ট্যাপ করে জানুন আপনি বাধার জন্য কোন সেটিংস সেট করেছেন"</string>
 </resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 1d1a36c..da059ad 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -1107,13 +1107,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Pokretanje aplikacija."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Pokretanje pri kraju."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"Pokrenuta je aplikacija <xliff:g id="APP">%1$s</xliff:g>"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Dodirnite da biste se prebacili na aplikaciju"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Želite se prebaciti na drugu aplikaciju?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Već je pokrenuta jedna aplikacija koju morate zaustaviti prije pokretanja nove."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Vrati se na aplikaciju <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Ne pokretati novu aplikaciju."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Pokreni <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Zaustaviti staru aplikaciju bez spašavanja podataka."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> premašuje ograničenje memorije"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Snimak dinamičkog stanja memorije je napravljen; dodirnite da biste dijelili"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Želite li dijeliti snimak dinamičkog dijela memorije?"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index a58339c..e5f208d 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"S\'estan iniciant les aplicacions."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"S\'està finalitzant l\'actualització."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> s\'està executant"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Toca per anar a l\'aplicació"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Vols canviar aplicacions?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Ja s\'està executant una altra aplicació que s\'ha d\'aturar abans de poder iniciar-ne una de nova."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Torna a <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"No iniciïs l\'aplicació nova."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Inicia <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Atura l\'aplicació antiga sense desar."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ha superat el límit de memòria"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"S\'ha recopilat un procés \"heap dump\"; toca per compartir-lo"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Vols compartir el \"heap dump\"?"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index d17a488..d9e15b2 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1125,13 +1125,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Spouštění aplikací."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Dokončování inicializace."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"Běží aplikace <xliff:g id="APP">%1$s</xliff:g>"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Klepnutím přepnete do aplikace"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Přepnout aplikace?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Než spustíte novou aplikaci, je třeba zastavit jinou spuštěnou aplikaci."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Návrat do aplikace <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Nespouštět novou aplikaci."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Do aplikace <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Zastavit starou aplikaci bez uložení."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"Proces <xliff:g id="PROC">%1$s</xliff:g> překročil limit paměti"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Byl shromážděn výpis haldy, klepnutím jej můžete sdílet"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Sdílet výpis haldy?"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 861ace0..47cf038 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Åbner dine apps."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Gennemfører start."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> er i gang"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Tryk for at skifte til appen"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Vil du skifte apps?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Der kører allerede en anden app, der skal stoppes, før du kan starte en ny."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Tilbage til <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Åbn ikke den nye app."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Start <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Stop den gamle app uden at gemme."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> har overskredet sin hukommelsesgrænse"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"En heap dump er blevet indsamlet. Tryk for at dele"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Vil du dele en heap dump?"</string>
@@ -1834,5 +1839,5 @@
     <string name="screenshot_edit" msgid="7867478911006447565">"Rediger"</string>
     <string name="notification_channel_system_changes" msgid="5072715579030948646">"Systemændringer"</string>
     <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"Tilstanden Forstyr ikke blev ændret"</string>
-    <string name="zen_upgrade_notification_content" msgid="6603123479476554768">"Tryk for at tjekke indstillingerne for adfærd ved afbrydelser"</string>
+    <string name="zen_upgrade_notification_content" msgid="6603123479476554768">"Tryk for at tjekke indstillingerne for adfærd ved underretninger"</string>
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index f291f62..aab6858 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Apps werden gestartet..."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Start wird abgeschlossen..."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> läuft"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Zum Wechseln der App tippen"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Apps wechseln?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Es wird bereits eine andere App ausgeführt, die vor dem Start einer neuen beendet werden muss."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Zu <xliff:g id="OLD_APP">%1$s</xliff:g> zurückkehren"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Neue App nicht starten"</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> starten"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Alte App beenden, ohne zu speichern"</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"Speicherlimit für \"<xliff:g id="PROC">%1$s</xliff:g>\" überschritten"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Heap-Dump wurde erfasst. Zum Teilen tippen"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Heap-Dump teilen?"</string>
@@ -1198,7 +1203,7 @@
     <string name="sim_added_message" msgid="6599945301141050216">"Starte zur Nutzung des Mobilfunknetzes dein Gerät neu."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Neu starten"</string>
     <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"Mobilfunkdienst aktivieren"</string>
-    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Mobilfunkanbieter-App herunterladen, um deine neue SIM-Karte zu aktivieren"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Mobilfunkanbieter-App herunterladen, um meine neue SIM-Karte zu aktivieren"</string>
     <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"App herunterladen"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"Neue SIM-Karte eingelegt"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"Zum Einrichten tippen"</string>
@@ -1834,5 +1839,5 @@
     <string name="screenshot_edit" msgid="7867478911006447565">"Bearbeiten"</string>
     <string name="notification_channel_system_changes" msgid="5072715579030948646">"Systemänderungen"</string>
     <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"\"Bitte nicht stören\" wurde geändert"</string>
-    <string name="zen_upgrade_notification_content" msgid="6603123479476554768">"Zum Prüfen der Verhaltenseinstellungen für Unterbrechungen hier tippen"</string>
+    <string name="zen_upgrade_notification_content" msgid="6603123479476554768">"Tippen, um Einstellungen für den Modus \"Bitte nicht stören\" zu überprüfen"</string>
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 5e657c8..1371000 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Έναρξη εφαρμογών."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Ολοκλήρωση εκκίνησης."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"Η εφαρμογή <xliff:g id="APP">%1$s</xliff:g> εκτελείται"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Πατήστε για εναλλαγή στην εφαρμογή"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Να γίνει εναλλαγή μεταξύ εφαρμογών;"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Εκτελείται ήδη άλλη εφαρμογή την οποία πρέπει να διακόψετε για να είναι δυνατή η εκτέλεση της νέας."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Επιστροφή σε <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Μην εκκινήσετε τη νέα εφαρμογή."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Εκκίνηση της εφαρμογής <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Διακοπή της παλιάς εφαρμογής χωρίς αποθήκευση."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"Η διαδικασία <xliff:g id="PROC">%1$s</xliff:g> υπερβαίνει το όριο μνήμης"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Έγινε λήψη του στιγμιότυπου μνήμης, πατήστε για κοινή χρήση"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Κοινή χρήση στιγμιότυπου μνήμης;"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 87a410e..0fddeac 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -305,7 +305,7 @@
     <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Perform gestures"</string>
     <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Can tap, swipe, pinch and perform other gestures."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Fingerprint gestures"</string>
-    <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Can capture gestures performed on the devices fingerprint sensor."</string>
+    <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Can capture gestures performed on the device\'s fingerprint sensor."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"disable or modify status bar"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Allows the app to disable the status bar or add and remove system icons."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"be the status bar"</string>
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Starting apps."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Finishing boot."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> running"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Tap to switch to app"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Switch apps?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Another app is already running that must be stopped before you can start a new one."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Return to <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Don\'t start the new app."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Start <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Stop the old app without saving."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> exceeded memory limit"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Heap dump has been collected; tap to share"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Share heap dump?"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 87a410e..0fddeac 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -305,7 +305,7 @@
     <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Perform gestures"</string>
     <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Can tap, swipe, pinch and perform other gestures."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Fingerprint gestures"</string>
-    <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Can capture gestures performed on the devices fingerprint sensor."</string>
+    <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Can capture gestures performed on the device\'s fingerprint sensor."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"disable or modify status bar"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Allows the app to disable the status bar or add and remove system icons."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"be the status bar"</string>
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Starting apps."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Finishing boot."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> running"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Tap to switch to app"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Switch apps?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Another app is already running that must be stopped before you can start a new one."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Return to <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Don\'t start the new app."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Start <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Stop the old app without saving."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> exceeded memory limit"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Heap dump has been collected; tap to share"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Share heap dump?"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 87a410e..0fddeac 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -305,7 +305,7 @@
     <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Perform gestures"</string>
     <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Can tap, swipe, pinch and perform other gestures."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Fingerprint gestures"</string>
-    <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Can capture gestures performed on the devices fingerprint sensor."</string>
+    <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Can capture gestures performed on the device\'s fingerprint sensor."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"disable or modify status bar"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Allows the app to disable the status bar or add and remove system icons."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"be the status bar"</string>
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Starting apps."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Finishing boot."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> running"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Tap to switch to app"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Switch apps?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Another app is already running that must be stopped before you can start a new one."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Return to <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Don\'t start the new app."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Start <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Stop the old app without saving."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> exceeded memory limit"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Heap dump has been collected; tap to share"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Share heap dump?"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 87a410e..0fddeac 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -305,7 +305,7 @@
     <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Perform gestures"</string>
     <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Can tap, swipe, pinch and perform other gestures."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Fingerprint gestures"</string>
-    <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Can capture gestures performed on the devices fingerprint sensor."</string>
+    <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Can capture gestures performed on the device\'s fingerprint sensor."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"disable or modify status bar"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Allows the app to disable the status bar or add and remove system icons."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"be the status bar"</string>
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Starting apps."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Finishing boot."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> running"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Tap to switch to app"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Switch apps?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Another app is already running that must be stopped before you can start a new one."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Return to <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Don\'t start the new app."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Start <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Stop the old app without saving."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> exceeded memory limit"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Heap dump has been collected; tap to share"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Share heap dump?"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index f9aa02c..04e776d 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‏‎‏‏‏‏‎‏‏‎‏‏‎‎‎‏‏‎‏‎‏‎‏‎‏‏‎‎‏‏‏‏‎‎‏‎Starting apps.‎‏‎‎‏‎"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎‏‎‎‎‏‏‎‎‏‏‎‎‏‎‏‏‎‎‏‎‎‏‎‏‏‎‏‎‏‎‎‏‏‏‏‎‎‏‏‏‏‎‏‎Finishing boot.‎‏‎‎‏‎"</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‏‎‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‎‏‏‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‎‏‎‎‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎ running‎‏‎‎‏‎"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‎‏‎‎‏‏‏‏‏‎‏‎‎‎‎‏‏‏‎‏‏‏‏‎‎‏‏‎‏‏‎‎‎‏‎‎‎‎‎‎‏‎‎‏‏‎‎‎‎‏‎‎Tap to switch to app‎‏‎‎‏‎"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‎‏‎‏‎‎‏‎‎‏‏‏‏‎‎‏‎‎‎‎‏‎‏‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‏‏‎‎‏‎‏‏‏‏‎‎‏‎Switch apps?‎‏‎‎‏‎"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‏‎‏‎‏‎‏‏‎‎‏‏‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‏‎‎‎‏‏‎‎‎‎‏‏‏‎‏‏‎‏‎‎‎‎‎‎‏‏‎Another app is already running that must be stopped before you can start a new one.‎‏‎‎‏‎"</string>
-    <string name="old_app_action" msgid="493129172238566282">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‏‏‎‎‏‎‎‏‎‏‏‏‏‎‏‎‎‏‎‎‏‏‏‎‏‎‏‎‎‏‏‎‎‎‎‎‏‏‏‎‎‎‏‎‏‎‎Return to ‎‏‎‎‏‏‎<xliff:g id="OLD_APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎‏‎‏‎‎‎‏‎‏‎‏‏‎‏‏‎‏‏‎‎‏‎‏‎‏‎‎‏‏‎‏‎‏‏‏‎‏‏‎‏‏‎‏‏‎‏‎‎‎‎‏‎Don\'t start the new app.‎‏‎‎‏‎"</string>
-    <string name="new_app_action" msgid="5472756926945440706">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‎‏‏‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‎‏‎‏‎‎‏‎‎‎‎‏‏‎‎‏‏‏‏‎‎‎‎‏‎‎Start ‎‏‎‎‏‏‎<xliff:g id="OLD_APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎‏‏‏‎‏‏‎‏‎‎‎‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‏‏‎‏‏‏‏‎‎‎Stop the old app without saving.‎‏‎‎‏‎"</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‎‏‎‏‏‎‏‎‎‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‎‏‎‏‎‏‏‏‏‎‎‎‏‏‎‏‏‎‎‏‏‏‎‏‏‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="PROC">%1$s</xliff:g>‎‏‎‎‏‏‏‎ exceeded memory limit‎‏‎‎‏‎"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‏‎‏‎‏‎‏‎‏‎‎‎‎‎‎‏‎‎‎‎‎‎‎‏‏‎‏‎‎‏‎‏‎‏‏‎‏‎‎‎‏‎‏‎‏‎‎Heap dump has been collected; tap to share‎‏‎‎‏‎"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‎‎‎‏‎‎‎‏‎‎‏‏‎‏‎‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‎‎‎‏‎‏‏‎‎‏‎Share heap dump?‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index c92db3d..950b977 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Iniciando aplicaciones"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Finalizando el inicio"</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> en ejecución"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Presiona para cambiar a la app"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"¿Deseas cambiar aplicaciones?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Ya se está ejecutando una aplicación que debe detenerse antes de iniciar una nueva."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Regresar a <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"No iniciar la nueva aplicación."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Inicio <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Interrumpe la aplicación anterior sin guardar los cambios."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> superó el límite de memoria."</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Se recopiló el volcado de pila. Presiona para compartir."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"¿Compartir volcado de pila?"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index cb74241..0893201 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Iniciando aplicaciones"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Finalizando inicio..."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> en ejecución"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Toca para cambiar a la aplicación"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"¿Cambiar aplicaciones?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Se está ejecutando otra aplicación. Para iniciar una aplicación nueva, debes detenerla."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Volver a <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"No iniciar la nueva aplicación"</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Iniciar <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Detener la aplicación anterior sin guardar"</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ha superado el límite de memoria"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Se ha recopilado un volcado de pila. Toca para compartirlo"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"¿Compartir volcado de pila?"</string>
@@ -1198,7 +1203,7 @@
     <string name="sim_added_message" msgid="6599945301141050216">"Reinicia el dispositivo para acceder a la red móvil."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Reiniciar"</string>
     <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"Activar servicio móvil"</string>
-    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Descara la aplicación del operador para activar tu nueva tarjeta SIM"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Descarga la aplicación del operador para activar tu nueva tarjeta SIM"</string>
     <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"Descargar aplicación"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"Nueva SIM insertada"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"Toca para configurar"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index de44b89..3f99415 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS-sõnumid"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Kõnepostisõnumid"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"WiFi-kõned"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"SIM-kaardi olek"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"Partner taotles TTY-režiimi TÄIELIK"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"Partner taotles TTY-režiimi HCO"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"Partner taotles TTY-režiimi VCO"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"Seaded"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"Abi"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Häälabi"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"Lukustamine"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"Uus märguanne"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuaalne klaviatuur"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"Vihje: suurendamiseks ja vähendamiseks puudutage kaks korda."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Automaatne täitmine"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Automaatse täitmise seadistamine"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"Automaattäide"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Rakenduste käivitamine."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Käivitamise lõpuleviimine."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> töötab"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Puudutage rakendusele lülitumiseks"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Kas lülituda teisele rakendusele?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Teine rakendus juba töötab ja see tuleb peatada, et saaksite uue käivitada."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Tagasi rakendusse <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Ärge käivitage uut rakendust."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Käivitage rakendus <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Peatage vana rakendus salvestamata."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"Protsess <xliff:g id="PROC">%1$s</xliff:g> ületas mälupiirangu"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Mälutõmmis salvestati; puudutage jagamiseks"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Kas jagada mälutõmmist?"</string>
@@ -1200,12 +1202,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"SIM-kaart lisatud"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"Mobiilsidevõrku pääsemiseks taaskäivitage seade."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Taaskäivita"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"Mobiilsideteenuse aktiveerimine"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Laadige alla operaatori rakendus, et aktiveerida oma uus SIM-kaart"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"Laadi alla rakendus"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"Uus SIM-kaart on sisestatud"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"Puudutage seadistamiseks"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Kellaaja määramine"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 55b48a6..0bf4802 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Aplikazioak abiarazten."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Bertsio-berritzea amaitzen."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> exekutatzen"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Sakatu aplikaziora joateko"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Aplikazioz aldatu?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Beste aplikazio bat exekutatzen ari da eta gelditu egin behar duzu beste bat abiarazi aurretik."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Itzuli <xliff:g id="OLD_APP">%1$s</xliff:g> aplikaziora"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Ez abiarazi aplikazio berria."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Hasi <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Gelditu aplikazio zaharra ezer gorde gabe."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> prozesuak memoria-muga gainditu du"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Uneko memoria-prozesuaren txostena sortu da; sakatu partekatzeko"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Uneko memoria-prozesuaren txostena partekatu nahi duzu?"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 8be3480..52e986a 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"در حال آغاز برنامه‌ها."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"در حال اتمام راه‌اندازی."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> در حال اجرا"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"برای رفتن به برنامه ضربه بزنید"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"برنامه عوض شود؟"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"برنامه دیگری از قبل در حال اجراست که باید متوقف شود تا بتوانید برنامه جدید را شروع کنید."</string>
-    <string name="old_app_action" msgid="493129172238566282">"بازگشت به <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"برنامه جدید شروع نشود."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"شروع <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"برنامه قدیمی را بدون ذخیره متوقف کنید."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> از حد مجاز حافظه فراتر رفت"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"رون حافظه آزاد جمع‌آوری شد؛ برای اشتراک‌گذاری، ضربه بزنید"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"رونوشت حافظه آزاد به اشتراک گذاشته شود؟"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 98b667f..9dc6e95 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Käynnistetään sovelluksia."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Viimeistellään päivitystä."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> käynnissä"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Vaihda sovellukseen napauttamalla."</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Vaihdetaanko sovellusta?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Toinen sovellus on jo käynnissä. Sulje kyseinen sovellus, niin voit käynnistää uuden."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Palaa kohteeseen <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Älä käynnistä uutta sovellusta."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Käynnistä <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Pysäytä vanha sovellus tallentamatta."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ylitti muistirajan."</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Keon vedos on kerätty, jaa se napauttamalla."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Jaetaanko keon vedos?"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index c989856..faa8598 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Lancement des applications…"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Finalisation de la mise à jour."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> en cours d\'exécution"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Touchez pour passer à l\'application"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Changer d\'application?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Une autre application est déjà en cours d\'exécution. Arrêtez-la avant d\'en lancer une nouvelle."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Revenir à <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Ne pas lancer la nouvelle application"</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Démarrer <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Arrêtez l\'ancienne application sans enregistrer."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> a dépassé la limite de mémoire"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"L\'empreinte de mémoire a été recueillie. Touchez pour la partager."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Partager l\'empreinte de mémoire?"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 924a9a3..f840922 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Lancement des applications…"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Finalisation de la mise à jour."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> en cours d\'exécution"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Appuyez ici pour changer d\'application."</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Changer d\'application ?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Une autre application est déjà en cours d\'exécution. Arrêtez-la avant d\'en lancer une nouvelle."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Revenir à <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Ne pas lancer la nouvelle application"</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Démarrer <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Arrêtez l\'ancienne application sans enregistrer."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"Le processus \"<xliff:g id="PROC">%1$s</xliff:g>\" a dépassé la limite de mémoire"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Une empreinte de la mémoire a bien été générée. Appuyez pour partager."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Partager l\'empreinte de la mémoire ?"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index d36e4a6..5114ba0 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"Mensaxes SMS"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Mensaxes de correo de voz"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"Chamadas por wifi"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"Estado da SIM"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"Outro dispositivo solicitou o modo TTY COMPLETO"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"Outro dispositivo solicitou o modo TTY HCO"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"Outro dispositivo solicitou o modo TTY VCO"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"Configuración"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"Asistencia"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Asistente voz"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"Bloquear"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"Notificación nova"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Teclado virtual"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"Consello: Toca dúas veces para achegar e afastar o zoom."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Encher"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Conf. autocompletar"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"Autocompletar"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Iniciando aplicacións."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Está finalizando o arranque"</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> está en execución"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Toca para cambiar á aplicación"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Queres cambiar as aplicacións?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Xa hai unha aplicación executándose que debe deterse para que poidas iniciar outra nova."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Volver a <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Non inicies a aplicación nova."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Iniciar <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Deter a aplicación antiga sen gardar."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> superou o límite de memoria"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Recompilouse o baleirado de montóns. Toca para compartir"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Queres compartir o baleirado de montóns?"</string>
@@ -1201,12 +1203,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"Engadiuse unha tarxeta SIM"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"Reinicia o dispositivo para acceder á rede móbil."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Reiniciar"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"Activar o servizo móbil"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Descarga a aplicación do operador para activar a túa nova SIM"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"Descargar aplicación"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"Introduciuse unha nova SIM"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"Tocar para configurar"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Configurar hora"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index bb6ac6d..bf48ded 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS સંદેશા"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"વૉઇસમેઇલ સંદેશા"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"વાઇ-ફાઇ કૉલિંગ"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"સિમનું સ્ટેટસ"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"પીઅરે TTY મોડ પૂર્ણની વિનંતી કરી"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"પીઅરે TTY મોડ HCO ની વિનંતી કરી"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"પીઅરે TTY મોડ VCO ની વિનંતી કરી"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"સેટિંગ્સ"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"સહાય"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"વૉઇસ સહાય"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"લૉકડાઉન"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"નવું નોટિફિકેશન"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"વર્ચ્યુઅલ કીબોર્ડ"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"ટિપ: ઝૂમ વધારવા અને ઘટાડવા માટે બે વાર ટેપ કરો."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"સ્વતઃભરણ"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"સ્વતઃભરણ સેટ કરો"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"આપમેળે ભરાઈ જશે"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"ઍપ્લિકેશનો શરૂ કરી રહ્યાં છે."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"બૂટ સમાપ્ત કરી રહ્યાં છે."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> ચાલુ છે"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"ઍપ્લિકેશન પર સ્વિચ કરવા માટે ટૅપ કરો"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"એપ્લિકેશન્સને સ્વિચ કરીએ?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"પહેલાંથી ચાલી રહેલ બીજી એપ્લિકેશનને તમે નવી પ્રારંભ કરો તે પહેલાં બંધ કરવી આવશ્યક છે."</string>
-    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g> પર પાછા ફરો"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"નવી ઍપ્લિકેશન પ્રારંભ કરશો નહીં."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> ને પ્રારંભ કરો"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"જૂની એપ્લિકેશનને સાચવ્યાં વગર રોકો."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> એ મેમરી સીમા વટાવી"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"હીપ ડમ્પ ભેગો કરવામાં આવ્યો છે; શેર કરવા માટે ટૅપ કરો"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"હીપ ડમ્પ શેર કરીએ?"</string>
@@ -1201,12 +1203,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"સિમ કાર્ડ ઉમેર્યો"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"મોબાઇલ નેટવર્કને ઍક્સેસ કરવા માટે તમારા ઉપકરણને પુનઃપ્રારંભ કરો."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"રિસ્ટાર્ટ કરો"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"મોબાઇલ સેવાને સક્રિય કરો"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"તમારું નવું સિમ સક્રિય કરવા માટે કૅરિઅર ઍપ ડાઉનલોડ કરો"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"ઍપ ડાઉનલોડ કરો"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"નવું સિમ દાખલ કર્યું"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"તેને સેટ કરવા માટે ટૅપ કરો"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"સમય સેટ કરો"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 5b81d3e..bb1af18 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"मैसेज (एसएमएस)"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"वॉइसमेल संदेश"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"वाई-फ़ाई कॉलिंग"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"सिम की स्थिति"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"पीयर ने टेलीटाइपराइटर (TTY) मोड फ़ुल का अनुरोध किया"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"पीयर ने टेलीटाइपराइटर (TTY) मोड एचसीओ (HCO) का अनुरोध किया"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"पीयर ने टेलीटाइपराइटर (TTY) मोड वीसीअो (VCO) का अनुरोध किया"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"सेटिंग"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"सहायता"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"आवाज़ से डिवाइस का इस्तेमाल"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"फ़ाेन लॉक करें"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"नई सूचना"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"वर्चुअल कीबोर्ड"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"सलाह: ज़ूम इन और आउट करने के लिए दो बार छूएं."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"स्‍वत: भरण"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"स्वत: भरण सेट करें"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"अपने आप जानकारी भरने की सुविधा"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"ऐप्स  प्रारंभ होने वाले हैं"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"बूट समाप्‍त हो रहा है."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> चल रही है"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"ऐप्लिकेशन पर स्विच करने के लिए टैप करें"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"ऐप्स  स्विच करें?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"दूसरा ऐप्स  पहले से चल रहा है जिसे किसी नए ऐप्स को प्रारंभ करने के पहले बंद किया जाना आवश्‍यक है."</string>
-    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g> पर वापस लौटें"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"नया ऐप्स प्रारंभ न करें."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> शुरू करें"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"पुराने ऐप्स को बिना सहेजे बंद करें."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> मेमोरी सीमा को पार कर गई है"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"हीप डंप का संग्रह कर लिया गया है; शेयर करने के लिए टैप करें"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"हीप डंप शेयर करें?"</string>
@@ -1200,12 +1202,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"सिम कार्ड जोड़ा गया"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"मोबाइल नेटवर्क की पहुंच पाने लिए अपना डिवाइस फिर से चालू करें."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"फिर से शुरू करें"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"माेबाइल सेवा चालू करें"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"अपने नए सिम काे चालू करने के लिए इंटरनेट सेवा देने वाली कंपनी का एेप्लिकेशन डाउनलोड करें"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"ऐप्लिकेशन डाउनलोड करें"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"नई SIM डाली गई"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"इसे सेट करने के लिए टैप करें"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"समय सेट करें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 857ef36..f740d74 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1105,13 +1105,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Pokretanje aplikacija."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Završetak inicijalizacije."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"Izvodi se <xliff:g id="APP">%1$s</xliff:g>"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Dodirnite da biste prešli na aplikaciju"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Izmijeniti aplikacije?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Već se izvodi neka druga aplikacija koja se mora zaustaviti prije pokretanja nove."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Natrag na <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Ne pokreći novu aplikaciju."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Pokreni <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Zaustavi staru aplikaciju bez spremanja."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"Proces <xliff:g id="PROC">%1$s</xliff:g> premašio je ograničenje memorije"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Generirana je snimka memorije procesa. Dodirnite za dijeljenje."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Žalite li dijeliti snimku memorije procesa?"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 41d9355..1fb05b2 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Kezdő alkalmazások."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Rendszerindítás befejezése."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> fut"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Koppintson az alkalmazásra váltáshoz"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Átvált az alkalmazások között?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Már fut egy másik alkalmazás, amelyet le kell állítania, mielőtt egy újat indíthatna el."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Visszatérés a(z) <xliff:g id="OLD_APP">%1$s</xliff:g> alkalmazáshoz"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Ne indítsa el az új alkalmazást."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> indítása"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"A régi alkalmazás leállítása mentés nélkül."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"A(z) <xliff:g id="PROC">%1$s</xliff:g> túllépte a memóriakorlátot"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Elkészült a memória-pillanatfelvétel (heap dump); a megosztáshoz koppintson rá"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Megosztja a memória-pillanatfelvételt?"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index ca46497..b299ecf 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Հավելվածները մեկնարկում են:"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Բեռնումն ավարտվում է:"</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g>-ն աշխատում է"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Հպեք՝ հավելվածին անցնելու համար"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Փոխարկե՞լ հավելվածները:"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Մեկ այլ ծրագիր արդեն աշխատում է, որը պետք է դադարեցնել, նախքան դուք կկարողանաք սկսել նորը:"</string>
-    <string name="old_app_action" msgid="493129172238566282">"Վերադառնալ <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Չսկսել նոր հավելված:"</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Սկիզբ <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Դադարեցնել նախկին ծրագիրն առանց պահպանման:"</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> գործընթացը գերազանցել է հիշողության սահմանաչափը"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Օգտագործվող օբյեկտների վերաբերյալ տվյալները հավաքվել են: Հպեք՝ դրանք տրամադրելու համար"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Տրամադրե՞լ օգտագործվող օբյեկտների վերաբերյալ տվյալները:"</string>
@@ -1834,5 +1839,5 @@
     <string name="screenshot_edit" msgid="7867478911006447565">"Փոփոխել"</string>
     <string name="notification_channel_system_changes" msgid="5072715579030948646">"Համակարգի փոփոխություններ"</string>
     <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"«Չանհանգստացնել» ռեժիմի կարգավորումները փոխվել են"</string>
-    <string name="zen_upgrade_notification_content" msgid="6603123479476554768">"Հպեք՝ ծանուցման կարգավորումները ստուգելու համար"</string>
+    <string name="zen_upgrade_notification_content" msgid="6603123479476554768">"Հպեք՝ կարգավորումները ստուգելու համար"</string>
 </resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 1717814..6ac404c 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Memulai aplikasi."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Menyelesaikan boot."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> berjalan"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Ketuk untuk beralih ke aplikasi"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Beralih aplikasi?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Apl lain sudah berjalan dan harus dihentikan agar Anda dapat memulai yang baru."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Kembali ke<xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Jangan memulai aplikasi baru."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Mulai <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Hentikan apl lama tanpa menyimpan."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> melampaui batas memori"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Informasi memori elah dikumpulkan; ketuk untuk membagikan"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Share tumpukan membuang?"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index e481900..2281a54 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Ræsir forrit."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Lýkur ræsingu."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> er í gangi"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Ýttu til að skipta yfir í forrit"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Skipta um forrit?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Annað forrit er þegar í gangi og það þarf að stöðva áður en hægt er að ræsa nýtt."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Til baka í <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Ekki ræsa nýja forritið."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Ræsa <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Stöðva gamla forritið án þess að vista."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> er yfir minnishámarki"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Minnisgögnum hefur verið safnað, ýttu til að deila"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Deila minnisgögnum?"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index c950f3b..9c782bc 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Avvio applicazioni."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Conclusione dell\'avvio."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> in esecuzione"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Tocca per passare all\'app"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Cambiare applicazione?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Un\'altra applicazione già in esecuzione deve essere chiusa prima di poterne avviare un\'altra."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Torna a <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Non avviare la nuova applicazione."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Avvia <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Interrompi la vecchia applicazione senza salvare."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ha superato il limite di memoria"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Dump dell\'heap raccolto; tocca per condividere"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Condividere il dump dell\'heap?"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 5702ee5..56cafa9 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -95,8 +95,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"‏הודעות SMS"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"הודעות קוליות"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"‏שיחות Wi-Fi"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"‏סטטוס SIM"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"‏העמית ביקש TTY במצב FULL"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"‏העמית ביקש TTY במצב HCO"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"‏העמית ביקש TTY במצב VCO"</string>
@@ -246,8 +245,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"הגדרות"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"סיוע"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"נעילה"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"הודעה חדשה"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"מקלדת וירטואלית"</string>
@@ -834,8 +832,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"טיפ: הקש פעמיים כדי להגדיל ולהקטין."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"מילוי אוטומטי"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"הגדר מילוי אוטומטי"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"מילוי אוטומטי"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1128,13 +1125,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"מפעיל אפליקציות."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"מסיים אתחול."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> פועל"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"הקש כדי לעבור לאפליקציה"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"להחליף אפליקציות?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"אפליקציה אחרת כבר פועלת ועליך לעצור אותה לפני שתוכל להפעיל אפליקציה חדשה."</string>
-    <string name="old_app_action" msgid="493129172238566282">"חזור אל <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"אל תפעיל את האפליקציה החדש."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"הפעל את <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"עצור את האפליקציה הישן ללא שמירה."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> חורג מהגבלת הזיכרון"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"‏Dump של ערימה נאסף. הקש כדי לשתף"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"‏האם לשתף את נתוני ה-Dump של הערימה?"</string>
@@ -1244,12 +1246,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"‏כרטיס ה-SIM נוסף"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"הפעל מחדש את המכשיר כדי לגשת אל הרשת הסלולרית."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"הפעלה מחדש"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"הפעלה של השירות הסלולרי"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"‏הורדה של אפליקציית הספק כדי להפעיל את כרטיס ה-SIM החדש"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"הורדת אפליקציה"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"‏ה-SIM החדש הוכנס"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"הקש כדי להגדיר"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"הגדרת שעה"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 00aeab9..15fa7dc 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS メッセージ"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"ボイスメール メッセージ"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi 通話"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"SIM のステータス"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"ピアから、TTY モードを FULL にするようリクエストされました"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"ピアから、TTYモードをHCOにするようリクエストされました"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"ピアから、TTYモードをVCOにするようリクエストされました"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"設定"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"サポート"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"音声アシスト"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"ロックダウン"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"新しい通知"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"仮想キーボード"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"ヒント: ダブルタップで拡大/縮小できます。"</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"自動入力"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"自動入力を設定"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"自動入力"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$3$2$1"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">"、 "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"アプリを起動しています。"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"ブートを終了しています。"</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g>を実行中"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"タップしてアプリを切り替えます"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"アプリを切り替えますか?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"別のアプリが既に実行中です。新しいアプリを起動する前に実行中のアプリを停止してください。"</string>
-    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g>に戻る"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"新しいアプリを起動しません。"</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g>を起動"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"古いアプリを保存せずに停止します。"</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g>はメモリの上限を超えました"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"ヒープダンプが収集されました。タップして共有できます"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"ヒープダンプを共有しますか?"</string>
@@ -1200,12 +1202,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"SIMカードが追加されました"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"モバイルネットワークにアクセスするには端末を再起動してください。"</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"再起動"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"モバイル サービスを有効にする"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"新しい SIM を有効にするには携帯通信会社のアプリをダウンロードします"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"アプリをダウンロード"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"新しい SIM が挿入されました"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"タップして設定"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"時刻設定"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 174a770..a0ff3b8 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS შეტყობინებები"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"ხმოვანი ფოსტის შეტყობინებები"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"დარეკვა Wi-Fi-ს მეშვეობით"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"SIM სტატუსი"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"მოთხოვნილია კვანძი TTY რეჟიმი FULL"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"მოთხოვნილია კვანძი TTY რეჟიმი HCO"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"მოთხოვნილია კვანძი TTY რეჟიმი VCO"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"პარამეტრები"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"დახმარება"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ხმოვანი ასისტ."</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"დაბლოკვა"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"ახალი შეტყობინება"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ვირტუალური კლავიატურა"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"რჩევა: მასშტაბის შესაცვლელად გამოიყენეთ ორმაგი შეხება."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"ავტოშევსება"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"ავტოშევსების დაყენება"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"ავტომატური შევსება"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"აპების ჩართვა"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"ჩატვირთვის დასასრული."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> გაშვებულია"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"შეეხეთ აპზე გადასართველად"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"გსურთ, აპების გადართვა?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"სხვა აპი არის უკვე გაშვებული, რომელიც უნდა შეჩერდეს ახლის დაწყებამდე."</string>
-    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g>-თან დაბრუნება"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"არ ჩართოთ ახალი აპი."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"დასაწყისი <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"შეაჩერე ძველი აპი ცვლილებების შენახვის გარეშე."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g>-მა გადააჭარბა მეხსიერების ლიმიტს"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"გროვის ამონაწერი მომზადდა; შეეხეთ გასაზიარებლად"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"გავაზიაროთ გროვის ამონაწერი?"</string>
@@ -1200,12 +1202,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"SIM ბარათი დაემატა"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"გადატვირთეთ თქვენი მოწყობილობა მობილურ ქსელზე წვდომისთვის."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"გადატვირთვა"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"გაააქტიურეთ მობილური სერვისი"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"ჩამოტვირთეთ ოპერატორის აპი, რათა თქვენი ახალი SIM გაააქტიუროთ"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"აპის ჩამოტვირთვა"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"მოთავსებულია ახალი SIM ბარათი"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"შეეხეთ პარამეტრების დასაყენებლად"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"დროის დაყენება"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index d4f3e7d..4b106a2 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS хабарлары"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Дауыстық пошта хабарлары"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi қоңыраулары"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"SIM күйі"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"Пир TTY режимі ТОЛЫҚ сұрады"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"Пир TTY режимінің HCO сұрады"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"Пир TTY режимінің VCO сұрады"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"Параметрлер"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"Көмек"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Дауыс көмекшісі"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"Құлыптау"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"Жаңа хабарландыру"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Виртуалды пернетақта"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"Кеңес: Ұлғайту немесе кішірейту үшін екі рет түртіңіз."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Aвто толтыру"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Автотолтыруды орнату"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"Aвтотолтыру"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Қолданбалар іске қосылуда."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Қосуды аяқтауда."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> қосылған"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Қолданбаға ауысу үшін түртіңіз"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Қолданбаларды ауыстыру керек пе?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Жаңасын іске қосу алдында тоқтату керек басқа қолданба әлдеқашан жұмыс істеп жатыр."</string>
-    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g> қолданбасына оралу"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Жаңа қолданбаны іске қоспау."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> қолданбасын қосу"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Ескі қолданбаны сақтаусыз тоқтату."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> жад шегінен асты"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Үйінді дамп жиналды; бөлісу үшін түртіңіз"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Үйінді дамппен бөлісу қажет пе?"</string>
@@ -1201,12 +1203,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"SIM картасы қосылды"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"Ұялы желіге кіру үшін құрылғыны қайта бастаңыз."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Қайта бастау"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"Мобильдік қызметті іске қосыңыз"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Жаңа SIM картасын іске қосу үшін оператор қолданбасын жүктеп алыңыз"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"Қолданбаны жүктеп алу"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"Жаңа SIM салынды"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"Оны орнату үшін түртіңіз"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Уақытты реттеу"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index a78d527..1e65a76 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1087,13 +1087,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"ចាប់ផ្ដើម​កម្មវិធី។"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"បញ្ចប់​ការ​ចាប់ផ្ដើម។"</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> កំពុង​ដំណើរការ"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"ប៉ះដើម្បីប្តូរកម្មវិធី"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"ប្ដូរ​កម្មវិធី?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"កម្មវិធី​ផ្សេង​កំពុង​ដំណើរការ​រួច​ហើយ​ ដែល​តម្រូវ​ឲ្យ​បញ្ឈប់​មុន​ពេល​អ្នក​អាច​ចាប់ផ្ដើម​ថ្មី។"</string>
-    <string name="old_app_action" msgid="493129172238566282">"ត្រឡប់​ទៅ <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"កុំ​ចាប់ផ្ដើម​កម្មវិធី​ថ្មី។"</string>
-    <string name="new_app_action" msgid="5472756926945440706">"ចាប់ផ្ដើម <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"បញ្ឈប់​កម្មវិធី​ចាស់​ដោយ​មិន​រក្សាទុក"</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> លើសពីកម្រិតកំណត់មេម៉ូរី"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Heap dump ត្រូវបានប្រមូល សូមប៉ះដើម្បីចែករំលែក"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"ចែករំលែក heap dump?"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index adf234b..1adc210 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"ಎಸ್‌ಎಂಎಸ್ ಸಂದೇಶಗಳು"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"ಧ್ವನಿಮೇಲ್ ಸಂದೇಶಗಳು"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"ವೈ-ಫೈ ಕರೆ ಮಾಡುವಿಕೆ"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"ಸಿಮ್‌ ಸ್ಥಿತಿ"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"ಪೀರ್ ವಿನಂತಿಸಿಕೊಂಡ TTY ಮೋಡ್ ಪೂರ್ಣಗೊಂಡಿದೆ"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"ಪೀರ್ ವಿನಂತಿಸಿಕೊಂಡ TTY ಮೋಡ್ HCO"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"ಪೀರ್ ವಿನಂತಿಸಿಕೊಂಡ TTY ಮೋಡ್ VCO"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"ಸಹಾಯ ಮಾಡು"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ಧ್ವನಿ ಸಹಾಯಕ"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"ಲಾಕ್‌ಡೌನ್‌"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"ಹೊಸ ಅಧಿಸೂಚನೆ"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ವರ್ಚುಯಲ್ ಕೀಬೋರ್ಡ್"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"ಸಲಹೆ: ಝೂಮ್ ಇನ್ ಮತ್ತು ಝೂಮ್ ಔಟ್ ಮಾಡಲು ಡಬಲ್-ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"ಸ್ವಯಂತುಂಬುವಿಕೆ"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"ಸ್ವಯಂತುಂಬುವಿಕೆಯನ್ನು ಹೊಂದಿಸಿ"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"ಸ್ವಯಂತುಂಬುವಿಕೆ"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"ಬೂಟ್ ಪೂರ್ಣಗೊಳಿಸಲಾಗುತ್ತಿದೆ."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> ರನ್ ಆಗುತ್ತಿದೆ"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"ಅಪ್ಲಿಕೇಶನ್‌ ಬದಲಾಯಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಬದಲಾಯಿಸುವುದೇ?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"ಮತ್ತೊಂದು ಅಪ್ಲಿಕೇಶನ್‌ ಈಗಾಗಲೇ ಚಾಲ್ತಿಯಲ್ಲಿದೆ ನೀವು ಹೊಸದೊಂದು ಪ್ರಾರಂಭಿಸುವ ಮೊದಲು ಅದನ್ನು ನಿಲ್ಲಿಸಬೇಕು."</string>
-    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g> ಗೆ ಹಿಂತಿರುಗಿ"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"ಹೊಸ ಅಪ್ಲಿಕೇಶನ್‌ ಪ್ರಾರಂಭಿಸಬೇಡಿ."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> ಪ್ರಾರಂಭಿಸಿ"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"ಉಳಿಸದೇ ಹಳೆಯ ಅಪ್ಲಿಕೇಶನ್ ನಿಲ್ಲಿಸಿ."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ಮೆಮೊರಿ ಮಿತಿಯನ್ನು ಮೀರಿದೆ"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"ಹೀಪ್ ಡಂಪ್ ಅನ್ನು ಸಂಗ್ರಹಿಸಲಾಗಿದೆ; ಹಂಚಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"ಹೀಪ್ ಡಂಪ್ ಹಂಚಿಕೊಳ್ಳುವುದೇ?"</string>
@@ -1201,12 +1203,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"ಸಿಮ್‌ ಕಾರ್ಡ್ ಸೇರಿಸಲಾಗಿದೆ"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"ಮೊಬೈಲ್ ನೆಟ್‍ವರ್ಕ್ ಪ್ರವೇಶಿಸಲು ನಿಮ್ಮ ಸಾಧನವನ್ನು ಮರುಪ್ರಾರಂಭಿಸಿ."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"ಮರುಪ್ರಾರಂಭಿಸು"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"ಮೊಬೈಲ್ ಸೇವೆಯನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"ನಿಮ್ಮ ಹೊಸ ಸಿಮ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲು ವಾಹಕ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಬಳಸಿ"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"ಅಪ್ಲಿಕೇಶನ್ ಡೌನ್‌ಲೋಡ್ ಮಾಡಿ"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"ಹೊಸ ಸಿಮ್ ಸೇರಿಸಲಾಗಿದೆ"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"ಇದನ್ನು ಸ್ಥಾಪಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"ಸಮಯವನ್ನು ಹೊಂದಿಸಿ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 77e6971..2eb5bcf 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS 메시지"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"음성사서함 메시지"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi 통화"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"SIM 상태"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"피어가 TTY 모드 FULL을 요청했습니다."</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"피어가 TTY 모드 HCO를 요청했습니다."</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"피어가 TTY 모드 VCO를 요청했습니다."</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"설정"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"지원"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"음성 지원"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"잠금"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"새 알림"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"가상 키보드"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"도움말: 확대/축소하려면 두 번 탭합니다."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"자동완성"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"자동완성 설정..."</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"자동 완성"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$3$2$1"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"앱을 시작하는 중입니다."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"부팅 완료"</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> 실행 중"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"앱을 전환하려면 탭하세요."</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"앱을 전환하시겠습니까?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"다른 앱이 이미 실행 중입니다. 새 앱을 시작하려면 실행 중인 앱을 중단해야 합니다."</string>
-    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g>(으)로 돌아가기"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"새 앱을 시작하지 마세요."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> 시작"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"저장하지 않고 이전 앱을 중단합니다."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g>에서 메모리 제한을 초과했습니다."</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"힙 덤프가 수집되었습니다. 공유하려면 탭하세요."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"힙 덤프를 공유할까요?"</string>
@@ -1200,12 +1202,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"SIM 카드 추가됨"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"모바일 네트워크에 액세스하려면 기기를 다시 시작하세요."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"다시 시작"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"모바일 서비스 활성화"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"이동통신사 앱을 다운로드하여 새로운 SIM 활성화"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"앱 다운로드"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"새 SIM이 삽입됨"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"탭하여 설정"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"시간 설정"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index ef40d0e..84abf19 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS билдирүүлөрү"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Үн почтасынын билдирүүлөрү"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi аркылуу чалуу"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"SIM-картанын абалы"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"Peer TTY режимин FULL кылууну суранды"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"Peer TTY режимин HCO кылууну суранды"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"Peer TTY режимин VCO кылууну суранды"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"Жөндөөлөр"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"Жардам"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Үн жардамчысы"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"Бекем кулпулоо"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"Жаңы эскертме"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Виртуалдык баскычтоп"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"Кыйытма: Чоңойтуп-кичирейтиш үчүн эки жолу басыңыз."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Авто-толтуруу"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Автотолтурууну тууралоо"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"Автотолтуруу"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Колдонмолорду иштетип баштоо"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Жүктөө аякталууда."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> иштеп жатат"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Колдонмого которулуу үчүн таптап коюңуз"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Колдонмолор которуштурулсунбу?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Жаңы колдонмону иштетээрден мурун, учурда иштеп жатканын өчүрүшүңүз керек."</string>
-    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g> колдонмосуна кайтуу"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Жаңы колдонмо башталбасын"</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> колдонмосун жүргүзүү"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Эски колдонмону сактабастан токтотуу."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> эстутум чегинен ашып кетти"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Үймө дамп топтолду; бөлүшүү үчүн таптап коюңуз"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Үймө дамп бөлүшүлсүнбү?"</string>
@@ -1201,12 +1203,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"SIM-карта кошулду"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"Мобилдик түйүнкгө жетки алуу үчүн, түзмөгүңүздү өчүрүп кайра жандырыңыз."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Кайра баштоо"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"Мобилдик кызматты жандыруу"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Жаңы SIM-картаны жандыруу үчүн байланыш операторунун колдонмосун жүктөп алыңыз"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"Колдонмону жүктөп алуу"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"Жаңы SIM карта салынды"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"Аны жөндөө үчүн таптап коюңуз"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Убакытты коюу"</string>
diff --git a/core/res/res/values-land/dimens.xml b/core/res/res/values-land/dimens.xml
index 4f0c0fb..265eaaf 100644
--- a/core/res/res/values-land/dimens.xml
+++ b/core/res/res/values-land/dimens.xml
@@ -27,6 +27,9 @@
     <dimen name="password_keyboard_spacebar_vertical_correction">2dip</dimen>
     <dimen name="preference_widget_width">72dp</dimen>
 
+    <!-- Height of the status bar -->
+    <dimen name="status_bar_height">@dimen/status_bar_height_landscape</dimen>
+
     <!-- Default height of an action bar. -->
     <dimen name="action_bar_default_height">40dip</dimen>
     <!-- Vertical padding around action bar icons. -->
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index c75b1ff..86c317d 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"ກຳລັງເປີດແອັບຯ."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"ກຳລັງສຳເລັດການເປີດລະບົບ."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> ກຳລັງເຮັດວຽກ"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"ແຕະເພື່ອສະລັບໄປຫາແອັບ"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"ສະລັບແອັບຯບໍ່?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"ທ່ານຈະຕ້ອງຢຸດນຳໃຊ້ແອັບຯໂຕອື່ນກ່ອນ ກ່ອນທີ່ທ່ານຈະເປີດໃຊ້ແອັບຯໃໝ່ໄດ້."</string>
-    <string name="old_app_action" msgid="493129172238566282">"ກັບໄປ <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"ຫ້າມເປີດແອັບຯໃໝ່."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"ເລີ່ມຕົ້ນ <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"ຢຸດແອັບຯເກົ່າໂດຍບໍ່ຕ້ອງບັນທຶກ."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ເກີນ​ຂີດ​ຄວາມ​ຈຳ​ແລ້ວ"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"ເກັບກຳຂໍ້ມູນ Head dump ແລ້ວ; ແຕະເພື່ອແບ່ງປັນ"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"ແບ່ງ​ປັນ​ການ​ເທກອງ​ບໍ?"</string>
@@ -1832,7 +1837,7 @@
     <string name="harmful_app_warning_title" msgid="8982527462829423432">"ກວດສອບແອັບທີ່ເປັນອັນຕະລາຍ"</string>
     <string name="slices_permission_request" msgid="8484943441501672932">"<xliff:g id="APP_0">%1$s</xliff:g> ຕ້ອງການສະແດງ <xliff:g id="APP_2">%2$s</xliff:g> ສະໄລ້"</string>
     <string name="screenshot_edit" msgid="7867478911006447565">"ແກ້ໄຂ"</string>
-    <string name="notification_channel_system_changes" msgid="5072715579030948646">"System changes"</string>
-    <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"Do Not Disturb has changed"</string>
-    <string name="zen_upgrade_notification_content" msgid="6603123479476554768">"Tap to check your behavior settings for interruptions"</string>
+    <string name="notification_channel_system_changes" msgid="5072715579030948646">"ການປ່ຽນແປງລະບົບ"</string>
+    <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"ປ່ຽນໂໝດຫ້າມລົບກວນແລ້ວ"</string>
+    <string name="zen_upgrade_notification_content" msgid="6603123479476554768">"ແຕະເພື່ອກວດສອບການຕັ້ງຄ່າພຶດຕິກຳສຳລັບການລົບກວນ"</string>
 </resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 72ef6ffe..d419a2d 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1125,13 +1125,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Paleidžiamos programos."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Užbaigiamas paleidimas."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"Vykdoma „<xliff:g id="APP">%1$s</xliff:g>“"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Palieskite, kad perjungtumėte į programą"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Perjungti programas?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Jau vykdoma kita programa, kurią reikia sustabdyti prieš paleidžiant naują."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Grįžti į <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Nepaleiskite naujos programos."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Paleisti „<xliff:g id="OLD_APP">%1$s</xliff:g>“"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Sustabdyti seną programą jos neišsaugant."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"„<xliff:g id="PROC">%1$s</xliff:g>“ viršijo atminties limitą"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Atminties išklotinės duomenys surinkti; palieskite, kad bendrintumėte"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Bendrinti atminties išklotinę?"</string>
@@ -1902,10 +1907,7 @@
     <string name="harmful_app_warning_title" msgid="8982527462829423432">"Aptikta žalinga programa"</string>
     <string name="slices_permission_request" msgid="8484943441501672932">"„<xliff:g id="APP_0">%1$s</xliff:g>“ nori rodyti „<xliff:g id="APP_2">%2$s</xliff:g>“ fragmentus"</string>
     <string name="screenshot_edit" msgid="7867478911006447565">"Redaguoti"</string>
-    <!-- no translation found for notification_channel_system_changes (5072715579030948646) -->
-    <skip />
-    <!-- no translation found for zen_upgrade_notification_title (3799603322910377294) -->
-    <skip />
-    <!-- no translation found for zen_upgrade_notification_content (6603123479476554768) -->
-    <skip />
+    <string name="notification_channel_system_changes" msgid="5072715579030948646">"Sistemos pakeitimai"</string>
+    <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"Netrukdymo režimas pakeistas"</string>
+    <string name="zen_upgrade_notification_content" msgid="6603123479476554768">"Palieskite, kad patikrintumėte pertraukčių elgsenos nustatymus"</string>
 </resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index d63558f..696fce6 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -94,8 +94,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"Īsziņas"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Balss pasta ziņojumi"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi zvani"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"SIM kartes statuss"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"Vienādranga ierīce pieprasīja teksta tālruņa režīmu FULL"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"Vienādranga ierīce pieprasīja teksta tālruņa režīmu HCO"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"Vienādranga ierīce pieprasīja teksta tālruņa režīmu VCO"</string>
@@ -243,8 +242,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"Iestatījumi"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"Palīdzība"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Balss palīgs"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"Bloķēšana"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"Pārsniedz"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"Jauns paziņojums"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuālā tastatūra"</string>
@@ -831,8 +829,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"Padoms. Divreiz pieskarieties, lai tuvinātu un tālinātu."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Automātiskā aizpilde"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Iest. aut. aizp."</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"Automātiskā aizpilde"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1108,13 +1105,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Notiek lietotņu palaišana."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Tiek pabeigta sāknēšana."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> darbojas"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Pieskarieties, lai pārslēgtos uz lietotni."</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Vai pārslēgt lietotnes?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Jau darbojas cita lietotne. Tās darbība ir jāaptur, lai varētu startēt jaunu lietotni."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Atgriezties: <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Nestartējiet jauno lietotni."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Startēt: <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Aptur vecās lietotnes darbību, neko nesaglabājot."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"Process <xliff:g id="PROC">%1$s</xliff:g> pārsniedza atmiņas ierobežojumu."</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Tika apkopots kaudzes izraksts. Pieskarieties, lai to kopīgotu."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Vai kopīgot kaudzes izrakstu?"</string>
@@ -1222,12 +1224,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"SIM karte ir pievienota."</string>
     <string name="sim_added_message" msgid="6599945301141050216">"Ierīces restartēšana, lai piekļūtu mobilo sakaru tīklam."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Restartēt"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"Aktivizējiet mobilo ierīci."</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Lejupielādējiet mobilo sakaru operatora lietotni, lai aktivizētu jauno SIM karti."</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"Lejupielādēt lietotni"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"Ievietota jauna SIM karte"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"Pieskarieties, lai to iestatītu."</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Iestatīt laiku"</string>
@@ -1873,10 +1872,7 @@
     <string name="harmful_app_warning_title" msgid="8982527462829423432">"Konstatēta kaitīga lietotne"</string>
     <string name="slices_permission_request" msgid="8484943441501672932">"Lietotne <xliff:g id="APP_0">%1$s</xliff:g> vēlas rādīt lietotnes <xliff:g id="APP_2">%2$s</xliff:g> sadaļas"</string>
     <string name="screenshot_edit" msgid="7867478911006447565">"Rediģēt"</string>
-    <!-- no translation found for notification_channel_system_changes (5072715579030948646) -->
-    <skip />
-    <!-- no translation found for zen_upgrade_notification_title (3799603322910377294) -->
-    <skip />
-    <!-- no translation found for zen_upgrade_notification_content (6603123479476554768) -->
-    <skip />
+    <string name="notification_channel_system_changes" msgid="5072715579030948646">"Sistēmas izmaiņas"</string>
+    <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"Režīms “Netraucēt” ir mainīts"</string>
+    <string name="zen_upgrade_notification_content" msgid="6603123479476554768">"Pieskarieties, lai pārbaudītu rīcības iestatījumu paziņojumus"</string>
 </resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 8bfe424..2bd910f 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS-пораки"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Пораки од говорна пошта"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"Повикување преку Wi-Fi"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"Статус на SIM-картичка"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"Рамноправен уред го побара режимот на TTY „FULL“"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"Рамноправен уред го побара режимот на TTY „HCO“"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"Рамноправен уред го побара режимот на TTY „VCO“"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"Поставки"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"Асистенција"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Гласовна помош"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"Заклучување"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"Ново известување"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Виртуелна тастатура"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"Совет: допри двапати за да зумираш и да одзумираш."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Автоматско пополнување"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Постави „Автоматско пополнување“"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"Автоматско пополнување"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Се стартуваат апликациите."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Подигањето завршува."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> работи"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Допрете за да се префрли на апликација"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Промени апликации?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Веќе работи една апликација што треба да ја запрете пред да стартувате нова."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Врати се на <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Не стартувајте ја новата апликација."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Вклучи <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Запрете ја старата апликација без зачувување."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> го надмина ограничувањето на меморијата"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Сликата од меморијата е собрана. Допрете за споделување"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Сподели слика од меморија?"</string>
@@ -1201,12 +1203,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"Додадена е SIM картичка"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"Рестартирај го својот уред за да пристапиш на мобилната мрежа."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Рестартирај"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"Активирајте мобилна услуга"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Преземете ја апликацијата на операторот за да ја активирате новата SIM-картичка"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"Преземете апликација"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"Вметната е нова SIM-картичка"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"Допрете за да поставите"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Постави време"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index c0bc727..340d7f9 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS സന്ദേശങ്ങൾ"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"വോയ്‌സ്‌മെയിൽ സന്ദേശങ്ങൾ"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"വൈഫൈ കോളിംഗ്"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"സിം നില"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"പിയർ അഭ്യർത്ഥിച്ച TTY മോഡ് \'ഫുൾ\'"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"പിയർ അഭ്യർത്ഥിച്ച TTY മോഡ് HCO"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"പിയർ അഭ്യർത്ഥിച്ച TTY മോഡ് VCO"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"ക്രമീകരണം"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"അസിസ്റ്റ്"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"വോയ്‌സ് സഹായം"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"ലോക്ക്‌ഡൗൺ"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"പുതിയ അറിയിപ്പ്"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"വെർച്വൽ കീബോർഡ്"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"നുറുങ്ങ്: സൂം ഇൻ ചെയ്യാനും സൂം ഔട്ട് ചെയ്യാനും ഇരട്ട-ടാപ്പുചെയ്യുക."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"ഓട്ടോഫിൽ"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"ഓട്ടോഫിൽ സജ്ജീകരിക്കുക"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"സ്വമേധയാ പൂരിപ്പിക്കൽ"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"അപ്ലിക്കേഷനുകൾ ആരംഭിക്കുന്നു."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"ബൂട്ട് ചെയ്യൽ പൂർത്തിയാകുന്നു."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> പ്രവർത്തിക്കുന്നു"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"ആപ്പിലേക്ക് മാറുന്നതിന് ടാപ്പുചെയ്യുക"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"അപ്ലിക്കേഷനുകൾ മാറണോ?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"നിങ്ങൾക്ക് പുതിയ ഒരു അപ്ലിക്കേഷൻ ആരംഭിക്കാനാവുന്നതിന് മുമ്പ്, ഇതിനകം പ്രവർത്തിക്കുന്ന മറ്റ് അപ്ലിക്കേഷൻ നിർത്തണം."</string>
-    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g> എന്നതിലേക്ക് മടങ്ങുക"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"പുതിയ അപ്ലിക്കേഷൻ ആരംഭിക്കരുത്."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> ആരംഭിക്കുക"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"സംരക്ഷിക്കാതെ തന്നെ പഴയ അപ്ലിക്കേഷൻ നിർത്തുക."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> മെമ്മറി പരിധി കവിഞ്ഞു"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"ഹീപ്പ് ഡംപ് ശേഖരിച്ചു; പങ്കിടാൻ ടാപ്പുചെയ്യുക"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"ഹീപ്പ് ഡംപ് പങ്കിടണോ?"</string>
@@ -1201,12 +1203,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"സിം കാർഡ് ചേർത്തു"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"മൊബൈൽ നെറ്റ്‌വർക്ക് ആക്‌സസ്സുചെയ്യാൻ നിങ്ങളുടെ ഉപകരണം പുനരാരംഭിക്കുക."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"പുനരാരംഭിക്കുക"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"മൊബൈൽ സേവനം സജീവമാക്കുക"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"പുതിയ സിം സജീവമാക്കാൻ കാരിയർ ആപ്പ് ഡൗൺലോഡ് ചെയ്യുക"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"ആപ്പ് ഡൗൺലോഡ് ചെയ്യുക"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"പുതിയ സിം ഇട്ടു"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"ഇത് സജ്ജമാക്കുന്നതിന് ടാപ്പുചെയ്യുക"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"സമയം സജ്ജീകരിക്കുക"</string>
@@ -1841,5 +1840,5 @@
     <string name="screenshot_edit" msgid="7867478911006447565">"എഡിറ്റ് ചെയ്യുക"</string>
     <string name="notification_channel_system_changes" msgid="5072715579030948646">"സിസ്‌റ്റത്തിലെ മാറ്റങ്ങൾ"</string>
     <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"\'ശല്യപ്പെടുത്തരുത്\' മാറ്റി"</string>
-    <string name="zen_upgrade_notification_content" msgid="6603123479476554768">"തടസ്സങ്ങൾക്കായുള്ള പ്രവർത്തന ക്രമീകരണം പരിശോധിക്കാൻ ടാപ്പ് ചെയ്യുക"</string>
+    <string name="zen_upgrade_notification_content" msgid="6603123479476554768">"തടസ്സങ്ങൾക്കായി ക്രമീകരിച്ചിട്ടുള്ളത് എന്താണെന്ന് പരിശോധിക്കാൻ ടാപ്പ് ചെയ്യുക"</string>
 </resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 5d6a1eb..a5e6860 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Апп-г эхлүүлж байна."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Эхлэлийг дуусгаж байна."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> ажиллаж байна"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Апп руу шилжүүлэх бол товшино уу"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Апп сэлгэх үү?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Та шинэ апп-г ажиллуулахын өмнө зогсоох ёстой өөр апп ажиллаж байна."</string>
-    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g>-руу буцах"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Шинэ апп-г эхлүүлж болохгүй."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> эхлүүлэх"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Хуучин апп-г хадгалахгүйгээр зогсооно уу."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> санах ойн хязгаараас давсан"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Хэт их мэдээлэл цуглуулсан байна. Хуваалцахын тулд товшино уу"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Хэт их хуримтлагдсан мэдээллийг хуваалцах уу?"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index a7d07f6..00eb8fd 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS संदेश"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"व्हॉइसमेल संदेश"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"वाय-फाय कॉलिंग"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"सिम स्थिती"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"समवयस्क व्यक्तीने TTY मोड पूर्ण ची विनंती केली"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"समवयस्क व्यक्तीने TTY मोड HCO ची विनंती केली"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"समवयस्क व्यक्तीने TTY मोड VCO ची विनंती केली"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"सेटिंग्ज"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"सहाय्यता"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"व्हॉइस सहाय्य"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"लॉकडाउन"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"नवीन सूचना"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"व्हर्च्युअल कीबोर्ड"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"टीप: झूम कमी करण्यासाठी आणि वाढवण्यासाठी दोनदा-टॅप करा."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"स्वयं-भरण"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"स्वयं-भरण सेट करा"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"अॉटोफिल"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"अॅप्स प्रारंभ करत आहे."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"बूट समाप्त होत आहे."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> चालत आहे"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"अॅपवर स्विच करण्यासाठी टॅप करा"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"अॅप्स स्विच करायचे?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"आपण एक नवीन प्रारंभ करण्यापूर्वी आधीपासून चालणारा दुसरा अॅप थांबविणे आवश्यक आहे."</string>
-    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g> कडे परत"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"नवीन अॅप प्रारंभ करू नका."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> सुरू करा"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"जतन न करता जुना अॅप थांबवा."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ने मेमेरी मर्यादा वाढविली"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"हीप डंप संकलित केला गेला आहे; सामायिक करण्यासाठी टॅप करा"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"हीप डंप सामायिक करायचे?"</string>
@@ -1201,12 +1203,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"सिम कार्ड जोडले"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"मोबाईल नेटवर्कवर अॅक्सेस करण्यासाठी तुमचे डिव्हाइस रीस्टार्ट करा."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"रीस्टार्ट"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"मोबाइल सेवा अ‍ॅक्टिव्हेट करा"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"तुमचे नवीन सिम अ‍ॅक्टिव्हेट करण्यासाठी वाहकाचे अ‍ॅप डाउनलोड करा"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"अ‍ॅप डाउनलोड करा"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"नवीन सिम घाला"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"ते सेट करण्यासाठी टॅप करा"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"वेळ सेट करा"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 5536229..5108c91 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"Mesej SMS"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Mesej mel suara"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"Panggilan Wi-Fi"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"Status SIM"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"Rakan meminta Mod TTY PENUH"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"Rakan meminta Mod TTY HCO"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"Rakan meminta Mod TTY VCO"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"Tetapan"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"Bantu"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Bantuan Suara"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"Kunci semua"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"Pemberitahuan baharu"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Papan kekunci maya"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"Petua: Ketik dua kali untuk mengezum masuk dan keluar."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Auto isi"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Sediakan Autoisi"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"Autolengkap"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Memulakan apl."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"But akhir."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> dijalankan"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Ketik untuk beralih ke apl"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Tukar apl?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Apl lain sudah pun dijalankan yang mesti dihentikan sebelum anda boleh memulakan yang baharu."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Kembali ke <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Jangan mulakan apl baharu."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Mulakan <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Hentikan apl lama tanpa menyimpan."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> melebihi had memori"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Longgokan timbunan telah dikumpulkan; ketik untuk berkongsi"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Kongsikan longgokan timbunan?"</string>
@@ -1200,12 +1202,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"Kad SIM ditambah"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"Mulakan semula peranti anda untuk mengakses rangkaian mudah alih."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Mulakan semula"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"Aktifkan perkhidmatan mudah alih"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Muat turun apl pembawa untuk mengaktifkan SIM baharu"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"Muat turun apl"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"SIM baharu dimasukkan"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"Ketik untuk menyediakannya"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Tetapkan masa"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 77b83cc..176ecff 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -93,7 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS မက်ဆေ့ဂျ်များ"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"အသံမေးလ် မက်ဆေ့ဂျ်များ"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi ခေါ်ဆိုမှု"</string>
-    <string name="notification_channel_sim" msgid="4052095493875188564">"ဆင်းမ် အခြေအနေ"</string>
+    <string name="notification_channel_sim" msgid="4052095493875188564">"ဆင်းမ်ကဒ် အခြေအနေ"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"အခြားစက်မှ TTY မုဒ် FULL ပြုရန် တောင်းဆို၏"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"အခြားစက်မှ TTY မုဒ် HCO ပြုရန် တောင်းဆို၏"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"TTY မုဒ် VCO ပြုရန် အခြားစက်မှ တောင်းဆို၏"</string>
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"အက်ပ်များကို စတင်နေ"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"လုပ်ငန်းစနစ်ထည့်သွင်း၍ ပြန်လည်စတင်ရန် ပြီးပါပြီ"</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> က အလုပ်လုပ်နေသည်"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"အက်ပ်သို့ပြောင်းရန် တို့ပါ"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"အက်ပ်များကို ပြောင်းမလား?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"အခြား အက်ပ်တစ်ခု အလုပ်လုပ်နေ၍ သင်က အသစ် တစ်ခုကို မစမီ ၎င်းကို ရပ်ပစ်ရမည်။"</string>
-    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g>သို့ပြန်သွားရန်"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"pp အသစ်ကို မစတင်ပါနှင့်။"</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g>စတင်ပါ"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"အက်ပ်အဟောင်းကို မသိမ်းဆည်းဘဲ ရပ်လိုက်ပါ။"</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> သိမ်းထားနိုင်မှု အကန့်အသတ် ကျော်လွန်နေ"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"သိမ်းဆည်းနိုင်မှု ပမာဏကျော်လွန်သွားပါပြီ။ မျှဝေရန် တို့ပါ"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"အရေးပေါ် သိမ်းထားပေးမှု ကို မျှဝေမလား။"</string>
@@ -1199,7 +1204,7 @@
     <string name="sim_added_message" msgid="6599945301141050216">"မိုးဘိုင်းကွန်ရက်ကို ဆက်သွယ်ရန် စက်ကို ပြန် စ ပါ"</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"အစက ပြန်စရန်"</string>
     <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"မိုဘိုင်းဝန်ဆောင်မှု စတင်ဖွင့်လှစ်ရန်"</string>
-    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"သင့်ဆင်းမ် အသစ်ကို စတင်အသုံးပြုရန် ဝန်ဆောင်မှုပေးသူအက်ပ်ကို ဒေါင်းလုဒ်လုပ်ပါ"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"သင့်ဆင်းမ်ကဒ်အသစ်ကို စတင်အသုံးပြုရန် ဝန်ဆောင်မှုပေးသူအက်ပ်ကို ဒေါင်းလုဒ်လုပ်ပါ"</string>
     <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"အက်ပ် ဒေါင်းလုဒ်လုပ်ရန်"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"SIM အသစ်ထည့်သွင်းလိုက်ပါသည်"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"၎င်းကိုတပ်ဆင်ရန် တို့ပါ"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 59b4ffa..b1a254f 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS-meldinger"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Talepostmeldinger"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi-anrop"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"SIM-status"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"Motpart ba om TTY-modus FULL"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"Motpart ba om TTY-modus HCO"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"Motpart ba om TTY-modus VCO"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"Innstillinger"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"Hjelp"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Talehjelp"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"Låsing"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"Nytt varsel"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuelt tastatur"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"Tips: Dobbelttrykk for å zoome inn og ut."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Autofyll"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Konfig. autofyll"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"Autofyll"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Starter apper."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Ferdigstiller oppstart."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> kjører"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Trykk for å bytte til appen"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Vil du bytte app?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"En annen app kjører og må stoppes før du kan starte en ny app."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Gå tilbake til <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Ikke start den nye appen."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Start <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Stopp den gamle appen uten å lagre."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> er over minnegrensen"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Minnedumpen («heap dump») er samlet inn – trykk for å dele"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Vil du dele minnedumpen («heap dump»)?"</string>
@@ -1200,12 +1202,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"SIM-kort er lagt til"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"Start enheten på nytt for å få tilgang til det mobile nettverket."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Start på nytt"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"Aktiver mobiltjeneste"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Last ned operatørappen for å aktivere det nye SIM-kortet ditt"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"Last ned appen"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"Et nytt SIM-kort er satt inn"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"Trykk for å konfigurere"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Stille klokken"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 7685084..1eb0028 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS सन्देशहरू"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"भ्वाइस मेल सन्देशहरू"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi कल"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"SIM को स्थिति"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"सहकर्मी अनुरोध गरियो। TTY मोड पूर्ण"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"सहकर्मी अनुरोध गरियो। TTY मोड HCO"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"सहकर्मी अनुरोध गरियो। TTY मोड VCO"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"सेटिङहरू"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"सहायता दिनुहोस्"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"आवाज सहायता"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"लकडाउन गर्नु…"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"९९९+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"नयाँ सूचना"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"भर्चुअल किबोर्ड"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"जुक्ति: जुमलाई ठूलो र सानो पार्न दुई पटक हान्नुहोस्।"</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"स्वतः भर्ने"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"अटोफिल सेटअप गर्नुहोस्"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"स्वतः भरण"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$१$२$३"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1094,13 +1091,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"सुरुवात अनुप्रयोगहरू।"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"बुट पुरा हुँदै।"</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> चलिरहेको छ"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"अनुप्रयोगमा स्विच गर्न ट्याप गर्नुहोस्"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"अनुप्रयोगहरू स्विच गर्ने हो?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"अर्को अनुप्रयोग पहिले नै चालु छ जुन तपाईंले एउटा नयाँ सुरु गर्नु अघि बन्द गर्नुपर्ने हुन्छ।"</string>
-    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g> मा फर्कनुहोस्"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"नयाँ अनुप्रयोग सुरु नगर्नुहोस्।"</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> सुरु गर्नुहोस्"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"बचत नगरी पुरानो अनुप्रयोग रोक्नुहोस्।"</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ले मेमोरी सीमा नाघ्यो"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"हिप डम्पलाई संग्रह गरिएको छ, साझेदारी गर्न छुनुहोस्"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"हिप डम्प साझेदारी गर्नुहुन्छ?"</string>
@@ -1206,12 +1208,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"SIM कार्ड थप गरियो"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"मोबाइल नेटवर्क पहुँच गर्न तपाईँको उपकरण पुनःस्टार्ट गर्नुहोस्।"</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"पुनः सुरु गर्नुहोस्"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"मोबाइल सेवा सक्रिय गर्नुहोस्"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"आफ्नो नयाँ SIM सक्रिय गर्न सेवा प्रदायकको अनुप्रयोग डाउनलोड गर्नुहोस्"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"अनुप्रयोग डाउनलोड गर्नुहोस्"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"नयाँ SIM घुसाइयो"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"यसलाई सेटअप गर्न ट्याप गर्नुहोस्"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"समय मिलाउनुहोस्"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 87be867..c0965e5 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Apps starten."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Opstarten afronden."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> wordt uitgevoerd"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Tik om over te schakelen naar de app"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Schakelen tussen apps?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Er wordt al een andere app uitgevoerd die moet worden gestopt voordat u een nieuwe app kunt starten."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Terug naar <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"De nieuwe app niet starten."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> starten"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"De oude app stoppen zonder opslaan."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> heeft geheugenlimiet overschreden"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Heap dump is verzameld. Tik om te delen."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Heap dump delen?"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index c4f068b..5672d48 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS ਸੁਨੇਹੇ"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"ਵੌਇਸਮੇਲ ਸੁਨੇਹੇ"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"ਵਾਈ-ਫਾਈ ਕਾਲਿੰਗ"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"ਸਿਮ ਅਵਸਥਾ"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"ਪੀਅਰ ਨੇ TTY Mode FULL ਦੀ ਬੇਨਤੀ ਕੀਤੀ"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"ਪੀਅਰ ਨੇ TTY Mode HCO ਦੀ ਬੇਨਤੀ ਕੀਤੀ"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"ਪੀਅਰ ਨੇ TTY Mode VCO ਦੀ ਬੇਨਤੀ ਕੀਤੀ"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"ਸੈਟਿੰਗਾਂ"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"ਸਹਾਇਤਾ ਕਰੋ"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ਅਵਾਜ਼ੀ ਸਹਾਇਕ"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"ਲਾਕਡਾਊਨ"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"ਨਵੀਂ ਸੂਚਨਾ"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ਆਭਾਸੀ ਕੀ-ਬੋਰਡ"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"ਨੁਕਤਾ: ਜ਼ੂਮ ਵਧਾਉਣ ਅਤੇ ਘਟਾਉਣ ਲਈ ਡਬਲ ਟੈਪ ਕਰੋ।"</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"ਆਟੋਫਿਲ"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"ਆਟੋਫਿਲ ਸੈਟ ਅਪ ਕਰੋ"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"ਆਟੋਫਿਲ"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"ਐਪਸ ਚਾਲੂ ਕਰ ਰਿਹਾ ਹੈ।"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"ਬੂਟ ਪੂਰਾ ਕਰ ਰਿਹਾ ਹੈ।"</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> ਚੱਲ ਰਿਹਾ ਹੈ"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"ਵਾਪਸ ਐਪ \'ਤੇ ਸਵਿੱਚ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"ਕੀ ਐਪਾਂ \'ਤੇ ਸਵਿੱਚ ਕਰਨਾ ਹੈ?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"ਦੂਜਾ ਐਪ ਪਹਿਲਾਂ ਹੀ ਚੱਲ ਰਿਹਾ ਹੈ, ਜਿਸਨੂੰ ਤੁਹਾਡੇ ਵੱਲੋਂ ਇੱਕ ਨਵਾਂ ਐਪ ਚਾਲੂ ਕਰ ਸਕਣ ਤੋਂ ਪਹਿਲਾਂ ਹੀ ਰੋਕਿਆ ਜਾਣਾ ਚਾਹੀਦਾ ਹੈ।"</string>
-    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g> ਤੇ ਵਾਪਸ ਜਾਓ"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"ਨਵਾਂ ਐਪ ਚਾਲੂ ਨਾ ਕਰੋ।"</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"ਸੁਰੱਖਿਅਤ ਕੀਤੇ ਬਿਨਾਂ ਪੁਰਾਣਾ ਐਪ ਬੰਦ ਕਰੋ।"</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ਦੀ ਮੈਮਰੀ ਸੀਮਾ ਵਧ ਗਈ ਹੈ"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"ਹੀਪ ਡੰਪ ਇਕੱਤਰ ਕੀਤਾ ਗਿਆ; ਸਾਂਝਾ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"ਕੀ ਹੀਪ ਡੰਪ ਸ਼ੇਅਰ ਕਰਨਾ ਹੈ?"</string>
@@ -1201,12 +1203,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"SIM ਕਾਰਡ ਜੋੜਿਆ ਗਿਆ"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਤੱਕ ਪਹੁੰਚ ਲਈ ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਮੁੜ-ਚਾਲੂ ਕਰੋ।"</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"ਰੀਸਟਾਰਟ ਕਰੋ"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"ਮੋਬਾਈਲ ਸੇਵਾ ਕਿਰਿਆਸ਼ੀਲ ਕਰੋ"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"ਆਪਣੇ ਨਵੇਂ ਸਿਮ ਨੂੰ ਕਿਰਿਆਸ਼ੀਲ ਕਰਨ ਲਈ ਕੈਰੀਅਰ ਐਪ ਡਾਊਨਲੋਡ ਕਰੋ"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"ਐਪ ਡਾਊਨਲੋਡ ਕਰੋ"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"ਨਵੀਂ SIM ਦਾਖਲ ਕੀਤੀ ਗਈ"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"ਇਸ ਨੂੰ ਸੈੱਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"ਸਮਾਂ ਸੈੱਟ ਕਰੋ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index f7ba675..2172aae 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1125,13 +1125,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Uruchamianie aplikacji."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Kończenie uruchamiania."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"Działa <xliff:g id="APP">%1$s</xliff:g>"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Kliknij, by przełączyć na aplikację"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Czy przełączyć aplikacje?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Działa już inna aplikacja, którą trzeba zatrzymać, aby możliwe było uruchomienie nowej."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Powrót do aplikacji <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Nie uruchamiaj nowej aplikacji."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Uruchom <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Zatrzymaj starą aplikację bez zapisywania."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"Proces <xliff:g id="PROC">%1$s</xliff:g> przekroczył limit pamięci"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Pobrano zrzut sterty – kliknij, by go udostępnić"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Udostępnić zrzut stosu?"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 4c88bc6..45512a5 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Iniciando apps."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Concluindo a inicialização."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> em execução"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Toque para alternar para o app"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Alternar entre apps?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Outro app já está em execução e deve ser interrompido antes que você inicie um novo app."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Voltar para <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Não inicie o novo app."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Iniciar <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Parar o app antigo sem salvar."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> excedeu o limite de memória"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"O despejo de heap foi coletado. Toque para compartilhar"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Compartilhar despejo de heap?"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index c9e0a60..a3c8087 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"A iniciar aplicações"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"A concluir o arranque."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> em execução"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Toque para mudar para a aplicação"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Mudar de aplicação?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Já está em execução outra aplicação, que terá de ser parada para que possa iniciar uma nova."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Regressar a <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Não iniciar a nova aplicação."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Iniciar <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Parar a aplicação antiga sem guardar."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> excedeu o limite da memória"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Foi recolhida a captura da área dinâmica para dados. Toque para partilhar."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Pretende partilhar a captura da área dinâmica para dados?"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 4c88bc6..45512a5 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Iniciando apps."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Concluindo a inicialização."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> em execução"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Toque para alternar para o app"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Alternar entre apps?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Outro app já está em execução e deve ser interrompido antes que você inicie um novo app."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Voltar para <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Não inicie o novo app."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Iniciar <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Parar o app antigo sem salvar."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> excedeu o limite de memória"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"O despejo de heap foi coletado. Toque para compartilhar"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Compartilhar despejo de heap?"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 792e7e2..0e25356 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1105,13 +1105,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Se pornesc aplicațiile."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Se finalizează pornirea."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"Rulează <xliff:g id="APP">%1$s</xliff:g>"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Atingeți ca să comutați la aplicație"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Comutați între aplicații?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"O altă aplicație rulează deja și trebuie oprită înainte a putea porni o aplicație nouă."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Reveniți la <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Nu porniți aplicația nouă."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Porniți <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Opriți vechea aplicație fără să salvați."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> a depășit limita de memorie"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Datele privind memoria au fost culese; atingeți pentru a trimite"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Trimiteți datele privind memoria?"</string>
@@ -1867,7 +1872,7 @@
     <string name="harmful_app_warning_title" msgid="8982527462829423432">"Aplicație dăunătoare detectată"</string>
     <string name="slices_permission_request" msgid="8484943441501672932">"<xliff:g id="APP_0">%1$s</xliff:g> vrea să afișeze porțiuni din <xliff:g id="APP_2">%2$s</xliff:g>"</string>
     <string name="screenshot_edit" msgid="7867478911006447565">"Editați"</string>
-    <string name="notification_channel_system_changes" msgid="5072715579030948646">"Modificări ale Sistem"</string>
+    <string name="notification_channel_system_changes" msgid="5072715579030948646">"Modificări de sistem"</string>
     <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"Funcția Nu deranja s-a schimbat"</string>
     <string name="zen_upgrade_notification_content" msgid="6603123479476554768">"Atingeți pentru a verifica setările de comportament pentru întreruperi"</string>
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 0689833..bea3f8b 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1125,13 +1125,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Запуск приложений."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Окончание загрузки..."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"Приложение <xliff:g id="APP">%1$s</xliff:g> запущено"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Нажмите, чтобы перейти в приложение."</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Переключение приложений"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Выполняется другое приложение, которое необходимо остановить перед запуском нового."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Вернуться к приложению <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Не запускать новое приложение."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Запустить приложение <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Остановить старое приложение без сохранения изменений."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"Объем памяти процесса \"<xliff:g id="PROC">%1$s</xliff:g>\" превышен"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Создан дамп кучи. Нажмите, чтобы отправить его."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Отправить дамп кучи?"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 5db0730..7106d9d 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1087,13 +1087,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"යෙදුම් ආරම්භ කරමින්."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"ඇරඹුම අවසාන කරමින්."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> ධාවනය වෙමින්"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"යෙදුමට මාරු වීමට තට්ටු කරන්න"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"යෙදුම් මාරු වනවාද?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"අලුත් යෙදුමක් ආරම්භ කිරීමට පෙර තවමත් ක්‍රියාවෙහි යෙදෙමින් පවතින යෙදුම නැවැත්විය යුතුයි."</string>
-    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g> වෙත ආපසු යන්න"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"නව යෙදුම ආරම්භ නොකරන්න."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> අරඹන්න"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"සුරැකීමකින් තොරව පරණ යෙදුම නවත්වන්න."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> මතකයේ සීමාව ඉක්මවා ඇත"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"ඉවත දැමීම් ගොඩ රැස් කර ඇත. බෙදා ගැනීමට තට්ටු කරන්න"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"සංච නික්ෂේපය බෙදාගන්න ද?"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 4f7f599..8317c75 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1125,13 +1125,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Prebieha spúšťanie aplikácií."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Prebieha dokončovanie spúšťania."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"Spustená aplikácia: <xliff:g id="APP">%1$s</xliff:g>"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Klepnutím prepnite na aplikáciu"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Prepnúť aplikácie?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Pred spustením novej aplikácie treba zastaviť inú spustenú aplikáciu."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Návrat k <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Nespúšťať novú aplikáciu."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Spustiť <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Zastaviť starú aplikáciu bez uloženia."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"Proces <xliff:g id="PROC">%1$s</xliff:g> prekročil limit pamäte"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Boli zhromaždené zálohy údajov; zdieľajte ich klepnutím"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Chcete zdieľať zálohy údajov?"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index dacff53..7642544 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -95,8 +95,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"Sporočila SMS"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Sporočila v odzivniku"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"Klicanje prek Wi-Fi-ja"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"Stanje kartice SIM"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"Enakovredna naprava je zahtevala način TTY FULL"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"Enakovredna naprava je zahtevala način TTY HCO"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"Enakovredna naprava je zahtevala način TTY VCO"</string>
@@ -246,8 +245,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"Nastavitve"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"Pomoč"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Glas. pomočnik"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"Zakleni"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999 +"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"Novo obvestilo"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Navidezna tipkovnica"</string>
@@ -834,8 +832,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"Nasvet: Tapnite dvakrat, če želite povečati ali pomanjšati."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Samoizp."</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Nastavi samoizp."</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"Samodejno izpolnjevanje"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1128,13 +1125,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Zagon aplikacij."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Dokončevanje zagona."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> se izvaja"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Dotaknite se, če želite preklopiti na aplikacijo"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Želite preklopiti aplikacije?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Preden zaženete novo aplikacijo, ustavite izvajano."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Vrni se na <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Ne zaženite nove aplikacije."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Začni <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Ustavi prejšnjo aplikacijo brez shranjevanja."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"Proces <xliff:g id="PROC">%1$s</xliff:g> je presegel omejitev pomnilnika"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Izvoz kopice je zbran; dotaknite se za deljenje z drugimi"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Deljenje izvoza kopice z drugimi?"</string>
@@ -1244,12 +1246,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"Kartica SIM dodana"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"Za dostop do mobilnega omrežja znova zaženite napravo."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Vnovičen zagon"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"Aktivirajte mobilno storitev"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Prenesite aplikacijo operaterja, da boste lahko aktivirali novo kartico SIM"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"Prenos aplikacije"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"Nova kartica SIM je vstavljena"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"Dotaknite se za nastavitev"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Nastavi uro"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index f3b912d..a981222 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"Mesazhet SMS"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Mesazhet e postës zanore"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"Telefonata me Wi-Fi"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"Statusi i kartës SIM"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"Homologu yt kërkoi modalitet \"TTY\" të plotë"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"Homologu kërkoi modalitet \"TTY\" të llojit \"HCO\""</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"Homologu yt kërkoi modalitet \"TTY\" të llojit \"VCO\""</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"Cilësimet"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"Ndihma"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Ndihma zanore"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"Blloko"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"Njoftim i ri"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Tastiera virtuale"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"Këshillë! Trokit dy herë për të zmadhuar dhe zvogëluar."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Plotësim automatik"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Konfiguro plotësuesin automatik"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"Plotësim automatik"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Aplikacionet e fillimit."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Po përfundon nisjen."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> është në punë"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Trokit për të kaluar tek aplikacioni"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Të ndryshohen aplikacionet?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Një tjetër aplikacion është në punë dhe duhet ndaluar përpara se të nisësh një tjetër."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Kthehu në <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Mos e fillo aplikacion të ri."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Fillo <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Ndalo aplikacionin e vjetër pa e ruajtur."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> e ka kaluar kufirin e memories"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Stiva e skedarëve fiktivë është mbledhur; trokit për t\'i ndarë"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Të ndahet stiva e skedarëve fiktivë?"</string>
@@ -1201,12 +1203,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"Karta SIM u shtua"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"Rinise pajisjen për të pasur qasje në rrjetin celular."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Rifillo"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"Aktivizo shërbimin celular"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Shkarko aplikacionin e operatorit celular për të aktivizuar kartën e re SIM"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"Shkarko aplikacionin"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"Është futur kartë e re SIM"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"Trokit për ta konfiguruar"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Cakto kohën"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index ced2b51..aa5226b 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1105,13 +1105,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Покретање апликација."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Завршавање покретања."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"Апликација <xliff:g id="APP">%1$s</xliff:g> је покренута"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Додирните да бисте прешли на апликацију"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Желите ли да пређете на другу апликацију?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Већ је покренута друга апликација која мора да буде заустављена да бисте могли да покренете нову."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Врати се у <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Не покрећите нову апликацију."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Покрени <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Зауставља стару апликацију без чувања."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> премашује ограничење меморије"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Снимак динамичког дела меморије је направљен; додирните за дељење"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Желите ли да делите снимак динамичког дела меморије?"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index be9e3dd..e713c30 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"Sms"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Röstmeddelanden"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi-samtal"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"Status för SIM-kort"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"Peer-enheten begärde texttelefonläget FULL"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"Peer-enheten begärde texttelefonläget HCO"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"Peer-enheten begärde texttelefonläget VCO"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"Inställningar"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"Hjälp"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"Låsning"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"Ny avisering"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuellt tangentbord"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"Tips! Dubbelknacka om du vill zooma in eller ut."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Autofyll"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Ange Autofyll"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"Autofyll"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Appar startas."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Uppgraderingen är klar."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> körs"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Tryck om du vill byta till appen"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Vill du byta app?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"En annan app som körs måste avslutas innan du kan starta en ny."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Gå tillbaka till <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Starta inte den nya appen."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Starta <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Avbryt den gamla appen utan att spara."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"Minnesgränsen har överskridits för <xliff:g id="PROC">%1$s</xliff:g>"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"En minnesdump har skapats – tryck här om du vill dela den"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Vill du dela minnesdumpen?"</string>
@@ -1200,12 +1202,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"SIM-kort lades till"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"Du måste starta om enheten för att ansluta till det mobila nätverket."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Starta om"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"Aktivera mobiltjänst"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Ladda ned operatörens app och aktivera det nya SIM-kortet"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"Ladda ned appen"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"Nytt SIM-kort har satts in"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"Tryck om du vill konfigurera"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Ange tid"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 1c9ae55..3eeed7f 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1083,13 +1083,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Programu zinaanza"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Inamaliza kuwasha."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> inaendelea"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Gusa ili uende kwenye programu"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Badilisha programu?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Programmu nyingine tayari inaendeshwa na lazima hiyo ikomeshwe kabla ya kuanza nyingine mpya."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Rejea katika <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Usianzishe programu mpya."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Anza <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Komesha programu ya zamani bila kuhifadhi."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> imezidi kiwango cha hifadhi kinachotakikana"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Imezidi kikomo cha hifadhi; gusa ili uishiriki"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Ungependa kushiriki picha ya binafsi?"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index f912b6d..e251ca4 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS செய்திகள்"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"குரலஞ்சல் செய்திகள்"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"வைஃபை அழைப்பு"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"சிம் நிலை"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"TTY Mode FULLஐ இணைச் செயல்பாடு கோரியது"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"TTY Mode HCOஐ இணைச் செயல்பாடு கோரியது"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"TTY Mode VCOஐ இணைச் செயல்பாடு கோரியது"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"அமைப்பு"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"உதவி"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"குரல் உதவி"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"பூட்டு"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"புதிய அறிவிப்பு"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"விர்ச்சுவல் விசைப்பலகை"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"உதவிக்குறிப்பு: அளவைப் பெரிதாக்க மற்றும் குறைக்க இருமுறைத் தட்டவும்."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"தன்னிரப்பி"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"தன்னிரப்பியை அமை"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"தன்னிரப்பி"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"பயன்பாடுகள் தொடங்கப்படுகின்றன."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"துவக்குதலை முடிக்கிறது."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> இயங்குகிறது"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"பயன்பாட்டிற்கு மாற, தட்டவும்"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"பயன்பாடுகளை மாற்றவா?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"ஏற்கனவே ஒரு பயன்பாடு இயக்கத்தில் உள்ளது, புதிய ஒன்றைத் தொடங்கும்போது முன்பு இதை நிறுத்த வேண்டும்."</string>
-    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g> க்குத் திரும்பு"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"புதிய பயன்பாட்டைத் தொடங்க வேண்டாம்."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> ஐத் தொடங்கு"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"சேமிக்காமல், பழைய பயன்பாட்டை நிறுத்தவும்."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"நினைவக வரம்பை <xliff:g id="PROC">%1$s</xliff:g> மீறியது"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"ஹீப் டம்ப் சேகரிக்கப்பட்டது; பகிர, தட்டவும்"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"ஹீப் டம்பைப் பகிரவா?"</string>
@@ -1201,12 +1203,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"சிம் கார்டு சேர்க்கப்பட்டது"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"மொபைல் நெட்வொர்க்கை அணுக உங்கள் சாதனத்தை மறுதொடக்கம் செய்யவும்."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"மீண்டும் தொடங்கு"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"மொபைல் சேவையை இயக்கு"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"உங்கள் புதிய சிம்மை இயக்க, தொலைத்தொடர்பு நிறுவனத்தின் பயன்பாட்டைப் பதிவிறக்கவும்"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"பயன்பாட்டைப் பதிவிறக்கு"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"புதிய சிம் செருகப்பட்டது"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"அமைக்க, தட்டவும்"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"நேரத்தை அமை"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index b123224..b05ce97 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS సందేశాలు"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"వాయిస్ మెయిల్ సందేశాలు"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi కాలింగ్"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"SIM స్థితి"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"అవతలి వారు FULL TTY మోడ్‌ని అభ్యర్థించారు"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"అవతలి వారు HCO TTY మోడ్‌ని అభ్యర్థించారు"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"అవతలి వారు VCO TTY మోడ్‌ని అభ్యర్థించారు"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"సెట్టింగ్‌లు"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"సహాయం"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"వాయిస్ అసిస్టెంట్"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"లాక్ చేయి"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"కొత్త నోటిఫికేషన్"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"వర్చువల్ కీబోర్డ్"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"చిట్కా: దగ్గరకు మరియు దూరానికి జూమ్ చేయడానికి రెండు సార్లు నొక్కండి."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"స్వీయ పూరింపు"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"స్వీయ పూరణను సెటప్ చేయండి"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"స్వీయ పూరింపు"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"అనువర్తనాలను ప్రారంభిస్తోంది."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"బూట్‌ను ముగిస్తోంది."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> అమలవుతోంది"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"అనువర్తనానికి మారడానికి నొక్కండి"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"అనువర్తనాలను మార్చాలా?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"మరో యాప్ ఇప్పటికే అమలవుతోంది, మీరు మరోదాన్ని ప్రారంభించడానికి ముందు అది తప్పనిసరిగా ఆపివేయబడాలి."</string>
-    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g>కు తిరిగి వెళ్లండి"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"కొత్త యాప్‌ను ప్రారంభించవద్దు."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g>ని ప్రారంభించండి"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"పాత యాప్‌ను సేవ్ చేయకుండానే ఆపివేయండి."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> మెమరీ పరిమితిని మించిపోయింది"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"కుప్పలు తెప్పలుగా సేకరించబడింది; షేర్ చేయడానికి నొక్కండి"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"హీప్ డంప్‌ను భాగస్వామ్యం చేయాలా?"</string>
@@ -1201,12 +1203,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"సిమ్ కార్డు జోడించబడింది"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"మొబైల్ నెట్‌వర్క్‌ను యాక్సెస్ చేయడానికి మీ పరికరాన్ని పునఃప్రారంభించండి."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"పునఃప్రారంభించు"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"మొబైల్ సేవను సక్రియం చేయండి"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"మీ కొత్త SIMని సక్రియం చేయడానికి క్యారియర్ యాప్‌ను డౌన్‌లోడ్ చేయండి"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"యాప్‌ని డౌన్‌లోడ్ చేయి"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"కొత్త SIM చొప్పించారు"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"దీన్ని సెటప్ చేయడానికి నొక్కండి"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"సమయాన్ని సెట్ చేయండి"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 8444ff0..7aa594a 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"กำลังเริ่มต้นแอปพลิเคชัน"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"เสร็จสิ้นการบูต"</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> กำลังทำงาน"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"แตะเพื่อสลับไปยังแอป"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"สลับแอปพลิเคชันหรือไม่"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"มีแอปพลิเคชันอื่นที่กำลังทำงานอยู่แล้ว ซึ่งต้องหยุดทำงานก่อนที่คุณจะเริ่มแอปพลิเคชันใหม่ได้"</string>
-    <string name="old_app_action" msgid="493129172238566282">"กลับสู่ <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"อย่าเริ่มแอปพลิเคชันใหม่"</string>
-    <string name="new_app_action" msgid="5472756926945440706">"เริ่มต้น <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"หยุดการทำงานของแอปพลิเคชันเก่าโดยไม่บันทึก"</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> เกินขีดจำกัดของหน่วยความจำ"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"รวบรวมฮีพดัมพ์แล้ว แตะเพื่อแชร์"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"แชร์ฮีพดัมพ์ไหม"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 6c8e47d..9bb64e0 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Sinisimulan ang apps."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Pagtatapos ng pag-boot."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"Tumatakbo ang <xliff:g id="APP">%1$s</xliff:g>"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"I-tap upang lumipat sa app"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Lumipat ng apps?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"May tumatakbo nang isa pang app na dapat na ihinto bago ka makapagsimula ng bago."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Bumalik sa <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Huwag simulan ang bagong app."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Simulan ang <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Ihinto ang lumang app nang hindi nagse-save."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"Lumampas ang <xliff:g id="PROC">%1$s</xliff:g> sa limitasyon ng memory"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Nakolekta na ang heap dump; i-tap upang ibahagi"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Ibahagi ang heap dump?"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 8858388..e63e319 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"SMS mesajları"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Sesli mesajlar"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"Kablosuz çağrı"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"SIM durumu"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"Karşı taraf TTY Modunu TAM yaptı"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"Karşı taraf TTY Modunu HCO yaptı"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"Karşı taraf TTY Modunu VCO yaptı"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"Ayarlar"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"Asist"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Sesli Yardım"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"Tam gizlilik"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"Yeni bildirim"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Sanal klavye"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"İpucu: Yakınlaştırmak ve uzaklaştırmak için iki kez dokunun."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Otomatik Doldur"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Otomatik doldurma ayarla"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"Otomatik doldur"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1072,7 +1069,7 @@
     <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Bunu Sistem ayarları &gt; Uygulamalar &gt; İndirilenler bölümünden yeniden etkinleştirin."</string>
     <string name="unsupported_display_size_message" msgid="6545327290756295232">"<xliff:g id="APP_NAME">%1$s</xliff:g> geçerli Ekran boyutu ayarını desteklemiyor ve beklenmedik bir şekilde davranabilir."</string>
     <string name="unsupported_display_size_show" msgid="7969129195360353041">"Her zaman göster"</string>
-    <string name="unsupported_compile_sdk_message" msgid="4253168368781441759">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulaması Android OS\'un uyumlu olmayan önceki bir sürümü için geliştirilmiştir ve beklenmedik şekilde davranabilir. Uygulamanın güncellenmiş bir sürümü mevcut olabilir."</string>
+    <string name="unsupported_compile_sdk_message" msgid="4253168368781441759">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulaması Android OS\'in uyumlu olmayan önceki bir sürümü için geliştirilmiştir ve beklenmedik şekilde davranabilir. Uygulamanın güncellenmiş bir sürümü mevcut olabilir."</string>
     <string name="unsupported_compile_sdk_show" msgid="2681877855260970231">"Her zaman göster"</string>
     <string name="unsupported_compile_sdk_check_update" msgid="3312723623323216101">"Güncellemeleri denetle"</string>
     <string name="smv_application" msgid="3307209192155442829">"<xliff:g id="APPLICATION">%1$s</xliff:g> uygulaması (<xliff:g id="PROCESS">%2$s</xliff:g> işlemi) kendiliğinden uyguladığı StrictMode politikasını ihlal etti."</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Uygulamalar başlatılıyor"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Açılış tamamlanıyor."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> çalışıyor"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Uygulamaya geçmek için dokunun"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Uygulama değiştirilsin mi?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Başka bir uygulama zaten çalışıyor. Yeni bir uygulama başlatmadan bu uygulama durdurulmalıdır."</string>
-    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g> öğesine geri dön"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Yeni uygulamayı başlatmayın."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> uygulamasını başlat"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Kaydetmeden eski uygulamayı durdurun."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> bellek sınırını aştı"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Yığın dökümü toplandı. Paylaşmak için dokunun"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Yığın dökümü paylaşılsın mı?"</string>
@@ -1200,12 +1202,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"SIM kart eklendi"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"Mobil ağa erişmek için cihazınızı yeniden başlatın."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Yeniden başlat"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"Mobil hizmeti etkinleştirin"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Yeni SIM\'inizi etkinleştirmek için operatörün uygulamasını indirin"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"Uygulama indir"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"Yeni SIM kart takıldı"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"Kurmak için dokunun"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Saati ayarlayın"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index b9fba79..61f74bf 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1125,13 +1125,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Запуск програм."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Завершення завантаження."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"Працює <xliff:g id="APP">%1$s</xliff:g>"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Торкніться, щоб відкрити додаток"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Переключитися між програмами?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Уже працює інша програма, яку потрібно зупинити перед тим, як запускати нову програму."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Поверн. до <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Не запускати нову програму."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Запуст. <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Зупинити попередню програму без збереження."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"Процес <xliff:g id="PROC">%1$s</xliff:g> перевищив ліміт пам’яті"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Дані динамічної пам’яті зібрано. Торкніться, щоб поділитися"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Поділитися даними динамічної пам’яті?"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index f9e26ca..73a1146 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"‏SMS پیغامات"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"صوتی میل پیغامات"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"‏Wi-Fi کالنگ"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"‏SIM کا اسٹیٹس"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"‏ہمسر نے TTY وضع مکمل کی درخواست کی"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"‏ہمسر نے TTY وضع HCO کی درخواست کی"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"‏ہمسر نے TTY وضع VCO کی درخواست کی"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"ترتیبات"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"اسسٹ"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"مقفل"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"‎999+‎"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"نئی اطلاع"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ورچوئل کی بورڈ"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"تجویز: زوم ان اور آؤٹ کیلئے دو بار تھپتھپائیں۔"</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"آٹوفل"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"آٹوفل مقرر کریں"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"آٹو فل"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">"، "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"ایپس شروع ہو رہی ہیں۔"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"بوٹ مکمل ہو رہا ہے۔"</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> چل رہی ہے"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"ایپ پر سوئچ کرنے کیلئے تھپتھپائیں"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"ایپس سوئچ کریں؟"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"ایک دوسری ایپ پہلے سے چل رہی ہے، جس کا بند ہونا ضروری ہے تاکہ آپ ایک نئی ایپ شروع کر سکیں۔"</string>
-    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g> پر واپس جائیں"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"نئی ایپ شروع نہ کریں۔"</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> شروع کریں"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"محفوظ کیے بغیر پرانی ایپ بند کریں۔"</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> میموری کی حد سے تجاوز کرگئی"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"ہیپ ڈمپ جمع ہو گیا ہے، اشتراک کرنے کیلئے تھپتھپائیں"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"ہیپ ڈمپ کا اشتراک کریں؟"</string>
@@ -1201,12 +1203,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"‏SIM شامل کیا گیا"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"موبائل نیٹ ورک تک رسائی کیلئے اپنا آلہ دوبارہ سٹارٹ کریں۔"</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"دوبارہ شروع کریں"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"موبائل سروس فعال کریں"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"‏اپنا نیا SIM فعال کرنے کیلئے کیریئر ایپ ڈاؤن لوڈ کریں"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"ایپ ڈاؤن لوڈ کریں"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"‏نئی SIM داخل ہو گئی"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"اسے سیٹ اپ کرنے کیلئے تھپتھپائیں"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"وقت سیٹ کریں"</string>
@@ -1840,6 +1839,6 @@
     <string name="slices_permission_request" msgid="8484943441501672932">"<xliff:g id="APP_0">%1$s</xliff:g> <xliff:g id="APP_2">%2$s</xliff:g> کے سلائسز دکھانا چاہتی ہے"</string>
     <string name="screenshot_edit" msgid="7867478911006447565">"ترمیم کریں"</string>
     <string name="notification_channel_system_changes" msgid="5072715579030948646">"سسٹم کی تبدیلیاں"</string>
-    <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"\'ڈسٹرب نہ کریں\' تبدیل ہو گيا"</string>
+    <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"\'ڈسٹرب نہ کریں\' تبدیل ہو گيا ہے"</string>
     <string name="zen_upgrade_notification_content" msgid="6603123479476554768">"مداخلتوں کے مد نظر اپنے برتاؤ کی ترتیبات چیک کرنے کیلئے تھپتھپائیں"</string>
 </resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 735a66c..3d48f84 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Ilovalar ishga tushirilmoqda."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Tizimni yuklashni tugatish."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> ishlamoqda"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Ilovaga o‘tish uchun bosing"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Ilovalar almashtirilsinmi?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Boshqa ilova ishlab turibdi. Yangisini ishga tushirishdan oldin avvalgisini yoping."</string>
-    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g>ga qaytish"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Yangi ilova ishga tushirilmasin."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g>ni ishga tushirish"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"O‘zgarishlarni saqlamasdan, eski ilova yopilsin"</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> foydalanish uchun ajratilgan xotira chegarasidan o‘tib ketdi"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Hip-damp yaratildi; uni yuborish uchun bosing"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Hip-damp ma’lumotlari bilan ulashasizmi?"</string>
@@ -1833,7 +1838,7 @@
     <string name="harmful_app_warning_title" msgid="8982527462829423432">"Zararli ilova aniqlandi"</string>
     <string name="slices_permission_request" msgid="8484943441501672932">"<xliff:g id="APP_0">%1$s</xliff:g> ilovasi <xliff:g id="APP_2">%2$s</xliff:g> ilovasidan fragmentlar ko‘rsatish uchun ruxsat so‘ramoqda"</string>
     <string name="screenshot_edit" msgid="7867478911006447565">"Tahrirlash"</string>
-    <string name="notification_channel_system_changes" msgid="5072715579030948646">"Tizimda o‘zgartirishlar"</string>
+    <string name="notification_channel_system_changes" msgid="5072715579030948646">"Tizimga oid o‘zgarishlar"</string>
     <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"Bezovta qilinmasin rejimi sozlamalari o‘zgartirildi"</string>
     <string name="zen_upgrade_notification_content" msgid="6603123479476554768">"Ularni tekshirish uchun bosing."</string>
 </resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 303ef78..1671cd6 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"Tin nhắn SMS"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Thư thoại"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"Gọi qua Wi-Fi"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"Trạng thái SIM"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"TTY theo yêu cầu của thiết bị ngang hàng ở chế độ ĐẦY ĐỦ"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"TTY theo yêu cầu của thiết bị ngang hàng ở chế độ HCO"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"TTY theo yêu cầu của thiết bị ngang hàng ở chế độ VCO"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"Cài đặt"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"Hỗ trợ"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Trợ lý thoại"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"Khóa"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"Thông báo mới"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Bàn phím ảo"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"Mẹo: Nhấn đúp để phóng to và thu nhỏ."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Tự động điền"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Thiết lập Tự động điền"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"Tự động điền"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Khởi động ứng dụng."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Hoàn tất khởi động."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> đang hoạt động"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Nhấn để chuyển sang ứng dụng"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Chuyển đổi ứng dụng?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Bạn phải dừng một ứng dụng khác hiện đang chạy trước khi khởi động một ứng dụng mới."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Quay lại <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Không khởi động ứng dụng mới."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Bắt đầu <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Dừng ứng dụng cũ mà không lưu."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> đã vượt quá giới hạn bộ nhớ"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Tệp báo lỗi đã được thu thập; nhấn để chia sẻ"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Chia sẻ tệp báo lỗi?"</string>
@@ -1200,12 +1202,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"Đã thêm thẻ SIM"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"Khởi động lại thiết bị của bạn để truy cập mạng di động."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Khởi động lại"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"Kích hoạt dịch vụ di động"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Tải xuống ứng dụng của nhà cung cấp dịch vụ để kích hoạt SIM mới"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"Tải xuống ứng dụng"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"Đã lắp SIM mới"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"Nhấn để thiết lập"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Đặt giờ"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 2c43023..ff11ef5 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"短信"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"语音邮件"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"WLAN 通话"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"SIM 卡状态"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"对方请求使用“TTY 完整”模式"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"对方请求使用“TTY HCO”模式"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"对方请求使用“TTY VCO”模式"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"设置"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"助理"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"语音助理"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"锁定"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"新通知"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"虚拟键盘"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"提示:点按两次可放大或缩小。"</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"自动填充"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"设置自动填充"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"自动填充"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"正在启动应用。"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"即将完成启动。"</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g>正在运行"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"点按即可切换到应用"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"切换应用吗?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"已有一个应用正在运行,要启动新的应用,您必须先停止该应用。"</string>
-    <string name="old_app_action" msgid="493129172238566282">"返回至<xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"不启动新的应用。"</string>
-    <string name="new_app_action" msgid="5472756926945440706">"启动<xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"停止旧的应用,但不保存。"</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g>占用的内存已超出限制"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"已收集堆转储数据;点按即可共享"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"要共享堆转储数据吗?"</string>
@@ -1200,12 +1202,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"已添加SIM卡"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"请重新启动您的设备,以便访问移动网络。"</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"重新启动"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"激活移动网络服务"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"下载运营商应用即可激活您的新 SIM 卡"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"下载应用"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"已插入新 SIM 卡"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"点按即可进行设置"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"设置时间"</string>
@@ -1838,7 +1837,7 @@
     <string name="harmful_app_warning_title" msgid="8982527462829423432">"检测到有害应用"</string>
     <string name="slices_permission_request" msgid="8484943441501672932">"“<xliff:g id="APP_0">%1$s</xliff:g>”想要显示“<xliff:g id="APP_2">%2$s</xliff:g>”图块"</string>
     <string name="screenshot_edit" msgid="7867478911006447565">"编辑"</string>
-    <string name="notification_channel_system_changes" msgid="5072715579030948646">"系统更改"</string>
-    <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"“勿扰”设置已更改"</string>
+    <string name="notification_channel_system_changes" msgid="5072715579030948646">"系统变更"</string>
+    <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"“勿扰”设置有变更"</string>
     <string name="zen_upgrade_notification_content" msgid="6603123479476554768">"点按即可查看您的干扰行为设置"</string>
 </resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index e837ae7..5bf1a37 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"短訊"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"留言訊息"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi 通話"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"SIM 卡狀態"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"對方曾要求 TTY 完整模式"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"對方曾要求 TTY 模式 (HCO)"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"對方曾要求 TTY 模式 (VCO)"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"設定"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"協助"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"語音助手"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"鎖定"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"新通知"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"虛擬鍵盤"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"提示:輕按兩下即可放大縮小。"</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"自動填入"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"設定自動填入功能"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"自動填入"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"正在啟動應用程式。"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"啟動完成。"</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"正在執行 <xliff:g id="APP">%1$s</xliff:g>"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"輕按即可切換至應用程式"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"切換應用程式?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"另一個應用程式已在執行,您必須停止執行該應用程式,才能啟動新的應用程式。"</string>
-    <string name="old_app_action" msgid="493129172238566282">"返回 <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"請勿啟動新的應用程式。"</string>
-    <string name="new_app_action" msgid="5472756926945440706">"啟動 <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"停止舊的應用程式,且不儲存。"</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> 的記憶體用量已超過限額"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"已收集堆轉儲;輕按即可分享"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"分享堆轉儲?"</string>
@@ -1200,12 +1202,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"SIM 卡已新增"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"重新啟動裝置,才能使用流動網絡。"</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"重新啟動"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"啟動流動服務"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"下載流動網絡供應商應用程式,即可啟用新 SIM 卡"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"下載應用程式"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"已插入新的 SIM 卡"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"輕按即可設定"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"設定時間"</string>
@@ -1838,10 +1837,7 @@
     <string name="harmful_app_warning_title" msgid="8982527462829423432">"偵測到有害的應用程式"</string>
     <string name="slices_permission_request" msgid="8484943441501672932">"「<xliff:g id="APP_0">%1$s</xliff:g>」想顯示「<xliff:g id="APP_2">%2$s</xliff:g>」的快訊"</string>
     <string name="screenshot_edit" msgid="7867478911006447565">"編輯"</string>
-    <!-- no translation found for notification_channel_system_changes (5072715579030948646) -->
-    <skip />
-    <!-- no translation found for zen_upgrade_notification_title (3799603322910377294) -->
-    <skip />
-    <!-- no translation found for zen_upgrade_notification_content (6603123479476554768) -->
-    <skip />
+    <string name="notification_channel_system_changes" msgid="5072715579030948646">"系統變更"</string>
+    <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"請勿騷擾已變更"</string>
+    <string name="zen_upgrade_notification_content" msgid="6603123479476554768">"輕按即可查看您的干擾行為設定"</string>
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 2bff388..ed24a35 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -93,8 +93,7 @@
     <string name="notification_channel_sms" msgid="3441746047346135073">"簡訊"</string>
     <string name="notification_channel_voice_mail" msgid="3954099424160511919">"語音留言"</string>
     <string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi 通話"</string>
-    <!-- no translation found for notification_channel_sim (4052095493875188564) -->
-    <skip />
+    <string name="notification_channel_sim" msgid="4052095493875188564">"SIM 卡狀態"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"通訊對象要求使用 TTY 的 FULL 模式"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"通訊對象要求使用 TTY 的 HCO 模式"</string>
     <string name="peerTtyModeVco" msgid="1742404978686538049">"通訊對象要求使用 TTY 的 VCO 模式"</string>
@@ -240,8 +239,7 @@
     <string name="global_action_settings" msgid="1756531602592545966">"設定"</string>
     <string name="global_action_assist" msgid="3892832961594295030">"協助"</string>
     <string name="global_action_voice_assist" msgid="7751191495200504480">"語音小幫手"</string>
-    <!-- no translation found for global_action_lockdown (1099326950891078929) -->
-    <skip />
+    <string name="global_action_lockdown" msgid="1099326950891078929">"鎖定"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"超過 999"</string>
     <string name="notification_hidden_text" msgid="6351207030447943784">"新通知"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"虛擬鍵盤"</string>
@@ -828,8 +826,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"提示:輕觸兩下即可縮放。"</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"自動填入功能"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"設定自動填入功能"</string>
-    <!-- no translation found for autofill_window_title (921006636895825007) -->
-    <skip />
+    <string name="autofill_window_title" msgid="921006636895825007">"自動填入"</string>
     <string name="autofill_address_name_separator" msgid="6350145154779706772">" //*** Empty segment here as a separator ***//"</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -1088,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"正在啟動應用程式。"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"啟動完成。"</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> 執行中"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"輕觸即可切換至應用程式"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"切換應用程式?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"其他應用程式已在執行中,你必須停止執行該應用程式,才能啟動新的應用程式。"</string>
-    <string name="old_app_action" msgid="493129172238566282">"返回 <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"請勿啟動新的應用程式。"</string>
-    <string name="new_app_action" msgid="5472756926945440706">"啟動 <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"停止舊的應用程式且不儲存。"</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> 已超出記憶體上限"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"已取得記憶體快照資料;輕觸即可分享"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"分享記憶體快照資料?"</string>
@@ -1200,12 +1202,9 @@
     <string name="sim_added_title" msgid="3719670512889674693">"SIM 卡已新增"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"請重新啟動裝置,才能使用行動網路。"</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"重新啟動"</string>
-    <!-- no translation found for install_carrier_app_notification_title (9056007111024059888) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_text (3346681446158696001) -->
-    <skip />
-    <!-- no translation found for install_carrier_app_notification_button (3094206295081900849) -->
-    <skip />
+    <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"啟用行動服務"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"下載電信業者應用程式以啟用你的新 SIM 卡"</string>
+    <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"下載應用程式"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"已插入新的 SIM 卡"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"輕觸這裡即可進行設定"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"設定時間"</string>
@@ -1838,10 +1837,7 @@
     <string name="harmful_app_warning_title" msgid="8982527462829423432">"偵測到有害應用程式"</string>
     <string name="slices_permission_request" msgid="8484943441501672932">"「<xliff:g id="APP_0">%1$s</xliff:g>」想要顯示「<xliff:g id="APP_2">%2$s</xliff:g>」的區塊"</string>
     <string name="screenshot_edit" msgid="7867478911006447565">"編輯"</string>
-    <!-- no translation found for notification_channel_system_changes (5072715579030948646) -->
-    <skip />
-    <!-- no translation found for zen_upgrade_notification_title (3799603322910377294) -->
-    <skip />
-    <!-- no translation found for zen_upgrade_notification_content (6603123479476554768) -->
-    <skip />
+    <string name="notification_channel_system_changes" msgid="5072715579030948646">"系統變更"</string>
+    <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"「零打擾」設定已變更"</string>
+    <string name="zen_upgrade_notification_content" msgid="6603123479476554768">"輕觸即可查看你的干擾行為設定"</string>
 </resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index e292e3a..74bca25 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1085,13 +1085,18 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Qalisa izinhlelo zokusebenza."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Qedela ukuqala kabusha."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> iyasebenza"</string>
-    <string name="heavy_weight_notification_detail" msgid="867643381388543170">"Thepha ukuze ushintshele kuhlelo lokusebenza"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Shintsha izinhlelo zokusebenza?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Olunye uhlelo lokusebenza luvele luyasebenza lokho kumele kumiswe ngaphambi kokuba uqalise olusha."</string>
-    <string name="old_app_action" msgid="493129172238566282">"Buyisela ku:<xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Ungayiqali uhlelo lokusebenza entsha."</string>
-    <string name="new_app_action" msgid="5472756926945440706">"Qala <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Misa uhlelo lokusebenza endala ngaphandle kokulondoloza."</string>
+    <!-- no translation found for heavy_weight_notification_detail (2304833848484424985) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_title (387882830435195342) -->
+    <skip />
+    <!-- no translation found for heavy_weight_switcher_text (4176781660362912010) -->
+    <skip />
+    <!-- no translation found for old_app_action (3044685170829526403) -->
+    <skip />
+    <!-- no translation found for new_app_action (6694851182870774403) -->
+    <skip />
+    <!-- no translation found for new_app_description (5894852887817332322) -->
+    <skip />
     <string name="dump_heap_notification" msgid="2618183274836056542">"I-<xliff:g id="PROC">%1$s</xliff:g> idlule umkhawulo wememori"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"Ukulahlwa kwehipu kuqoqiwe; thepha ukuze wabelane"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Yabelana ngokulahlwa kwehipu?"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index d26567e..ffabdab 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1019,6 +1019,9 @@
         <!-- Corner radius of buttons. -->
         <attr name="buttonCornerRadius" format="dimension" />
 
+        <!-- Corner radius of progress bars. -->
+        <attr name="progressBarCornerRadius" format="dimension" />
+
         <!-- Style for the search query widget. -->
         <attr name="searchViewStyle" format="reference" />
 
@@ -2113,6 +2116,45 @@
              Corresponds to setting {@link android.view.View#SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR} on
              the decor view. -->
         <attr name="windowLightNavigationBar" format="boolean" />
+
+        <!-- Controls how the window is laid out if there is a {@code DisplayCutout}.
+        <p>
+        Defaults to {@code default}.
+
+        @see android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
+        @see android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
+        @see android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
+        @see android.view.DisplayCutout
+        @see android.R.attr#layoutInDisplayCutoutMode -->
+        <attr name="windowLayoutInDisplayCutoutMode">
+            <!-- The window is allowed to extend into the {@code DisplayCutout} area, only if the
+            {@code DisplayCutout} is fully contained within the status bar. Otherwise, the window is
+            laid out such that it does not overlap with the {@code DisplayCutout} area.
+
+            @see android.view.DisplayCutout
+            @see android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
+            -->
+            <enum name="default" value="0" />
+            <!-- The window is always allowed to extend into the {@code DisplayCutout} area,
+            even if fullscreen or in landscape.
+            <p>
+            The window must make sure that no important content overlaps with the
+            {@link DisplayCutout}.
+
+            @see android.view.DisplayCutout
+            @see android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
+            -->
+            <enum name="always" value="1" />
+            <!-- The window is never allowed to overlap with the DisplayCutout area.
+            <p>
+            This should be used with windows that transiently set {@code SYSTEM_UI_FLAG_FULLSCREEN}
+            to avoid a relayout of the window when the flag is set or cleared.
+
+            @see android.view.DisplayCutout
+            @see android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
+            -->
+            <enum name="never" value="2" />
+        </attr>
     </declare-styleable>
 
     <!-- The set of attributes that describe a AlertDialog's theme. -->
@@ -4472,6 +4514,8 @@
         <attr name="textSize" />
         <!-- Style (normal, bold, italic, bold|italic) for the text. -->
         <attr name="textStyle" />
+        <!-- Weight for the font used in the TextView. -->
+        <attr name="textFontWeight" />
         <!-- Typeface (normal, sans, serif, monospace) for the text. -->
         <attr name="typeface" />
         <!-- Font family (named by string or as a font resource reference) for the text. -->
@@ -4561,6 +4605,8 @@
         <attr name="typeface" />
         <!-- Style (normal, bold, italic, bold|italic) for the text. -->
         <attr name="textStyle" />
+        <!-- Weight for the font used in the TextView. -->
+        <attr name="textFontWeight" />
         <!-- Font family (named by string or as a font resource reference) for the text. -->
         <attr name="fontFamily" />
         <!-- Text color for links. -->
@@ -5905,6 +5951,9 @@
         <!-- Identifier of the image file. This attribute is mandatory.
              It must be an image file with multiple frames, e.g. gif or webp -->
         <attr name="src" />
+        <!-- Indicates if the drawable needs to be mirrored when its layout direction is
+             RTL (right-to-left). -->
+        <attr name="autoMirrored" />
     </declare-styleable>
 
     <!-- Drawable used to draw bitmaps. -->
@@ -6328,6 +6377,9 @@
         <!-- Special option for window animations: if this window is on top
              of a wallpaper, don't animate the wallpaper with it. -->
         <attr name="detachWallpaper" format="boolean" />
+        <!-- Special option for window animations: show the wallpaper behind when running this
+             animation. -->
+        <attr name="showWallpaper" format="boolean" />
     </declare-styleable>
 
     <declare-styleable name="AnimationSet">
@@ -8000,6 +8052,8 @@
         <attr name="icon"/>
         <!-- The activity to launch when the setting is clicked on. -->
         <attr name="settingsActivity"/>
+        <!-- The user restriction for this preference. -->
+        <attr name="userRestriction"/>
     </declare-styleable>
 
     <!-- =============================== -->
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 32fe2b2..c4fa190 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -173,10 +173,10 @@
          values listed below. If no protectionLevel is defined for a custom
          permission, the system assigns the default ("normal").
          <p>Each protection level consists of a base permission type and zero or
-         more flags:
+         more flags. Use the following functions to extract those.
          <pre>
-         int basePermissionType = protectionLevel & {@link android.content.pm.PermissionInfo#PROTECTION_MASK_BASE};
-         int permissionFlags = protectionLevel & {@link android.content.pm.PermissionInfo#PROTECTION_MASK_FLAGS};
+         int basePermissionType = permissionInfo.getProtection();
+         int permissionFlags = permissionInfo.getProtectionFlags();
          </pre>
          -->
     <attr name="protectionLevel">
@@ -265,6 +265,9 @@
         <!-- Additional flag from base permission type: this permission can be granted to
              privileged apps in vendor partition. -->
         <flag name="vendorPrivileged" value="0x8000" />
+        <!-- Additional flag from base permission type: this permission can be automatically
+            granted to the system default text classifier -->
+        <flag name="textClassifier" value="0x10000" />
     </attr>
 
     <!-- Flags indicating more context for a permission group. -->
@@ -2345,6 +2348,16 @@
         <attr name="logo" />
         <attr name="priority" />
         <attr name="autoVerify" />
+        <!-- Within an application, multiple intent filters may match a particular
+             intent. This allows the app author to specify the order filters should
+             be considered. We don't want to use priority because that is global
+             across applications.
+             <p>Only use if you really need to forcibly set the order in which
+             filters are evaluated. It is preferred to target an activity with a
+             directed intent instead.
+             <p>The value is a single integer, with higher numbers considered to
+             be better. If not specified, the default order is 0. -->
+        <attr name="order" />
     </declare-styleable>
 
     <!-- Attributes that can be supplied in an AndroidManifest.xml
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index a078d8b..722102e 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -167,8 +167,8 @@
     <color name="user_icon_default_white">#ffffffff</color><!-- white -->
 
     <!-- Default profile badge colors -->
-    <color name="profile_badge_1">#ffff6d00</color><!-- Orange -->
-    <color name="profile_badge_2">#ff000000</color><!-- Black -->
+    <color name="profile_badge_1">#ff1A73E8</color><!-- Blue -->
+    <color name="profile_badge_2">#ffff6d00</color><!-- Orange -->
     <color name="profile_badge_3">#ff22f033</color><!-- Green -->
 
     <!-- Default instant app badge color -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 01da14f..f3aa054 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1636,6 +1636,9 @@
     <!-- Operating volatage for bluetooth controller. 0 by default-->
     <integer translatable="false" name="config_bluetooth_operating_voltage_mv">0</integer>
 
+    <!-- Max number of connected audio devices supported by Bluetooth stack -->
+    <integer name="config_bluetooth_max_connected_audio_devices">1</integer>
+
     <!-- Whether supported profiles should be reloaded upon enabling bluetooth -->
     <bool name="config_bluetooth_reload_supported_profiles_when_enabled">false</bool>
 
@@ -2372,7 +2375,7 @@
          obtain user consent to access their location through other means. -->
     <string-array name="config_disabledUntilUsedPreinstalledCarrierApps" translatable="false" />
 
-    <!-- The list of classes that should be added to the notification ranking pipline.
+    <!-- The list of classes that should be added to the notification ranking pipeline.
      See {@link com.android.server.notification.NotificationSignalExtractor}
       If you add a new extractor to this list make sure to update
       NotificationManagerService.handleRankingSort()-->
@@ -2384,11 +2387,14 @@
         <!-- depends on AdjustmentExtractor-->
         <item>com.android.server.notification.ValidateNotificationPeople</item>
         <item>com.android.server.notification.PriorityExtractor</item>
+        <!-- depends on PriorityExtractor -->
+        <item>com.android.server.notification.ZenModeExtractor</item>
         <item>com.android.server.notification.ImportanceExtractor</item>
         <!-- depends on ImportanceExtractor-->
         <item>com.android.server.notification.NotificationIntrusivenessExtractor</item>
         <item>com.android.server.notification.VisibilityExtractor</item>
         <item>com.android.server.notification.BadgeExtractor</item>
+
     </string-array>
 
     <!-- Flag indicating that this device does not rotate and will always remain in its default
@@ -2515,6 +2521,32 @@
          in the display pipeline plus some slack just to be sure. -->
     <integer name="config_drawLockTimeoutMillis">120</integer>
 
+    <!-- An array of device capabilities defined by GSMA SGP.22 v2.0.
+         The first item is the capability name that the device supports. The second item is the
+         major version. The minor and revision versions are default to 0s.
+         The device capabilities and their definition in the spec are:
+             gsm : gsmSupportedRelease
+             utran : utranSupportedRelease
+             cdma1x : cdma2000onexSupportedRelease
+             hrpd : cdma2000hrpdSupportedRelease
+             ehrpd : cdma2000ehrpdSupportedRelease
+             eutran : eutranSupportedRelease
+             nfc : contactlessSupportedRelease
+             crl : rspCrlSupportedVersion
+    -->
+    <string-array translatable="false" name="config_telephonyEuiccDeviceCapabilities">
+        <!-- Example:
+        <item>"gsm,11"</item>
+        <item>"utran,11"</item>
+        <item>"cdma1x,1"</item>
+        <item>"hrpd,3"</item>
+        <item>"ehrpd,12"</item>
+        <item>"eutran,11"</item>
+        <item>"nfc,1"</item>
+        <item>"crl,1"</item>
+        -->
+    </string-array>
+
     <!-- default telephony hardware configuration for this platform.
     -->
     <!-- this string array should be overridden by the device to present a list
@@ -3158,14 +3190,14 @@
     -->
     <string name="config_defaultAutofillService" translatable="false"></string>
 
-    <!-- The component name, flattened to a string, for the default system textclassifier service.
+    <!-- The package name for the default system textclassifier service.
          This service must be trusted, as it can be activated without explicit consent of the user.
-         (e.g. com.android.textclassifier/.TextClassifierServiceImpl).
+         Example: "com.android.textclassifier"
          If no textclassifier service with the specified name exists on the device (or if this is
          set to empty string), a default textclassifier will be loaded in the calling app's process.
          See android.view.textclassifier.TextClassificationManager.
     -->
-    <string name="config_defaultTextClassifierService" translatable="false"></string>
+    <string name="config_defaultTextClassifierPackage" translatable="false"></string>
 
     <!-- Whether the device uses the default focus highlight when focus state isn't specified. -->
     <bool name="config_useDefaultFocusHighlight">true</bool>
@@ -3299,6 +3331,8 @@
     <dimen name="config_dialogCornerRadius">2dp</dimen>
     <!-- Corner radius of system buttons -->
     <dimen name="config_buttonCornerRadius">@dimen/control_corner_material</dimen>
+    <!-- Corner radius of system progress bars -->
+    <dimen name="config_progressBarCornerRadius">@dimen/progress_bar_corner_material</dimen>
     <!-- Controls whether system buttons use all caps for text -->
     <bool name="config_buttonTextAllCaps">true</bool>
     <!-- Name of the font family used for system surfaces where the font should use medium weight -->
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index cfaab6a..7ff96fa 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -32,7 +32,11 @@
 
     <dimen name="toast_y_offset">24dp</dimen>
     <!-- Height of the status bar -->
-    <dimen name="status_bar_height">24dp</dimen>
+    <dimen name="status_bar_height">@dimen/status_bar_height_portrait</dimen>
+    <!-- Height of the status bar in portrait -->
+    <dimen name="status_bar_height_portrait">24dp</dimen>
+    <!-- Height of the status bar in landscape -->
+    <dimen name="status_bar_height_landscape">@dimen/status_bar_height_portrait</dimen>
     <!-- Height of area above QQS where battery/time go -->
     <dimen name="quick_qs_offset_height">48dp</dimen>
     <!-- Total height of QQS (quick_qs_offset_height + 128) -->
@@ -176,13 +180,13 @@
     <dimen name="notification_extra_margin_ambient">16dp</dimen>
 
     <!-- The height of the notification action list -->
-    <dimen name="notification_action_list_height">56dp</dimen>
+    <dimen name="notification_action_list_height">60dp</dimen>
 
     <!-- height of the content margin to accomodate for the header -->
     <dimen name="notification_content_margin_top">46dp</dimen>
 
-    <!-- height of the content margin on the bottom -->
-    <dimen name="notification_content_margin_bottom">20dp</dimen>
+    <!-- height of the content margin that is applied at the end of the notification content -->
+    <dimen name="notification_content_margin">20dp</dimen>
 
     <!-- The height of the progress bar. -->
     <dimen name="notification_progress_bar_height">15dp</dimen>
@@ -541,7 +545,7 @@
     <!-- Magnifier dimensions -->
     <dimen name="magnifier_width">100dp</dimen>
     <dimen name="magnifier_height">48dp</dimen>
-    <dimen name="magnifier_elevation">2dp</dimen>
+    <dimen name="magnifier_elevation">4dp</dimen>
     <dimen name="magnifier_offset">42dp</dimen>
     <item type="dimen" format="float" name="magnifier_zoom_scale">1.25</item>
 
diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml
index e3fdcec..210f30e 100644
--- a/core/res/res/values/dimens_material.xml
+++ b/core/res/res/values/dimens_material.xml
@@ -135,6 +135,7 @@
     <dimen name="seekbar_track_progress_height_material">2dp</dimen>
 
     <dimen name="progress_bar_height_material">4dp</dimen>
+    <dimen name="progress_bar_corner_material">0dp</dimen>
 
     <!-- Material time picker dimensions. -->
     <!-- Text size for the time picker header HH:MM label. This value is large
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 82fefef..7d5d1ba 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2870,6 +2870,10 @@
       <public name="outlineAmbientShadowColor" />
       <public name="maxLongVersionCode" />
       <public name="urlBarResourceId" />
+      <!-- @hide @SystemApi -->
+      <public name="userRestriction" />
+      <public name="textFontWeight" />
+      <public name="windowLayoutInDisplayCutoutMode" />
     </public-group>
 
     <public-group type="style" first-id="0x010302e0">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index e6186023..c3ae5fa 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -379,7 +379,7 @@
     <!-- Text message in the factory reset warning dialog. This says that the the device admin app
          is missing or corrupted. As a result the device will be erased. [CHAR LIMIT=NONE]-->
     <string name="factory_reset_message">The admin app can\'t be used. Your device will now be
-        erased.\n\nIf you have questions, contact your organization's admin.</string>
+        erased.\n\nIf you have questions, contact your organization\'s admin.</string>
 
     <!-- A toast message displayed when printing is attempted but disabled by policy. -->
     <string name="printing_disabled_by">Printing disabled by <xliff:g id="owner_app">%s</xliff:g>.</string>
@@ -764,7 +764,7 @@
     <string name="capability_title_canCaptureFingerprintGestures">Fingerprint gestures</string>
     <!-- Description for the capability of an accessibility service to perform gestures. -->
     <string name="capability_desc_canCaptureFingerprintGestures">Can capture gestures performed on
-        the device's fingerprint sensor.</string>
+        the device\'s fingerprint sensor.</string>
 
     <!--  Permissions -->
 
@@ -2106,6 +2106,10 @@
     <string name="keyguard_accessibility_face_unlock">Face unlock.</string>
     <!-- Accessibility description of the pin lock. [CHAR_LIMIT=none] -->
     <string name="keyguard_accessibility_pin_unlock">Pin unlock.</string>
+    <!-- Accessibility description of the sim pin lock. [CHAR_LIMIT=none] -->
+    <string name="keyguard_accessibility_sim_pin_unlock">Sim Pin unlock.</string>
+    <!-- Accessibility description of the sim puk lock. [CHAR_LIMIT=none] -->
+    <string name="keyguard_accessibility_sim_puk_unlock">Sim Puk unlock.</string>
     <!-- Accessibility description of the password lock. [CHAR_LIMIT=none] -->
     <string name="keyguard_accessibility_password_unlock">Password unlock.</string>
     <!-- Accessibility description of the unlock pattern area. [CHAR_LIMIT=none] -->
@@ -3200,9 +3204,10 @@
     <string name="sim_restart_button">Restart</string>
     <!-- See Carrier_App_Dialog. This is the message of that dialog. -->
     <string name="install_carrier_app_notification_title">Activate mobile service</string>
-    <string name="install_carrier_app_notification_text">
-        Download the carrier app to activate your new SIM
-    </string>
+    <!-- Notification message that shows when the user inserts a SIM card that requires a carrier app download, but the app name is unknown -->
+    <string name="install_carrier_app_notification_text">Download the carrier app to activate your new SIM</string>
+    <!-- Notification message that shows when the user inserts a SIM card that requires a carrier app download.  App name is known -->
+    <string name="install_carrier_app_notification_text_app_name">Download the <xliff:g id="app_name">%1$s</xliff:g> app to activate your new SIM</string>
     <!-- See Carrier_App_Notification. This is the button of that dialog. -->
     <string name="install_carrier_app_notification_button">Download app</string>
     <!-- See carrier_app_notification. This is the headline. -->
@@ -3768,31 +3773,23 @@
     <string name="extract_edit_menu_button">Edit</string>
 
     <!-- Notification title when data usage has exceeded warning threshold. [CHAR LIMIT=50] -->
-    <string name="data_usage_warning_title">Data usage alert</string>
+    <string name="data_usage_warning_title">Data warning</string>
     <!-- Notification body when data usage has exceeded warning threshold. [CHAR LIMIT=32] -->
-    <string name="data_usage_warning_body">Tap to view usage and settings.</string>
+    <string name="data_usage_warning_body">You\'ve used <xliff:g id="app" example="3.8GB">%s</xliff:g> of data</string>
 
-    <!-- Notification title when 2G-3G data usage has exceeded limit threshold, and has been disabled. [CHAR LIMIT=32] -->
-    <string name="data_usage_3g_limit_title">2G-3G data limit reached</string>
-    <!-- Notification title when 4G data usage has exceeded limit threshold, and has been disabled. [CHAR LIMIT=32] -->
-    <string name="data_usage_4g_limit_title">4G data limit reached</string>
     <!-- Notification title when mobile data usage has exceeded limit threshold, and has been disabled. [CHAR LIMIT=50] -->
     <string name="data_usage_mobile_limit_title">Mobile data limit reached</string>
     <!-- Notification title when Wi-Fi data usage has exceeded limit threshold, and has been disabled. [CHAR LIMIT=32] -->
     <string name="data_usage_wifi_limit_title">Wi-Fi data limit reached</string>
     <!-- Notification body when data usage has exceeded limit threshold, and has been disabled. -->
-    <string name="data_usage_limit_body">Data paused for rest of cycle</string>
+    <string name="data_usage_limit_body">Data paused for the rest of your cycle</string>
 
-    <!-- Notification title when 2G-3G data usage has exceeded limit threshold. [CHAR LIMIT=32] -->
-    <string name="data_usage_3g_limit_snoozed_title">2G-3G data limit exceeded</string>
-    <!-- Notification title when 4G data usage has exceeded limit threshold. [CHAR LIMIT=32] -->
-    <string name="data_usage_4g_limit_snoozed_title">4G data limit exceeded</string>
     <!-- Notification title when mobile data usage has exceeded limit threshold. [CHAR LIMIT=32] -->
-    <string name="data_usage_mobile_limit_snoozed_title">Mobile data limit exceeded</string>
+    <string name="data_usage_mobile_limit_snoozed_title">Over your mobile data limit</string>
     <!-- Notification title when Wi-Fi data usage has exceeded limit threshold. [CHAR LIMIT=32] -->
-    <string name="data_usage_wifi_limit_snoozed_title">Wi-Fi data limit exceeded</string>
+    <string name="data_usage_wifi_limit_snoozed_title">Over your Wi-Fi data limit</string>
     <!-- Notification body when data usage has exceeded limit threshold. -->
-    <string name="data_usage_limit_snoozed_body"><xliff:g id="size" example="3.8GB">%s</xliff:g> over specified limit.</string>
+    <string name="data_usage_limit_snoozed_body">You\'ve gone <xliff:g id="size" example="3.8GB">%s</xliff:g> over your set limit</string>
 
     <!-- Notification title when background data usage is limited. [CHAR LIMIT=32] -->
     <string name="data_usage_restricted_title">Background data restricted</string>
@@ -3800,9 +3797,11 @@
     <string name="data_usage_restricted_body">Tap to remove restriction.</string>
 
     <!-- Notification title when there has been recent excessive data usage. [CHAR LIMIT=32] -->
-    <string name="data_usage_rapid_title">Large data usage</string>
+    <string name="data_usage_rapid_title">High mobile data usage</string>
     <!-- Notification body when there has been recent excessive data usage. [CHAR LIMIT=128] -->
-    <string name="data_usage_rapid_body">Your data usage over the last few days is larger than normal. Tap to view usage and settings.</string>
+    <string name="data_usage_rapid_body">Your apps have used more data than usual</string>
+    <!-- Notification body when there has been recent excessive data usage by a specific app. [CHAR LIMIT=128] -->
+    <string name="data_usage_rapid_app_body"><xliff:g id="app" example="Calculator">%s</xliff:g> has used more data than usual</string>
 
     <!-- SSL Certificate dialogs -->
     <!-- Title for an SSL Certificate dialog -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 863a8cd..3b96861 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -218,6 +218,10 @@
   <java-symbol type="id" name="selection_end_handle" />
   <java-symbol type="id" name="insertion_handle" />
   <java-symbol type="id" name="accessibilityActionClickOnClickableSpan" />
+  <java-symbol type="id" name="camera" />
+  <java-symbol type="id" name="mic" />
+  <java-symbol type="id" name="overlay" />
+  <java-symbol type="id" name="app_ops" />
 
   <java-symbol type="attr" name="actionModeShareDrawable" />
   <java-symbol type="attr" name="alertDialogCenterButtons" />
@@ -405,6 +409,7 @@
   <java-symbol type="integer" name="config_wifi_framework_current_network_boost" />
   <java-symbol type="integer" name="config_bluetooth_max_advertisers" />
   <java-symbol type="integer" name="config_bluetooth_max_scan_filters" />
+  <java-symbol type="integer" name="config_bluetooth_max_connected_audio_devices" />
   <java-symbol type="integer" name="config_burnInProtectionMinHorizontalOffset" />
   <java-symbol type="integer" name="config_burnInProtectionMaxHorizontalOffset" />
   <java-symbol type="integer" name="config_burnInProtectionMinVerticalOffset" />
@@ -808,7 +813,6 @@
   <java-symbol type="string" name="number_picker_increment_scroll_action" />
   <java-symbol type="string" name="number_picker_increment_scroll_mode" />
   <java-symbol type="string" name="old_app_action" />
-  <java-symbol type="string" name="old_app_description" />
   <java-symbol type="string" name="older" />
   <java-symbol type="string" name="open_permission_deny" />
   <java-symbol type="string" name="orgTypeCustom" />
@@ -1222,6 +1226,7 @@
   <java-symbol type="array" name="config_disabledUntilUsedPreinstalledCarrierApps" />
   <java-symbol type="array" name="config_callBarringMMI" />
   <java-symbol type="array" name="config_globalActionsList" />
+  <java-symbol type="array" name="config_telephonyEuiccDeviceCapabilities" />
   <java-symbol type="array" name="config_telephonyHardware" />
   <java-symbol type="array" name="config_keySystemUuidMapping" />
   <java-symbol type="array" name="config_gpsParameters" />
@@ -1388,6 +1393,9 @@
 
   <java-symbol type="drawable" name="stat_notify_mmcc_indication_icn" />
   <java-symbol type="drawable" name="autofilled_highlight"/>
+  <java-symbol type="drawable" name="ic_camera" />
+  <java-symbol type="drawable" name="ic_mic" />
+  <java-symbol type="drawable" name="ic_alert_window_layer" />
 
   <java-symbol type="drawable" name="ic_account_circle" />
   <java-symbol type="color" name="user_icon_1" />
@@ -1970,10 +1978,6 @@
   <java-symbol type="string" name="config_wimaxServiceClassname" />
   <java-symbol type="string" name="config_wimaxServiceJarLocation" />
   <java-symbol type="string" name="config_wimaxStateTrackerClassname" />
-  <java-symbol type="string" name="data_usage_3g_limit_snoozed_title" />
-  <java-symbol type="string" name="data_usage_3g_limit_title" />
-  <java-symbol type="string" name="data_usage_4g_limit_snoozed_title" />
-  <java-symbol type="string" name="data_usage_4g_limit_title" />
   <java-symbol type="string" name="data_usage_limit_body" />
   <java-symbol type="string" name="data_usage_limit_snoozed_body" />
   <java-symbol type="string" name="data_usage_mobile_limit_snoozed_title" />
@@ -1986,6 +1990,7 @@
   <java-symbol type="string" name="data_usage_wifi_limit_title" />
   <java-symbol type="string" name="data_usage_rapid_title" />
   <java-symbol type="string" name="data_usage_rapid_body" />
+  <java-symbol type="string" name="data_usage_rapid_app_body" />
   <java-symbol type="string" name="default_wallpaper_component" />
   <java-symbol type="string" name="device_storage_monitor_notification_channel" />
   <java-symbol type="string" name="dlg_ok" />
@@ -2646,7 +2651,7 @@
   <java-symbol type="dimen" name="notification_content_margin_end" />
   <java-symbol type="dimen" name="notification_content_picture_margin" />
   <java-symbol type="dimen" name="notification_content_margin_top" />
-  <java-symbol type="dimen" name="notification_content_margin_bottom" />
+  <java-symbol type="dimen" name="notification_content_margin" />
   <java-symbol type="dimen" name="notification_header_background_height" />
   <java-symbol type="dimen" name="notification_header_height" />
   <java-symbol type="dimen" name="notification_header_expand_icon_size" />
@@ -2776,6 +2781,7 @@
 
   <java-symbol type="string" name="install_carrier_app_notification_title" />
   <java-symbol type="string" name="install_carrier_app_notification_text" />
+  <java-symbol type="string" name="install_carrier_app_notification_text_app_name" />
   <java-symbol type="string" name="install_carrier_app_notification_button" />
   <java-symbol type="string" name="carrier_app_notification_title" />
   <java-symbol type="string" name="carrier_app_notification_text" />
@@ -3111,7 +3117,7 @@
   <java-symbol type="string" name="notification_channel_heavy_weight_app" />
   <java-symbol type="string" name="notification_channel_system_changes" />
   <java-symbol type="string" name="config_defaultAutofillService" />
-  <java-symbol type="string" name="config_defaultTextClassifierService" />
+  <java-symbol type="string" name="config_defaultTextClassifierPackage" />
 
   <java-symbol type="string" name="notification_channel_foreground_service" />
   <java-symbol type="string" name="foreground_service_app_in_background" />
@@ -3233,6 +3239,14 @@
   <java-symbol type="string" name="unsupported_compile_sdk_check_update" />
 
   <java-symbol type="string" name="battery_saver_warning_title" />
+  <java-symbol type="string" name="keyguard_accessibility_pattern_unlock" />
+  <java-symbol type="string" name="keyguard_accessibility_pin_unlock" />
+  <java-symbol type="string" name="keyguard_accessibility_sim_pin_unlock" />
+  <java-symbol type="string" name="keyguard_accessibility_sim_puk_unlock" />
+  <java-symbol type="string" name="keyguard_accessibility_password_unlock" />
+
+  <java-symbol type="dimen" name="status_bar_height_portrait" />
+  <java-symbol type="dimen" name="status_bar_height_landscape" />
 
   <java-symbol type="string" name="global_action_logout" />
   <java-symbol type="string" name="config_mainBuiltInDisplayCutout" />
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 39310a8..cb11d8d 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -126,6 +126,7 @@
         <item name="progressBarStyleInverse">@style/Widget.DeviceDefault.ProgressBar.Inverse</item>
         <item name="progressBarStyleSmallInverse">@style/Widget.DeviceDefault.ProgressBar.Small.Inverse</item>
         <item name="progressBarStyleLargeInverse">@style/Widget.DeviceDefault.ProgressBar.Large.Inverse</item>
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
         <item name="seekBarStyle">@style/Widget.DeviceDefault.SeekBar</item>
         <item name="ratingBarStyle">@style/Widget.DeviceDefault.RatingBar</item>
         <item name="ratingBarStyleIndicator">@style/Widget.DeviceDefault.RatingBar.Indicator</item>
@@ -227,6 +228,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault} with no action bar and no status bar.  This theme
@@ -247,6 +251,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault} with no action bar and no status bar and
@@ -269,6 +276,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault} that has no title bar and translucent
@@ -290,6 +300,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- DeviceDefault theme for dialog windows and activities. This changes the window to be
@@ -319,6 +332,9 @@
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
         <item name="alertDialogTheme">@style/Theme.DeviceDefault.Dialog.Alert</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Dialog} that has a nice minimum width for a
@@ -339,6 +355,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Dialog} without an action bar -->
@@ -358,6 +377,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Dialog_NoActionBar} that has a nice minimum width
@@ -378,6 +400,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- Variant of Theme.DeviceDefault.Dialog that has a fixed size. -->
@@ -414,6 +439,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- DeviceDefault theme for a window without an action bar that will be displayed either
@@ -435,6 +463,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- DeviceDefault theme for a presentation window on a secondary display. -->
@@ -454,6 +485,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- DeviceDefault theme for panel windows. This removes all extraneous window
@@ -475,6 +509,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- DeviceDefault theme for windows that want to have the user's selected wallpaper appear
@@ -495,6 +532,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- DeviceDefault theme for windows that want to have the user's selected wallpaper appear
@@ -515,6 +555,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- DeviceDefault style for input methods, which is used by the
@@ -535,6 +578,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- DeviceDefault style for input methods, which is used by the
@@ -555,6 +601,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <style name="Theme.DeviceDefault.Dialog.Alert" parent="Theme.Material.Dialog.Alert">
@@ -575,6 +624,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <style name="Theme.DeviceDefault.SearchBar" parent="Theme.Material.SearchBar">
@@ -593,6 +645,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <style name="Theme.DeviceDefault.Dialog.NoFrame" parent="Theme.Material.Dialog.NoFrame">
@@ -611,6 +666,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault} with a light-colored style -->
@@ -689,6 +747,7 @@
         <item name="progressBarStyleInverse">@style/Widget.DeviceDefault.Light.ProgressBar.Inverse</item>
         <item name="progressBarStyleSmallInverse">@style/Widget.DeviceDefault.Light.ProgressBar.Small.Inverse</item>
         <item name="progressBarStyleLargeInverse">@style/Widget.DeviceDefault.Light.ProgressBar.Large.Inverse</item>
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
         <item name="seekBarStyle">@style/Widget.DeviceDefault.Light.SeekBar</item>
         <item name="ratingBarStyle">@style/Widget.DeviceDefault.Light.RatingBar</item>
         <item name="ratingBarStyleIndicator">@style/Widget.DeviceDefault.Light.RatingBar.Indicator</item>
@@ -785,6 +844,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar -->
@@ -804,6 +866,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar and no status bar.
@@ -824,6 +889,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar and no status bar
@@ -846,6 +914,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} that has no title bar and translucent
@@ -867,6 +938,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- DeviceDefault light theme for dialog windows and activities. This changes the window to be
@@ -894,6 +968,9 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog} that has a nice minimum width for a
@@ -914,6 +991,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
      <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog} without an action bar -->
@@ -933,6 +1013,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog_NoActionBar} that has a nice minimum
@@ -953,6 +1036,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- Variant of Theme.DeviceDefault.Dialog that has a fixed size. -->
@@ -999,6 +1085,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- DeviceDefault light theme for a window without an action bar that will be displayed either
@@ -1020,6 +1109,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- DeviceDefault light theme for a presentation window on a secondary display. -->
@@ -1039,6 +1131,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- DeviceDefault light theme for panel windows. This removes all extraneous window
@@ -1060,6 +1155,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <style name="Theme.DeviceDefault.Light.Dialog.Alert" parent="Theme.Material.Light.Dialog.Alert">
@@ -1080,6 +1178,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <style name="Theme.DeviceDefault.Light.SearchBar" parent="Theme.Material.Light.SearchBar">
@@ -1098,6 +1199,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <style name="Theme.DeviceDefault.Light.Voice" parent="Theme.Material.Light.Voice">
@@ -1116,6 +1220,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- DeviceDefault theme for a window that should look like the Settings app.  -->
@@ -1147,6 +1254,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- @hide DeviceDefault theme for a window that should use Settings theme colors
@@ -1166,6 +1276,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <style name="Theme.DeviceDefault.QuickSettings.Dialog" parent="Theme.DeviceDefault.Light.Dialog">
@@ -1175,6 +1288,9 @@
         <item name="colorSecondary">@color/secondary_device_default_settings_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
         <item name="alertDialogTheme">@style/Theme.DeviceDefault.Light.Dialog.Alert</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Settings_Dark} with no action bar -->
@@ -1195,6 +1311,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <style name="Theme.DeviceDefault.Settings.Dialog" parent="Theme.Material.Settings.Dialog">
@@ -1214,6 +1333,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <style name="Theme.DeviceDefault.Settings.DialogWhenLarge" parent="Theme.Material.Settings.DialogWhenLarge">
@@ -1233,6 +1355,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <style name="Theme.DeviceDefault.Settings.Dialog.Alert" parent="Theme.Material.Settings.Dialog.Alert">
@@ -1252,6 +1377,9 @@
         <!-- Button styles -->
         <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
         <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <style name="Theme.DeviceDefault.Settings.Dialog.NoActionBar" parent="Theme.DeviceDefault.Light.Dialog.NoActionBar" />
@@ -1278,6 +1406,9 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+
+        <!-- Progress bar attributes -->
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
     </style>
 
     <!-- DeviceDefault theme for the default system theme.  -->
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index 6ae0ef3..76d9ea6 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -259,6 +259,7 @@
         <item name="progressBarStyleInverse">@style/Widget.Material.ProgressBar.Inverse</item>
         <item name="progressBarStyleSmallInverse">@style/Widget.Material.ProgressBar.Small.Inverse</item>
         <item name="progressBarStyleLargeInverse">@style/Widget.Material.ProgressBar.Large.Inverse</item>
+        <item name="progressBarCornerRadius">@dimen/progress_bar_corner_material</item>
         <item name="seekBarStyle">@style/Widget.Material.SeekBar</item>
         <item name="ratingBarStyle">@style/Widget.Material.RatingBar</item>
         <item name="ratingBarStyleIndicator">@style/Widget.Material.RatingBar.Indicator</item>
@@ -631,6 +632,7 @@
         <item name="progressBarStyleInverse">@style/Widget.Material.Light.ProgressBar.Inverse</item>
         <item name="progressBarStyleSmallInverse">@style/Widget.Material.Light.ProgressBar.Small.Inverse</item>
         <item name="progressBarStyleLargeInverse">@style/Widget.Material.Light.ProgressBar.Large.Inverse</item>
+        <item name="progressBarCornerRadius">@dimen/progress_bar_corner_material</item>
         <item name="seekBarStyle">@style/Widget.Material.Light.SeekBar</item>
         <item name="ratingBarStyle">@style/Widget.Material.Light.RatingBar</item>
         <item name="ratingBarStyleIndicator">@style/Widget.Material.Light.RatingBar.Indicator</item>
diff --git a/core/tests/BTtraffic/Android.mk b/core/tests/BTtraffic/Android.mk
index 7d83527..f826ae9 100644
--- a/core/tests/BTtraffic/Android.mk
+++ b/core/tests/BTtraffic/Android.mk
@@ -9,6 +9,7 @@
     $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := bttraffic
+LOCAL_SDK_VERSION := current
 LOCAL_CERTIFICATE := platform
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/ConnectivityManagerTest/Android.mk b/core/tests/ConnectivityManagerTest/Android.mk
index 5ed93f3..8c0a330 100644
--- a/core/tests/ConnectivityManagerTest/Android.mk
+++ b/core/tests/ConnectivityManagerTest/Android.mk
@@ -25,6 +25,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := ConnectivityManagerTest
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_CERTIFICATE := platform
 
diff --git a/core/tests/SvcMonitor/Android.mk b/core/tests/SvcMonitor/Android.mk
index 2b80455..94ddccb 100644
--- a/core/tests/SvcMonitor/Android.mk
+++ b/core/tests/SvcMonitor/Android.mk
@@ -9,6 +9,7 @@
     $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := svcmonitor
+LOCAL_SDK_VERSION := current
 LOCAL_CERTIFICATE := platform
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/bandwidthtests/Android.mk b/core/tests/bandwidthtests/Android.mk
index ff9a0fe..dc80d00 100644
--- a/core/tests/bandwidthtests/Android.mk
+++ b/core/tests/bandwidthtests/Android.mk
@@ -29,6 +29,7 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := junit
 LOCAL_PACKAGE_NAME := BandwidthTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 include $(BUILD_PACKAGE)
 
diff --git a/core/tests/bluetoothtests/Android.mk b/core/tests/bluetoothtests/Android.mk
index 744e5b0..bb4e302 100644
--- a/core/tests/bluetoothtests/Android.mk
+++ b/core/tests/bluetoothtests/Android.mk
@@ -11,6 +11,7 @@
 LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
 LOCAL_STATIC_JAVA_LIBRARIES := junit
 LOCAL_PACKAGE_NAME := BluetoothTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_CERTIFICATE := platform
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk
index 2ea1b46..2d25c7811 100644
--- a/core/tests/coretests/Android.mk
+++ b/core/tests/coretests/Android.mk
@@ -56,6 +56,7 @@
     framework-atb-backward-compatibility \
 
 LOCAL_PACKAGE_NAME := FrameworksCoreTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_COMPATIBILITY_SUITE := device-tests
 
 LOCAL_CERTIFICATE := platform
diff --git a/core/tests/coretests/BinderProxyCountingTestApp/Android.mk b/core/tests/coretests/BinderProxyCountingTestApp/Android.mk
index e31d50f..c3af6bd 100644
--- a/core/tests/coretests/BinderProxyCountingTestApp/Android.mk
+++ b/core/tests/coretests/BinderProxyCountingTestApp/Android.mk
@@ -21,6 +21,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := BinderProxyCountingTestApp
+LOCAL_SDK_VERSION := current
 LOCAL_CERTIFICATE := platform
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/coretests/BinderProxyCountingTestService/Android.mk b/core/tests/coretests/BinderProxyCountingTestService/Android.mk
index a63cf0e..34016ed 100644
--- a/core/tests/coretests/BinderProxyCountingTestService/Android.mk
+++ b/core/tests/coretests/BinderProxyCountingTestService/Android.mk
@@ -21,6 +21,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := BinderProxyCountingTestService
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_CERTIFICATE := platform
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/coretests/BstatsTestApp/Android.mk b/core/tests/coretests/BstatsTestApp/Android.mk
index 6280257..e04536b 100644
--- a/core/tests/coretests/BstatsTestApp/Android.mk
+++ b/core/tests/coretests/BstatsTestApp/Android.mk
@@ -25,6 +25,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := BstatsTestApp
+LOCAL_SDK_VERSION := current
 LOCAL_CERTIFICATE := platform
 LOCAL_DEX_PREOPT := false
 LOCAL_PROGUARD_ENABLED := disabled
diff --git a/core/tests/coretests/DisabledTestApp/Android.mk b/core/tests/coretests/DisabledTestApp/Android.mk
index a5daedf..e4304f7 100644
--- a/core/tests/coretests/DisabledTestApp/Android.mk
+++ b/core/tests/coretests/DisabledTestApp/Android.mk
@@ -6,6 +6,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := DisabledTestApp
+LOCAL_SDK_VERSION := current
 LOCAL_CERTIFICATE := platform
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/coretests/EnabledTestApp/Android.mk b/core/tests/coretests/EnabledTestApp/Android.mk
index 4b986d3..cd37f08 100644
--- a/core/tests/coretests/EnabledTestApp/Android.mk
+++ b/core/tests/coretests/EnabledTestApp/Android.mk
@@ -6,6 +6,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := EnabledTestApp
+LOCAL_SDK_VERSION := current
 LOCAL_CERTIFICATE := platform
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/coretests/apks/FrameworkCoreTests_apk.mk b/core/tests/coretests/apks/FrameworkCoreTests_apk.mk
index 1e03270..8a7d72a5 100644
--- a/core/tests/coretests/apks/FrameworkCoreTests_apk.mk
+++ b/core/tests/coretests/apks/FrameworkCoreTests_apk.mk
@@ -6,6 +6,7 @@
 
 # Make sure every package name gets the FrameworkCoreTests_ prefix.
 LOCAL_PACKAGE_NAME := FrameworkCoreTests_$(LOCAL_PACKAGE_NAME)
+LOCAL_SDK_VERSION := current
 
 # Every package should have a native library
 LOCAL_JNI_SHARED_LIBRARIES := libframeworks_coretests_jni
diff --git a/core/tests/coretests/assets/fonts/ascent10em-descent10em.ttf b/core/tests/coretests/assets/fonts/ascent10em-descent10em.ttf
new file mode 100644
index 0000000..47ab623
--- /dev/null
+++ b/core/tests/coretests/assets/fonts/ascent10em-descent10em.ttf
Binary files differ
diff --git a/core/tests/coretests/assets/fonts/ascent10em-descent10em.ttx b/core/tests/coretests/assets/fonts/ascent10em-descent10em.ttx
new file mode 100644
index 0000000..5540277
--- /dev/null
+++ b/core/tests/coretests/assets/fonts/ascent10em-descent10em.ttx
@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.0">
+
+  <GlyphOrder>
+    <GlyphID id="0" name=".notdef"/>
+    <GlyphID id="1" name="1em"/>
+  </GlyphOrder>
+
+  <head>
+    <tableVersion value="1.0"/>
+    <fontRevision value="1.0"/>
+    <checkSumAdjustment value="0x640cdb2f"/>
+    <magicNumber value="0x5f0f3cf5"/>
+    <flags value="00000000 00000011"/>
+    <unitsPerEm value="1000"/>
+    <created value="Fri Mar 17 07:26:00 2017"/>
+    <macStyle value="00000000 00000000"/>
+    <lowestRecPPEM value="7"/>
+    <fontDirectionHint value="2"/>
+    <glyphDataFormat value="0"/>
+  </head>
+
+  <hhea>
+    <tableVersion value="0x10000"/>
+    <ascent value="10000"/>
+    <descent value="-10000"/>
+    <lineGap value="0"/>
+    <caretSlopeRise value="1"/>
+    <caretSlopeRun value="0"/>
+    <caretOffset value="0"/>
+    <reserved0 value="0"/>
+    <reserved1 value="0"/>
+    <reserved2 value="0"/>
+    <reserved3 value="0"/>
+    <metricDataFormat value="0"/>
+  </hhea>
+
+  <maxp>
+    <tableVersion value="0x10000"/>
+    <maxZones value="0"/>
+    <maxTwilightPoints value="0"/>
+    <maxStorage value="0"/>
+    <maxFunctionDefs value="0"/>
+    <maxInstructionDefs value="0"/>
+    <maxStackElements value="0"/>
+    <maxSizeOfInstructions value="0"/>
+    <maxComponentElements value="0"/>
+  </maxp>
+
+  <OS_2>
+    <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
+         will be recalculated by the compiler -->
+    <version value="3"/>
+    <xAvgCharWidth value="594"/>
+    <usWeightClass value="400"/>
+    <usWidthClass value="5"/>
+    <fsType value="00000000 00001000"/>
+    <ySubscriptXSize value="650"/>
+    <ySubscriptYSize value="600"/>
+    <ySubscriptXOffset value="0"/>
+    <ySubscriptYOffset value="75"/>
+    <ySuperscriptXSize value="650"/>
+    <ySuperscriptYSize value="600"/>
+    <ySuperscriptXOffset value="0"/>
+    <ySuperscriptYOffset value="350"/>
+    <yStrikeoutSize value="50"/>
+    <yStrikeoutPosition value="300"/>
+    <sFamilyClass value="0"/>
+    <panose>
+      <bFamilyType value="0"/>
+      <bSerifStyle value="0"/>
+      <bWeight value="5"/>
+      <bProportion value="0"/>
+      <bContrast value="0"/>
+      <bStrokeVariation value="0"/>
+      <bArmStyle value="0"/>
+      <bLetterForm value="0"/>
+      <bMidline value="0"/>
+      <bXHeight value="0"/>
+    </panose>
+    <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/>
+    <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
+    <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
+    <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
+    <achVendID value="UKWN"/>
+    <fsSelection value="00000000 01000000"/>
+    <usFirstCharIndex value="32"/>
+    <usLastCharIndex value="122"/>
+    <sTypoAscender value="800"/>
+    <sTypoDescender value="-200"/>
+    <sTypoLineGap value="200"/>
+    <usWinAscent value="1000"/>
+    <usWinDescent value="200"/>
+    <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
+    <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
+    <sxHeight value="500"/>
+    <sCapHeight value="700"/>
+    <usDefaultChar value="0"/>
+    <usBreakChar value="32"/>
+    <usMaxContext value="0"/>
+  </OS_2>
+
+  <hmtx>
+    <mtx name=".notdef" width="1000" lsb="0"/>
+    <mtx name="1em" width="1000" lsb="0"/>
+  </hmtx>
+
+  <cmap>
+    <tableVersion version="0"/>
+    <cmap_format_4 platformID="3" platEncID="10" language="0">
+      <map code="0x000A" name="1em" /> <!-- LINE FEED -->
+      <map code="0x000D" name="1em" /> <!-- CARRIAGE RETURN -->
+    </cmap_format_4>
+  </cmap>
+
+  <loca>
+    <!-- The 'loca' table will be calculated by the compiler -->
+  </loca>
+
+  <glyf>
+    <TTGlyph name=".notdef" xMin="0" yMin="0" xMax="0" yMax="0" />
+    <TTGlyph name="1em" xMin="0" yMin="0" xMax="0" yMax="0" />
+  </glyf>
+
+  <name>
+    <namerecord nameID="0" platformID="3" platEncID="1" langID="0x409">
+      Copyright (C) 2017 The Android Open Source Project
+    </namerecord>
+    <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
+      Sample Font
+    </namerecord>
+    <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
+      Regular
+    </namerecord>
+    <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
+      Sample Font
+    </namerecord>
+    <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
+      SampleFont-Regular
+    </namerecord>
+    <namerecord nameID="13" platformID="3" platEncID="1" langID="0x409">
+      Licensed under the Apache License, Version 2.0 (the "License");
+      you may not use this file except in compliance with the License.
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      See the License for the specific language governing permissions and
+      limitations under the License.
+    </namerecord>
+    <namerecord nameID="14" platformID="3" platEncID="1" langID="0x409">
+      http://www.apache.org/licenses/LICENSE-2.0
+    </namerecord>
+  </name>
+
+  <post>
+    <formatType value="3.0"/>
+    <italicAngle value="0.0"/>
+    <underlinePosition value="-75"/>
+    <underlineThickness value="50"/>
+    <isFixedPitch value="0"/>
+    <minMemType42 value="0"/>
+    <maxMemType42 value="0"/>
+    <minMemType1 value="0"/>
+    <maxMemType1 value="0"/>
+  </post>
+
+</ttFont>
diff --git a/core/tests/coretests/res/values/styles.xml b/core/tests/coretests/res/values/styles.xml
index 7a90197..ef3a481 100644
--- a/core/tests/coretests/res/values/styles.xml
+++ b/core/tests/coretests/res/values/styles.xml
@@ -19,4 +19,16 @@
         <item name="android:taskToBackEnterAnimation">@null</item>
         <item name="android:taskToBackExitAnimation">@null</item>
     </style>
+
+    <style name="LayoutInDisplayCutoutModeUnset">
+    </style>
+    <style name="LayoutInDisplayCutoutModeDefault">
+        <item name="android:windowLayoutInDisplayCutoutMode">default</item>
+    </style>
+    <style name="LayoutInDisplayCutoutModeAlways">
+        <item name="android:windowLayoutInDisplayCutoutMode">always</item>
+    </style>
+    <style name="LayoutInDisplayCutoutModeNever">
+        <item name="android:windowLayoutInDisplayCutoutMode">never</item>
+    </style>
 </resources>
diff --git a/core/tests/coretests/src/android/app/backup/FullBackupTest.java b/core/tests/coretests/src/android/app/backup/FullBackupTest.java
index bc6fc15..58ee7a7 100644
--- a/core/tests/coretests/src/android/app/backup/FullBackupTest.java
+++ b/core/tests/coretests/src/android/app/backup/FullBackupTest.java
@@ -19,6 +19,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import android.app.backup.FullBackup.BackupScheme.PathWithRequiredFlags;
 import android.content.Context;
 import android.support.test.filters.LargeTest;
 import android.test.AndroidTestCase;
@@ -43,8 +44,8 @@
     private XmlPullParser mXpp;
     private Context mContext;
 
-    Map<String, Set<String>> includeMap;
-    Set<String> excludesSet;
+    Map<String, Set<PathWithRequiredFlags>> includeMap;
+    Set<PathWithRequiredFlags> excludesSet;
 
     @Override
     public void setUp() throws Exception {
@@ -52,8 +53,8 @@
         mXpp = mFactory.newPullParser();
         mContext = getContext();
 
-        includeMap = new ArrayMap();
-        excludesSet = new ArraySet();
+        includeMap = new ArrayMap<>();
+        excludesSet = new ArraySet<>();
     }
 
     public void testparseBackupSchemeFromXml_onlyInclude() throws Exception {
@@ -68,11 +69,127 @@
         assertEquals("Excluding files when there was no <exclude/> tag.", 0, excludesSet.size());
         assertEquals("Unexpected number of <include/>s", 1, includeMap.size());
 
-        Set<String> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
+        Set<PathWithRequiredFlags> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
         assertEquals("Didn't find expected file domain include.", 1, fileDomainIncludes.size());
+        PathWithRequiredFlags include = fileDomainIncludes.iterator().next();
         assertEquals("Invalid path parsed for <include/>",
                 new File(mContext.getFilesDir(), "onlyInclude.txt").getCanonicalPath(),
-                fileDomainIncludes.iterator().next());
+                include.getPath());
+        assertEquals("Invalid requireFlags parsed for <include/>", 0, include.getRequiredFlags());
+    }
+
+    public void testparseBackupSchemeFromXml_onlyIncludeRequireEncryptionFlag() throws Exception {
+        mXpp.setInput(new StringReader(
+                "<full-backup-content>" +
+                        "<include path=\"onlyInclude.txt\" domain=\"file\""
+                        + " requireFlags=\"clientSideEncryption\"/>" +
+                "</full-backup-content>"));
+
+        FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext);
+        bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap);
+
+        assertEquals("Excluding files when there was no <exclude/> tag.", 0, excludesSet.size());
+        assertEquals("Unexpected number of <include/>s", 1, includeMap.size());
+
+        Set<PathWithRequiredFlags> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
+        assertEquals("Didn't find expected file domain include.", 1, fileDomainIncludes.size());
+        PathWithRequiredFlags include = fileDomainIncludes.iterator().next();
+        assertEquals("Invalid path parsed for <include/>",
+                new File(mContext.getFilesDir(), "onlyInclude.txt").getCanonicalPath(),
+                include.getPath());
+        assertEquals("Invalid requireFlags parsed for <include/>",
+                BackupAgent.FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED,
+                include.getRequiredFlags());
+    }
+
+    public void testparseBackupSchemeFromXml_onlyIncludeRequireD2DFlag() throws Exception {
+        mXpp.setInput(new StringReader(
+                "<full-backup-content>" +
+                        "<include path=\"onlyInclude.txt\" domain=\"file\""
+                        + " requireFlags=\"deviceToDeviceTransfer\"/>" +
+                "</full-backup-content>"));
+
+        FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext);
+        bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap);
+
+        assertEquals("Excluding files when there was no <exclude/> tag.", 0, excludesSet.size());
+        assertEquals("Unexpected number of <include/>s", 1, includeMap.size());
+
+        Set<PathWithRequiredFlags> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
+        assertEquals("Didn't find expected file domain include.", 1, fileDomainIncludes.size());
+        PathWithRequiredFlags include = fileDomainIncludes.iterator().next();
+        assertEquals("Invalid path parsed for <include/>",
+                new File(mContext.getFilesDir(), "onlyInclude.txt").getCanonicalPath(),
+                include.getPath());
+        assertEquals("Invalid requireFlags parsed for <include/>",
+                BackupAgent.FLAG_DEVICE_TO_DEVICE_TRANSFER,
+                include.getRequiredFlags());
+    }
+
+    public void testparseBackupSchemeFromXml_onlyIncludeRequireEncryptionAndD2DFlags()
+            throws Exception {
+        mXpp.setInput(new StringReader(
+                "<full-backup-content>" +
+                        "<include path=\"onlyInclude.txt\" domain=\"file\""
+                        + " requireFlags=\"clientSideEncryption|deviceToDeviceTransfer\"/>" +
+                "</full-backup-content>"));
+
+        FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext);
+        bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap);
+
+        assertEquals("Excluding files when there was no <exclude/> tag.", 0, excludesSet.size());
+        assertEquals("Unexpected number of <include/>s", 1, includeMap.size());
+
+        Set<PathWithRequiredFlags> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
+        assertEquals("Didn't find expected file domain include.", 1, fileDomainIncludes.size());
+        PathWithRequiredFlags include = fileDomainIncludes.iterator().next();
+        assertEquals("Invalid path parsed for <include/>",
+                new File(mContext.getFilesDir(), "onlyInclude.txt").getCanonicalPath(),
+                include.getPath());
+        assertEquals("Invalid requireFlags parsed for <include/>",
+                BackupAgent.FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED
+                        | BackupAgent.FLAG_DEVICE_TO_DEVICE_TRANSFER,
+                include.getRequiredFlags());
+    }
+
+    public void testparseBackupSchemeFromXml_onlyIncludeRequireD2DFlagAndIngoreGarbage()
+            throws Exception {
+        mXpp.setInput(new StringReader(
+                "<full-backup-content>" +
+                        "<include path=\"onlyInclude.txt\" domain=\"file\""
+                        + " requireFlags=\"deviceToDeviceTransfer|garbageFlag\"/>" +
+                "</full-backup-content>"));
+
+        FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext);
+        bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap);
+
+        assertEquals("Excluding files when there was no <exclude/> tag.", 0, excludesSet.size());
+        assertEquals("Unexpected number of <include/>s", 1, includeMap.size());
+
+        Set<PathWithRequiredFlags> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
+        assertEquals("Didn't find expected file domain include.", 1, fileDomainIncludes.size());
+        PathWithRequiredFlags include = fileDomainIncludes.iterator().next();
+        assertEquals("Invalid path parsed for <include/>",
+                new File(mContext.getFilesDir(), "onlyInclude.txt").getCanonicalPath(),
+                include.getPath());
+        assertEquals("Invalid requireFlags parsed for <include/>",
+                BackupAgent.FLAG_DEVICE_TO_DEVICE_TRANSFER,
+                include.getRequiredFlags());
+    }
+
+    public void testparseBackupSchemeFromXml_onlyExcludeRequireFlagsNotSupported()
+            throws Exception {
+        mXpp.setInput(new StringReader(
+                "<full-backup-content>" +
+                        "<exclude path=\"onlyExclude.txt\" domain=\"file\""
+                        + " requireFlags=\"deviceToDeviceTransfer\"/>" +
+                "</full-backup-content>"));
+
+        try {
+            FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext);
+            bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap);
+            fail("Having more than 3 attributes in exclude should throw an XmlPullParserException");
+        } catch (XmlPullParserException expected) {}
     }
 
     public void testparseBackupSchemeFromXml_onlyExclude() throws Exception {
@@ -88,7 +205,7 @@
         assertEquals("Unexpected number of <exclude/>s", 1, excludesSet.size());
         assertEquals("Invalid path parsed for <exclude/>",
                 new File(mContext.getFilesDir(), "onlyExclude.txt").getCanonicalPath(),
-                excludesSet.iterator().next());
+                excludesSet.iterator().next().getPath());
     }
 
     public void testparseBackupSchemeFromXml_includeAndExclude() throws Exception {
@@ -101,16 +218,16 @@
         FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext);
         bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap);
 
-        Set<String> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
+        Set<PathWithRequiredFlags> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
         assertEquals("Didn't find expected file domain include.", 1, fileDomainIncludes.size());
         assertEquals("Invalid path parsed for <include/>",
                 new File(mContext.getFilesDir(), "include.txt").getCanonicalPath(),
-                fileDomainIncludes.iterator().next());
+                fileDomainIncludes.iterator().next().getPath());
 
         assertEquals("Unexpected number of <exclude/>s", 1, excludesSet.size());
         assertEquals("Invalid path parsed for <exclude/>",
                 new File(mContext.getFilesDir(), "exclude.txt").getCanonicalPath(),
-                excludesSet.iterator().next());
+                excludesSet.iterator().next().getPath());
     }
 
     public void testparseBackupSchemeFromXml_lotsOfIncludesAndExcludes() throws Exception {
@@ -126,61 +243,74 @@
                         "<include path=\"include4.xml\" domain=\"sharedpref\"/>" +
                 "</full-backup-content>"));
 
-
         FullBackup.BackupScheme bs = FullBackup.getBackupSchemeForTest(mContext);
         bs.parseBackupSchemeFromXmlLocked(mXpp, excludesSet, includeMap);
 
-        Set<String> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
+        Set<PathWithRequiredFlags> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
         assertEquals("Didn't find expected file domain include.", 1, fileDomainIncludes.size());
         assertEquals("Invalid path parsed for <include/>",
                 new File(mContext.getFilesDir(), "include1.txt").getCanonicalPath(),
-                fileDomainIncludes.iterator().next());
+                fileDomainIncludes.iterator().next().getPath());
 
-        Set<String> databaseDomainIncludes = includeMap.get(FullBackup.DATABASE_TREE_TOKEN);
+        Set<PathWithRequiredFlags> databaseDomainIncludes =
+                includeMap.get(FullBackup.DATABASE_TREE_TOKEN);
+        Set<String> databaseDomainIncludesPaths = new ArraySet<>();
+        for (PathWithRequiredFlags databaseInclude : databaseDomainIncludes) {
+            databaseDomainIncludesPaths.add(databaseInclude.getPath());
+        }
         // Three expected here because of "-journal" and "-wal" files
         assertEquals("Didn't find expected database domain include.",
                 3, databaseDomainIncludes.size());
         assertTrue("Invalid path parsed for <include/>",
-                databaseDomainIncludes.contains(
+                databaseDomainIncludesPaths.contains(
                         new File(mContext.getDatabasePath("foo").getParentFile(), "include2.txt")
                                 .getCanonicalPath()));
         assertTrue("Invalid path parsed for <include/>",
-                databaseDomainIncludes.contains(
+                databaseDomainIncludesPaths.contains(
                         new File(
                                 mContext.getDatabasePath("foo").getParentFile(),
                                 "include2.txt-journal")
                                 .getCanonicalPath()));
         assertTrue("Invalid path parsed for <include/>",
-                databaseDomainIncludes.contains(
+                databaseDomainIncludesPaths.contains(
                         new File(
                                 mContext.getDatabasePath("foo").getParentFile(),
                                 "include2.txt-wal")
                                 .getCanonicalPath()));
 
-        List<String> sharedPrefDomainIncludes = new ArrayList<String>(
+        List<PathWithRequiredFlags> sharedPrefDomainIncludes = new ArrayList<PathWithRequiredFlags>(
                 includeMap.get(FullBackup.SHAREDPREFS_TREE_TOKEN));
-        Collections.sort(sharedPrefDomainIncludes);
+        ArrayList<String> sharedPrefDomainIncludesPaths = new ArrayList<>();
+        for (PathWithRequiredFlags sharedPrefInclude : sharedPrefDomainIncludes) {
+            sharedPrefDomainIncludesPaths.add(sharedPrefInclude.getPath());
+        }
+        // Sets are annoying to iterate over b/c order isn't enforced - convert to an array and
+        // sort lexicographically.
+        Collections.sort(sharedPrefDomainIncludesPaths);
 
         assertEquals("Didn't find expected sharedpref domain include.",
                 3, sharedPrefDomainIncludes.size());
         assertEquals("Invalid path parsed for <include/>",
                 new File(mContext.getSharedPrefsFile("foo").getParentFile(), "include3")
                         .getCanonicalPath(),
-                sharedPrefDomainIncludes.get(0));
+                sharedPrefDomainIncludesPaths.get(0));
         assertEquals("Invalid path parsed for <include/>",
                 new File(mContext.getSharedPrefsFile("foo").getParentFile(), "include3.xml")
                         .getCanonicalPath(),
-                sharedPrefDomainIncludes.get(1));
+                sharedPrefDomainIncludesPaths.get(1));
         assertEquals("Invalid path parsed for <include/>",
                 new File(mContext.getSharedPrefsFile("foo").getParentFile(), "include4.xml")
                         .getCanonicalPath(),
-                sharedPrefDomainIncludes.get(2));
+                sharedPrefDomainIncludesPaths.get(2));
 
 
         assertEquals("Unexpected number of <exclude/>s", 7, excludesSet.size());
         // Sets are annoying to iterate over b/c order isn't enforced - convert to an array and
         // sort lexicographically.
-        List<String> arrayedSet = new ArrayList<String>(excludesSet);
+        ArrayList<String> arrayedSet = new ArrayList<>();
+        for (PathWithRequiredFlags exclude : excludesSet) {
+            arrayedSet.add(exclude.getPath());
+        }
         Collections.sort(arrayedSet);
 
         assertEquals("Invalid path parsed for <exclude/>",
@@ -260,9 +390,10 @@
 
         assertEquals("Didn't throw away invalid \"..\" path.", 0, includeMap.size());
 
-        Set<String> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
+        Set<PathWithRequiredFlags> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
         assertNull("Didn't throw away invalid \"..\" path.", fileDomainIncludes);
     }
+
     public void testDoubleDotInPath_isIgnored() throws Exception {
         mXpp.setInput(new StringReader(
                 "<full-backup-content>" +
@@ -274,7 +405,7 @@
 
         assertEquals("Didn't throw away invalid \"..\" path.", 0, includeMap.size());
 
-        Set<String> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
+        Set<PathWithRequiredFlags> fileDomainIncludes = includeMap.get(FullBackup.FILES_TREE_TOKEN);
         assertNull("Didn't throw away invalid \"..\" path.", fileDomainIncludes);
     }
 
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
index e575650..3eefc36 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
@@ -24,6 +24,9 @@
 import static android.app.servertransaction.ActivityLifecycleItem.ON_START;
 import static android.app.servertransaction.ActivityLifecycleItem.ON_STOP;
 import static android.app.servertransaction.ActivityLifecycleItem.PRE_ON_CREATE;
+import static android.app.servertransaction.ActivityLifecycleItem.UNDEFINED;
+
+import static junit.framework.Assert.assertEquals;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.mockito.ArgumentMatchers.any;
@@ -48,6 +51,10 @@
 import org.mockito.InOrder;
 
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
 
 /** Test {@link TransactionExecutor} logic. */
 @RunWith(AndroidJUnit4.class)
@@ -56,6 +63,7 @@
 public class TransactionExecutorTests {
 
     private TransactionExecutor mExecutor;
+    private TransactionExecutorHelper mExecutorHelper;
     private ClientTransactionHandler mTransactionHandler;
     private ActivityClientRecord mClientRecord;
 
@@ -67,6 +75,7 @@
         when(mTransactionHandler.getActivityClient(any())).thenReturn(mClientRecord);
 
         mExecutor = spy(new TransactionExecutor(mTransactionHandler));
+        mExecutorHelper = new TransactionExecutorHelper();
     }
 
     @Test
@@ -166,10 +175,42 @@
                 pathExcludeLast(ON_DESTROY));
     }
 
+    @Test(expected = IllegalArgumentException.class)
+    public void testLifecycleUndefinedStartState() {
+        mClientRecord.setState(UNDEFINED);
+        path(ON_CREATE);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testLifecycleUndefinedFinishState() {
+        mClientRecord.setState(PRE_ON_CREATE);
+        path(UNDEFINED);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testLifecycleInvalidPreOnCreateFinishState() {
+        mClientRecord.setState(ON_CREATE);
+        path(PRE_ON_CREATE);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testLifecycleInvalidOnRestartStartState() {
+        mClientRecord.setState(ON_RESTART);
+        path(ON_RESUME);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testLifecycleInvalidOnRestartFinishState() {
+        mClientRecord.setState(ON_CREATE);
+        path(ON_RESTART);
+    }
+
     @Test
     public void testTransactionResolution() {
         ClientTransactionItem callback1 = mock(ClientTransactionItem.class);
+        when(callback1.getPostExecutionState()).thenReturn(UNDEFINED);
         ClientTransactionItem callback2 = mock(ClientTransactionItem.class);
+        when(callback2.getPostExecutionState()).thenReturn(UNDEFINED);
         ActivityLifecycleItem stateRequest = mock(ActivityLifecycleItem.class);
         IBinder token = mock(IBinder.class);
 
@@ -189,7 +230,7 @@
     }
 
     @Test
-    public void testRequiredStateResolution() {
+    public void testActivityResultRequiredStateResolution() {
         ActivityResultItem activityResultItem = ActivityResultItem.obtain(new ArrayList<>());
 
         IBinder token = mock(IBinder.class);
@@ -197,20 +238,161 @@
                 token /* activityToken */);
         transaction.addCallback(activityResultItem);
 
+        // Verify resolution that should get to onPause
+        mClientRecord.setState(ON_RESUME);
         mExecutor.executeCallbacks(transaction);
-
         verify(mExecutor, times(1)).cycleToPath(eq(mClientRecord), eq(ON_PAUSE));
+
+        // Verify resolution that should get to onStart
+        mClientRecord.setState(ON_STOP);
+        mExecutor.executeCallbacks(transaction);
+        verify(mExecutor, times(1)).cycleToPath(eq(mClientRecord), eq(ON_START));
+    }
+
+    @Test
+    public void testClosestStateResolutionForSameState() {
+        final int[] allStates = new int[] {
+                ON_CREATE, ON_START, ON_RESUME, ON_PAUSE, ON_STOP, ON_DESTROY};
+
+        mClientRecord.setState(ON_CREATE);
+        assertEquals(ON_CREATE, mExecutorHelper.getClosestOfStates(mClientRecord,
+                shuffledArray(allStates)));
+
+        mClientRecord.setState(ON_START);
+        assertEquals(ON_START, mExecutorHelper.getClosestOfStates(mClientRecord,
+                shuffledArray(allStates)));
+
+        mClientRecord.setState(ON_RESUME);
+        assertEquals(ON_RESUME, mExecutorHelper.getClosestOfStates(mClientRecord,
+                shuffledArray(allStates)));
+
+        mClientRecord.setState(ON_PAUSE);
+        assertEquals(ON_PAUSE, mExecutorHelper.getClosestOfStates(mClientRecord,
+                shuffledArray(allStates)));
+
+        mClientRecord.setState(ON_STOP);
+        assertEquals(ON_STOP, mExecutorHelper.getClosestOfStates(mClientRecord,
+                shuffledArray(allStates)));
+
+        mClientRecord.setState(ON_DESTROY);
+        assertEquals(ON_DESTROY, mExecutorHelper.getClosestOfStates(mClientRecord,
+                shuffledArray(allStates)));
+
+        mClientRecord.setState(PRE_ON_CREATE);
+        assertEquals(PRE_ON_CREATE, mExecutorHelper.getClosestOfStates(mClientRecord,
+                new int[] {PRE_ON_CREATE}));
+    }
+
+    @Test
+    public void testClosestStateResolution() {
+        mClientRecord.setState(PRE_ON_CREATE);
+        assertEquals(ON_CREATE, mExecutorHelper.getClosestOfStates(mClientRecord, shuffledArray(
+                new int[] {ON_CREATE, ON_START, ON_RESUME, ON_PAUSE, ON_STOP, ON_DESTROY})));
+        assertEquals(ON_START, mExecutorHelper.getClosestOfStates(mClientRecord, shuffledArray(
+                new int[] {ON_START, ON_RESUME, ON_PAUSE, ON_STOP, ON_DESTROY})));
+        assertEquals(ON_RESUME, mExecutorHelper.getClosestOfStates(mClientRecord, shuffledArray(
+                new int[] {ON_RESUME, ON_PAUSE, ON_STOP, ON_DESTROY})));
+        assertEquals(ON_PAUSE, mExecutorHelper.getClosestOfStates(mClientRecord, shuffledArray(
+                new int[] {ON_PAUSE, ON_STOP, ON_DESTROY})));
+        assertEquals(ON_STOP, mExecutorHelper.getClosestOfStates(mClientRecord, shuffledArray(
+                new int[] {ON_STOP, ON_DESTROY})));
+        assertEquals(ON_DESTROY, mExecutorHelper.getClosestOfStates(mClientRecord, shuffledArray(
+                new int[] {ON_DESTROY})));
+    }
+
+    @Test
+    public void testClosestStateResolutionFromOnCreate() {
+        mClientRecord.setState(ON_CREATE);
+        assertEquals(ON_START, mExecutorHelper.getClosestOfStates(mClientRecord, shuffledArray(
+                new int[] {ON_START, ON_RESUME, ON_PAUSE, ON_STOP, ON_DESTROY})));
+    }
+
+    @Test
+    public void testClosestStateResolutionFromOnStart() {
+        mClientRecord.setState(ON_START);
+        assertEquals(ON_RESUME, mExecutorHelper.getClosestOfStates(mClientRecord, shuffledArray(
+                new int[] {ON_CREATE, ON_RESUME, ON_PAUSE, ON_STOP, ON_DESTROY})));
+        assertEquals(ON_CREATE, mExecutorHelper.getClosestOfStates(mClientRecord, shuffledArray(
+                new int[] {ON_CREATE})));
+    }
+
+    @Test
+    public void testClosestStateResolutionFromOnResume() {
+        mClientRecord.setState(ON_RESUME);
+        assertEquals(ON_PAUSE, mExecutorHelper.getClosestOfStates(mClientRecord, shuffledArray(
+                new int[] {ON_CREATE, ON_START, ON_PAUSE, ON_STOP, ON_DESTROY})));
+        assertEquals(ON_DESTROY, mExecutorHelper.getClosestOfStates(mClientRecord, shuffledArray(
+                new int[] {ON_CREATE, ON_DESTROY})));
+        assertEquals(ON_START, mExecutorHelper.getClosestOfStates(mClientRecord, shuffledArray(
+                new int[] {ON_CREATE, ON_START})));
+        assertEquals(ON_CREATE, mExecutorHelper.getClosestOfStates(mClientRecord, shuffledArray(
+                new int[] {ON_CREATE})));
+    }
+
+    @Test
+    public void testClosestStateResolutionFromOnPause() {
+        mClientRecord.setState(ON_PAUSE);
+        assertEquals(ON_RESUME, mExecutorHelper.getClosestOfStates(mClientRecord, shuffledArray(
+                new int[] {ON_CREATE, ON_START, ON_RESUME, ON_DESTROY})));
+        assertEquals(ON_STOP, mExecutorHelper.getClosestOfStates(mClientRecord, shuffledArray(
+                new int[] {ON_CREATE, ON_START, ON_STOP, ON_DESTROY})));
+        assertEquals(ON_START, mExecutorHelper.getClosestOfStates(mClientRecord, shuffledArray(
+                new int[] {ON_CREATE, ON_START})));
+        assertEquals(ON_CREATE, mExecutorHelper.getClosestOfStates(mClientRecord, shuffledArray(
+                new int[] {ON_CREATE})));
+    }
+
+    @Test
+    public void testClosestStateResolutionFromOnStop() {
+        mClientRecord.setState(ON_STOP);
+        assertEquals(ON_RESUME, mExecutorHelper.getClosestOfStates(mClientRecord, shuffledArray(
+                new int[] {ON_CREATE, ON_RESUME, ON_PAUSE, ON_DESTROY})));
+        assertEquals(ON_DESTROY, mExecutorHelper.getClosestOfStates(mClientRecord, shuffledArray(
+                new int[] {ON_CREATE, ON_DESTROY})));
+        assertEquals(ON_START, mExecutorHelper.getClosestOfStates(mClientRecord, shuffledArray(
+                new int[] {ON_CREATE, ON_START, ON_RESUME, ON_PAUSE})));
+    }
+
+    @Test
+    public void testClosestStateResolutionFromOnDestroy() {
+        mClientRecord.setState(ON_DESTROY);
+        assertEquals(ON_CREATE, mExecutorHelper.getClosestOfStates(mClientRecord, shuffledArray(
+                new int[] {ON_CREATE, ON_START, ON_RESUME, ON_PAUSE, ON_STOP})));
+    }
+
+    @Test
+    public void testClosestStateResolutionToUndefined() {
+        mClientRecord.setState(ON_CREATE);
+        assertEquals(UNDEFINED,
+                mExecutorHelper.getClosestPreExecutionState(mClientRecord, UNDEFINED));
+    }
+
+    @Test
+    public void testClosestStateResolutionToOnResume() {
+        mClientRecord.setState(ON_DESTROY);
+        assertEquals(ON_START,
+                mExecutorHelper.getClosestPreExecutionState(mClientRecord, ON_RESUME));
+        mClientRecord.setState(ON_START);
+        assertEquals(ON_START,
+                mExecutorHelper.getClosestPreExecutionState(mClientRecord, ON_RESUME));
+        mClientRecord.setState(ON_PAUSE);
+        assertEquals(ON_PAUSE,
+                mExecutorHelper.getClosestPreExecutionState(mClientRecord, ON_RESUME));
+    }
+
+    private static int[] shuffledArray(int[] inputArray) {
+        final List<Integer> list = Arrays.stream(inputArray).boxed().collect(Collectors.toList());
+        Collections.shuffle(list);
+        return list.stream().mapToInt(Integer::intValue).toArray();
     }
 
     private int[] path(int finish) {
-        mExecutor.initLifecyclePath(mClientRecord.getLifecycleState(), finish,
-                false /* excludeLastState */);
-        return mExecutor.getLifecycleSequence();
+        return mExecutorHelper.getLifecyclePath(mClientRecord.getLifecycleState(), finish,
+                false /* excludeLastState */).toArray();
     }
 
     private int[] pathExcludeLast(int finish) {
-        mExecutor.initLifecyclePath(mClientRecord.getLifecycleState(), finish,
-                true /* excludeLastState */);
-        return mExecutor.getLifecycleSequence();
+        return mExecutorHelper.getLifecyclePath(mClientRecord.getLifecycleState(), finish,
+                true /* excludeLastState */).toArray();
     }
 }
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 38e20a1..d6580d6 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -155,6 +155,7 @@
                     Settings.Global.CAPTIVE_PORTAL_USER_AGENT,
                     Settings.Global.CAR_DOCK_SOUND,
                     Settings.Global.CARRIER_APP_WHITELIST,
+                    Settings.Global.CARRIER_APP_NAMES,
                     Settings.Global.CAR_UNDOCK_SOUND,
                     Settings.Global.CDMA_CELL_BROADCAST_SMS,
                     Settings.Global.CDMA_ROAMING_MODE,
@@ -305,6 +306,7 @@
                     Settings.Global.NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS,
                     Settings.Global.NETWORK_WATCHLIST_ENABLED,
                     Settings.Global.NEW_CONTACT_AGGREGATOR,
+                    Settings.Global.NIGHT_DISPLAY_FORCED_AUTO_MODE_AVAILABLE,
                     Settings.Global.NITZ_UPDATE_DIFF,
                     Settings.Global.NITZ_UPDATE_SPACING,
                     Settings.Global.NOTIFICATION_SNOOZE_OPTIONS,
@@ -312,6 +314,8 @@
                     Settings.Global.NTP_SERVER,
                     Settings.Global.NTP_TIMEOUT,
                     Settings.Global.OTA_DISABLE_AUTOMATIC_UPDATE,
+                    Settings.Global.OFF_BODY_RADIOS_OFF_FOR_SMALL_BATTERY_ENABLED,
+                    Settings.Global.OFF_BODY_RADIOS_OFF_DELAY_MS,
                     Settings.Global.OVERLAY_DISPLAY_DEVICES,
                     Settings.Global.PAC_CHANGE_DELAY,
                     Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
@@ -376,6 +380,7 @@
                     Settings.Global.SYS_STORAGE_THRESHOLD_MAX_BYTES,
                     Settings.Global.SYS_STORAGE_THRESHOLD_PERCENTAGE,
                     Settings.Global.SYS_VDSO,
+                    Settings.Global.SYS_UIDCPUPOWER,
                     Settings.Global.FPS_DEVISOR,
                     Settings.Global.TCP_DEFAULT_INIT_RWND,
                     Settings.Global.TETHER_DUN_APN,
@@ -521,6 +526,7 @@
                  Settings.Secure.NFC_PAYMENT_FOREGROUND,
                  Settings.Secure.NIGHT_DISPLAY_ACTIVATED,
                  Settings.Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
+                 Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED,
                  Settings.Secure.PACKAGE_VERIFIER_STATE,
                  Settings.Secure.PACKAGE_VERIFIER_USER_CONSENT,
                  Settings.Secure.PARENTAL_CONTROL_LAST_UPDATE,
diff --git a/core/tests/coretests/src/android/security/keystore/recovery/KeyChainProtectionParamsTest.java b/core/tests/coretests/src/android/security/keystore/recovery/KeyChainProtectionParamsTest.java
new file mode 100644
index 0000000..0c9c4c1
--- /dev/null
+++ b/core/tests/coretests/src/android/security/keystore/recovery/KeyChainProtectionParamsTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore.recovery;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import android.os.Parcel;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class KeyChainProtectionParamsTest {
+
+    private static final byte[] SALT = new byte[] { 0, 1, 2, 3, 4, 5 };
+    private static final byte[] SECRET = new byte[] { 5, 4, 3, 2, 1, 0 };
+    private static final int USER_SECRET_TYPE = KeyChainProtectionParams.TYPE_LOCKSCREEN;
+    private static final int LOCK_SCREEN_UI_FORMAT = KeyChainProtectionParams.UI_FORMAT_PATTERN;
+
+    @Test
+    public void build_setsSecret() {
+        assertArrayEquals(SECRET, createTestParams().getSecret());
+    }
+
+    @Test
+    public void build_setsLockScreenUiFormat() {
+        assertEquals(LOCK_SCREEN_UI_FORMAT, createTestParams().getLockScreenUiFormat());
+    }
+
+    @Test
+    public void build_setsUserSecretType() {
+        assertEquals(USER_SECRET_TYPE, createTestParams().getUserSecretType());
+    }
+
+    @Test
+    public void build_setsKeyDerivationParams() {
+        KeyChainProtectionParams protParams = createTestParams();
+        KeyDerivationParams keyDerivationParams = protParams.getKeyDerivationParams();
+
+        assertEquals(KeyDerivationParams.ALGORITHM_SHA256, keyDerivationParams.getAlgorithm());
+        assertArrayEquals(SALT, keyDerivationParams.getSalt());
+    }
+
+    @Test
+    public void writeToParcel_writesSecret() {
+        KeyChainProtectionParams protParams = writeToThenReadFromParcel(createTestParams());
+
+        assertArrayEquals(SECRET, protParams.getSecret());
+    }
+
+    @Test
+    public void writeToParcel_writesUserSecretType() {
+        KeyChainProtectionParams protParams = writeToThenReadFromParcel(createTestParams());
+
+        assertEquals(USER_SECRET_TYPE, protParams.getUserSecretType());
+    }
+
+    @Test
+    public void writeToParcel_writesLockScreenUiFormat() {
+        KeyChainProtectionParams protParams = writeToThenReadFromParcel(createTestParams());
+
+        assertEquals(LOCK_SCREEN_UI_FORMAT, protParams.getLockScreenUiFormat());
+    }
+
+    @Test
+    public void writeToParcel_writesKeyDerivationParams() {
+        KeyChainProtectionParams protParams = writeToThenReadFromParcel(createTestParams());
+        KeyDerivationParams keyDerivationParams = protParams.getKeyDerivationParams();
+
+        assertEquals(KeyDerivationParams.ALGORITHM_SHA256, keyDerivationParams.getAlgorithm());
+        assertArrayEquals(SALT, keyDerivationParams.getSalt());
+    }
+
+    private KeyChainProtectionParams writeToThenReadFromParcel(KeyChainProtectionParams params) {
+        Parcel parcel = Parcel.obtain();
+        params.writeToParcel(parcel, /*flags=*/ 0);
+        parcel.setDataPosition(0);
+        KeyChainProtectionParams fromParcel =
+                KeyChainProtectionParams.CREATOR.createFromParcel(parcel);
+        parcel.recycle();
+        return fromParcel;
+    }
+
+    private KeyChainProtectionParams createTestParams() {
+        return new KeyChainProtectionParams.Builder()
+                .setKeyDerivationParams(KeyDerivationParams.createSha256Params(SALT))
+                .setSecret(SECRET)
+                .setUserSecretType(USER_SECRET_TYPE)
+                .setLockScreenUiFormat(LOCK_SCREEN_UI_FORMAT)
+                .build();
+    }
+}
diff --git a/core/tests/coretests/src/android/security/keystore/recovery/KeyChainSnapshotTest.java b/core/tests/coretests/src/android/security/keystore/recovery/KeyChainSnapshotTest.java
new file mode 100644
index 0000000..8d6fbd5
--- /dev/null
+++ b/core/tests/coretests/src/android/security/keystore/recovery/KeyChainSnapshotTest.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore.recovery;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import android.os.Parcel;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.google.common.collect.Lists;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+// TODO(b/73862682): Add tests for RecoveryCertPath
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class KeyChainSnapshotTest {
+
+    private static final int COUNTER_ID = 42;
+    private static final int SNAPSHOT_VERSION = 13;
+    private static final byte[] SALT = new byte[] { 0, 1, 0, 1 };
+    private static final byte[] SERVER_PARAMS = new byte[] { 6, 7, 9, 2 };
+    private static final byte[] RECOVERY_KEY_BLOB = new byte[] { 9, 1, 4, 6, 7 };
+    private static final int MAX_ATTEMPTS = 10;
+    private static final int LOCK_SCREEN_UI_FORMAT = KeyChainProtectionParams.UI_FORMAT_PASSWORD;
+    private static final int USER_SECRET_TYPE = KeyChainProtectionParams.TYPE_LOCKSCREEN;
+    private static final String KEY_ALIAS = "steph";
+    private static final byte[] KEY_MATERIAL = new byte[] { 3, 5, 7, 9, 1 };
+
+    @Test
+    public void build_setsCounterId() {
+        assertEquals(COUNTER_ID, createKeyChainSnapshot().getCounterId());
+    }
+
+    @Test
+    public void build_setsSnapshotVersion() {
+        assertEquals(SNAPSHOT_VERSION, createKeyChainSnapshot().getSnapshotVersion());
+    }
+
+    @Test
+    public void build_setsMaxAttempts() {
+        assertEquals(MAX_ATTEMPTS, createKeyChainSnapshot().getMaxAttempts());
+    }
+
+    @Test
+    public void build_setsServerParams() {
+        assertArrayEquals(SERVER_PARAMS, createKeyChainSnapshot().getServerParams());
+    }
+
+    @Test
+    public void build_setsRecoveryKeyBlob() {
+        assertArrayEquals(RECOVERY_KEY_BLOB,
+                createKeyChainSnapshot().getEncryptedRecoveryKeyBlob());
+    }
+
+    @Test
+    public void build_setsKeyChainProtectionParams() {
+        KeyChainSnapshot snapshot = createKeyChainSnapshot();
+
+        assertEquals(1, snapshot.getKeyChainProtectionParams().size());
+        KeyChainProtectionParams keyChainProtectionParams =
+                snapshot.getKeyChainProtectionParams().get(0);
+        assertEquals(USER_SECRET_TYPE, keyChainProtectionParams.getUserSecretType());
+        assertEquals(LOCK_SCREEN_UI_FORMAT, keyChainProtectionParams.getLockScreenUiFormat());
+        KeyDerivationParams keyDerivationParams = keyChainProtectionParams.getKeyDerivationParams();
+        assertEquals(KeyDerivationParams.ALGORITHM_SHA256, keyDerivationParams.getAlgorithm());
+        assertArrayEquals(SALT, keyDerivationParams.getSalt());
+    }
+
+    @Test
+    public void build_setsWrappedApplicationKeys() {
+        KeyChainSnapshot snapshot = createKeyChainSnapshot();
+
+        assertEquals(1, snapshot.getWrappedApplicationKeys().size());
+        WrappedApplicationKey wrappedApplicationKey = snapshot.getWrappedApplicationKeys().get(0);
+        assertEquals(KEY_ALIAS, wrappedApplicationKey.getAlias());
+        assertArrayEquals(KEY_MATERIAL, wrappedApplicationKey.getEncryptedKeyMaterial());
+    }
+
+    @Test
+    public void writeToParcel_writesCounterId() {
+        KeyChainSnapshot snapshot = writeToThenReadFromParcel(createKeyChainSnapshot());
+
+        assertEquals(COUNTER_ID, snapshot.getCounterId());
+    }
+
+    @Test
+    public void writeToParcel_writesSnapshotVersion() {
+        KeyChainSnapshot snapshot = writeToThenReadFromParcel(createKeyChainSnapshot());
+
+        assertEquals(SNAPSHOT_VERSION, snapshot.getSnapshotVersion());
+    }
+
+    @Test
+    public void writeToParcel_writesMaxAttempts() {
+        KeyChainSnapshot snapshot = writeToThenReadFromParcel(createKeyChainSnapshot());
+
+        assertEquals(MAX_ATTEMPTS, snapshot.getMaxAttempts());
+    }
+
+    @Test
+    public void writeToParcel_writesServerParams() {
+        KeyChainSnapshot snapshot = writeToThenReadFromParcel(createKeyChainSnapshot());
+
+        assertArrayEquals(SERVER_PARAMS, snapshot.getServerParams());
+    }
+
+    @Test
+    public void writeToParcel_writesKeyRecoveryBlob() {
+        KeyChainSnapshot snapshot = writeToThenReadFromParcel(createKeyChainSnapshot());
+
+        assertArrayEquals(RECOVERY_KEY_BLOB, snapshot.getEncryptedRecoveryKeyBlob());
+    }
+
+    @Test
+    public void writeToParcel_writesKeyChainProtectionParams() {
+        KeyChainSnapshot snapshot = writeToThenReadFromParcel(createKeyChainSnapshot());
+
+        assertEquals(1, snapshot.getKeyChainProtectionParams().size());
+        KeyChainProtectionParams keyChainProtectionParams =
+                snapshot.getKeyChainProtectionParams().get(0);
+        assertEquals(USER_SECRET_TYPE, keyChainProtectionParams.getUserSecretType());
+        assertEquals(LOCK_SCREEN_UI_FORMAT, keyChainProtectionParams.getLockScreenUiFormat());
+        KeyDerivationParams keyDerivationParams = keyChainProtectionParams.getKeyDerivationParams();
+        assertEquals(KeyDerivationParams.ALGORITHM_SHA256, keyDerivationParams.getAlgorithm());
+        assertArrayEquals(SALT, keyDerivationParams.getSalt());
+    }
+
+    @Test
+    public void writeToParcel_writesWrappedApplicationKeys() {
+        KeyChainSnapshot snapshot = writeToThenReadFromParcel(createKeyChainSnapshot());
+
+        assertEquals(1, snapshot.getWrappedApplicationKeys().size());
+        WrappedApplicationKey wrappedApplicationKey = snapshot.getWrappedApplicationKeys().get(0);
+        assertEquals(KEY_ALIAS, wrappedApplicationKey.getAlias());
+        assertArrayEquals(KEY_MATERIAL, wrappedApplicationKey.getEncryptedKeyMaterial());
+    }
+
+    private static KeyChainSnapshot createKeyChainSnapshot() {
+        return new KeyChainSnapshot.Builder()
+                .setCounterId(COUNTER_ID)
+                .setSnapshotVersion(SNAPSHOT_VERSION)
+                .setServerParams(SERVER_PARAMS)
+                .setMaxAttempts(MAX_ATTEMPTS)
+                .setEncryptedRecoveryKeyBlob(RECOVERY_KEY_BLOB)
+                .setKeyChainProtectionParams(Lists.newArrayList(createKeyChainProtectionParams()))
+                .setWrappedApplicationKeys(Lists.newArrayList(createWrappedApplicationKey()))
+                .build();
+    }
+
+    private static KeyChainProtectionParams createKeyChainProtectionParams() {
+        return new KeyChainProtectionParams.Builder()
+                .setKeyDerivationParams(createKeyDerivationParams())
+                .setUserSecretType(USER_SECRET_TYPE)
+                .setLockScreenUiFormat(LOCK_SCREEN_UI_FORMAT)
+                .build();
+    }
+
+    private static KeyDerivationParams createKeyDerivationParams() {
+        return KeyDerivationParams.createSha256Params(SALT);
+    }
+
+    private static WrappedApplicationKey createWrappedApplicationKey() {
+        return new WrappedApplicationKey.Builder()
+                .setAlias(KEY_ALIAS)
+                .setEncryptedKeyMaterial(KEY_MATERIAL)
+                .build();
+    }
+
+    private static KeyChainSnapshot writeToThenReadFromParcel(KeyChainSnapshot params) {
+        Parcel parcel = Parcel.obtain();
+        params.writeToParcel(parcel, /*flags=*/ 0);
+        parcel.setDataPosition(0);
+        KeyChainSnapshot fromParcel = KeyChainSnapshot.CREATOR.createFromParcel(parcel);
+        parcel.recycle();
+        return fromParcel;
+    }
+}
diff --git a/core/tests/coretests/src/android/security/keystore/recovery/KeyDerivationParamsTest.java b/core/tests/coretests/src/android/security/keystore/recovery/KeyDerivationParamsTest.java
new file mode 100644
index 0000000..b6af9bb
--- /dev/null
+++ b/core/tests/coretests/src/android/security/keystore/recovery/KeyDerivationParamsTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore.recovery;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import android.os.Parcel;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class KeyDerivationParamsTest {
+
+    private static final byte[] SALT = new byte[] { 0, 1, 2, 3 };
+
+    @Test
+    public void createSha256Params_setsAlgorithm() {
+        KeyDerivationParams keyDerivationParams = KeyDerivationParams.createSha256Params(SALT);
+
+        assertEquals(KeyDerivationParams.ALGORITHM_SHA256, keyDerivationParams.getAlgorithm());
+    }
+
+    @Test
+    public void createSha256Params_setsSalt() {
+        KeyDerivationParams keyDerivationParams = KeyDerivationParams.createSha256Params(SALT);
+
+        assertArrayEquals(SALT, keyDerivationParams.getSalt());
+    }
+
+    @Test
+    public void writeToParcel_writesAlgorithm() {
+        KeyDerivationParams keyDerivationParams =
+                writeToThenReadFromParcel(KeyDerivationParams.createSha256Params(SALT));
+
+        assertEquals(KeyDerivationParams.ALGORITHM_SHA256, keyDerivationParams.getAlgorithm());
+    }
+
+    @Test
+    public void writeToParcel_writesSalt() {
+        KeyDerivationParams keyDerivationParams =
+                writeToThenReadFromParcel(KeyDerivationParams.createSha256Params(SALT));
+
+        assertArrayEquals(SALT, keyDerivationParams.getSalt());
+    }
+
+    private KeyDerivationParams writeToThenReadFromParcel(KeyDerivationParams params) {
+        Parcel parcel = Parcel.obtain();
+        params.writeToParcel(parcel, /*flags=*/ 0);
+        parcel.setDataPosition(0);
+        KeyDerivationParams fromParcel =
+                KeyDerivationParams.CREATOR.createFromParcel(parcel);
+        parcel.recycle();
+        return fromParcel;
+    }
+}
diff --git a/core/tests/coretests/src/android/security/keystore/recovery/WrappedApplicationKeyTest.java b/core/tests/coretests/src/android/security/keystore/recovery/WrappedApplicationKeyTest.java
new file mode 100644
index 0000000..15afbdd
--- /dev/null
+++ b/core/tests/coretests/src/android/security/keystore/recovery/WrappedApplicationKeyTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore.recovery;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import android.os.Parcel;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class WrappedApplicationKeyTest {
+
+    private static final String ALIAS = "karlin";
+    private static final byte[] KEY_MATERIAL = new byte[] { 0, 1, 2, 3, 4 };
+
+    private Parcel mParcel;
+
+    @Before
+    public void setUp() {
+        mParcel = Parcel.obtain();
+    }
+
+    @After
+    public void tearDown() {
+        mParcel.recycle();
+    }
+
+    @Test
+    public void build_setsAlias() {
+        assertEquals(ALIAS, buildTestKey().getAlias());
+    }
+
+    @Test
+    public void build_setsEncryptedKeyMaterial() {
+        assertArrayEquals(KEY_MATERIAL, buildTestKey().getEncryptedKeyMaterial());
+    }
+
+    @Test
+    public void writeToParcel_writesAliasToParcel() {
+        buildTestKey().writeToParcel(mParcel, /*flags=*/ 0);
+
+        mParcel.setDataPosition(0);
+        WrappedApplicationKey readFromParcel =
+                WrappedApplicationKey.CREATOR.createFromParcel(mParcel);
+        assertEquals(ALIAS, readFromParcel.getAlias());
+    }
+
+    @Test
+    public void writeToParcel_writesKeyMaterial() {
+        buildTestKey().writeToParcel(mParcel, /*flags=*/ 0);
+
+        mParcel.setDataPosition(0);
+        WrappedApplicationKey readFromParcel =
+                WrappedApplicationKey.CREATOR.createFromParcel(mParcel);
+        assertArrayEquals(KEY_MATERIAL, readFromParcel.getEncryptedKeyMaterial());
+    }
+
+    private WrappedApplicationKey buildTestKey() {
+        return new WrappedApplicationKey.Builder()
+                .setAlias(ALIAS)
+                .setEncryptedKeyMaterial(KEY_MATERIAL)
+                .build();
+    }
+}
diff --git a/core/tests/coretests/src/android/text/StaticLayoutTest.java b/core/tests/coretests/src/android/text/StaticLayoutTest.java
index d817278..2521712 100644
--- a/core/tests/coretests/src/android/text/StaticLayoutTest.java
+++ b/core/tests/coretests/src/android/text/StaticLayoutTest.java
@@ -822,6 +822,9 @@
                 + "  <family>"
                 + "    <font weight='400' style='normal'>ascent3em-descent4em.ttf</font>"
                 + "  </family>"
+                + "  <family>"
+                + "    <font weight='400' style='normal'>ascent10em-descent10em.ttf</font>"
+                + "  </family>"
                 + "</familyset>";
 
         try (FontFallbackSetup setup =
@@ -833,7 +836,7 @@
             assertEquals(2 * textSize, paint.descent(), 0.0f);
 
             final int paraWidth = 5 * textSize;
-            final String text = "aaaaa aabaa aaaaa"; // This should result in three lines.
+            final String text = "aaaaa\naabaa\naaaaa\n"; // This should result in three lines.
 
             // Old line spacing. All lines should get their ascent and descents from the first font.
             StaticLayout layout = StaticLayout.Builder
@@ -841,13 +844,17 @@
                     .setIncludePad(false)
                     .setUseLineSpacingFromFallbacks(false)
                     .build();
-            assertEquals(3, layout.getLineCount());
+            assertEquals(4, layout.getLineCount());
             assertEquals(-textSize, layout.getLineAscent(0));
             assertEquals(2 * textSize, layout.getLineDescent(0));
             assertEquals(-textSize, layout.getLineAscent(1));
             assertEquals(2 * textSize, layout.getLineDescent(1));
             assertEquals(-textSize, layout.getLineAscent(2));
             assertEquals(2 * textSize, layout.getLineDescent(2));
+            // The last empty line spacing should be the default line spacing.
+            // Maybe good to be a previous line spacing?
+            assertEquals(-textSize, layout.getLineAscent(3));
+            assertEquals(2 * textSize, layout.getLineDescent(3));
 
             // New line spacing. The second line has a 'b', so it needs more ascent and descent.
             layout = StaticLayout.Builder
@@ -855,26 +862,52 @@
                     .setIncludePad(false)
                     .setUseLineSpacingFromFallbacks(true)
                     .build();
-            assertEquals(3, layout.getLineCount());
+            assertEquals(4, layout.getLineCount());
             assertEquals(-textSize, layout.getLineAscent(0));
             assertEquals(2 * textSize, layout.getLineDescent(0));
             assertEquals(-3 * textSize, layout.getLineAscent(1));
             assertEquals(4 * textSize, layout.getLineDescent(1));
             assertEquals(-textSize, layout.getLineAscent(2));
             assertEquals(2 * textSize, layout.getLineDescent(2));
+            assertEquals(-textSize, layout.getLineAscent(3));
+            assertEquals(2 * textSize, layout.getLineDescent(3));
 
             // The default is the old line spacing, for backward compatibility.
             layout = StaticLayout.Builder
                     .obtain(text, 0, text.length(), paint, paraWidth)
                     .setIncludePad(false)
                     .build();
-            assertEquals(3, layout.getLineCount());
+            assertEquals(4, layout.getLineCount());
             assertEquals(-textSize, layout.getLineAscent(0));
             assertEquals(2 * textSize, layout.getLineDescent(0));
             assertEquals(-textSize, layout.getLineAscent(1));
             assertEquals(2 * textSize, layout.getLineDescent(1));
             assertEquals(-textSize, layout.getLineAscent(2));
             assertEquals(2 * textSize, layout.getLineDescent(2));
+            assertEquals(-textSize, layout.getLineAscent(3));
+            assertEquals(2 * textSize, layout.getLineDescent(3));
+
+            layout = StaticLayout.Builder
+                    .obtain("\n", 0, 1, paint, textSize)
+                    .setIncludePad(false)
+                    .setUseLineSpacingFromFallbacks(false)
+                    .build();
+            assertEquals(2, layout.getLineCount());
+            assertEquals(-textSize, layout.getLineAscent(0));
+            assertEquals(2 * textSize, layout.getLineDescent(0));
+            assertEquals(-textSize, layout.getLineAscent(1));
+            assertEquals(2 * textSize, layout.getLineDescent(1));
+
+            layout = StaticLayout.Builder
+                    .obtain("\n", 0, 1, paint, textSize)
+                    .setIncludePad(false)
+                    .setUseLineSpacingFromFallbacks(true)
+                    .build();
+            assertEquals(2, layout.getLineCount());
+            assertEquals(-textSize, layout.getLineAscent(0));
+            assertEquals(2 * textSize, layout.getLineDescent(0));
+            assertEquals(-textSize, layout.getLineAscent(1));
+            assertEquals(2 * textSize, layout.getLineDescent(1));
         }
     }
 
diff --git a/core/tests/coretests/src/android/view/DisplayCutoutTest.java b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
index ee4bc34..d807353 100644
--- a/core/tests/coretests/src/android/view/DisplayCutoutTest.java
+++ b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
@@ -18,10 +18,14 @@
 
 import static android.view.DisplayCutout.NO_CUTOUT;
 import static android.view.DisplayCutout.fromBoundingRect;
+import static android.view.DisplayCutout.fromSpec;
 
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.sameInstance;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 
 import android.graphics.Rect;
@@ -271,6 +275,30 @@
     }
 
     @Test
+    public void fromSpec_caches() {
+        DisplayCutout cached = fromSpec("L1,0 L1,1 L0,1 z", 200, 1f);
+        assertThat(fromSpec("L1,0 L1,1 L0,1 z", 200, 1f), sameInstance(cached));
+    }
+
+    @Test
+    public void fromSpec_wontCacheIfSpecChanges() {
+        DisplayCutout cached = fromSpec("L1,0 L1000,1000 L0,1 z", 200, 1f);
+        assertThat(fromSpec("L1,0 L1,1 L0,1 z", 200, 1f), not(sameInstance(cached)));
+    }
+
+    @Test
+    public void fromSpec_wontCacheIfScreenWidthChanges() {
+        DisplayCutout cached = fromSpec("L1,0 L1,1 L0,1 z", 2000, 1f);
+        assertThat(fromSpec("L1,0 L1,1 L0,1 z", 200, 1f), not(sameInstance(cached)));
+    }
+
+    @Test
+    public void fromSpec_wontCacheIfDensityChanges() {
+        DisplayCutout cached = fromSpec("L1,0 L1,1 L0,1 z", 200, 2f);
+        assertThat(fromSpec("L1,0 L1,1 L0,1 z", 200, 1f), not(sameInstance(cached)));
+    }
+
+    @Test
     public void parcel_unparcel_nocutout() {
         Parcel p = Parcel.obtain();
 
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassificationConstantsTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassificationConstantsTest.java
new file mode 100644
index 0000000..54007fb
--- /dev/null
+++ b/core/tests/coretests/src/android/view/textclassifier/TextClassificationConstantsTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.textclassifier;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TextClassificationConstantsTest {
+
+    @Test
+    public void testLoadFromString() {
+        final String s = "local_textclassifier_enabled=true,"
+                + "system_textclassifier_enabled=true,"
+                + "model_dark_launch_enabled=true,"
+                + "smart_selection_enabled=true,"
+                + "smart_text_share_enabled=true,"
+                + "smart_linkify_enabled=true,"
+                + "smart_select_animation_enabled=true,"
+                + "suggest_selection_max_range_length=10,"
+                + "classify_text_max_range_length=11,"
+                + "generate_links_max_text_length=12,"
+                + "generate_links_log_sample_rate=13";
+        final TextClassificationConstants constants =
+                TextClassificationConstants.loadFromString(s);
+        assertTrue("local_textclassifier_enabled",
+                constants.isLocalTextClassifierEnabled());
+        assertTrue("system_textclassifier_enabled",
+                constants.isSystemTextClassifierEnabled());
+        assertTrue("model_dark_launch_enabled", constants.isModelDarkLaunchEnabled());
+        assertTrue("smart_selection_enabled", constants.isSmartSelectionEnabled());
+        assertTrue("smart_text_share_enabled", constants.isSmartTextShareEnabled());
+        assertTrue("smart_linkify_enabled", constants.isSmartLinkifyEnabled());
+        assertTrue("smart_select_animation_enabled", constants.isSmartSelectionAnimationEnabled());
+        assertEquals("suggest_selection_max_range_length",
+                10, constants.getSuggestSelectionMaxRangeLength());
+        assertEquals("classify_text_max_range_length",
+                11, constants.getClassifyTextMaxRangeLength());
+        assertEquals("generate_links_max_text_length",
+                12, constants.getGenerateLinksMaxTextLength());
+        assertEquals("generate_links_log_sample_rate",
+                13, constants.getGenerateLinksLogSampleRate());
+    }
+
+    @Test
+    public void testLoadFromString_differentValues() {
+        final String s = "local_textclassifier_enabled=false,"
+                + "system_textclassifier_enabled=false,"
+                + "model_dark_launch_enabled=false,"
+                + "smart_selection_enabled=false,"
+                + "smart_text_share_enabled=false,"
+                + "smart_linkify_enabled=false,"
+                + "smart_select_animation_enabled=false,"
+                + "suggest_selection_max_range_length=8,"
+                + "classify_text_max_range_length=7,"
+                + "generate_links_max_text_length=6,"
+                + "generate_links_log_sample_rate=5";
+        final TextClassificationConstants constants =
+                TextClassificationConstants.loadFromString(s);
+        assertFalse("local_textclassifier_enabled",
+                constants.isLocalTextClassifierEnabled());
+        assertFalse("system_textclassifier_enabled",
+                constants.isSystemTextClassifierEnabled());
+        assertFalse("model_dark_launch_enabled", constants.isModelDarkLaunchEnabled());
+        assertFalse("smart_selection_enabled", constants.isSmartSelectionEnabled());
+        assertFalse("smart_text_share_enabled", constants.isSmartTextShareEnabled());
+        assertFalse("smart_linkify_enabled", constants.isSmartLinkifyEnabled());
+        assertFalse("smart_select_animation_enabled",
+                constants.isSmartSelectionAnimationEnabled());
+        assertEquals("suggest_selection_max_range_length",
+                8, constants.getSuggestSelectionMaxRangeLength());
+        assertEquals("classify_text_max_range_length",
+                7, constants.getClassifyTextMaxRangeLength());
+        assertEquals("generate_links_max_text_length",
+                6, constants.getGenerateLinksMaxTextLength());
+        assertEquals("generate_links_log_sample_rate",
+                5, constants.getGenerateLinksLogSampleRate());
+    }
+
+    @Test
+    public void testEntityListParsing() {
+        final TextClassificationConstants constants = TextClassificationConstants.loadFromString(
+                "entity_list_default=phone,"
+                        + "entity_list_not_editable=address:flight,"
+                        + "entity_list_editable=date:datetime");
+        assertEquals(1, constants.getEntityListDefault().size());
+        assertEquals("phone", constants.getEntityListDefault().get(0));
+        assertEquals(2, constants.getEntityListNotEditable().size());
+        assertEquals("address", constants.getEntityListNotEditable().get(0));
+        assertEquals("flight", constants.getEntityListNotEditable().get(1));
+        assertEquals(2, constants.getEntityListEditable().size());
+        assertEquals("date", constants.getEntityListEditable().get(0));
+        assertEquals("datetime", constants.getEntityListEditable().get(1));
+    }
+}
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
index b7869d0..57db153 100644
--- a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
@@ -22,7 +22,9 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 
+import android.content.Context;
 import android.os.LocaleList;
+import android.service.textclassifier.TextClassifierService;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -41,9 +43,10 @@
 @RunWith(AndroidJUnit4.class)
 public class TextClassificationManagerTest {
 
-    private static final LocaleList LOCALES = LocaleList.forLanguageTags("en");
+    private static final LocaleList LOCALES = LocaleList.forLanguageTags("en-US");
     private static final String NO_TYPE = null;
 
+    private Context mContext;
     private TextClassificationManager mTcm;
     private TextClassifier mClassifier;
     private TextSelection.Options mSelectionOptions;
@@ -52,8 +55,8 @@
 
     @Before
     public void setup() {
-        mTcm = InstrumentationRegistry.getTargetContext()
-                .getSystemService(TextClassificationManager.class);
+        mContext = InstrumentationRegistry.getTargetContext();
+        mTcm = mContext.getSystemService(TextClassificationManager.class);
         mTcm.setTextClassifier(null);
         mClassifier = mTcm.getTextClassifier();
         mSelectionOptions = new TextSelection.Options().setDefaultLocales(LOCALES);
@@ -181,6 +184,42 @@
     }
 
     @Test
+    public void testTextClassifyText_date() {
+        if (isTextClassifierDisabled()) return;
+
+        String text = "Let's meet on January 9, 2018.";
+        String classifiedText = "January 9, 2018";
+        int startIndex = text.indexOf(classifiedText);
+        int endIndex = startIndex + classifiedText.length();
+
+        TextClassification classification = mClassifier.classifyText(
+                text, startIndex, endIndex, mClassificationOptions);
+        assertThat(classification,
+                isTextClassification(
+                        classifiedText,
+                        TextClassifier.TYPE_DATE,
+                        null));
+    }
+
+    @Test
+    public void testTextClassifyText_datetime() {
+        if (isTextClassifierDisabled()) return;
+
+        String text = "Let's meet 2018/01/01 10:30:20.";
+        String classifiedText = "2018/01/01 10:30:20";
+        int startIndex = text.indexOf(classifiedText);
+        int endIndex = startIndex + classifiedText.length();
+
+        TextClassification classification = mClassifier.classifyText(
+                text, startIndex, endIndex, mClassificationOptions);
+        assertThat(classification,
+                isTextClassification(
+                        classifiedText,
+                        TextClassifier.TYPE_DATE_TIME,
+                        null));
+    }
+
+    @Test
     public void testGenerateLinks_phone() {
         if (isTextClassifierDisabled()) return;
         String text = "The number is +12122537077. See you tonight!";
@@ -246,6 +285,18 @@
         assertEquals(classifier, mTcm.getTextClassifier());
     }
 
+    @Test
+    public void testGetLocalTextClassifier() {
+        assertTrue(mTcm.getTextClassifier(TextClassifier.LOCAL) instanceof TextClassifierImpl);
+    }
+
+    @Test
+    public void testGetSystemTextClassifier() {
+        assertTrue(
+                TextClassifierService.getServiceComponentName(mContext) == null
+                || mTcm.getTextClassifier(TextClassifier.SYSTEM) instanceof SystemTextClassifier);
+    }
+
     private boolean isTextClassifierDisabled() {
         return mClassifier == TextClassifier.NO_OP;
     }
@@ -334,7 +385,8 @@
                             && text.equals(result.getText())
                             && result.getEntityCount() > 0
                             && type.equals(result.getEntity(0))
-                            && intentUri.equals(result.getIntent().getDataString());
+                            && (intentUri == null
+                                || intentUri.equals(result.getIntent().getDataString()));
                     // TODO: Include other properties.
                 }
                 return false;
diff --git a/core/tests/coretests/src/android/view/textclassifier/logging/GenerateLinksLoggerTest.java b/core/tests/coretests/src/android/view/textclassifier/logging/GenerateLinksLoggerTest.java
new file mode 100644
index 0000000..b920ca3
--- /dev/null
+++ b/core/tests/coretests/src/android/view/textclassifier/logging/GenerateLinksLoggerTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.textclassifier.logging;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+
+import android.metrics.LogMaker;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.ArrayMap;
+import android.view.textclassifier.TextClassifier;
+import android.view.textclassifier.TextLinks;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class GenerateLinksLoggerTest {
+
+    private static final String PACKAGE_NAME = "packageName";
+    private static final String ZERO = "0";
+    private static final int LATENCY_MS = 123;
+
+    @Test
+    public void testLogGenerateLinks() {
+        final String phoneText = "+12122537077";
+        final String addressText = "1600 Amphitheater Parkway, Mountain View, CA";
+        final String testText = "The number is " + phoneText + ", the address is " + addressText;
+        final int phoneOffset = testText.indexOf(phoneText);
+        final int addressOffset = testText.indexOf(addressText);
+
+        final Map<String, Float> phoneEntityScores = new ArrayMap<>();
+        phoneEntityScores.put(TextClassifier.TYPE_PHONE, 0.9f);
+        phoneEntityScores.put(TextClassifier.TYPE_OTHER, 0.1f);
+        final Map<String, Float> addressEntityScores = new ArrayMap<>();
+        addressEntityScores.put(TextClassifier.TYPE_ADDRESS, 1f);
+
+        TextLinks links = new TextLinks.Builder(testText)
+                .addLink(phoneOffset, phoneOffset + phoneText.length(), phoneEntityScores)
+                .addLink(addressOffset, addressOffset + addressText.length(), addressEntityScores)
+                .build();
+
+        // Set up mock.
+        MetricsLogger metricsLogger = mock(MetricsLogger.class);
+        ArgumentCaptor<LogMaker> logMakerCapture = ArgumentCaptor.forClass(LogMaker.class);
+        doNothing().when(metricsLogger).write(logMakerCapture.capture());
+
+        // Generate the log.
+        GenerateLinksLogger logger = new GenerateLinksLogger(1 /* sampleRate */, metricsLogger);
+        logger.logGenerateLinks(testText, links, PACKAGE_NAME, LATENCY_MS);
+
+        // Validate.
+        List<LogMaker> logs = logMakerCapture.getAllValues();
+        assertEquals(3, logs.size());
+        assertHasLog(logs, "" /* entityType */, 2, phoneText.length() + addressText.length(),
+                testText.length());
+        assertHasLog(logs, TextClassifier.TYPE_ADDRESS, 1, addressText.length(),
+                testText.length());
+        assertHasLog(logs, TextClassifier.TYPE_PHONE, 1, phoneText.length(),
+                testText.length());
+    }
+
+    private void assertHasLog(List<LogMaker> logs, String entityType, int numLinks,
+            int linkTextLength, int textLength) {
+        for (LogMaker log : logs) {
+            if (!entityType.equals(getEntityType(log))) {
+                continue;
+            }
+            assertEquals(PACKAGE_NAME, log.getPackageName());
+            assertNotNull(Objects.toString(log.getTaggedData(MetricsEvent.FIELD_LINKIFY_CALL_ID)));
+            assertEquals(numLinks, getIntValue(log, MetricsEvent.FIELD_LINKIFY_NUM_LINKS));
+            assertEquals(linkTextLength, getIntValue(log, MetricsEvent.FIELD_LINKIFY_LINK_LENGTH));
+            assertEquals(textLength, getIntValue(log, MetricsEvent.FIELD_LINKIFY_TEXT_LENGTH));
+            assertEquals(LATENCY_MS, getIntValue(log, MetricsEvent.FIELD_LINKIFY_LATENCY));
+            return;
+        }
+        fail("No log for entity type \"" + entityType + "\"");
+    }
+
+    private static String getEntityType(LogMaker log) {
+        return Objects.toString(log.getTaggedData(MetricsEvent.FIELD_LINKIFY_ENTITY_TYPE), "");
+    }
+
+    private static int getIntValue(LogMaker log, int eventField) {
+        return Integer.parseInt(Objects.toString(log.getTaggedData(eventField), ZERO));
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
index 449e374..a15d337 100644
--- a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
+++ b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
@@ -398,6 +398,17 @@
     }
 
     @Test
+    public void testOnAccessibilityShortcut_forServiceWithNoSummary_doesNotCrash()
+            throws Exception {
+        configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
+        configureValidShortcutService();
+        when(mServiceInfo.loadSummary(any())).thenReturn(null);
+        Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 1);
+        getController().performAccessibilityShortcut();
+        verify(mAccessibilityManagerService).performAccessibilityShortcut();
+    }
+
+    @Test
     public void testOnAccessibilityShortcut_forFrameworkFeature_callsServiceWithNoToast()
             throws Exception {
         configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
index 702f4b8..98b7a3f 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
@@ -36,6 +36,7 @@
         BatteryStatsTimerTest.class,
         BatteryStatsUidTest.class,
         BatteryStatsUserLifecycleTests.class,
+        KernelCpuProcReaderTest.class,
         KernelMemoryBandwidthStatsTest.class,
         KernelSingleUidTimeReaderTest.class,
         KernelUidCpuFreqTimeReaderTest.class,
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuProcReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuProcReaderTest.java
new file mode 100644
index 0000000..efdd7e9
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuProcReaderTest.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.os;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.os.FileUtils;
+import android.os.SystemClock;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.file.Files;
+import java.util.Arrays;
+import java.util.Random;
+
+/**
+ * Test class for {@link KernelCpuProcReader}.
+ *
+ * $ atest FrameworksCoreTests:com.android.internal.os.KernelCpuProcReader
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class KernelCpuProcReaderTest {
+
+    private File mRoot;
+    private File mTestDir;
+    private File mTestFile;
+    private Random mRand = new Random();
+
+    private KernelCpuProcReader mKernelCpuProcReader;
+
+    private Context getContext() {
+        return InstrumentationRegistry.getContext();
+    }
+
+    @Before
+    public void setUp() {
+        mTestDir = getContext().getDir("test", Context.MODE_PRIVATE);
+        mRoot = getContext().getFilesDir();
+        mTestFile = new File(mTestDir, "test.file");
+        mKernelCpuProcReader = new KernelCpuProcReader(mTestFile.getAbsolutePath());
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        FileUtils.deleteContents(mTestDir);
+        FileUtils.deleteContents(mRoot);
+    }
+
+
+    /**
+     * Tests that reading will return null if the file does not exist.
+     */
+    @Test
+    public void testReadInvalidFile() throws Exception {
+        assertEquals(null, mKernelCpuProcReader.readBytes());
+    }
+
+    /**
+     * Tests that reading will always return null after 5 failures.
+     */
+    @Test
+    public void testReadErrorsLimit() throws Exception {
+        mKernelCpuProcReader.setThrottleInterval(0);
+        for (int i = 0; i < 3; i++) {
+            assertNull(mKernelCpuProcReader.readBytes());
+            SystemClock.sleep(50);
+        }
+
+        final byte[] data = new byte[1024];
+        mRand.nextBytes(data);
+        try (OutputStream os = Files.newOutputStream(mTestFile.toPath())) {
+            os.write(data);
+        }
+        assertTrue(Arrays.equals(data, toArray(mKernelCpuProcReader.readBytes())));
+
+        assertTrue(mTestFile.delete());
+        for (int i = 0; i < 3; i++) {
+            assertNull(mKernelCpuProcReader.readBytes());
+            SystemClock.sleep(50);
+        }
+        try (OutputStream os = Files.newOutputStream(mTestFile.toPath())) {
+            os.write(data);
+        }
+        assertNull(mKernelCpuProcReader.readBytes());
+    }
+
+    /**
+     * Tests reading functionality.
+     */
+    @Test
+    public void testSimpleRead() throws Exception {
+        final byte[] data = new byte[1024];
+        mRand.nextBytes(data);
+        try (OutputStream os = Files.newOutputStream(mTestFile.toPath())) {
+            os.write(data);
+        }
+        assertTrue(Arrays.equals(data, toArray(mKernelCpuProcReader.readBytes())));
+    }
+
+    /**
+     * Tests multiple reading functionality.
+     */
+    @Test
+    public void testMultipleRead() throws Exception {
+        mKernelCpuProcReader.setThrottleInterval(0);
+        for (int i = 0; i < 100; i++) {
+            final byte[] data = new byte[mRand.nextInt(102400) + 4];
+            mRand.nextBytes(data);
+            try (OutputStream os = Files.newOutputStream(mTestFile.toPath())) {
+                os.write(data);
+            }
+            assertTrue(Arrays.equals(data, toArray(mKernelCpuProcReader.readBytes())));
+            assertTrue(mTestFile.delete());
+        }
+    }
+
+    /**
+     * Tests reading with resizing.
+     */
+    @Test
+    public void testReadWithResize() throws Exception {
+        final byte[] data = new byte[128001];
+        mRand.nextBytes(data);
+        try (OutputStream os = Files.newOutputStream(mTestFile.toPath())) {
+            os.write(data);
+        }
+        assertTrue(Arrays.equals(data, toArray(mKernelCpuProcReader.readBytes())));
+    }
+
+    /**
+     * Tests that reading a file over the limit (1MB) will return null.
+     */
+    @Test
+    public void testReadOverLimit() throws Exception {
+        final byte[] data = new byte[1228800];
+        mRand.nextBytes(data);
+        try (OutputStream os = Files.newOutputStream(mTestFile.toPath())) {
+            os.write(data);
+        }
+        assertNull(mKernelCpuProcReader.readBytes());
+    }
+
+    /**
+     * Tests throttling. Deleting underlying file should not affect cache.
+     */
+    @Test
+    public void testThrottle() throws Exception {
+        mKernelCpuProcReader.setThrottleInterval(3000);
+        final byte[] data = new byte[20001];
+        mRand.nextBytes(data);
+        try (OutputStream os = Files.newOutputStream(mTestFile.toPath())) {
+            os.write(data);
+        }
+        assertTrue(Arrays.equals(data, toArray(mKernelCpuProcReader.readBytes())));
+        assertTrue(mTestFile.delete());
+        for (int i = 0; i < 5; i++) {
+            assertTrue(Arrays.equals(data, toArray(mKernelCpuProcReader.readBytes())));
+            SystemClock.sleep(10);
+        }
+        SystemClock.sleep(5000);
+        assertNull(mKernelCpuProcReader.readBytes());
+    }
+
+    private byte[] toArray(ByteBuffer buffer) {
+        assertNotNull(buffer);
+        byte[] arr = new byte[buffer.remaining()];
+        buffer.get(arr);
+        return arr;
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelUidCpuActiveTimeReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelUidCpuActiveTimeReaderTest.java
index 1ac82bd..312af16 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelUidCpuActiveTimeReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelUidCpuActiveTimeReaderTest.java
@@ -16,8 +16,6 @@
 
 package com.android.internal.os;
 
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
@@ -25,18 +23,15 @@
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
-import java.io.BufferedReader;
-import java.util.Arrays;
-import java.util.List;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 import java.util.Random;
 
 /**
@@ -44,75 +39,64 @@
  *
  * To run it:
  * bit FrameworksCoreTests:com.android.internal.os.KernelUidCpuActiveTimeReaderTest
- *
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class KernelUidCpuActiveTimeReaderTest {
-    @Mock private BufferedReader mBufferedReader;
-    @Mock private KernelUidCpuActiveTimeReader.Callback mCallback;
-
+    @Mock
+    private KernelCpuProcReader mProcReader;
+    @Mock
+    private KernelUidCpuActiveTimeReader.Callback mCallback;
     private KernelUidCpuActiveTimeReader mReader;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mReader = new KernelUidCpuActiveTimeReader();
-    }
-
-    public class Temp {
-
-        public void method() {
-            method1(new long[][]{{1,2,3}, {2,3,4}});
-            method1(new long[][]{{2,2,3}, {2,3,4}});
-        }
-        public int method1(long[][] array) {
-            return array.length * array[0].length;
-        }
+        mReader = new KernelUidCpuActiveTimeReader(mProcReader);
+        mReader.setThrottleInterval(0);
     }
 
     @Test
     public void testReadDelta() throws Exception {
         final int cores = 8;
-        final String info = "active: 8";
         final int[] uids = {1, 22, 333, 4444, 5555};
 
         final long[][] times = increaseTime(new long[uids.length][cores]);
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times));
-        mReader.readDeltaInternal(mBufferedReader, mCallback);
-        for(int i=0;i<uids.length;i++){
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times));
+        mReader.readDelta(mCallback);
+        for (int i = 0; i < uids.length; i++) {
             verify(mCallback).onUidCpuActiveTime(uids[i], getTotal(times[i]));
         }
         verifyNoMoreInteractions(mCallback);
 
         // Verify that a second call will only return deltas.
-        Mockito.reset(mCallback, mBufferedReader);
+        Mockito.reset(mCallback);
         final long[][] times1 = increaseTime(times);
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times1));
-        mReader.readDeltaInternal(mBufferedReader, mCallback);
-        for(int i=0;i<uids.length;i++){
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times1));
+        mReader.readDelta(mCallback);
+        for (int i = 0; i < uids.length; i++) {
             verify(mCallback).onUidCpuActiveTime(uids[i], getTotal(subtract(times1[i], times[i])));
         }
         verifyNoMoreInteractions(mCallback);
 
         // Verify that there won't be a callback if the proc file values didn't change.
-        Mockito.reset(mCallback, mBufferedReader);
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times1));
-        mReader.readDeltaInternal(mBufferedReader, mCallback);
+        Mockito.reset(mCallback);
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times1));
+        mReader.readDelta(mCallback);
         verifyNoMoreInteractions(mCallback);
 
         // Verify that calling with a null callback doesn't result in any crashes
-        Mockito.reset(mCallback, mBufferedReader);
+        Mockito.reset(mCallback);
         final long[][] times2 = increaseTime(times1);
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times2));
-        mReader.readDeltaInternal(mBufferedReader, null);
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times2));
+        mReader.readDelta(null);
 
         // Verify that the readDelta call will only return deltas when
         // the previous call had null callback.
-        Mockito.reset(mCallback, mBufferedReader);
+        Mockito.reset(mCallback);
         final long[][] times3 = increaseTime(times2);
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times3));
-        mReader.readDeltaInternal(mBufferedReader, mCallback);
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times3));
+        mReader.readDelta(mCallback);
         for (int i = 0; i < uids.length; ++i) {
             verify(mCallback).onUidCpuActiveTime(uids[i], getTotal(subtract(times3[i], times2[i])));
         }
@@ -122,78 +106,76 @@
     @Test
     public void testReadDelta_malformedData() throws Exception {
         final int cores = 8;
-        final String info = "active: 8";
         final int[] uids = {1, 22, 333, 4444, 5555};
         final long[][] times = increaseTime(new long[uids.length][cores]);
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times));
-        mReader.readDeltaInternal(mBufferedReader, mCallback);
-        for(int i=0;i<uids.length;i++){
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times));
+        mReader.readDelta(mCallback);
+        for (int i = 0; i < uids.length; i++) {
             verify(mCallback).onUidCpuActiveTime(uids[i], getTotal(times[i]));
         }
         verifyNoMoreInteractions(mCallback);
 
-        // Verify that there is no callback if subsequent call provides wrong # of entries.
-        Mockito.reset(mCallback, mBufferedReader);
-        final long[][] temp = increaseTime(times);
-        final long[][] times1 = new long[uids.length][];
-        for(int i=0;i<temp.length;i++){
-            times1[i] = Arrays.copyOfRange(temp[i], 0, 6);
-        }
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times1));
-        mReader.readDeltaInternal(mBufferedReader, mCallback);
+        // Verify that there is no callback if subsequent call is in wrong format.
+        Mockito.reset(mCallback);
+        final long[][] times1 = increaseTime(times);
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times1).putInt(0, 5));
+        mReader.readDelta(mCallback);
         verifyNoMoreInteractions(mCallback);
 
         // Verify that the internal state was not modified if the given core count does not match
         // the following # of entries.
-        Mockito.reset(mCallback, mBufferedReader);
+        Mockito.reset(mCallback);
         final long[][] times2 = increaseTime(times);
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times2));
-        mReader.readDeltaInternal(mBufferedReader, mCallback);
-        for(int i=0;i<uids.length;i++){
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times2));
+        mReader.readDelta(mCallback);
+        for (int i = 0; i < uids.length; i++) {
             verify(mCallback).onUidCpuActiveTime(uids[i], getTotal(subtract(times2[i], times[i])));
         }
         verifyNoMoreInteractions(mCallback);
 
         // Verify that there is no callback if any value in the proc file is -ve.
-        Mockito.reset(mCallback, mBufferedReader);
+        Mockito.reset(mCallback);
         final long[][] times3 = increaseTime(times2);
         times3[uids.length - 1][cores - 1] *= -1;
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times3));
-        mReader.readDeltaInternal(mBufferedReader, mCallback);
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times3));
+        mReader.readDelta(mCallback);
         for (int i = 0; i < uids.length - 1; ++i) {
             verify(mCallback).onUidCpuActiveTime(uids[i], getTotal(subtract(times3[i], times2[i])));
         }
         verifyNoMoreInteractions(mCallback);
 
         // Verify that the internal state was not modified when the proc file had -ve value.
-        Mockito.reset(mCallback, mBufferedReader);
+        Mockito.reset(mCallback);
         for (int i = 0; i < cores; i++) {
-            times3[uids.length - 1][i] = times2[uids.length - 1][i] + uids[uids.length - 1] * 1000;
+            times3[uids.length - 1][i] = times2[uids.length - 1][i] + uids[uids.length - 1] * 2520;
         }
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times3));
-        mReader.readDeltaInternal(mBufferedReader, mCallback);
-        verify(mCallback).onUidCpuActiveTime(uids[uids.length - 1], getTotal(subtract(times3[uids.length - 1], times2[uids.length - 1])));
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times3));
+        mReader.readDelta(mCallback);
+        verify(mCallback).onUidCpuActiveTime(uids[uids.length - 1],
+                getTotal(subtract(times3[uids.length - 1], times2[uids.length - 1])));
         verifyNoMoreInteractions(mCallback);
 
         // Verify that there is no callback if the values in the proc file are decreased.
-        Mockito.reset(mCallback, mBufferedReader);
+        Mockito.reset(mCallback);
         final long[][] times4 = increaseTime(times3);
-        times4[uids.length - 1][cores - 1] = times3[uids.length - 1][cores - 1] - 1;
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times4));
-        mReader.readDeltaInternal(mBufferedReader, mCallback);
+        System.arraycopy(times3[uids.length - 1], 0, times4[uids.length - 1], 0, cores);
+        times4[uids.length - 1][cores - 1] -= 100;
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times4));
+        mReader.readDelta(mCallback);
         for (int i = 0; i < uids.length - 1; ++i) {
             verify(mCallback).onUidCpuActiveTime(uids[i], getTotal(subtract(times4[i], times3[i])));
         }
         verifyNoMoreInteractions(mCallback);
 
         // Verify that the internal state was not modified when the proc file had decreased values.
-        Mockito.reset(mCallback, mBufferedReader);
+        Mockito.reset(mCallback);
         for (int i = 0; i < cores; i++) {
-            times4[uids.length - 1][i] = times3[uids.length - 1][i] + uids[uids.length - 1] * 1000;
+            times4[uids.length - 1][i] = times3[uids.length - 1][i] + uids[uids.length - 1] * 2520;
         }
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times4));
-        mReader.readDeltaInternal(mBufferedReader, mCallback);
-        verify(mCallback).onUidCpuActiveTime(uids[uids.length - 1], getTotal(subtract(times4[uids.length - 1], times3[uids.length - 1])));
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times4));
+        mReader.readDelta(mCallback);
+        verify(mCallback).onUidCpuActiveTime(uids[uids.length - 1],
+                getTotal(subtract(times4[uids.length - 1], times3[uids.length - 1])));
         verifyNoMoreInteractions(mCallback);
     }
 
@@ -205,36 +187,50 @@
         return val;
     }
 
-    private String[] formatTime(int[] uids, long[][] times) {
-        String[] lines = new String[uids.length + 1];
-        for (int i=0;i<uids.length;i++){
-            StringBuilder sb = new StringBuilder();
-            sb.append(uids[i]).append(':');
-            for(int j=0;j<times[i].length;j++){
-                sb.append(' ').append(times[i][j]);
-            }
-            lines[i] = sb.toString();
-        }
-        lines[uids.length] = null;
-        return lines;
-    }
-
+    /**
+     * Unit of original and return value is 10ms. What's special about 2520? 2520 is LCM of 1, 2, 3,
+     * ..., 10. So that when wedivide shared cpu time by concurrent thread count, we always get a
+     * nice integer, avoiding rounding errors.
+     */
     private long[][] increaseTime(long[][] original) {
         long[][] newTime = new long[original.length][original[0].length];
         Random rand = new Random();
-        for(int i = 0;i<original.length;i++){
-            for(int j=0;j<original[0].length;j++){
-                newTime[i][j] = original[i][j] + rand.nextInt(1000_000) + 10000;
+        for (int i = 0; i < original.length; i++) {
+            for (int j = 0; j < original[0].length; j++) {
+                newTime[i][j] = original[i][j] + rand.nextInt(1000) * 2520 + 2520;
             }
         }
         return newTime;
     }
 
+    // Unit of times is 10ms
     private long getTotal(long[] times) {
         long sum = 0;
-        for(int i=0;i<times.length;i++){
-            sum+=times[i] * 10 / (i+1);
+        for (int i = 0; i < times.length; i++) {
+            sum += times[i] * 10 / (i + 1);
         }
         return sum;
     }
+
+    /**
+     * Format uids and times (in 10ms) into the following format:
+     * [n, uid0, time0a, time0b, ..., time0n,
+     * uid1, time1a, time1b, ..., time1n,
+     * uid2, time2a, time2b, ..., time2n, etc.]
+     * where n is the total number of cpus (num_possible_cpus)
+     */
+    private ByteBuffer getUidTimesBytes(int[] uids, long[][] times) {
+        int size = (1 + uids.length * (times[0].length + 1)) * 4;
+        ByteBuffer buf = ByteBuffer.allocate(size);
+        buf.order(ByteOrder.nativeOrder());
+        buf.putInt(times[0].length);
+        for (int i = 0; i < uids.length; i++) {
+            buf.putInt(uids[i]);
+            for (int j = 0; j < times[i].length; j++) {
+                buf.putInt((int) times[i][j]);
+            }
+        }
+        buf.flip();
+        return buf.order(ByteOrder.nativeOrder());
+    }
 }
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelUidCpuClusterTimeReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelUidCpuClusterTimeReaderTest.java
index 0d1f852..d21f541 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelUidCpuClusterTimeReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelUidCpuClusterTimeReaderTest.java
@@ -16,26 +16,25 @@
 
 package com.android.internal.os;
 
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.mockito.Mockito.when;
 
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.util.SparseArray;
 
-import static org.junit.Assert.*;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
-import java.io.BufferedReader;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 import java.util.Arrays;
-import java.util.List;
 import java.util.Random;
 
 /**
@@ -43,147 +42,163 @@
  *
  * To run it:
  * bit FrameworksCoreTests:com.android.internal.os.KernelUidCpuClusterTimeReaderTest
- *
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class KernelUidCpuClusterTimeReaderTest {
-    @Mock private BufferedReader mBufferedReader;
-    @Mock private KernelUidCpuClusterTimeReader.Callback mCallback;
-
+    @Mock
+    private KernelCpuProcReader mProcReader;
     private KernelUidCpuClusterTimeReader mReader;
+    private VerifiableCallback mCallback;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mReader = new KernelUidCpuClusterTimeReader();
+        mReader = new KernelUidCpuClusterTimeReader(mProcReader);
+        mCallback = new VerifiableCallback();
+        mReader.setThrottleInterval(0);
     }
 
     @Test
     public void testReadDelta() throws Exception {
-        final String info = "policy0: 2 policy4: 4";
+        VerifiableCallback cb = new VerifiableCallback();
         final int cores = 6;
-        final int[] cluster = {2, 4};
+        final int[] clusters = {2, 4};
         final int[] uids = {1, 22, 333, 4444, 5555};
 
         // Verify initial call
         final long[][] times = increaseTime(new long[uids.length][cores]);
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times));
-        mReader.readDeltaInternal(mBufferedReader, mCallback);
-        for (int i=0;i<uids.length;i++){
-            verify(mCallback).onUidCpuPolicyTime(uids[i], getTotal(cluster, times[i]));
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times));
+        mReader.readDelta(cb);
+        for (int i = 0; i < uids.length; i++) {
+            cb.verify(uids[i], getTotal(clusters, times[i]));
         }
+        cb.verifyNoMoreInteractions();
 
         // Verify that a second call will only return deltas.
-        Mockito.reset(mCallback, mBufferedReader);
+        cb.clear();
+        Mockito.reset(mProcReader);
         final long[][] times1 = increaseTime(times);
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times1));
-        mReader.readDeltaInternal(mBufferedReader, mCallback);
-        for (int i=0;i<uids.length;i++){
-            verify(mCallback).onUidCpuPolicyTime(uids[i], getTotal(cluster, subtract(times1[i], times[i])));
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times1));
+        mReader.readDelta(cb);
+        for (int i = 0; i < uids.length; i++) {
+            cb.verify(uids[i], getTotal(clusters, subtract(times1[i], times[i])));
         }
+        cb.verifyNoMoreInteractions();
 
         // Verify that there won't be a callback if the proc file values didn't change.
-        Mockito.reset(mCallback, mBufferedReader);
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times1));
-        mReader.readDeltaInternal(mBufferedReader, mCallback);
-        verifyNoMoreInteractions(mCallback);
+        cb.clear();
+        Mockito.reset(mProcReader);
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times1));
+        mReader.readDelta(cb);
+        cb.verifyNoMoreInteractions();
 
         // Verify that calling with a null callback doesn't result in any crashes
-        Mockito.reset(mCallback, mBufferedReader);
+        Mockito.reset(mProcReader);
         final long[][] times2 = increaseTime(times1);
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times2));
-        mReader.readDeltaInternal(mBufferedReader, null);
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times2));
+        mReader.readDelta(null);
 
         // Verify that the readDelta call will only return deltas when
         // the previous call had null callback.
-        Mockito.reset(mCallback, mBufferedReader);
+        cb.clear();
+        Mockito.reset(mProcReader);
         final long[][] times3 = increaseTime(times2);
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times3));
-        mReader.readDeltaInternal(mBufferedReader, mCallback);
-        for (int i=0;i<uids.length;i++){
-            verify(mCallback).onUidCpuPolicyTime(uids[i], getTotal(cluster, subtract(times3[i], times2[i])));
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times3));
+        mReader.readDelta(cb);
+        for (int i = 0; i < uids.length; i++) {
+            cb.verify(uids[i], getTotal(clusters, subtract(times3[i], times2[i])));
         }
+        cb.verifyNoMoreInteractions();
 
     }
 
     @Test
     public void testReadDelta_malformedData() throws Exception {
-        final String info = "policy0: 2 policy4: 4";
         final int cores = 6;
-        final int[] cluster = {2, 4};
+        final int[] clusters = {2, 4};
         final int[] uids = {1, 22, 333, 4444, 5555};
 
         // Verify initial call
         final long[][] times = increaseTime(new long[uids.length][cores]);
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times));
-        mReader.readDeltaInternal(mBufferedReader, mCallback);
-        for (int i=0;i<uids.length;i++){
-            verify(mCallback).onUidCpuPolicyTime(uids[i], getTotal(cluster, times[i]));
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times));
+        mReader.readDelta(mCallback);
+        for (int i = 0; i < uids.length; i++) {
+            mCallback.verify(uids[i], getTotal(clusters, times[i]));
         }
+        mCallback.verifyNoMoreInteractions();
 
-        // Verify that there is no callback if subsequent call provides wrong # of entries.
-        Mockito.reset(mCallback, mBufferedReader);
+        // Verify that there is no callback if a call has wrong format
+        mCallback.clear();
+        Mockito.reset(mProcReader);
         final long[][] temp = increaseTime(times);
         final long[][] times1 = new long[uids.length][];
-        for(int i=0;i<temp.length;i++){
+        for (int i = 0; i < temp.length; i++) {
             times1[i] = Arrays.copyOfRange(temp[i], 0, 4);
         }
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times1));
-        mReader.readDeltaInternal(mBufferedReader, mCallback);
-        verifyNoMoreInteractions(mCallback);
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times1));
+        mReader.readDelta(mCallback);
+        mCallback.verifyNoMoreInteractions();
 
         // Verify that the internal state was not modified if the given core count does not match
         // the following # of entries.
-        Mockito.reset(mCallback, mBufferedReader);
+        mCallback.clear();
+        Mockito.reset(mProcReader);
         final long[][] times2 = increaseTime(times);
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times2));
-        mReader.readDeltaInternal(mBufferedReader, mCallback);
-        for (int i=0;i<uids.length;i++){
-            verify(mCallback).onUidCpuPolicyTime(uids[i], getTotal(cluster, subtract(times2[i], times[i])));
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times2));
+        mReader.readDelta(mCallback);
+        for (int i = 0; i < uids.length; i++) {
+            mCallback.verify(uids[i], getTotal(clusters, subtract(times2[i], times[i])));
         }
+        mCallback.verifyNoMoreInteractions();
 
         // Verify that there is no callback if any value in the proc file is -ve.
-        Mockito.reset(mCallback, mBufferedReader);
+        mCallback.clear();
+        Mockito.reset(mProcReader);
         final long[][] times3 = increaseTime(times2);
         times3[uids.length - 1][cores - 1] *= -1;
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times3));
-        mReader.readDeltaInternal(mBufferedReader, mCallback);
-        for (int i=0;i<uids.length-1;i++){
-            verify(mCallback).onUidCpuPolicyTime(uids[i], getTotal(cluster, subtract(times3[i], times2[i])));
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times3));
+        mReader.readDelta(mCallback);
+        for (int i = 0; i < uids.length - 1; i++) {
+            mCallback.verify(uids[i], getTotal(clusters, subtract(times3[i], times2[i])));
         }
-        verifyNoMoreInteractions(mCallback);
+        mCallback.verifyNoMoreInteractions();
 
         // Verify that the internal state was not modified when the proc file had -ve value.
-        Mockito.reset(mCallback, mBufferedReader);
-        for(int i=0;i<cores;i++){
-            times3[uids.length -1][i] = times2[uids.length -1][i] + uids[uids.length -1]*1000;
+        mCallback.clear();
+        Mockito.reset(mProcReader);
+        for (int i = 0; i < cores; i++) {
+            times3[uids.length - 1][i] = times2[uids.length - 1][i] + uids[uids.length - 1] * 2520;
         }
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times3));
-        mReader.readDeltaInternal(mBufferedReader, mCallback);
-        verify(mCallback, times(1)).onUidCpuPolicyTime(uids[uids.length-1], getTotal(cluster, subtract(times3[uids.length -1], times2[uids.length -1])));
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times3));
+        mReader.readDelta(mCallback);
+        mCallback.verify(uids[uids.length - 1],
+                getTotal(clusters, subtract(times3[uids.length - 1], times2[uids.length - 1])));
 
-        // // Verify that there is no callback if the values in the proc file are decreased.
-        Mockito.reset(mCallback, mBufferedReader);
+        // Verify that there is no callback if the values in the proc file are decreased.
+        mCallback.clear();
+        Mockito.reset(mProcReader);
         final long[][] times4 = increaseTime(times3);
-        times4[uids.length - 1][cores - 1] = times3[uids.length - 1][cores - 1] - 1;
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times4));
-        mReader.readDeltaInternal(mBufferedReader, mCallback);
-        for (int i=0;i<uids.length-1;i++){
-            verify(mCallback).onUidCpuPolicyTime(uids[i], getTotal(cluster, subtract(times4[i], times3[i])));
+        System.arraycopy(times3[uids.length - 1], 0, times4[uids.length - 1], 0, cores);
+        times4[uids.length - 1][cores - 1] -= 100;
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times4));
+        mReader.readDelta(mCallback);
+        for (int i = 0; i < uids.length - 1; i++) {
+            mCallback.verify(uids[i], getTotal(clusters, subtract(times4[i], times3[i])));
         }
-        verifyNoMoreInteractions(mCallback);
+        mCallback.verifyNoMoreInteractions();
 
         // Verify that the internal state was not modified when the proc file had decreased values.
-        Mockito.reset(mCallback, mBufferedReader);
-        for(int i=0;i<cores;i++){
-            times4[uids.length -1][i] = times3[uids.length -1][i] + uids[uids.length -1]*1000;
+        mCallback.clear();
+        Mockito.reset(mProcReader);
+        for (int i = 0; i < cores; i++) {
+            times4[uids.length - 1][i] = times3[uids.length - 1][i] + uids[uids.length - 1] * 2520;
         }
-        when(mBufferedReader.readLine()).thenReturn(info, formatTime(uids, times4));
-        mReader.readDeltaInternal(mBufferedReader, mCallback);
-        verify(mCallback, times(1))
-                .onUidCpuPolicyTime(uids[uids.length-1], getTotal(cluster, subtract(times3[uids.length -1], times2[uids.length -1])));
-
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, clusters, times4));
+        mReader.readDelta(mCallback);
+        mCallback.verify(uids[uids.length - 1],
+                getTotal(clusters, subtract(times3[uids.length - 1], times2[uids.length - 1])));
+        mCallback.verifyNoMoreInteractions();
     }
 
 
@@ -195,26 +210,17 @@
         return val;
     }
 
-    private String[] formatTime(int[] uids, long[][] times) {
-        String[] lines = new String[uids.length + 1];
-        for (int i=0;i<uids.length;i++){
-            StringBuilder sb = new StringBuilder();
-            sb.append(uids[i]).append(':');
-            for(int j=0;j<times[i].length;j++){
-                sb.append(' ').append(times[i][j]);
-            }
-            lines[i] = sb.toString();
-        }
-        lines[uids.length] = null;
-        return lines;
-    }
-
+    /**
+     * Unit is 10ms. What's special about 2520? 2520 is LCM of 1, 2, 3, ..., 10. So that when we
+     * divide shared cpu time by concurrent thread count, we always get a nice integer, avoiding
+     * rounding errors.
+     */
     private long[][] increaseTime(long[][] original) {
         long[][] newTime = new long[original.length][original[0].length];
         Random rand = new Random();
-        for(int i = 0;i<original.length;i++){
-            for(int j=0;j<original[0].length;j++){
-                newTime[i][j] = original[i][j] + rand.nextInt(1000_000) + 10000;
+        for (int i = 0; i < original.length; i++) {
+            for (int j = 0; j < original[0].length; j++) {
+                newTime[i][j] = original[i][j] + rand.nextInt(1000) * 2520 + 2520;
             }
         }
         return newTime;
@@ -223,23 +229,69 @@
     // Format an array of cluster times according to the algorithm in KernelUidCpuClusterTimeReader
     private long[] getTotal(int[] cluster, long[] times) {
         int core = 0;
-        long[] sum = new long[cluster.length];
-        for(int i=0;i<cluster.length;i++){
-            for(int j=0;j<cluster[i];j++){
-                sum[i] += times[core++] * 10 / (j+1);
+        long[] sumTimes = new long[cluster.length];
+        for (int i = 0; i < cluster.length; i++) {
+            double sum = 0;
+            for (int j = 0; j < cluster[i]; j++) {
+                sum += (double) times[core++] * 10 / (j + 1);
             }
+            sumTimes[i] = (long) sum;
         }
-        return sum;
+        return sumTimes;
     }
 
-    // Compare array1 against flattened 2d array array2 element by element
-    private boolean testEqual(long[] array1, long[][] array2) {
-        int k=0;
-        for(int i=0;i<array2.length;i++){
-            for(int j=0;j<array2[i].length;j++){
-                if (k >= array1.length || array1[k++]!=array2[i][j])return false;
+    private class VerifiableCallback implements KernelUidCpuClusterTimeReader.Callback {
+
+        SparseArray<long[]> mData = new SparseArray<>();
+        int count = 0;
+
+        public void verify(int uid, long[] cpuClusterTimeMs) {
+            long[] array = mData.get(uid);
+            assertNotNull(array);
+            assertArrayEquals(cpuClusterTimeMs, array);
+            count++;
+        }
+
+        public void clear() {
+            mData.clear();
+            count = 0;
+        }
+
+        @Override
+        public void onUidCpuPolicyTime(int uid, long[] cpuClusterTimeMs) {
+            long[] array = new long[cpuClusterTimeMs.length];
+            System.arraycopy(cpuClusterTimeMs, 0, array, 0, array.length);
+            mData.put(uid, array);
+        }
+
+        public void verifyNoMoreInteractions() {
+            assertEquals(mData.size(), count);
+        }
+    }
+
+    /**
+     * Format uids and times (in 10ms) into the following format:
+     * [n, x0, ..., xn, uid0, time0a, time0b, ..., time0n,
+     * uid1, time1a, time1b, ..., time1n,
+     * uid2, time2a, time2b, ..., time2n, etc.]
+     * where n is the number of policies
+     * xi is the number cpus on a particular policy
+     */
+    private ByteBuffer getUidTimesBytes(int[] uids, int[] clusters, long[][] times) {
+        int size = (1 + clusters.length + uids.length * (times[0].length + 1)) * 4;
+        ByteBuffer buf = ByteBuffer.allocate(size);
+        buf.order(ByteOrder.nativeOrder());
+        buf.putInt(clusters.length);
+        for (int i = 0; i < clusters.length; i++) {
+            buf.putInt(clusters[i]);
+        }
+        for (int i = 0; i < uids.length; i++) {
+            buf.putInt(uids[i]);
+            for (int j = 0; j < times[i].length; j++) {
+                buf.putInt((int) (times[i][j]));
             }
         }
-        return k == array1.length;
+        buf.flip();
+        return buf.order(ByteOrder.nativeOrder());
     }
 }
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelUidCpuFreqTimeReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelUidCpuFreqTimeReaderTest.java
index 95b0b29..0950721 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelUidCpuFreqTimeReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelUidCpuFreqTimeReaderTest.java
@@ -19,15 +19,15 @@
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.util.SparseArray;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -37,6 +37,8 @@
 import org.mockito.MockitoAnnotations;
 
 import java.io.BufferedReader;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 import java.util.Arrays;
 
 /**
@@ -50,9 +52,9 @@
  *
  * Build: m FrameworksCoreTests
  * Install: adb install -r \
- *     ${ANDROID_PRODUCT_OUT}/data/app/FrameworksCoreTests/FrameworksCoreTests.apk
+ * ${ANDROID_PRODUCT_OUT}/data/app/FrameworksCoreTests/FrameworksCoreTests.apk
  * Run: adb shell am instrument -e class com.android.internal.os.KernelUidCpuFreqTimeReaderTest -w \
- *     com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner
+ * com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner
  *
  * or
  *
@@ -61,16 +63,22 @@
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class KernelUidCpuFreqTimeReaderTest {
-    @Mock private BufferedReader mBufferedReader;
-    @Mock private KernelUidCpuFreqTimeReader.Callback mCallback;
-    @Mock private PowerProfile mPowerProfile;
+    @Mock
+    private BufferedReader mBufferedReader;
+    @Mock
+    private KernelUidCpuFreqTimeReader.Callback mCallback;
+    @Mock
+    private PowerProfile mPowerProfile;
+    @Mock
+    private KernelCpuProcReader mProcReader;
 
     private KernelUidCpuFreqTimeReader mKernelUidCpuFreqTimeReader;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mKernelUidCpuFreqTimeReader = new KernelUidCpuFreqTimeReader();
+        mKernelUidCpuFreqTimeReader = new KernelUidCpuFreqTimeReader(mProcReader);
+        mKernelUidCpuFreqTimeReader.setThrottleInterval(0);
     }
 
     @Test
@@ -154,7 +162,7 @@
                 .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, times));
         mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback);
         for (int i = 0; i < uids.length; ++i) {
-            verify(mCallback).onUidCpuFreqTime(uids[i], times[i]);
+            Mockito.verify(mCallback).onUidCpuFreqTime(uids[i], times[i]);
         }
         verifyNoMoreInteractions(mCallback);
 
@@ -170,7 +178,7 @@
                 .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, newTimes1));
         mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback);
         for (int i = 0; i < uids.length; ++i) {
-            verify(mCallback).onUidCpuFreqTime(uids[i], subtract(newTimes1[i], times[i]));
+            Mockito.verify(mCallback).onUidCpuFreqTime(uids[i], subtract(newTimes1[i], times[i]));
         }
         verifyNoMoreInteractions(mCallback);
 
@@ -206,12 +214,89 @@
                 .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, newTimes3));
         mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback);
         for (int i = 0; i < uids.length; ++i) {
-            verify(mCallback).onUidCpuFreqTime(uids[i], subtract(newTimes3[i], newTimes2[i]));
+            Mockito.verify(mCallback).onUidCpuFreqTime(uids[i],
+                    subtract(newTimes3[i], newTimes2[i]));
         }
         verifyNoMoreInteractions(mCallback);
     }
 
     @Test
+    public void testReadDelta_Binary() throws Exception {
+        VerifiableCallback cb = new VerifiableCallback();
+        final long[] freqs = {110, 123, 145, 167, 289, 997};
+        final int[] uids = {1, 22, 333, 444, 555};
+        final long[][] times = new long[uids.length][freqs.length];
+        for (int i = 0; i < uids.length; ++i) {
+            for (int j = 0; j < freqs.length; ++j) {
+                times[i][j] = uids[i] * freqs[j] * 10;
+            }
+        }
+        when(mBufferedReader.readLine()).thenReturn(getFreqsLine(freqs));
+        long[] actualFreqs = mKernelUidCpuFreqTimeReader.readFreqs(mBufferedReader, mPowerProfile);
+
+        assertArrayEquals(freqs, actualFreqs);
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, times));
+        mKernelUidCpuFreqTimeReader.readDeltaBinary(cb);
+        for (int i = 0; i < uids.length; ++i) {
+            cb.verify(uids[i], times[i]);
+        }
+        cb.verifyNoMoreInteractions();
+
+        // Verify that a second call will only return deltas.
+        cb.clear();
+        Mockito.reset(mProcReader);
+        final long[][] newTimes1 = new long[uids.length][freqs.length];
+        for (int i = 0; i < uids.length; ++i) {
+            for (int j = 0; j < freqs.length; ++j) {
+                newTimes1[i][j] = times[i][j] + (uids[i] + freqs[j]) * 50;
+            }
+        }
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, newTimes1));
+        mKernelUidCpuFreqTimeReader.readDeltaBinary(cb);
+        for (int i = 0; i < uids.length; ++i) {
+            cb.verify(uids[i], subtract(newTimes1[i], times[i]));
+        }
+        cb.verifyNoMoreInteractions();
+
+        // Verify that there won't be a callback if the proc file values didn't change.
+        cb.clear();
+        Mockito.reset(mProcReader);
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, newTimes1));
+        mKernelUidCpuFreqTimeReader.readDeltaBinary(cb);
+        cb.verifyNoMoreInteractions();
+
+        // Verify that calling with a null callback doesn't result in any crashes
+        cb.clear();
+        Mockito.reset(mProcReader);
+        final long[][] newTimes2 = new long[uids.length][freqs.length];
+        for (int i = 0; i < uids.length; ++i) {
+            for (int j = 0; j < freqs.length; ++j) {
+                newTimes2[i][j] = newTimes1[i][j] + (uids[i] * freqs[j]) * 30;
+            }
+        }
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, newTimes2));
+        mKernelUidCpuFreqTimeReader.readDeltaBinary(null);
+        cb.verifyNoMoreInteractions();
+
+        // Verify that the readDelta call will only return deltas when
+        // the previous call had null callback.
+        cb.clear();
+        Mockito.reset(mProcReader);
+        final long[][] newTimes3 = new long[uids.length][freqs.length];
+        for (int i = 0; i < uids.length; ++i) {
+            for (int j = 0; j < freqs.length; ++j) {
+                newTimes3[i][j] = newTimes2[i][j] + (uids[i] + freqs[j]) * 40;
+            }
+        }
+        when(mProcReader.readBytes()).thenReturn(getUidTimesBytes(uids, newTimes3));
+        mKernelUidCpuFreqTimeReader.readDeltaBinary(cb);
+        for (int i = 0; i < uids.length; ++i) {
+            cb.verify(uids[i], subtract(newTimes3[i], newTimes2[i]));
+        }
+        cb.verifyNoMoreInteractions();
+    }
+
+    @Test
     public void testReadDelta_malformedData() throws Exception {
         final long[] freqs = {1, 12, 123, 1234, 12345, 123456};
         final int[] uids = {1, 22, 333, 4444, 5555};
@@ -229,7 +314,7 @@
                 .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, times));
         mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback);
         for (int i = 0; i < uids.length; ++i) {
-            verify(mCallback).onUidCpuFreqTime(uids[i], times[i]);
+            Mockito.verify(mCallback).onUidCpuFreqTime(uids[i], times[i]);
         }
         verifyNoMoreInteractions(mCallback);
 
@@ -249,7 +334,7 @@
             if (i == uids.length - 1) {
                 continue;
             }
-            verify(mCallback).onUidCpuFreqTime(uids[i], subtract(newTimes1[i], times[i]));
+            Mockito.verify(mCallback).onUidCpuFreqTime(uids[i], subtract(newTimes1[i], times[i]));
         }
         verifyNoMoreInteractions(mCallback);
 
@@ -280,7 +365,8 @@
             if (i == uids.length - 1) {
                 continue;
             }
-            verify(mCallback).onUidCpuFreqTime(uids[i], subtract(newTimes2[i], newTimes1[i]));
+            Mockito.verify(mCallback).onUidCpuFreqTime(uids[i],
+                    subtract(newTimes2[i], newTimes1[i]));
         }
         verifyNoMoreInteractions(mCallback);
 
@@ -327,6 +413,21 @@
         return lines;
     }
 
+    private ByteBuffer getUidTimesBytes(int[] uids, long[][] times) {
+        int size = (1 + uids.length + uids.length * times[0].length) * 4;
+        ByteBuffer buf = ByteBuffer.allocate(size);
+        buf.order(ByteOrder.nativeOrder());
+        buf.putInt(times[0].length);
+        for (int i = 0; i < uids.length; i++) {
+            buf.putInt(uids[i]);
+            for (int j = 0; j < times[i].length; j++) {
+                buf.putInt((int) (times[i][j] / 10));
+            }
+        }
+        buf.flip();
+        return buf.asReadOnlyBuffer().order(ByteOrder.nativeOrder());
+    }
+
     private void setCpuClusterFreqs(int numClusters, int... clusterFreqs) {
         assertEquals(numClusters, clusterFreqs.length);
         when(mPowerProfile.getNumCpuClusters()).thenReturn(numClusters);
@@ -334,4 +435,33 @@
             when(mPowerProfile.getNumSpeedStepsInCpuCluster(i)).thenReturn(clusterFreqs[i]);
         }
     }
+
+    private class VerifiableCallback implements KernelUidCpuFreqTimeReader.Callback {
+
+        SparseArray<long[]> mData = new SparseArray<>();
+        int count = 0;
+
+        public void verify(int uid, long[] cpuFreqTimeMs) {
+            long[] array = mData.get(uid);
+            assertNotNull(array);
+            assertArrayEquals(cpuFreqTimeMs, array);
+            count++;
+        }
+
+        public void clear() {
+            mData.clear();
+            count = 0;
+        }
+
+        @Override
+        public void onUidCpuFreqTime(int uid, long[] cpuFreqTimeMs) {
+            long[] array = new long[cpuFreqTimeMs.length];
+            System.arraycopy(cpuFreqTimeMs, 0, array, 0, array.length);
+            mData.put(uid, array);
+        }
+
+        public void verifyNoMoreInteractions() {
+            assertEquals(mData.size(), count);
+        }
+    }
 }
diff --git a/core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java
new file mode 100644
index 0000000..c8994dd
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.policy;
+
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+import android.content.Context;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.FlakyTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.ActionMode;
+import android.view.ContextThemeWrapper;
+
+import com.android.frameworks.coretests.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests {@link PhoneWindow}'s {@link ActionMode} related methods.
+ */
+@SmallTest
+@Presubmit
+@FlakyTest(detail = "Promote to presubmit once monitored to be stable.")
+@RunWith(AndroidJUnit4.class)
+public final class PhoneWindowTest {
+
+    private PhoneWindow mPhoneWindow;
+    private Context mContext;
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getContext();
+    }
+
+    @Test
+    public void layoutInDisplayCutoutMode_unset() throws Exception {
+        createPhoneWindowWithTheme(R.style.LayoutInDisplayCutoutModeUnset);
+        installDecor();
+
+        assertThat(mPhoneWindow.getAttributes().layoutInDisplayCutoutMode,
+                is(LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT));
+    }
+
+    @Test
+    public void layoutInDisplayCutoutMode_default() throws Exception {
+        createPhoneWindowWithTheme(R.style.LayoutInDisplayCutoutModeDefault);
+        installDecor();
+
+        assertThat(mPhoneWindow.getAttributes().layoutInDisplayCutoutMode,
+                is(LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT));
+    }
+
+    @Test
+    public void layoutInDisplayCutoutMode_always() throws Exception {
+        createPhoneWindowWithTheme(R.style.LayoutInDisplayCutoutModeAlways);
+        installDecor();
+
+        assertThat(mPhoneWindow.getAttributes().layoutInDisplayCutoutMode,
+                is(LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS));
+    }
+
+    @Test
+    public void layoutInDisplayCutoutMode_never() throws Exception {
+        createPhoneWindowWithTheme(R.style.LayoutInDisplayCutoutModeNever);
+        installDecor();
+
+        assertThat(mPhoneWindow.getAttributes().layoutInDisplayCutoutMode,
+                is(LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER));
+    }
+
+    private void createPhoneWindowWithTheme(int theme) {
+        mPhoneWindow = new PhoneWindow(new ContextThemeWrapper(mContext, theme));
+    }
+
+    private void installDecor() {
+        mPhoneWindow.getDecorView();
+    }
+}
\ No newline at end of file
diff --git a/core/tests/hosttests/test-apps/DownloadManagerTestApp/Android.mk b/core/tests/hosttests/test-apps/DownloadManagerTestApp/Android.mk
index 1d9f624..cba9cbd 100644
--- a/core/tests/hosttests/test-apps/DownloadManagerTestApp/Android.mk
+++ b/core/tests/hosttests/test-apps/DownloadManagerTestApp/Android.mk
@@ -24,6 +24,7 @@
 LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
 
 LOCAL_PACKAGE_NAME := DownloadManagerTestApp
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 ifneq ($(TARGET_BUILD_VARIANT),user)
 # Need to run as system app to get access to Settings. This test won't work for user builds.
diff --git a/core/tests/notificationtests/Android.mk b/core/tests/notificationtests/Android.mk
index 30c2dca..73ee8b8 100644
--- a/core/tests/notificationtests/Android.mk
+++ b/core/tests/notificationtests/Android.mk
@@ -10,6 +10,9 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
 LOCAL_PACKAGE_NAME := NotificationStressTests
+# Could build against SDK if it wasn't for the @RepetitiveTest annotation.
+LOCAL_PRIVATE_PLATFORM_APIS := true
+
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
     junit \
diff --git a/core/tests/overlaytests/device/Android.mk b/core/tests/overlaytests/device/Android.mk
index 4ca3e4c..680ebeb 100644
--- a/core/tests/overlaytests/device/Android.mk
+++ b/core/tests/overlaytests/device/Android.mk
@@ -18,6 +18,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under,src)
 LOCAL_MODULE_TAGS := tests
 LOCAL_PACKAGE_NAME := OverlayDeviceTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
 LOCAL_COMPATIBILITY_SUITE := device-tests
 LOCAL_TARGET_REQUIRED_MODULES := \
diff --git a/core/tests/overlaytests/device/test-apps/AppOverlayOne/Android.mk b/core/tests/overlaytests/device/test-apps/AppOverlayOne/Android.mk
index 17e20ee..edad4b2 100644
--- a/core/tests/overlaytests/device/test-apps/AppOverlayOne/Android.mk
+++ b/core/tests/overlaytests/device/test-apps/AppOverlayOne/Android.mk
@@ -17,6 +17,7 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE_TAGS := tests
 LOCAL_PACKAGE_NAME := OverlayDeviceTests_AppOverlayOne
+LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := device-tests
 LOCAL_CERTIFICATE := platform
 include $(BUILD_PACKAGE)
diff --git a/core/tests/overlaytests/device/test-apps/AppOverlayTwo/Android.mk b/core/tests/overlaytests/device/test-apps/AppOverlayTwo/Android.mk
index c24bea9..3fae8e1 100644
--- a/core/tests/overlaytests/device/test-apps/AppOverlayTwo/Android.mk
+++ b/core/tests/overlaytests/device/test-apps/AppOverlayTwo/Android.mk
@@ -17,6 +17,7 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE_TAGS := tests
 LOCAL_PACKAGE_NAME := OverlayDeviceTests_AppOverlayTwo
+LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := device-tests
 LOCAL_CERTIFICATE := platform
 include $(BUILD_PACKAGE)
diff --git a/core/tests/overlaytests/device/test-apps/FrameworkOverlay/Android.mk b/core/tests/overlaytests/device/test-apps/FrameworkOverlay/Android.mk
index dc811c5..c352c05 100644
--- a/core/tests/overlaytests/device/test-apps/FrameworkOverlay/Android.mk
+++ b/core/tests/overlaytests/device/test-apps/FrameworkOverlay/Android.mk
@@ -17,6 +17,7 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE_TAGS := tests
 LOCAL_PACKAGE_NAME := OverlayDeviceTests_FrameworkOverlay
+LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := device-tests
 LOCAL_CERTIFICATE := platform
 include $(BUILD_PACKAGE)
diff --git a/core/tests/overlaytests/host/test-apps/SignatureOverlay/Android.mk b/core/tests/overlaytests/host/test-apps/SignatureOverlay/Android.mk
index 4249549..3d2410d 100644
--- a/core/tests/overlaytests/host/test-apps/SignatureOverlay/Android.mk
+++ b/core/tests/overlaytests/host/test-apps/SignatureOverlay/Android.mk
@@ -19,6 +19,7 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE_TAGS := tests
 LOCAL_PACKAGE_NAME := OverlayHostTests_BadSignatureOverlay
+LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := general-tests
 LOCAL_AAPT_FLAGS := --custom-package $(my_package_prefix)_bad
 include $(BUILD_PACKAGE)
@@ -26,6 +27,7 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE_TAGS := tests
 LOCAL_PACKAGE_NAME := OverlayHostTests_PlatformSignatureStaticOverlay
+LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := general-tests
 LOCAL_MANIFEST_FILE := static/AndroidManifest.xml
 LOCAL_AAPT_FLAGS := --custom-package $(my_package_prefix)_static
@@ -34,6 +36,7 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE_TAGS := tests
 LOCAL_PACKAGE_NAME := OverlayHostTests_PlatformSignatureOverlay
+LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := general-tests
 LOCAL_CERTIFICATE := platform
 LOCAL_AAPT_FLAGS := --custom-package $(my_package_prefix)_v1
diff --git a/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk b/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk
index bd6d73d..ab3faf0 100644
--- a/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk
+++ b/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk
@@ -18,6 +18,7 @@
 LOCAL_MODULE_TAGS := tests
 LOCAL_SRC_FILES := $(call all-java-files-under,src)
 LOCAL_PACKAGE_NAME := OverlayHostTests_UpdateOverlay
+LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := general-tests
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
 include $(BUILD_PACKAGE)
@@ -27,6 +28,7 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE_TAGS := tests
 LOCAL_PACKAGE_NAME := OverlayHostTests_FrameworkOverlayV1
+LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := general-tests
 LOCAL_CERTIFICATE := platform
 LOCAL_AAPT_FLAGS := --custom-package $(my_package_prefix)_v1
@@ -38,6 +40,7 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE_TAGS := tests
 LOCAL_PACKAGE_NAME := OverlayHostTests_FrameworkOverlayV2
+LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := general-tests
 LOCAL_CERTIFICATE := platform
 LOCAL_AAPT_FLAGS := --custom-package $(my_package_prefix)_v2
@@ -51,23 +54,25 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE_TAGS := tests
 LOCAL_PACKAGE_NAME := OverlayHostTests_AppOverlayV1
+LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := general-tests
 LOCAL_CERTIFICATE := platform
 LOCAL_AAPT_FLAGS := --custom-package $(my_package_prefix)_v1
 LOCAL_AAPT_FLAGS += --version-code 1 --version-name v1
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/app/v1/res
-LOCAL_MANIFEST_FILE := app/AndroidManifest.xml
+LOCAL_MANIFEST_FILE := app/v1/AndroidManifest.xml
 include $(BUILD_PACKAGE)
 
 include $(CLEAR_VARS)
 LOCAL_MODULE_TAGS := tests
 LOCAL_PACKAGE_NAME := OverlayHostTests_AppOverlayV2
+LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := general-tests
 LOCAL_CERTIFICATE := platform
 LOCAL_AAPT_FLAGS := --custom-package $(my_package_prefix)_v2
 LOCAL_AAPT_FLAGS += --version-code 2 --version-name v2
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/app/v2/res
-LOCAL_MANIFEST_FILE := app/AndroidManifest.xml
+LOCAL_MANIFEST_FILE := app/v2/AndroidManifest.xml
 include $(BUILD_PACKAGE)
 
 my_package_prefix :=
diff --git a/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/AndroidManifest.xml b/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v1/AndroidManifest.xml
similarity index 100%
rename from core/tests/overlaytests/host/test-apps/UpdateOverlay/app/AndroidManifest.xml
rename to core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v1/AndroidManifest.xml
diff --git a/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v2/AndroidManifest.xml b/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v2/AndroidManifest.xml
new file mode 100644
index 0000000..9ec7d06
--- /dev/null
+++ b/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v2/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.server.om.hosttest.app_overlay">
+    <overlay android:targetPackage="com.android.server.om.hosttest.update_overlay_test"
+        android:category="android.theme" />
+</manifest>
diff --git a/core/tests/packagemanagertests/Android.mk b/core/tests/packagemanagertests/Android.mk
index 5bfde78..f95231f 100644
--- a/core/tests/packagemanagertests/Android.mk
+++ b/core/tests/packagemanagertests/Android.mk
@@ -15,6 +15,7 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 LOCAL_PACKAGE_NAME := FrameworksCorePackageManagerTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_CERTIFICATE := platform
 
diff --git a/core/tests/privacytests/Android.mk b/core/tests/privacytests/Android.mk
index 7bba417..374d0d0 100644
--- a/core/tests/privacytests/Android.mk
+++ b/core/tests/privacytests/Android.mk
@@ -12,6 +12,7 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 LOCAL_PACKAGE_NAME := FrameworksPrivacyLibraryTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_CERTIFICATE := platform
 LOCAL_COMPATIBILITY_SUITE := device-tests
diff --git a/core/tests/systemproperties/Android.mk b/core/tests/systemproperties/Android.mk
index 57e2059..3458be0 100644
--- a/core/tests/systemproperties/Android.mk
+++ b/core/tests/systemproperties/Android.mk
@@ -12,6 +12,7 @@
 LOCAL_STATIC_JAVA_LIBRARIES := android-common frameworks-core-util-lib
 LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
 LOCAL_PACKAGE_NAME := FrameworksCoreSystemPropertiesTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_CERTIFICATE := platform
 
diff --git a/core/tests/utiltests/Android.mk b/core/tests/utiltests/Android.mk
index 2dc1059..5c60c81 100644
--- a/core/tests/utiltests/Android.mk
+++ b/core/tests/utiltests/Android.mk
@@ -22,6 +22,7 @@
 LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base android.test.mock
 
 LOCAL_PACKAGE_NAME := FrameworksUtilTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_CERTIFICATE := platform
 
diff --git a/data/etc/Android.mk b/data/etc/Android.mk
index b2c6840..936ad22 100644
--- a/data/etc/Android.mk
+++ b/data/etc/Android.mk
@@ -39,3 +39,11 @@
 LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
 LOCAL_SRC_FILES := $(LOCAL_MODULE)
 include $(BUILD_PREBUILT)
+
+########################
+include $(CLEAR_VARS)
+LOCAL_MODULE := hiddenapi-package-whitelist.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/sysconfig
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
diff --git a/data/etc/hiddenapi-package-whitelist.xml b/data/etc/hiddenapi-package-whitelist.xml
new file mode 100644
index 0000000..1d46d42
--- /dev/null
+++ b/data/etc/hiddenapi-package-whitelist.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2018 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<!--
+This XML file declares which system apps should be exempted from the hidden API blacklisting, i.e.
+which apps should be allowed to access the entire private API.
+-->
+
+<config>
+  <hidden-api-whitelisted-app package="android.car.cluster.loggingrenderer" />
+  <hidden-api-whitelisted-app package="android.car.input.service" />
+  <hidden-api-whitelisted-app package="android.car.usb.handler" />
+  <hidden-api-whitelisted-app package="android.ext.services" />
+  <hidden-api-whitelisted-app package="android.ext.shared" />
+  <hidden-api-whitelisted-app package="com.android.backupconfirm" />
+  <hidden-api-whitelisted-app package="com.android.bluetooth" />
+  <hidden-api-whitelisted-app package="com.android.bluetoothdebug" />
+  <hidden-api-whitelisted-app package="com.android.bluetoothmidiservice" />
+  <hidden-api-whitelisted-app package="com.android.calllogbackup" />
+  <hidden-api-whitelisted-app package="com.android.captiveportallogin" />
+  <hidden-api-whitelisted-app package="com.android.car" />
+  <hidden-api-whitelisted-app package="com.android.car.hvac" />
+  <hidden-api-whitelisted-app package="com.android.car.mapsplaceholder" />
+  <hidden-api-whitelisted-app package="com.android.car.media" />
+  <hidden-api-whitelisted-app package="com.android.car.media.localmediaplayer" />
+  <hidden-api-whitelisted-app package="com.android.car.radio" />
+  <hidden-api-whitelisted-app package="com.android.car.settings" />
+  <hidden-api-whitelisted-app package="com.android.car.systemupdater" />
+  <hidden-api-whitelisted-app package="com.android.car.trust" />
+  <hidden-api-whitelisted-app package="com.android.carrierconfig" />
+  <hidden-api-whitelisted-app package="com.android.carrierdefaultapp" />
+  <hidden-api-whitelisted-app package="com.android.cellbroadcastreceiver" />
+  <hidden-api-whitelisted-app package="com.android.certinstaller" />
+  <hidden-api-whitelisted-app package="com.android.customlocale2" />
+  <hidden-api-whitelisted-app package="com.android.defcontainer" />
+  <hidden-api-whitelisted-app package="com.android.documentsui" />
+  <hidden-api-whitelisted-app package="com.android.egg" />
+  <hidden-api-whitelisted-app package="com.android.email.policy" />
+  <hidden-api-whitelisted-app package="com.android.emergency" />
+  <hidden-api-whitelisted-app package="com.android.externalstorage" />
+  <hidden-api-whitelisted-app package="com.android.fakeoemfeatures" />
+  <hidden-api-whitelisted-app package="com.android.gallery" />
+  <hidden-api-whitelisted-app package="com.android.hotspot2" />
+  <hidden-api-whitelisted-app package="com.android.inputdevices" />
+  <hidden-api-whitelisted-app package="com.android.keychain" />
+  <hidden-api-whitelisted-app package="com.android.location.fused" />
+  <hidden-api-whitelisted-app package="com.android.managedprovisioning" />
+  <hidden-api-whitelisted-app package="com.android.mms.service" />
+  <hidden-api-whitelisted-app package="com.android.mtp" />
+  <hidden-api-whitelisted-app package="com.android.nfc" />
+  <hidden-api-whitelisted-app package="com.android.osu" />
+  <hidden-api-whitelisted-app package="com.android.packageinstaller" />
+  <hidden-api-whitelisted-app package="com.android.pacprocessor" />
+  <hidden-api-whitelisted-app package="com.android.phone" />
+  <hidden-api-whitelisted-app package="com.android.pmc" />
+  <hidden-api-whitelisted-app package="com.android.providers.blockednumber" />
+  <hidden-api-whitelisted-app package="com.android.providers.contacts" />
+  <hidden-api-whitelisted-app package="com.android.providers.downloads" />
+  <hidden-api-whitelisted-app package="com.android.providers.downloads.ui" />
+  <hidden-api-whitelisted-app package="com.android.providers.media" />
+  <hidden-api-whitelisted-app package="com.android.providers.settings" />
+  <hidden-api-whitelisted-app package="com.android.providers.telephony" />
+  <hidden-api-whitelisted-app package="com.android.providers.userdictionary" />
+  <hidden-api-whitelisted-app package="com.android.provision" />
+  <hidden-api-whitelisted-app package="com.android.proxyhandler" />
+  <hidden-api-whitelisted-app package="com.android.sdksetup" />
+  <hidden-api-whitelisted-app package="com.android.se" />
+  <hidden-api-whitelisted-app package="com.android.server.telecom" />
+  <hidden-api-whitelisted-app package="com.android.service.ims" />
+  <hidden-api-whitelisted-app package="com.android.service.ims.presence" />
+  <hidden-api-whitelisted-app package="com.android.settings" />
+  <hidden-api-whitelisted-app package="com.android.sharedstoragebackup" />
+  <hidden-api-whitelisted-app package="com.android.shell" />
+  <hidden-api-whitelisted-app package="com.android.stk" />
+  <hidden-api-whitelisted-app package="com.android.support.car.lenspicker" />
+  <hidden-api-whitelisted-app package="com.android.systemui" />
+  <hidden-api-whitelisted-app package="com.android.systemui.theme.dark" />
+  <hidden-api-whitelisted-app package="com.android.timezone.updater" />
+  <hidden-api-whitelisted-app package="com.android.traceur" />
+  <hidden-api-whitelisted-app package="com.android.tv.settings" />
+  <hidden-api-whitelisted-app package="com.android.vpndialogs" />
+  <hidden-api-whitelisted-app package="com.android.wallpaper.livepicker" />
+  <hidden-api-whitelisted-app package="com.android.wallpaperbackup" />
+  <hidden-api-whitelisted-app package="com.android.wallpapercropper" />
+  <hidden-api-whitelisted-app package="com.googlecode.android_scripting" />
+</config>
+
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 9d1fdbd..8e76dd3 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -158,6 +158,7 @@
         <permission name="android.permission.LOCAL_MAC_ADDRESS"/>
         <permission name="android.permission.MANAGE_USERS"/>
         <permission name="android.permission.MODIFY_PHONE_STATE"/>
+        <permission name="android.permission.PACKAGE_USAGE_STATS"/>
         <permission name="android.permission.PERFORM_CDMA_PROVISIONING"/>
         <permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/>
         <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
diff --git a/graphics/java/android/graphics/EmbossMaskFilter.java b/graphics/java/android/graphics/EmbossMaskFilter.java
index a9e180f..003678a 100644
--- a/graphics/java/android/graphics/EmbossMaskFilter.java
+++ b/graphics/java/android/graphics/EmbossMaskFilter.java
@@ -20,12 +20,15 @@
     /**
      * Create an emboss maskfilter
      *
+     * @deprecated This subclass is not supported and should not be instantiated.
+     *
      * @param direction  array of 3 scalars [x, y, z] specifying the direction of the light source
      * @param ambient    0...1 amount of ambient light
      * @param specular   coefficient for specular highlights (e.g. 8)
      * @param blurRadius amount to blur before applying lighting (e.g. 3)
      * @return           the emboss maskfilter
      */
+    @Deprecated
     public EmbossMaskFilter(float[] direction, float ambient, float specular, float blurRadius) {
         if (direction.length < 3) {
             throw new ArrayIndexOutOfBoundsException();
diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java
index 3cca47b..5abd31a 100644
--- a/graphics/java/android/graphics/ImageDecoder.java
+++ b/graphics/java/android/graphics/ImageDecoder.java
@@ -19,6 +19,8 @@
 import static android.system.OsConstants.SEEK_CUR;
 import static android.system.OsConstants.SEEK_SET;
 
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -28,32 +30,28 @@
 import android.content.res.AssetManager.AssetInputStream;
 import android.content.res.Resources;
 import android.graphics.drawable.AnimatedImageDrawable;
-import android.graphics.drawable.Drawable;
 import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
 import android.graphics.drawable.NinePatchDrawable;
 import android.net.Uri;
-import android.util.Size;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.util.DisplayMetrics;
+import android.util.Size;
 import android.util.TypedValue;
 
-import libcore.io.IoUtils;
 import dalvik.system.CloseGuard;
 
-import java.nio.ByteBuffer;
+import libcore.io.IoUtils;
+
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.lang.ArrayIndexOutOfBoundsException;
-import java.lang.AutoCloseable;
-import java.lang.NullPointerException;
-import java.lang.RuntimeException;
 import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import java.nio.ByteBuffer;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
@@ -494,7 +492,7 @@
     private int     mAllocator = ALLOCATOR_DEFAULT;
     private boolean mRequireUnpremultiplied = false;
     private boolean mMutable = false;
-    private boolean mPreferRamOverQuality = false;
+    private boolean mConserveMemory = false;
     private boolean mAsAlphaMask = false;
     private Rect    mCropRect;
     private Rect    mOutPaddingRect;
@@ -623,16 +621,18 @@
     /**
      * Create a new {@link Source} from a {@link java.nio.ByteBuffer}.
      *
-     * <p>The returned {@link Source} effectively takes ownership of the
-     * {@link java.nio.ByteBuffer}; i.e. no other code should modify it after
-     * this call.</p>
+     * <p>Decoding will start from {@link java.nio.ByteBuffer#position()}. The
+     * position of {@code buffer} will not be affected.</p>
      *
-     * Decoding will start from {@link java.nio.ByteBuffer#position()}. The
-     * position after decoding is undefined.
+     * <p>Note: If this {@code Source} is passed to {@link #decodeDrawable}, and
+     * the encoded image is animated, the returned {@link AnimatedImageDrawable}
+     * will continue reading from the {@code buffer}, so its contents must not
+     * be modified, even after the {@code AnimatedImageDrawable} is returned.
+     * {@code buffer}'s contents should never be modified during decode.</p>
      */
     @NonNull
     public static Source createSource(@NonNull ByteBuffer buffer) {
-        return new ByteBufferSource(buffer);
+        return new ByteBufferSource(buffer.slice());
     }
 
     /**
@@ -692,8 +692,9 @@
      *
      *  @param width must be greater than 0.
      *  @param height must be greater than 0.
+     *  @return this object for chaining.
      */
-    public void setResize(int width, int height) {
+    public ImageDecoder setResize(int width, int height) {
         if (width <= 0 || height <= 0) {
             throw new IllegalArgumentException("Dimensions must be positive! "
                     + "provided (" + width + ", " + height + ")");
@@ -701,6 +702,7 @@
 
         mDesiredWidth = width;
         mDesiredHeight = height;
+        return this;
     }
 
     /**
@@ -710,10 +712,11 @@
      *  {@link #getSampledSize} to {@link #setResize(int, int)}.</p>
      *
      *  @param sampleSize Sampling rate of the encoded image.
+     *  @return this object for chaining.
      */
-    public void setResize(int sampleSize) {
+    public ImageDecoder setResize(int sampleSize) {
         Size size = this.getSampledSize(sampleSize);
-        this.setResize(size.getWidth(), size.getHeight());
+        return this.setResize(size.getWidth(), size.getHeight());
     }
 
     private boolean requestedResize() {
@@ -758,8 +761,9 @@
 
     /** @hide **/
     @Retention(SOURCE)
-    @IntDef({ ALLOCATOR_DEFAULT, ALLOCATOR_SOFTWARE, ALLOCATOR_SHARED_MEMORY,
-              ALLOCATOR_HARDWARE })
+    @IntDef(value = { ALLOCATOR_DEFAULT, ALLOCATOR_SOFTWARE,
+              ALLOCATOR_SHARED_MEMORY, ALLOCATOR_HARDWARE },
+              prefix = {"ALLOCATOR_"})
     public @interface Allocator {};
 
     /**
@@ -768,18 +772,20 @@
      *  This is ignored for animated drawables.
      *
      *  @param allocator Type of allocator to use.
+     *  @return this object for chaining.
      */
-    public void setAllocator(@Allocator int allocator) {
+    public ImageDecoder setAllocator(@Allocator int allocator) {
         if (allocator < ALLOCATOR_DEFAULT || allocator > ALLOCATOR_HARDWARE) {
             throw new IllegalArgumentException("invalid allocator " + allocator);
         }
         mAllocator = allocator;
+        return this;
     }
 
     /**
      *  Specify whether the {@link Bitmap} should have unpremultiplied pixels.
      *
-     *  By default, ImageDecoder will create a {@link Bitmap} with
+     *  <p>By default, ImageDecoder will create a {@link Bitmap} with
      *  premultiplied pixels, which is required for drawing with the
      *  {@link android.view.View} system (i.e. to a {@link Canvas}). Calling
      *  this method with a value of {@code true} will result in
@@ -787,9 +793,13 @@
      *  pixels. See {@link Bitmap#isPremultiplied}. This is incompatible with
      *  {@link #decodeDrawable}; attempting to decode an unpremultiplied
      *  {@link Drawable} will throw an {@link java.lang.IllegalStateException}.
+     *  </p>
+     *
+     *  @return this object for chaining.
      */
-    public void setRequireUnpremultiplied(boolean requireUnpremultiplied) {
+    public ImageDecoder setRequireUnpremultiplied(boolean requireUnpremultiplied) {
         mRequireUnpremultiplied = requireUnpremultiplied;
+        return this;
     }
 
     /**
@@ -804,19 +814,25 @@
      *  <p>For an animated image, the drawing commands drawn on the
      *  {@link Canvas} will be recorded immediately and then applied to each
      *  frame.</p>
+     *
+     *  @return this object for chaining.
      */
-    public void setPostProcessor(@Nullable PostProcessor p) {
+    public ImageDecoder setPostProcessor(@Nullable PostProcessor p) {
         mPostProcessor = p;
+        return this;
     }
 
     /**
      *  Set (replace) the {@link OnPartialImageListener} on this object.
      *
-     *  Will be called if there is an error in the input. Without one, a
-     *  partial {@link Bitmap} will be created.
+     *  <p>Will be called if there is an error in the input. Without one, an
+     *  error will result in an Exception being thrown.</p>
+     *
+     *  @return this object for chaining.
      */
-    public void setOnPartialImageListener(@Nullable OnPartialImageListener l) {
+    public ImageDecoder setOnPartialImageListener(@Nullable OnPartialImageListener l) {
         mOnPartialImageListener = l;
+        return this;
     }
 
     /**
@@ -830,9 +846,12 @@
      *  <p>NOT intended as a replacement for
      *  {@link BitmapRegionDecoder#decodeRegion}. This supports all formats,
      *  but merely crops the output.</p>
+     *
+     *  @return this object for chaining.
      */
-    public void setCrop(@Nullable Rect subset) {
+    public ImageDecoder setCrop(@Nullable Rect subset) {
         mCropRect = subset;
+        return this;
     }
 
     /**
@@ -841,10 +860,13 @@
      *  If the image is a nine patch, this Rect will be set to the padding
      *  rectangle during decode. Otherwise it will not be modified.
      *
+     *  @return this object for chaining.
+     *
      *  @hide
      */
-    public void setOutPaddingRect(@NonNull Rect outPadding) {
+    public ImageDecoder setOutPaddingRect(@NonNull Rect outPadding) {
         mOutPaddingRect = outPadding;
+        return this;
     }
 
     /**
@@ -862,21 +884,31 @@
      *  which would require retrieving the Bitmap from the returned Drawable in
      *  order to modify. Attempting to decode a mutable {@link Drawable} will
      *  throw an {@link java.lang.IllegalStateException}.</p>
+     *
+     *  @return this object for chaining.
      */
-    public void setMutable(boolean mutable) {
+    public ImageDecoder setMutable(boolean mutable) {
         mMutable = mutable;
+        return this;
     }
 
     /**
      *  Specify whether to potentially save RAM at the expense of quality.
      *
-     *  Setting this to {@code true} may result in a {@link Bitmap} with a
-     *  denser {@link Bitmap.Config}, depending on the image. For example, for
-     *  an opaque {@link Bitmap}, this may result in a {@link Bitmap.Config}
-     *  with no alpha information.
+     *  <p>Setting this to {@code true} may result in a {@link Bitmap} with a
+     *  denser {@link Bitmap.Config}, depending on the image. For example, an
+     *  opaque {@link Bitmap} with 8 bits or precision for each of its red,
+     *  green and blue components would decode to
+     *  {@link Bitmap.Config#ARGB_8888} by default, but setting this to
+     *  {@code true} will result in decoding to {@link Bitmap.Config#RGB_565}.
+     *  This necessarily lowers the quality of the output, but saves half
+     *  the memory used.</p>
+     *
+     *  @return this object for chaining.
      */
-    public void setPreferRamOverQuality(boolean preferRamOverQuality) {
-        mPreferRamOverQuality = preferRamOverQuality;
+    public ImageDecoder setConserveMemory(boolean conserveMemory) {
+        mConserveMemory = conserveMemory;
+        return this;
     }
 
     /**
@@ -890,9 +922,12 @@
      *  combine them will result in {@link #decodeDrawable}/
      *  {@link #decodeBitmap} throwing an
      *  {@link java.lang.IllegalStateException}.</p>
+     *
+     *  @return this object for chaining.
      */
-    public void setAsAlphaMask(boolean asAlphaMask) {
+    public ImageDecoder setAsAlphaMask(boolean asAlphaMask) {
         mAsAlphaMask = asAlphaMask;
+        return this;
     }
 
     @Override
@@ -957,7 +992,7 @@
         return nDecodeBitmap(mNativePtr, partialImagePtr,
                 postProcessPtr, mDesiredWidth, mDesiredHeight, mCropRect,
                 mMutable, mAllocator, mRequireUnpremultiplied,
-                mPreferRamOverQuality, mAsAlphaMask);
+                mConserveMemory, mAsAlphaMask);
     }
 
     private void callHeaderDecoded(@Nullable OnHeaderDecodedListener listener,
@@ -1171,7 +1206,7 @@
             int width, int height,
             @Nullable Rect cropRect, boolean mutable,
             int allocator, boolean requireUnpremul,
-            boolean preferRamOverQuality, boolean asAlphaMask)
+            boolean conserveMemory, boolean asAlphaMask)
         throws IOException;
     private static native Size nGetSampledSize(long nativePtr,
                                                int sampleSize);
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 8595165..38beebd 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -21,6 +21,7 @@
 import static android.content.res.FontResourcesParser.FontFileResourceEntry;
 import static android.content.res.FontResourcesParser.ProviderResourceEntry;
 
+import android.annotation.IntDef;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -49,6 +50,8 @@
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
 import java.util.ArrayList;
@@ -117,6 +120,11 @@
      */
     public long native_instance;
 
+    /** @hide */
+    @IntDef(value = {NORMAL, BOLD, ITALIC, BOLD_ITALIC})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Style {}
+
     // Style
     public static final int NORMAL = 0;
     public static final int BOLD = 1;
@@ -124,8 +132,15 @@
     public static final int BOLD_ITALIC = 3;
     /** @hide */ public static final int STYLE_MASK = 0x03;
 
-    private int mStyle = 0;
-    private int mWeight = 0;
+    private @Style int mStyle = 0;
+
+    /**
+     * A maximum value for the weight value.
+     * @hide
+     */
+    public static final int MAX_WEIGHT = 1000;
+
+    private @IntRange(from = 0, to = MAX_WEIGHT) int mWeight = 0;
 
     // Value for weight and italic. Indicates the value is resolved by font metadata.
     // Must be the same as the C++ constant in core/jni/android/graphics/FontFamily.cpp
@@ -153,7 +168,7 @@
     }
 
     /** Returns the typeface's intrinsic style attributes */
-    public int getStyle() {
+    public @Style int getStyle() {
         return mStyle;
     }
 
@@ -659,7 +674,7 @@
      *               e.g. NORMAL, BOLD, ITALIC, BOLD_ITALIC
      * @return The best matching typeface.
      */
-    public static Typeface create(String familyName, int style) {
+    public static Typeface create(String familyName, @Style int style) {
         return create(sSystemFontMap.get(familyName), style);
     }
 
@@ -680,7 +695,7 @@
      *               e.g. NORMAL, BOLD, ITALIC, BOLD_ITALIC
      * @return The best matching typeface.
      */
-    public static Typeface create(Typeface family, int style) {
+    public static Typeface create(Typeface family, @Style int style) {
         if ((style & ~STYLE_MASK) != 0) {
             style = NORMAL;
         }
@@ -776,7 +791,7 @@
      *
      * @return the default typeface that corresponds to the style
      */
-    public static Typeface defaultFromStyle(int style) {
+    public static Typeface defaultFromStyle(@Style int style) {
         return sDefaults[style];
     }
 
diff --git a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
index 598807d..f70d6e1 100644
--- a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
@@ -16,8 +16,6 @@
 
 package android.graphics.drawable;
 
-import dalvik.annotation.optimization.FastNative;
-
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -25,8 +23,6 @@
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
-import android.util.AttributeSet;
-import android.view.InflateException;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
@@ -35,20 +31,21 @@
 import android.graphics.Rect;
 import android.os.Handler;
 import android.os.Looper;
+import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.TypedValue;
 
 import com.android.internal.R;
 
+import dalvik.annotation.optimization.FastNative;
+
+import libcore.util.NativeAllocationRegistry;
+
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
-import libcore.io.IoUtils;
-import libcore.util.NativeAllocationRegistry;
-
 import java.io.IOException;
 import java.io.InputStream;
-import java.lang.Runnable;
 import java.util.ArrayList;
 
 /**
@@ -72,11 +69,14 @@
             mAssetFd = afd;
         }
 
-        public  final long mNativePtr;
+        final long mNativePtr;
 
         // These just keep references so the native code can continue using them.
         private final InputStream mInputStream;
         private final AssetFileDescriptor mAssetFd;
+
+        int[] mThemeAttrs = null;
+        boolean mAutoMirrored = false;
     }
 
     private State mState;
@@ -99,17 +99,27 @@
      *  <p>By default, the loop count in the encoded data is respected.</p>
      */
     public void setLoopCount(int loopCount) {
-        if (mState == null) {
+        if (mState.mNativePtr == 0) {
             throw new IllegalStateException("called setLoopCount on empty AnimatedImageDrawable");
         }
         nSetLoopCount(mState.mNativePtr, loopCount);
     }
 
     /**
+     * Retrieve the number of times the animation will loop.
+     */
+    public int getLoopCount() {
+        if (mState.mNativePtr == 0) {
+            throw new IllegalStateException("called getLoopCount on empty AnimatedImageDrawable");
+        }
+        return nGetLoopCount(mState.mNativePtr);
+    }
+
+    /**
      * Create an empty AnimatedImageDrawable.
      */
     public AnimatedImageDrawable() {
-        mState = null;
+        mState = new State(0, null, null);
     }
 
     @Override
@@ -123,6 +133,7 @@
 
     private void updateStateFromTypedArray(TypedArray a, int srcDensityOverride)
             throws XmlPullParserException {
+        State oldState = mState;
         final Resources r = a.getResources();
         final int srcResId = a.getResourceId(R.styleable.AnimatedImageDrawable_src, 0);
         if (srcResId != 0) {
@@ -172,6 +183,16 @@
             mIntrinsicWidth =  other.mIntrinsicWidth;
             mIntrinsicHeight = other.mIntrinsicHeight;
         }
+
+        mState.mThemeAttrs = a.extractThemeAttrs();
+        if (mState.mNativePtr == 0 && (mState.mThemeAttrs == null
+                || mState.mThemeAttrs[R.styleable.AnimatedImageDrawable_src] == 0)) {
+            throw new XmlPullParserException(a.getPositionDescription() +
+                    ": <animated-image> requires a valid 'src' attribute");
+        }
+
+        mState.mAutoMirrored = a.getBoolean(
+                R.styleable.AnimatedImageDrawable_autoMirrored, oldState.mAutoMirrored);
     }
 
     /**
@@ -225,7 +246,7 @@
 
     @Override
     public void draw(@NonNull Canvas canvas) {
-        if (mState == null) {
+        if (mState.mNativePtr == 0) {
             throw new IllegalStateException("called draw on empty AnimatedImageDrawable");
         }
 
@@ -256,7 +277,7 @@
                    + " 255! provided " + alpha);
         }
 
-        if (mState == null) {
+        if (mState.mNativePtr == 0) {
             throw new IllegalStateException("called setAlpha on empty AnimatedImageDrawable");
         }
 
@@ -266,7 +287,7 @@
 
     @Override
     public int getAlpha() {
-        if (mState == null) {
+        if (mState.mNativePtr == 0) {
             throw new IllegalStateException("called getAlpha on empty AnimatedImageDrawable");
         }
         return nGetAlpha(mState.mNativePtr);
@@ -274,7 +295,7 @@
 
     @Override
     public void setColorFilter(@Nullable ColorFilter colorFilter) {
-        if (mState == null) {
+        if (mState.mNativePtr == 0) {
             throw new IllegalStateException("called setColorFilter on empty AnimatedImageDrawable");
         }
 
@@ -298,11 +319,28 @@
     }
 
     @Override
+    public void setAutoMirrored(boolean mirrored) {
+        if (mState.mAutoMirrored != mirrored) {
+            mState.mAutoMirrored = mirrored;
+            invalidateSelf();
+        }
+    }
+
+    @Override
+    public final boolean isAutoMirrored() {
+        return mState.mAutoMirrored;
+    }
+
+    @Override
     public boolean setVisible(boolean visible, boolean restart) {
         if (!super.setVisible(visible, restart)) {
             return false;
         }
 
+        if (mState.mNativePtr == 0) {
+            throw new IllegalStateException("called setVisible on empty AnimatedImageDrawable");
+        }
+
         if (!visible) {
             nMarkInvisible(mState.mNativePtr);
         }
@@ -319,7 +357,7 @@
      */
     @Override
     public boolean isRunning() {
-        if (mState == null) {
+        if (mState.mNativePtr == 0) {
             throw new IllegalStateException("called isRunning on empty AnimatedImageDrawable");
         }
         return nIsRunning(mState.mNativePtr);
@@ -336,7 +374,7 @@
      */
     @Override
     public void start() {
-        if (mState == null) {
+        if (mState.mNativePtr == 0) {
             throw new IllegalStateException("called start on empty AnimatedImageDrawable");
         }
 
@@ -354,7 +392,7 @@
      */
     @Override
     public void stop() {
-        if (mState == null) {
+        if (mState.mNativePtr == 0) {
             throw new IllegalStateException("called stop on empty AnimatedImageDrawable");
         }
         if (nStop(mState.mNativePtr)) {
@@ -470,6 +508,8 @@
     @FastNative
     private static native boolean nStop(long nativePtr);
     @FastNative
+    private static native int nGetLoopCount(long nativePtr);
+    @FastNative
     private static native void nSetLoopCount(long nativePtr, int loopCount);
     // Pass the drawable down to native so it can call onAnimationEnd.
     private static native void nSetOnAnimationEndListener(long nativePtr,
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index 749b7594..361fe0b 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -18,11 +18,14 @@
 
 import android.annotation.ColorInt;
 import android.annotation.DrawableRes;
-import android.content.res.ColorStateList;
+import android.annotation.IdRes;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -60,17 +63,40 @@
 public final class Icon implements Parcelable {
     private static final String TAG = "Icon";
 
-    /** @hide */
+    /**
+     * An icon that was created using {@link Icon#createWithBitmap(Bitmap)}.
+     * @see #getType
+     */
     public static final int TYPE_BITMAP   = 1;
-    /** @hide */
+    /**
+     * An icon that was created using {@link Icon#createWithResource}.
+     * @see #getType
+     */
     public static final int TYPE_RESOURCE = 2;
-    /** @hide */
+    /**
+     * An icon that was created using {@link Icon#createWithData(byte[], int, int)}.
+     * @see #getType
+     */
     public static final int TYPE_DATA     = 3;
-    /** @hide */
+    /**
+     * An icon that was created using {@link Icon#createWithContentUri}
+     * or {@link Icon#createWithFilePath(String)}.
+     * @see #getType
+     */
     public static final int TYPE_URI      = 4;
-    /** @hide */
+    /**
+     * An icon that was created using {@link Icon#createWithAdaptiveBitmap}.
+     * @see #getType
+     */
     public static final int TYPE_ADAPTIVE_BITMAP = 5;
 
+    /**
+     * @hide
+     */
+    @IntDef({TYPE_BITMAP, TYPE_RESOURCE, TYPE_DATA, TYPE_URI, TYPE_ADAPTIVE_BITMAP})
+    public @interface IconType {
+    }
+
     private static final int VERSION_STREAM_SERIALIZER = 1;
 
     private final int mType;
@@ -99,14 +125,12 @@
     private int             mInt2;
 
     /**
-     * @return The type of image data held in this Icon. One of
-     * {@link #TYPE_BITMAP},
-     * {@link #TYPE_RESOURCE},
-     * {@link #TYPE_DATA}, or
-     * {@link #TYPE_URI}.
-     * {@link #TYPE_ADAPTIVE_BITMAP}
-     * @hide
+     * Gets the type of the icon provided.
+     * <p>
+     * Note that new types may be added later, so callers should guard against other
+     * types being returned.
      */
+    @IconType
     public int getType() {
         return mType;
     }
@@ -179,9 +203,13 @@
     }
 
     /**
-     * @return The package containing resources for this {@link #TYPE_RESOURCE} Icon.
-     * @hide
+     * Gets the package used to create this icon.
+     * <p>
+     * Only valid for icons of type {@link #TYPE_RESOURCE}.
+     * Note: This package may not be available if referenced in the future, and it is
+     * up to the caller to ensure safety if this package is re-used and/or persisted.
      */
+    @NonNull
     public String getResPackage() {
         if (mType != TYPE_RESOURCE) {
             throw new IllegalStateException("called getResPackage() on " + this);
@@ -190,9 +218,13 @@
     }
 
     /**
-     * @return The resource ID for this {@link #TYPE_RESOURCE} Icon.
-     * @hide
+     * Gets the resource used to create this icon.
+     * <p>
+     * Only valid for icons of type {@link #TYPE_RESOURCE}.
+     * Note: This resource may not be available if the application changes at all, and it is
+     * up to the caller to ensure safety if this resource is re-used and/or persisted.
      */
+    @IdRes
     public int getResId() {
         if (mType != TYPE_RESOURCE) {
             throw new IllegalStateException("called getResId() on " + this);
@@ -212,9 +244,13 @@
     }
 
     /**
-     * @return The {@link android.net.Uri} for this {@link #TYPE_URI} Icon.
-     * @hide
+     * Gets the uri used to create this icon.
+     * <p>
+     * Only valid for icons of type {@link #TYPE_URI}.
+     * Note: This uri may not be available in the future, and it is
+     * up to the caller to ensure safety if this uri is re-used and/or persisted.
      */
+    @NonNull
     public Uri getUri() {
         return Uri.parse(getUriString());
     }
diff --git a/graphics/java/android/view/PixelCopy.java b/graphics/java/android/view/PixelCopy.java
index a14609f..2797a4d 100644
--- a/graphics/java/android/view/PixelCopy.java
+++ b/graphics/java/android/view/PixelCopy.java
@@ -263,8 +263,16 @@
                     "Only able to copy windows with decor views");
         }
         Surface surface = null;
-        if (source.peekDecorView().getViewRootImpl() != null) {
-            surface = source.peekDecorView().getViewRootImpl().mSurface;
+        final ViewRootImpl root = source.peekDecorView().getViewRootImpl();
+        if (root != null) {
+            surface = root.mSurface;
+            final Rect surfaceInsets = root.mWindowAttributes.surfaceInsets;
+            if (srcRect == null) {
+                srcRect = new Rect(surfaceInsets.left, surfaceInsets.top,
+                        root.mWidth + surfaceInsets.left, root.mHeight + surfaceInsets.top);
+            } else {
+                srcRect.offset(surfaceInsets.left, surfaceInsets.top);
+            }
         }
         if (surface == null || !surface.isValid()) {
             throw new IllegalArgumentException(
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index e2aba04..1924bbe 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -545,9 +545,7 @@
         try {
             args = args != null ? args : new KeymasterArguments();
             entropy = entropy != null ? entropy : new byte[0];
-            OperationResult res = mBinder.begin(getToken(), alias, purpose, pruneable, args, entropy, uid);
-            // This result is -26 (KEY_USER_NOT_AUTHENTICATED) but why??
-            return res;
+            return mBinder.begin(getToken(), alias, purpose, pruneable, args, entropy, uid);
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
             return null;
@@ -565,8 +563,7 @@
         try {
             arguments = arguments != null ? arguments : new KeymasterArguments();
             input = input != null ? input : new byte[0];
-            OperationResult res = mBinder.update(token, arguments, input);
-            return res;
+            return mBinder.update(token, arguments, input);
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
             return null;
@@ -621,9 +618,9 @@
      * @return {@code KeyStore.NO_ERROR} on success, otherwise an error value corresponding to
      * a {@code KeymasterDefs.KM_ERROR_} value or {@code KeyStore} ResponseCode.
      */
-    public int addAuthToken(byte[] authToken, int userId) {
+    public int addAuthToken(byte[] authToken) {
         try {
-            return mBinder.addAuthToken(authToken, userId);
+            return mBinder.addAuthToken(authToken);
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
             return SYSTEM_ERROR;
@@ -787,6 +784,20 @@
     }
 
     /**
+     * Requests keystore to check if the confirmationui HAL is available.
+     *
+     * @return whether the confirmationUI HAL is available.
+     */
+    public boolean isConfirmationPromptSupported() {
+        try {
+            return mBinder.isConfirmationPromptSupported();
+        } catch (RemoteException e) {
+            Log.w(TAG, "Cannot connect to keystore", e);
+            return false;
+        }
+    }
+
+    /**
      * Returns a {@link KeyStoreException} corresponding to the provided keystore/keymaster error
      * code.
      */
@@ -835,14 +846,14 @@
     public InvalidKeyException getInvalidKeyException(
             String keystoreKeyAlias, int uid, KeyStoreException e) {
         switch (e.getErrorCode()) {
-            case LOCKED: // 2
+            case LOCKED:
                 return new UserNotAuthenticatedException();
-            case KeymasterDefs.KM_ERROR_KEY_EXPIRED: // -25
+            case KeymasterDefs.KM_ERROR_KEY_EXPIRED:
                 return new KeyExpiredException();
-            case KeymasterDefs.KM_ERROR_KEY_NOT_YET_VALID: // -2
+            case KeymasterDefs.KM_ERROR_KEY_NOT_YET_VALID:
                 return new KeyNotYetValidException();
-            case KeymasterDefs.KM_ERROR_KEY_USER_NOT_AUTHENTICATED: // -26
-            case OP_AUTH_NEEDED: // 15
+            case KeymasterDefs.KM_ERROR_KEY_USER_NOT_AUTHENTICATED:
+            case OP_AUTH_NEEDED:
             {
                 // We now need to determine whether the key/operation can become usable if user
                 // authentication is performed, or whether it can never become usable again.
@@ -882,7 +893,7 @@
                 // None of the key's SIDs can ever be authenticated
                 return new KeyPermanentlyInvalidatedException();
             }
-            case UNINITIALIZED: // 3
+            case UNINITIALIZED:
                 return new KeyPermanentlyInvalidatedException();
             default:
                 return new InvalidKeyException("Keystore operation failed", e);
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
index 419eb24..09b3b9b 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
@@ -243,7 +243,13 @@
                 // Check that user authentication related parameters are acceptable. This method
                 // will throw an IllegalStateException if there are issues (e.g., secure lock screen
                 // not set up).
-                KeymasterUtils.addUserAuthArgs(new KeymasterArguments(), spec);
+                KeymasterUtils.addUserAuthArgs(new KeymasterArguments(),
+                        spec.isUserAuthenticationRequired(),
+                        spec.getUserAuthenticationValidityDurationSeconds(),
+                        spec.isUserAuthenticationValidWhileOnBody(),
+                        spec.isInvalidatedByBiometricEnrollment(),
+                        GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */,
+                        spec.isUserConfirmationRequired());
             } catch (IllegalStateException | IllegalArgumentException e) {
                 throw new InvalidAlgorithmParameterException(e);
             }
@@ -279,7 +285,16 @@
         args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockModes);
         args.addEnums(KeymasterDefs.KM_TAG_PADDING, mKeymasterPaddings);
         args.addEnums(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigests);
-        KeymasterUtils.addUserAuthArgs(args, spec);
+        KeymasterUtils.addUserAuthArgs(args,
+                spec.isUserAuthenticationRequired(),
+                spec.getUserAuthenticationValidityDurationSeconds(),
+                spec.isUserAuthenticationValidWhileOnBody(),
+                spec.isInvalidatedByBiometricEnrollment(),
+                GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */,
+                spec.isUserConfirmationRequired());
+        if (spec.isTrustedUserPresenceRequired()) {
+            args.addBoolean(KeymasterDefs.KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED);
+        }
         KeymasterUtils.addMinMacLengthAuthorizationIfNecessary(
                 args,
                 mKeymasterAlgorithm,
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
index d68a33d..e33e3cd 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -344,7 +344,13 @@
                 // Check that user authentication related parameters are acceptable. This method
                 // will throw an IllegalStateException if there are issues (e.g., secure lock screen
                 // not set up).
-                KeymasterUtils.addUserAuthArgs(new KeymasterArguments(), mSpec);
+                KeymasterUtils.addUserAuthArgs(new KeymasterArguments(),
+                        mSpec.isUserAuthenticationRequired(),
+                        mSpec.getUserAuthenticationValidityDurationSeconds(),
+                        mSpec.isUserAuthenticationValidWhileOnBody(),
+                        mSpec.isInvalidatedByBiometricEnrollment(),
+                        GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */,
+                        mSpec.isUserConfirmationRequired());
             } catch (IllegalArgumentException | IllegalStateException e) {
                 throw new InvalidAlgorithmParameterException(e);
             }
@@ -535,7 +541,13 @@
         args.addEnums(KeymasterDefs.KM_TAG_PADDING, mKeymasterSignaturePaddings);
         args.addEnums(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigests);
 
-        KeymasterUtils.addUserAuthArgs(args, mSpec);
+        KeymasterUtils.addUserAuthArgs(args,
+                mSpec.isUserAuthenticationRequired(),
+                mSpec.getUserAuthenticationValidityDurationSeconds(),
+                mSpec.isUserAuthenticationValidWhileOnBody(),
+                mSpec.isInvalidatedByBiometricEnrollment(),
+                GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */,
+                mSpec.isUserConfirmationRequired());
         args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, mSpec.getKeyValidityStart());
         args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
                 mSpec.getKeyValidityForOriginationEnd());
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
index fc86ca0..05cc74a 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
@@ -497,7 +497,13 @@
                 importArgs.addEnums(KeymasterDefs.KM_TAG_PADDING, keymasterEncryptionPaddings);
                 importArgs.addEnums(KeymasterDefs.KM_TAG_PADDING,
                         KeyProperties.SignaturePadding.allToKeymaster(spec.getSignaturePaddings()));
-                KeymasterUtils.addUserAuthArgs(importArgs, spec);
+                KeymasterUtils.addUserAuthArgs(importArgs,
+                        spec.isUserAuthenticationRequired(),
+                        spec.getUserAuthenticationValidityDurationSeconds(),
+                        spec.isUserAuthenticationValidWhileOnBody(),
+                        spec.isInvalidatedByBiometricEnrollment(),
+                        spec.getBoundToSpecificSecureUserId(),
+                        spec.isUserConfirmationRequired());
                 importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME,
                         spec.getKeyValidityStart());
                 importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
@@ -694,7 +700,13 @@
             int[] keymasterPaddings = KeyProperties.EncryptionPadding.allToKeymaster(
                     params.getEncryptionPaddings());
             args.addEnums(KeymasterDefs.KM_TAG_PADDING, keymasterPaddings);
-            KeymasterUtils.addUserAuthArgs(args, params);
+            KeymasterUtils.addUserAuthArgs(args,
+                    params.isUserAuthenticationRequired(),
+                    params.getUserAuthenticationValidityDurationSeconds(),
+                    params.isUserAuthenticationValidWhileOnBody(),
+                    params.isInvalidatedByBiometricEnrollment(),
+                    params.getBoundToSpecificSecureUserId(),
+                    params.isUserConfirmationRequired());
             KeymasterUtils.addMinMacLengthAuthorizationIfNecessary(
                     args,
                     keymasterAlgorithm,
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index d0814c6..da23c70 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -21,7 +21,6 @@
 import android.annotation.Nullable;
 import android.app.KeyguardManager;
 import android.hardware.fingerprint.FingerprintManager;
-import android.security.GateKeeper;
 import android.security.KeyStore;
 import android.text.TextUtils;
 
@@ -233,7 +232,7 @@
  * key = (SecretKey) keyStore.getKey("key2", null);
  * }</pre>
  */
-public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAuthArgs {
+public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
 
     private static final X500Principal DEFAULT_CERT_SUBJECT = new X500Principal("CN=fake");
     private static final BigInteger DEFAULT_CERT_SERIAL_NUMBER = new BigInteger("1");
@@ -266,7 +265,6 @@
     private final boolean mInvalidatedByBiometricEnrollment;
     private final boolean mIsStrongBoxBacked;
     private final boolean mUserConfirmationRequired;
-    private final boolean mUnlockedDeviceRequired;
 
     /**
      * @hide should be built with Builder
@@ -297,8 +295,7 @@
             boolean userAuthenticationValidWhileOnBody,
             boolean invalidatedByBiometricEnrollment,
             boolean isStrongBoxBacked,
-            boolean userConfirmationRequired,
-            boolean unlockedDeviceRequired) {
+            boolean userConfirmationRequired) {
         if (TextUtils.isEmpty(keyStoreAlias)) {
             throw new IllegalArgumentException("keyStoreAlias must not be empty");
         }
@@ -347,7 +344,6 @@
         mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
         mIsStrongBoxBacked = isStrongBoxBacked;
         mUserConfirmationRequired = userConfirmationRequired;
-        mUnlockedDeviceRequired = unlockedDeviceRequired;
     }
 
     /**
@@ -673,22 +669,6 @@
     }
 
     /**
-     * Returns {@code true} if the key cannot be used unless the device screen is unlocked.
-     *
-     * @see Builder#SetUnlockedDeviceRequired(boolean)
-     */
-    public boolean isUnlockedDeviceRequired() {
-        return mUnlockedDeviceRequired;
-    }
-
-    /**
-     * @hide
-     */
-    public long getBoundToSpecificSecureUserId() {
-        return GateKeeper.INVALID_SECURE_USER_ID;
-    }
-
-    /**
      * Builder of {@link KeyGenParameterSpec} instances.
      */
     public final static class Builder {
@@ -719,7 +699,6 @@
         private boolean mInvalidatedByBiometricEnrollment = true;
         private boolean mIsStrongBoxBacked = false;
         private boolean mUserConfirmationRequired;
-        private boolean mUnlockedDeviceRequired = false;
 
         /**
          * Creates a new instance of the {@code Builder}.
@@ -1288,18 +1267,6 @@
         }
 
         /**
-         * Sets whether the keystore requires the screen to be unlocked before allowing decryption
-         * using this key. If this is set to {@code true}, any attempt to decrypt using this key
-         * while the screen is locked will fail. A locked device requires a PIN, password,
-         * fingerprint, or other trusted factor to access.
-         */
-        @NonNull
-        public Builder setUnlockedDeviceRequired(boolean unlockedDeviceRequired) {
-            mUnlockedDeviceRequired = unlockedDeviceRequired;
-            return this;
-        }
-
-        /**
          * Builds an instance of {@code KeyGenParameterSpec}.
          */
         @NonNull
@@ -1330,8 +1297,7 @@
                     mUserAuthenticationValidWhileOnBody,
                     mInvalidatedByBiometricEnrollment,
                     mIsStrongBoxBacked,
-                    mUserConfirmationRequired,
-                    mUnlockedDeviceRequired);
+                    mUserConfirmationRequired);
         }
     }
 }
diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java
index 7f8259b..b5b3281 100644
--- a/keystore/java/android/security/keystore/KeyProtection.java
+++ b/keystore/java/android/security/keystore/KeyProtection.java
@@ -212,7 +212,7 @@
  * ...
  * }</pre>
  */
-public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
+public final class KeyProtection implements ProtectionParameter {
     private final Date mKeyValidityStart;
     private final Date mKeyValidityForOriginationEnd;
     private final Date mKeyValidityForConsumptionEnd;
@@ -229,8 +229,6 @@
     private final long mBoundToSecureUserId;
     private final boolean mCriticalToDeviceEncryption;
     private final boolean mUserConfirmationRequired;
-    private final boolean mTrustedUserPresenceRequired;
-    private final boolean mUnlockedDeviceRequired;
 
     private KeyProtection(
             Date keyValidityStart,
@@ -244,13 +242,11 @@
             boolean randomizedEncryptionRequired,
             boolean userAuthenticationRequired,
             int userAuthenticationValidityDurationSeconds,
-            boolean trustedUserPresenceRequired,
             boolean userAuthenticationValidWhileOnBody,
             boolean invalidatedByBiometricEnrollment,
             long boundToSecureUserId,
             boolean criticalToDeviceEncryption,
-            boolean userConfirmationRequired,
-            boolean unlockedDeviceRequired) {
+            boolean userConfirmationRequired) {
         mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart);
         mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd);
         mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd);
@@ -269,8 +265,6 @@
         mBoundToSecureUserId = boundToSecureUserId;
         mCriticalToDeviceEncryption = criticalToDeviceEncryption;
         mUserConfirmationRequired = userConfirmationRequired;
-        mTrustedUserPresenceRequired = trustedUserPresenceRequired;
-        mUnlockedDeviceRequired = unlockedDeviceRequired;
     }
 
     /**
@@ -443,14 +437,6 @@
     }
 
     /**
-     * Returns {@code true} if the key is authorized to be used only if a test of user presence has
-     * been performed between the {@code Signature.initSign()} and {@code Signature.sign()} calls.
-     */
-    public boolean isTrustedUserPresenceRequired() {
-        return mTrustedUserPresenceRequired;
-    }
-
-    /**
      * Returns {@code true} if the key will be de-authorized when the device is removed from the
      * user's body.  This option has no effect on keys that don't have an authentication validity
      * duration, and has no effect if the device lacks an on-body sensor.
@@ -508,15 +494,6 @@
     }
 
     /**
-     * Returns {@code true} if the key cannot be used unless the device screen is unlocked.
-     *
-     * @see Builder#SetRequireDeviceUnlocked(boolean)
-     */
-    public boolean isUnlockedDeviceRequired() {
-        return mUnlockedDeviceRequired;
-    }
-
-    /**
      * Builder of {@link KeyProtection} instances.
      */
     public final static class Builder {
@@ -535,9 +512,6 @@
         private boolean mUserAuthenticationValidWhileOnBody;
         private boolean mInvalidatedByBiometricEnrollment = true;
         private boolean mUserConfirmationRequired;
-        private boolean mTrustedUserPresenceRequired = false;
-        private boolean mUnlockedDeviceRequired = false;
-
         private long mBoundToSecureUserId = GateKeeper.INVALID_SECURE_USER_ID;
         private boolean mCriticalToDeviceEncryption = false;
 
@@ -837,16 +811,6 @@
         }
 
         /**
-         * Sets whether a test of user presence is required to be performed between the
-         * {@code Signature.initSign()} and {@code Signature.sign()} method calls.
-         */
-        @NonNull
-        public Builder setTrustedUserPresenceRequired(boolean required) {
-            mTrustedUserPresenceRequired = required;
-            return this;
-        }
-
-        /**
          * Sets whether the key will remain authorized only until the device is removed from the
          * user's body up to the limit of the authentication validity period (see
          * {@link #setUserAuthenticationValidityDurationSeconds} and
@@ -928,18 +892,6 @@
         }
 
         /**
-         * Sets whether the keystore requires the screen to be unlocked before allowing decryption
-         * using this key. If this is set to {@code true}, any attempt to decrypt using this key
-         * while the screen is locked will fail. A locked device requires a PIN, password,
-         * fingerprint, or other trusted factor to access.
-         */
-        @NonNull
-        public Builder setUnlockedDeviceRequired(boolean unlockedDeviceRequired) {
-            mUnlockedDeviceRequired = unlockedDeviceRequired;
-            return this;
-        }
-
-        /**
          * Builds an instance of {@link KeyProtection}.
          *
          * @throws IllegalArgumentException if a required field is missing
@@ -958,13 +910,11 @@
                     mRandomizedEncryptionRequired,
                     mUserAuthenticationRequired,
                     mUserAuthenticationValidityDurationSeconds,
-                    mTrustedUserPresenceRequired,
                     mUserAuthenticationValidWhileOnBody,
                     mInvalidatedByBiometricEnrollment,
                     mBoundToSecureUserId,
                     mCriticalToDeviceEncryption,
-                    mUserConfirmationRequired,
-                    mUnlockedDeviceRequired);
+                    mUserConfirmationRequired);
         }
     }
 }
diff --git a/keystore/java/android/security/keystore/KeymasterUtils.java b/keystore/java/android/security/keystore/KeymasterUtils.java
index 5bd0e74..4e28601 100644
--- a/keystore/java/android/security/keystore/KeymasterUtils.java
+++ b/keystore/java/android/security/keystore/KeymasterUtils.java
@@ -18,7 +18,6 @@
 
 import android.util.Log;
 import android.hardware.fingerprint.FingerprintManager;
-import android.os.UserHandle;
 import android.security.GateKeeper;
 import android.security.KeyStore;
 import android.security.keymaster.KeymasterArguments;
@@ -102,27 +101,22 @@
      *         require user authentication.
      */
     public static void addUserAuthArgs(KeymasterArguments args,
-            UserAuthArgs spec) {
-        if (spec.isTrustedUserPresenceRequired()) {
-            args.addBoolean(KeymasterDefs.KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED);
-        }
-
-        if (spec.isUserConfirmationRequired()) {
+            boolean userAuthenticationRequired,
+            int userAuthenticationValidityDurationSeconds,
+            boolean userAuthenticationValidWhileOnBody,
+            boolean invalidatedByBiometricEnrollment,
+            long boundToSpecificSecureUserId,
+            boolean userConfirmationRequired) {
+        if (userConfirmationRequired) {
             args.addBoolean(KeymasterDefs.KM_TAG_TRUSTED_CONFIRMATION_REQUIRED);
         }
 
-        if (spec.isUnlockedDeviceRequired()) {
-            args.addBoolean(KeymasterDefs.KM_TAG_UNLOCKED_DEVICE_REQUIRED);
-            // Once keymaster is properly ignoring this tag, it should be added to every auth list
-            args.addUnsignedInt(KeymasterDefs.KM_TAG_USER_ID, UserHandle.getCallingUserId());
-        }
-
-        if (!spec.isUserAuthenticationRequired()) {
+        if (!userAuthenticationRequired) {
             args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
             return;
         }
 
-        if (spec.getUserAuthenticationValidityDurationSeconds() == -1) {
+        if (userAuthenticationValidityDurationSeconds == -1) {
             // Every use of this key needs to be authorized by the user. This currently means
             // fingerprint-only auth.
             FingerprintManager fingerprintManager =
@@ -138,9 +132,9 @@
             }
 
             long sid;
-            if (spec.getBoundToSpecificSecureUserId() != GateKeeper.INVALID_SECURE_USER_ID) {
-                sid = spec.getBoundToSpecificSecureUserId();
-            } else if (spec.isInvalidatedByBiometricEnrollment()) {
+            if (boundToSpecificSecureUserId != GateKeeper.INVALID_SECURE_USER_ID) {
+                sid = boundToSpecificSecureUserId;
+            } else if (invalidatedByBiometricEnrollment) {
                 // The fingerprint-only SID will change on fingerprint enrollment or removal of all,
                 // enrolled fingerprints, invalidating the key.
                 sid = fingerprintOnlySid;
@@ -153,14 +147,14 @@
             args.addUnsignedLong(
                     KeymasterDefs.KM_TAG_USER_SECURE_ID, KeymasterArguments.toUint64(sid));
             args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, KeymasterDefs.HW_AUTH_FINGERPRINT);
-            if (spec.isUserAuthenticationValidWhileOnBody()) {
+            if (userAuthenticationValidWhileOnBody) {
                 throw new ProviderException("Key validity extension while device is on-body is not "
                         + "supported for keys requiring fingerprint authentication");
             }
         } else {
             long sid;
-            if (spec.getBoundToSpecificSecureUserId() != GateKeeper.INVALID_SECURE_USER_ID) {
-                sid = spec.getBoundToSpecificSecureUserId();
+            if (boundToSpecificSecureUserId != GateKeeper.INVALID_SECURE_USER_ID) {
+                sid = boundToSpecificSecureUserId;
             } else {
                 // The key is authorized for use for the specified amount of time after the user has
                 // authenticated. Whatever unlocks the secure lock screen should authorize this key.
@@ -171,8 +165,8 @@
             args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE,
                     KeymasterDefs.HW_AUTH_PASSWORD | KeymasterDefs.HW_AUTH_FINGERPRINT);
             args.addUnsignedInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT,
-                    spec.getUserAuthenticationValidityDurationSeconds());
-            if (spec.isUserAuthenticationValidWhileOnBody()) {
+                    userAuthenticationValidityDurationSeconds);
+            if (userAuthenticationValidWhileOnBody) {
                 args.addBoolean(KeymasterDefs.KM_TAG_ALLOW_WHILE_ON_BODY);
             }
         }
diff --git a/keystore/java/android/security/keystore/UserAuthArgs.java b/keystore/java/android/security/keystore/UserAuthArgs.java
deleted file mode 100644
index 3a7017e..0000000
--- a/keystore/java/android/security/keystore/UserAuthArgs.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.security.keystore;
-
-/**
- * @hide
- *
- * This is an interface to encapsulate the user authentication arguments that
- * are passed to KeymasterUtils.addUserAuthArgs. Classes that represent
- * authorization characteristics for new or imported keys can implement this
- * interface to be passed to that method.
- */
-public interface UserAuthArgs {
-
-    boolean isUserAuthenticationRequired();
-    int getUserAuthenticationValidityDurationSeconds();
-    boolean isUserAuthenticationValidWhileOnBody();
-    boolean isInvalidatedByBiometricEnrollment();
-    boolean isTrustedUserPresenceRequired();
-    boolean isUnlockedDeviceRequired();
-    boolean isUserConfirmationRequired();
-    long getBoundToSpecificSecureUserId();
-
-}
diff --git a/keystore/tests/Android.mk b/keystore/tests/Android.mk
index 1167f76..596e5f5 100644
--- a/keystore/tests/Android.mk
+++ b/keystore/tests/Android.mk
@@ -24,6 +24,7 @@
     android-support-test
 
 LOCAL_PACKAGE_NAME := KeystoreTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
diff --git a/libs/androidfw/Asset.cpp b/libs/androidfw/Asset.cpp
index 247458d..c512a6b 100644
--- a/libs/androidfw/Asset.cpp
+++ b/libs/androidfw/Asset.cpp
@@ -26,7 +26,7 @@
 #include <androidfw/Util.h>
 #include <androidfw/ZipFileRO.h>
 #include <androidfw/ZipUtils.h>
-#include <utils/Atomic.h>
+#include <cutils/atomic.h>
 #include <utils/FileMap.h>
 #include <utils/Log.h>
 #include <utils/threads.h>
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index a5698af..fc625bb 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -28,7 +28,7 @@
 #include <androidfw/misc.h>
 #include <androidfw/ResourceTypes.h>
 #include <androidfw/ZipFileRO.h>
-#include <utils/Atomic.h>
+#include <cutils/atomic.h>
 #include <utils/Log.h>
 #include <utils/String8.h>
 #include <utils/String8.h>
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 696a00c..6268c40 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -32,7 +32,7 @@
 #include <androidfw/ByteBucketArray.h>
 #include <androidfw/ResourceTypes.h>
 #include <androidfw/TypeWrappers.h>
-#include <utils/Atomic.h>
+#include <cutils/atomic.h>
 #include <utils/ByteOrder.h>
 #include <utils/Debug.h>
 #include <utils/Log.h>
diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp
index ab27a0d..cf29e43 100644
--- a/libs/hwui/JankTracker.cpp
+++ b/libs/hwui/JankTracker.cpp
@@ -165,7 +165,7 @@
         ALOGI("%s", ss.str().c_str());
         // Just so we have something that counts up, the value is largely irrelevant
         ATRACE_INT(ss.str().c_str(), ++sDaveyCount);
-        android::util::stats_write(android::util::DAVEY_OCCURRED, ns2ms(totalDuration));
+        android::util::stats_write(android::util::DAVEY_OCCURRED, getuid(), ns2ms(totalDuration));
     }
 }
 
diff --git a/libs/hwui/hwui/AnimatedImageDrawable.h b/libs/hwui/hwui/AnimatedImageDrawable.h
index 07469d2..a5260be 100644
--- a/libs/hwui/hwui/AnimatedImageDrawable.h
+++ b/libs/hwui/hwui/AnimatedImageDrawable.h
@@ -72,6 +72,7 @@
     // already stopped)
     bool stop();
     bool isRunning();
+    int getRepetitionCount() const { return mSkAnimatedImage->getRepetitionCount(); }
     void setRepetitionCount(int count) { mSkAnimatedImage->setRepetitionCount(count); }
 
     void setOnAnimationEndListener(std::unique_ptr<OnAnimationEndListener> listener) {
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 8372331..778e768 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -94,12 +94,20 @@
 
     // Grab a copy of everything we need
     CanvasContext* context = mContext;
+    std::function<void(int64_t)> callback = std::move(mFrameCallback);
 
     // From this point on anything in "this" is *UNSAFE TO ACCESS*
     if (canUnblockUiThread) {
         unblockUiThread();
     }
 
+    // Even if we aren't drawing this vsync pulse the next frame number will still be accurate
+    if (CC_UNLIKELY(callback)) {
+        context->enqueueFrameWork([callback, frameNr = context->getFrameNumber()]() {
+            callback(frameNr);
+        });
+    }
+
     if (CC_LIKELY(canDrawThisFrame)) {
         context->draw();
     } else {
diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h
index ea51ae4..d8c43e0 100644
--- a/libs/hwui/renderthread/DrawFrameTask.h
+++ b/libs/hwui/renderthread/DrawFrameTask.h
@@ -74,6 +74,10 @@
 
     void run();
 
+    void setFrameCallback(std::function<void(int64_t)>&& callback) {
+        mFrameCallback = std::move(callback);
+    }
+
 private:
     void postAndWait();
     bool syncFrameState(TreeInfo& info);
@@ -96,6 +100,8 @@
     int64_t mSyncQueued;
 
     int64_t mFrameInfo[UI_THREAD_FRAME_INFO_SIZE];
+
+    std::function<void(int64_t)> mFrameCallback;
 };
 
 } /* namespace renderthread */
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 79e46ed..4be7a57 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -270,6 +270,10 @@
     mDrawFrameTask.setContentDrawBounds(left, top, right, bottom);
 }
 
+void RenderProxy::setFrameCallback(std::function<void(int64_t)>&& callback) {
+    mDrawFrameTask.setFrameCallback(std::move(callback));
+}
+
 void RenderProxy::serializeDisplayListTree() {
     mRenderThread.queue().post([=]() { mContext->serializeDisplayListTree(); });
 }
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index bc57d92..3425c5c 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -115,6 +115,7 @@
     ANDROID_API void removeRenderNode(RenderNode* node);
     ANDROID_API void drawRenderNode(RenderNode* node);
     ANDROID_API void setContentDrawBounds(int left, int top, int right, int bottom);
+    ANDROID_API void setFrameCallback(std::function<void(int64_t)>&& callback);
 
     ANDROID_API void addFrameMetricsObserver(FrameMetricsObserver* observer);
     ANDROID_API void removeFrameMetricsObserver(FrameMetricsObserver* observer);
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 9d246ff..21c91a2 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -310,7 +310,7 @@
     for (uint32_t i = 0; i < surface->mImageCount; ++i) {
         GrVkImageInfo info;
         info.fImage = surface->mImages[i];
-        info.fAlloc = {VK_NULL_HANDLE, 0, 0, 0};
+        info.fAlloc = GrVkAlloc();
         info.fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
         info.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
         info.fFormat = format;
diff --git a/libs/incident/proto/android/section.proto b/libs/incident/proto/android/section.proto
index 49bfe1e..ef6a8ff 100644
--- a/libs/incident/proto/android/section.proto
+++ b/libs/incident/proto/android/section.proto
@@ -40,6 +40,9 @@
 
     // incidentd calls logs for annotated field
     SECTION_LOG = 4;
+
+    // incidentd read file and gzip the data in bytes field
+    SECTION_GZIP = 5;
 }
 
 message SectionFlags {
diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp
index e3af655..0a90f85 100644
--- a/libs/input/PointerController.cpp
+++ b/libs/input/PointerController.cpp
@@ -24,15 +24,11 @@
 
 #include <log/log.h>
 
-// ToDo: Fix code to be warning free
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
 #include <SkBitmap.h>
 #include <SkCanvas.h>
 #include <SkColor.h>
 #include <SkPaint.h>
 #include <SkBlendMode.h>
-#pragma GCC diagnostic pop
 
 namespace android {
 
diff --git a/libs/protoutil/include/android/util/EncodedBuffer.h b/libs/protoutil/include/android/util/EncodedBuffer.h
index 0a8a5aa..bf698d4 100644
--- a/libs/protoutil/include/android/util/EncodedBuffer.h
+++ b/libs/protoutil/include/android/util/EncodedBuffer.h
@@ -154,7 +154,7 @@
     void editRawFixed32(size_t pos, uint32_t val);
 
     /**
-     * Copy _size_ bytes of data starting at __srcPos__ to wp.
+     * Copy _size_ bytes of data starting at __srcPos__ to wp, srcPos must be larger than wp.pos().
      */
     void copy(size_t srcPos, size_t size);
 
diff --git a/location/tests/locationtests/Android.mk b/location/tests/locationtests/Android.mk
index 44d290e..b2fd8ec 100644
--- a/location/tests/locationtests/Android.mk
+++ b/location/tests/locationtests/Android.mk
@@ -9,6 +9,7 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
 LOCAL_PACKAGE_NAME := FrameworksLocationTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
     android-support-test \
diff --git a/lowpan/tests/Android.mk b/lowpan/tests/Android.mk
index 99499dc..6fd47c6 100644
--- a/lowpan/tests/Android.mk
+++ b/lowpan/tests/Android.mk
@@ -59,6 +59,7 @@
 	android.test.base \
 
 LOCAL_PACKAGE_NAME := FrameworksLowpanApiTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_COMPATIBILITY_SUITE := device-tests
 
 LOCAL_CERTIFICATE := platform
diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java
index 3d879f5..86dfc9c 100644
--- a/media/java/android/media/AudioDeviceInfo.java
+++ b/media/java/android/media/AudioDeviceInfo.java
@@ -123,6 +123,10 @@
      * A device type describing a USB audio headset.
      */
     public static final int TYPE_USB_HEADSET       = 22;
+    /**
+     * A device type describing a Hearing Aid.
+     */
+    public static final int TYPE_HEARING_AID   = 23;
 
     /** @hide */
     @IntDef(flag = false, prefix = "TYPE", value = {
@@ -144,7 +148,8 @@
             TYPE_FM,
             TYPE_AUX_LINE,
             TYPE_IP,
-            TYPE_BUS }
+            TYPE_BUS,
+            TYPE_HEARING_AID }
     )
     @Retention(RetentionPolicy.SOURCE)
     public @interface AudioDeviceTypeOut {}
@@ -171,6 +176,7 @@
             case TYPE_AUX_LINE:
             case TYPE_IP:
             case TYPE_BUS:
+            case TYPE_HEARING_AID:
                 return true;
             default:
                 return false;
@@ -367,6 +373,7 @@
         INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_AUX_LINE, TYPE_AUX_LINE);
         INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_IP, TYPE_IP);
         INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BUS, TYPE_BUS);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_HEARING_AID, TYPE_HEARING_AID);
 
         INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BUILTIN_MIC, TYPE_BUILTIN_MIC);
         INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET, TYPE_BLUETOOTH_SCO);
@@ -415,6 +422,7 @@
         EXT_TO_INT_DEVICE_MAPPING.put(TYPE_AUX_LINE, AudioSystem.DEVICE_OUT_AUX_LINE);
         EXT_TO_INT_DEVICE_MAPPING.put(TYPE_IP, AudioSystem.DEVICE_OUT_IP);
         EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BUS, AudioSystem.DEVICE_OUT_BUS);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_HEARING_AID, AudioSystem.DEVICE_OUT_HEARING_AID);
     }
 }
 
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 9ff964b..5b627ec 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -53,6 +53,7 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
+import android.util.Pair;
 import android.util.Slog;
 import android.view.KeyEvent;
 
@@ -3913,6 +3914,21 @@
     }
 
      /**
+     * Indicate Hearing Aid connection state change.
+     * @param device Bluetooth device connected/disconnected
+     * @param state new connection state (BluetoothProfile.STATE_xxx)
+     * {@hide}
+     */
+    public void setHearingAidDeviceConnectionState(BluetoothDevice device, int state) {
+        final IAudioService service = getService();
+        try {
+            service.setHearingAidDeviceConnectionState(device, state);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+     /**
      * Indicate A2DP source or sink connection state change.
      * @param device Bluetooth device connected/disconnected
      * @param state  new connection state (BluetoothProfile.STATE_xxx)
@@ -4769,6 +4785,28 @@
     }
 
     /**
+     * Convert {@link AudioDeviceInfo} to {@link MicrophoneInfo}.
+     * @hide
+     */
+    public static MicrophoneInfo microphoneInfoFromAudioDeviceInfo(AudioDeviceInfo deviceInfo) {
+        int deviceType = deviceInfo.getType();
+        int micLocation = (deviceType == AudioDeviceInfo.TYPE_BUILTIN_MIC
+                || deviceType == AudioDeviceInfo.TYPE_TELEPHONY) ? MicrophoneInfo.LOCATION_MAINBODY
+                : deviceType == AudioDeviceInfo.TYPE_UNKNOWN ? MicrophoneInfo.LOCATION_UNKNOWN
+                        : MicrophoneInfo.LOCATION_PERIPHERAL;
+        MicrophoneInfo microphone = new MicrophoneInfo(
+                deviceInfo.getPort().name() + deviceInfo.getId(),
+                deviceInfo.getPort().type(), deviceInfo.getAddress(), micLocation,
+                MicrophoneInfo.GROUP_UNKNOWN, MicrophoneInfo.INDEX_IN_THE_GROUP_UNKNOWN,
+                MicrophoneInfo.POSITION_UNKNOWN, MicrophoneInfo.ORIENTATION_UNKNOWN,
+                new ArrayList<Pair<Float, Float>>(), new ArrayList<Pair<Integer, Integer>>(),
+                MicrophoneInfo.SENSITIVITY_UNKNOWN, MicrophoneInfo.SPL_UNKNOWN,
+                MicrophoneInfo.SPL_UNKNOWN, MicrophoneInfo.DIRECTIONALITY_UNKNOWN);
+        microphone.setId(deviceInfo.getId());
+        return microphone;
+    }
+
+    /**
      * Returns a list of {@link MicrophoneInfo} that corresponds to the characteristics
      * of all available microphones. The list is empty when no microphones are available
      * on the device. An error during the query will result in an IOException being thrown.
@@ -4785,6 +4823,15 @@
             return new ArrayList<MicrophoneInfo>(); // Always return a list.
         }
         setPortIdForMicrophones(microphones);
+        AudioDeviceInfo[] devices = getDevicesStatic(GET_DEVICES_INPUTS);
+        for (AudioDeviceInfo device : devices) {
+            if (device.getType() == AudioDeviceInfo.TYPE_BUILTIN_MIC ||
+                    device.getType() == AudioDeviceInfo.TYPE_TELEPHONY) {
+                continue;
+            }
+            MicrophoneInfo microphone = microphoneInfoFromAudioDeviceInfo(device);
+            microphones.add(microphone);
+        }
         return microphones;
     }
 
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 3847530..4f0dccb 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -41,6 +41,7 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
+import android.util.Pair;
 
 import com.android.internal.annotations.GuardedBy;
 
@@ -1630,6 +1631,20 @@
             return new ArrayList<MicrophoneInfo>();
         }
         AudioManager.setPortIdForMicrophones(activeMicrophones);
+
+        // Use routed device when there is not information returned by hal.
+        if (activeMicrophones.size() == 0) {
+            AudioDeviceInfo device = getRoutedDevice();
+            if (device != null) {
+                MicrophoneInfo microphone = AudioManager.microphoneInfoFromAudioDeviceInfo(device);
+                ArrayList<Pair<Integer, Integer>> channelMapping = new ArrayList<>();
+                for (int i = 0; i < mChannelCount; i++) {
+                    channelMapping.add(new Pair(i, MicrophoneInfo.CHANNEL_MAPPING_DIRECT));
+                }
+                microphone.setChannelMapping(channelMapping);
+                activeMicrophones.add(microphone);
+            }
+        }
         return activeMicrophones;
     }
 
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index be9fcb8..3885f90 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -401,6 +401,7 @@
     public static final int DEVICE_OUT_BUS = 0x1000000;
     public static final int DEVICE_OUT_PROXY = 0x2000000;
     public static final int DEVICE_OUT_USB_HEADSET = 0x4000000;
+    public static final int DEVICE_OUT_HEARING_AID = 0x8000000;
 
     public static final int DEVICE_OUT_DEFAULT = DEVICE_BIT_DEFAULT;
 
@@ -431,6 +432,7 @@
                                               DEVICE_OUT_BUS |
                                               DEVICE_OUT_PROXY |
                                               DEVICE_OUT_USB_HEADSET |
+                                              DEVICE_OUT_HEARING_AID |
                                               DEVICE_OUT_DEFAULT);
     public static final int DEVICE_OUT_ALL_A2DP = (DEVICE_OUT_BLUETOOTH_A2DP |
                                                    DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
@@ -546,6 +548,7 @@
     public static final String DEVICE_OUT_BUS_NAME = "bus";
     public static final String DEVICE_OUT_PROXY_NAME = "proxy";
     public static final String DEVICE_OUT_USB_HEADSET_NAME = "usb_headset";
+    public static final String DEVICE_OUT_HEARING_AID_NAME = "hearing_aid_out";
 
     public static final String DEVICE_IN_COMMUNICATION_NAME = "communication";
     public static final String DEVICE_IN_AMBIENT_NAME = "ambient";
@@ -628,6 +631,8 @@
             return DEVICE_OUT_PROXY_NAME;
         case DEVICE_OUT_USB_HEADSET:
             return DEVICE_OUT_USB_HEADSET_NAME;
+        case DEVICE_OUT_HEARING_AID:
+            return DEVICE_OUT_HEARING_AID_NAME;
         case DEVICE_OUT_DEFAULT:
         default:
             return Integer.toString(device);
diff --git a/media/java/android/media/DataSourceDesc.java b/media/java/android/media/DataSourceDesc.java
index 6dff07f..6d58a94 100644
--- a/media/java/android/media/DataSourceDesc.java
+++ b/media/java/android/media/DataSourceDesc.java
@@ -74,7 +74,7 @@
     private List<HttpCookie> mUriCookies;
     private Context mUriContext;
 
-    private long mId = 0;
+    private String mMediaId;
     private long mStartPositionMs = 0;
     private long mEndPositionMs = LONG_MAX;
 
@@ -82,11 +82,11 @@
     }
 
     /**
-     * Return the Id of data source.
-     * @return the Id of data source
+     * Return the media Id of data source.
+     * @return the media Id of data source
      */
-    public long getId() {
-        return mId;
+    public String getMediaId() {
+        return mMediaId;
     }
 
     /**
@@ -222,7 +222,7 @@
         private List<HttpCookie> mUriCookies;
         private Context mUriContext;
 
-        private long mId = 0;
+        private String mMediaId;
         private long mStartPositionMs = 0;
         private long mEndPositionMs = LONG_MAX;
 
@@ -248,7 +248,7 @@
             mUriCookies = dsd.mUriCookies;
             mUriContext = dsd.mUriContext;
 
-            mId = dsd.mId;
+            mMediaId = dsd.mMediaId;
             mStartPositionMs = dsd.mStartPositionMs;
             mEndPositionMs = dsd.mEndPositionMs;
         }
@@ -282,7 +282,7 @@
             dsd.mUriCookies = mUriCookies;
             dsd.mUriContext = mUriContext;
 
-            dsd.mId = mId;
+            dsd.mMediaId = mMediaId;
             dsd.mStartPositionMs = mStartPositionMs;
             dsd.mEndPositionMs = mEndPositionMs;
 
@@ -290,13 +290,13 @@
         }
 
         /**
-         * Sets the Id of this data source.
+         * Sets the media Id of this data source.
          *
-         * @param id the Id of this data source
+         * @param mediaId the media Id of this data source
          * @return the same Builder instance.
          */
-        public Builder setId(long id) {
-            mId = id;
+        public Builder setMediaId(String mediaId) {
+            mMediaId = mediaId;
             return this;
         }
 
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 05ba4c3..4af8850 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -151,6 +151,8 @@
     void setWiredDeviceConnectionState(int type, int state, String address, String name,
             String caller);
 
+    void setHearingAidDeviceConnectionState(in BluetoothDevice device, int state);
+
     int setBluetoothA2dpDeviceConnectionState(in BluetoothDevice device, int state, int profile);
 
     void handleBluetoothA2dpDeviceConfigChange(in BluetoothDevice device);
@@ -179,6 +181,10 @@
 
     oneway void unregisterAudioPolicyAsync(in IAudioPolicyCallback pcb);
 
+    int addMixForPolicy(in AudioPolicyConfig policyConfig, in IAudioPolicyCallback pcb);
+
+    int removeMixForPolicy(in AudioPolicyConfig policyConfig, in IAudioPolicyCallback pcb);
+
     int setFocusPropertiesForPolicy(int duckingBehavior, in IAudioPolicyCallback pcb);
 
     void setVolumePolicy(in VolumePolicy policy);
diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java
index fbe5561..6dd4f69 100644
--- a/media/java/android/media/Image.java
+++ b/media/java/android/media/Image.java
@@ -19,7 +19,9 @@
 import java.nio.ByteBuffer;
 import java.lang.AutoCloseable;
 
+import android.annotation.Nullable;
 import android.graphics.Rect;
+import android.hardware.HardwareBuffer;
 
 /**
  * <p>A single complete image buffer to use with a media source such as a
@@ -184,6 +186,23 @@
     public abstract long getTimestamp();
 
     /**
+     * Get the {@link android.hardware.HardwareBuffer HardwareBuffer} handle of the input image
+     * intended for GPU and/or hardware access.
+     * <p>
+     * The returned {@link android.hardware.HardwareBuffer HardwareBuffer} shall not be used
+     * after  {@link Image#close Image.close()} has been called.
+     * </p>
+     * @return the HardwareBuffer associated with this Image or null if this Image doesn't support
+     * this feature (e.g. {@link android.media.ImageWriter ImageWriter} or
+     * {@link android.media.MediaCodec MediaCodec} don't).
+     */
+    @Nullable
+    public HardwareBuffer getHardwareBuffer() {
+        throwISEIfImageIsInvalid();
+        return null;
+    }
+
+    /**
      * Set the timestamp associated with this frame.
      * <p>
      * The timestamp is measured in nanoseconds, and is normally monotonically
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index 1019580..fb0de5c 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -876,6 +876,12 @@
         }
 
         @Override
+        public HardwareBuffer getHardwareBuffer() {
+            throwISEIfImageIsInvalid();
+            return nativeGetHardwareBuffer();
+        }
+
+        @Override
         public void setTimestamp(long timestampNs) {
             throwISEIfImageIsInvalid();
             mTimestamp = timestampNs;
@@ -1017,6 +1023,7 @@
         private synchronized native int nativeGetWidth();
         private synchronized native int nativeGetHeight();
         private synchronized native int nativeGetFormat(int readerFormat);
+        private synchronized native HardwareBuffer nativeGetHardwareBuffer();
     }
 
     private synchronized native void nativeInit(Object weakSelf, int w, int h,
diff --git a/media/java/android/media/MediaBrowser2.java b/media/java/android/media/MediaBrowser2.java
index f03dbae..dea38a8 100644
--- a/media/java/android/media/MediaBrowser2.java
+++ b/media/java/android/media/MediaBrowser2.java
@@ -20,6 +20,8 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.media.MediaLibraryService2.MediaLibrarySession;
+import android.media.MediaSession2.ControllerInfo;
 import android.media.update.ApiLoader;
 import android.media.update.MediaBrowser2Provider;
 import android.os.Bundle;
@@ -29,7 +31,6 @@
 
 /**
  * Browses media content offered by a {@link MediaLibraryService2}.
- * @hide
  */
 public class MediaBrowser2 extends MediaController2 {
     // Equals to the ((MediaBrowser2Provider) getProvider())
@@ -49,16 +50,23 @@
          * @param rootMediaId media id of the library root. Can be {@code null}
          * @param rootExtra extra of the library root. Can be {@code null}
          */
-        public void onGetRootResult(Bundle rootHints, @Nullable String rootMediaId,
+        public void onGetLibraryRootDone(Bundle rootHints, @Nullable String rootMediaId,
                 @Nullable Bundle rootExtra) { }
 
         /**
          * Called when there's change in the parent's children.
+         * <p>
+         * This API is called when the library service called
+         * {@link MediaLibrarySession#notifyChildrenChanged(ControllerInfo, String, int, Bundle)} or
+         * {@link MediaLibrarySession#notifyChildrenChanged(String, int, Bundle)} for the parent.
          *
          * @param parentId parent id that you've specified with {@link #subscribe(String, Bundle)}
-         * @param extras extra bundle from the library service
+         * @param itemCount number of children
+         * @param extras extra bundle from the library service. Can be differ from extras that
+         *               you've specified with {@link #subscribe(String, Bundle)}.
          */
-        public void onChildrenChanged(@NonNull String parentId, @Nullable Bundle extras) { }
+        public void onChildrenChanged(@NonNull String parentId, int itemCount,
+                @Nullable Bundle extras) { }
 
         /**
          * Called when the list of items has been returned by the library service for the previous
@@ -72,7 +80,7 @@
          * @param result result. Can be {@code null}
          * @param extras extra bundle from the library service
          */
-        public void onChildrenLoaded(@NonNull String parentId, int page, int pageSize,
+        public void onGetChildrenDone(@NonNull String parentId, int page, int pageSize,
                 @Nullable List<MediaItem2> result, @Nullable Bundle extras) { }
 
         /**
@@ -84,7 +92,7 @@
          * @param mediaId media id
          * @param result result. Can be {@code null}
          */
-        public void onItemLoaded(@NonNull String mediaId, @Nullable MediaItem2 result) { }
+        public void onGetItemDone(@NonNull String mediaId, @Nullable MediaItem2 result) { }
 
         /**
          * Called when there's change in the search result requested by the previous
@@ -112,7 +120,7 @@
          * @param result result. Can be {@code null}.
          * @param extras extra bundle from the library service
          */
-        public void onSearchResultLoaded(@NonNull String query, int page, int pageSize,
+        public void onGetSearchResultDone(@NonNull String query, int page, int pageSize,
                 @Nullable List<MediaItem2> result, @Nullable Bundle extras) { }
     }
 
@@ -131,10 +139,10 @@
 
     /**
      * Get the library root. Result would be sent back asynchronously with the
-     * {@link BrowserCallback#onGetRootResult(Bundle, String, Bundle)}.
+     * {@link BrowserCallback#onGetLibraryRootDone(Bundle, String, Bundle)}.
      *
      * @param rootHints hint for the root
-     * @see BrowserCallback#onGetRootResult(Bundle, String, Bundle)
+     * @see BrowserCallback#onGetLibraryRootDone(Bundle, String, Bundle)
      */
     public void getLibraryRoot(Bundle rootHints) {
         mProvider.getLibraryRoot_impl(rootHints);
@@ -142,7 +150,7 @@
 
     /**
      * Subscribe to a parent id for the change in its children. When there's a change,
-     * {@link BrowserCallback#onChildrenChanged(String, Bundle)} will be called with the bundle
+     * {@link BrowserCallback#onChildrenChanged(String, int, Bundle)} will be called with the bundle
      * that you've specified. You should call {@link #getChildren(String, int, int, Bundle)} to get
      * the actual contents for the parent.
      *
@@ -156,17 +164,19 @@
     /**
      * Unsubscribe for changes to the children of the parent, which was previously subscribed with
      * {@link #subscribe(String, Bundle)}.
+     * <p>
+     * This unsubscribes all previous subscription with the parent id, regardless of the extra
+     * that was previously sent to the library service.
      *
      * @param parentId parent id
-     * @param extras extra bundle
      */
-    public void unsubscribe(String parentId, @Nullable Bundle extras) {
-        mProvider.unsubscribe_impl(parentId, extras);
+    public void unsubscribe(String parentId) {
+        mProvider.unsubscribe_impl(parentId);
     }
 
     /**
      * Get list of children under the parent. Result would be sent back asynchronously with the
-     * {@link BrowserCallback#onChildrenLoaded(String, int, int, List, Bundle)}.
+     * {@link BrowserCallback#onGetChildrenDone(String, int, int, List, Bundle)}.
      *
      * @param parentId parent id for getting the children.
      * @param page page number to get the result. Starts from {@code 1}
@@ -179,7 +189,7 @@
 
     /**
      * Get the media item with the given media id. Result would be sent back asynchronously with the
-     * {@link BrowserCallback#onItemLoaded(String, MediaItem2)}.
+     * {@link BrowserCallback#onGetItemDone(String, MediaItem2)}.
      *
      * @param mediaId media id for specifying the item
      */
@@ -201,7 +211,7 @@
 
     /**
      * Get the search result from lhe library service. Result would be sent back asynchronously with
-     * the {@link BrowserCallback#onSearchResultLoaded(String, int, int, List, Bundle)}.
+     * the {@link BrowserCallback#onGetSearchResultDone(String, int, int, List, Bundle)}.
      *
      * @param query search query that you've specified with {@link #search(String, Bundle)}
      * @param page page number to get search result. Starts from {@code 1}
diff --git a/media/java/android/media/MediaController2.java b/media/java/android/media/MediaController2.java
index bfd1fd4..38d5000 100644
--- a/media/java/android/media/MediaController2.java
+++ b/media/java/android/media/MediaController2.java
@@ -19,13 +19,13 @@
 import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SystemApi;
 import android.app.PendingIntent;
 import android.content.Context;
 import android.media.MediaSession2.Command;
 import android.media.MediaSession2.CommandButton;
 import android.media.MediaSession2.CommandGroup;
 import android.media.MediaSession2.ControllerInfo;
+import android.media.MediaSession2.ErrorCode;
 import android.media.MediaSession2.PlaylistParams;
 import android.media.session.MediaSessionManager;
 import android.media.update.ApiLoader;
@@ -64,9 +64,8 @@
  * <p>
  * @see MediaSession2
  * @see MediaSessionService2
- * @hide
  */
-public class MediaController2 implements AutoCloseable {
+public class MediaController2 implements AutoCloseable, MediaPlaylistController {
     /**
      * Interface for listening to change in activeness of the {@link MediaSession2}.  It's
      * active if and only if it has set a player.
@@ -126,19 +125,69 @@
 
         /**
          * Called when the playlist is changed.
+         * <p>
+         * When it's called, you should invalidate previous playback information such as position,
+         * player state, current item, etc.
          *
          * @param playlist A new playlist set by the session.
          */
+        // TODO(jaewan): Enhance doc
         public void onPlaylistChanged(@NonNull List<MediaItem2> playlist) { }
 
         /**
          * Called when the playback state is changed.
          *
          * @param state latest playback state
+         * @hide
          */
+        // TODo(jaewan): Remove
         public void onPlaybackStateChanged(@NonNull PlaybackState2 state) { }
 
         /**
+         * Called when the player state is changed.
+         *
+         * @param state
+         */
+        public void onPlayerStateChanged(int state) { }
+
+        /**
+         * Called when the player's position is changed
+         *
+         * @param updateTimeMs timestamp when the position information is sent from the session
+         * @param positionMs position in millis
+         */
+        public void onPositionChanged(long updateTimeMs, long positionMs) { }
+
+        /**
+         * Called when playback speed is changed.
+         *
+         * @param speed speed
+         */
+        public void onPlaybackSpeedChanged(float speed) { }
+
+        /**
+         * Called when the player's buffering position
+         *
+         * @param positionMs buffering position in millis
+         */
+        public void onBufferedPositionChanged(long positionMs) { }
+
+        /**
+         * Called when a error from
+         *
+         * @param errorCode error code
+         * @param extras extra information
+         */
+        public void onError(@ErrorCode int errorCode, @Nullable Bundle extras) { }
+
+        /**
+         * Called when the player's current playing item is changed
+         *
+         * @param item new item
+         */
+        public void onCurrentPlaylistItemChanged(MediaItem2 item) { }
+
+        /**
          * Called when the playlist parameters are changed.
          *
          * @param params The new play list parameters.
@@ -166,7 +215,6 @@
         /**
          * @hide
          */
-        @SystemApi
         public PlaybackInfo(PlaybackInfoProvider provider) {
             mProvider = provider;
         }
@@ -174,7 +222,6 @@
         /**
          * @hide
          */
-        @SystemApi
         public PlaybackInfoProvider getProvider() {
             return mProvider;
         }
@@ -281,7 +328,6 @@
     /**
      * @hide
      */
-    @SystemApi
     public MediaController2Provider getProvider() {
         return mProvider;
     }
@@ -325,7 +371,7 @@
      * Request that the player prepare its playback. In other words, other sessions can continue
      * to play during the preparation of this session. This method can be used to speed up the
      * start of the playback. Once the preparation is done, the session will change its playback
-     * state to {@link PlaybackState2#STATE_PAUSED}. Afterwards, {@link #play} can be called to
+     * state to {@link MediaPlayerBase#PLAYER_STATE_PAUSED}. Afterwards, {@link #play} can be called to
      * start playback.
      */
     public void prepare() {
@@ -360,12 +406,13 @@
     /**
      * Sets the index of current DataSourceDesc in the play list to be played.
      *
-     * @param index the index of DataSourceDesc in the play list you want to play
+     * @param item the index of DataSourceDesc in the play list you want to play
      * @throws IllegalArgumentException if the play list is null
      * @throws NullPointerException if index is outside play list range
      */
-    public void setCurrentPlaylistItem(int index) {
-        mProvider.setCurrentPlaylistItem_impl(index);
+    @Override
+    public void skipToPlaylistItem(@NonNull MediaItem2 item) {
+        mProvider.skipToPlaylistItem_impl(item);
     }
 
     /**
@@ -375,7 +422,7 @@
      * @param params A {@link PlaylistParams} object to set.
      * @throws IllegalArgumentException if given {@param param} is null.
      */
-    public void setPlaylistParams(PlaylistParams params) {
+    public void setPlaylistParams(@NonNull PlaylistParams params) {
         mProvider.setPlaylistParams_impl(params);
     }
 
@@ -428,12 +475,11 @@
         mProvider.playFromUri_impl(uri, extras);
     }
 
-
     /**
      * Request that the player prepare playback for a specific media id. In other words, other
      * sessions can continue to play during the preparation of this session. This method can be
      * used to speed up the start of the playback. Once the preparation is done, the session
-     * will change its playback state to {@link PlaybackState2#STATE_PAUSED}. Afterwards,
+     * will change its playback state to {@link MediaPlayerBase#PLAYER_STATE_PAUSED}. Afterwards,
      * {@link #play} can be called to start playback. If the preparation is not needed,
      * {@link #playFromMediaId} can be directly called without this method.
      *
@@ -450,7 +496,7 @@
      * query should be treated as a request to prepare any music. In other words, other sessions
      * can continue to play during the preparation of this session. This method can be used to
      * speed up the start of the playback. Once the preparation is done, the session will
-     * change its playback state to {@link PlaybackState2#STATE_PAUSED}. Afterwards,
+     * change its playback state to {@link MediaPlayerBase#PLAYER_STATE_PAUSED}. Afterwards,
      * {@link #play} can be called to start playback. If the preparation is not needed,
      * {@link #playFromSearch} can be directly called without this method.
      *
@@ -466,7 +512,7 @@
      * Request that the player prepare playback for a specific {@link Uri}. In other words,
      * other sessions can continue to play during the preparation of this session. This method
      * can be used to speed up the start of the playback. Once the preparation is done, the
-     * session will change its playback state to {@link PlaybackState2#STATE_PAUSED}. Afterwards,
+     * session will change its playback state to {@link MediaPlayerBase#PLAYER_STATE_PAUSED}. Afterwards,
      * {@link #play} can be called to start playback. If the preparation is not needed,
      * {@link #playFromUri} can be directly called without this method.
      *
@@ -521,24 +567,6 @@
     }
 
     /**
-     * Get the rating type supported by the session. One of:
-     * <ul>
-     * <li>{@link Rating2#RATING_NONE}</li>
-     * <li>{@link Rating2#RATING_HEART}</li>
-     * <li>{@link Rating2#RATING_THUMB_UP_DOWN}</li>
-     * <li>{@link Rating2#RATING_3_STARS}</li>
-     * <li>{@link Rating2#RATING_4_STARS}</li>
-     * <li>{@link Rating2#RATING_5_STARS}</li>
-     * <li>{@link Rating2#RATING_PERCENTAGE}</li>
-     * </ul>
-     *
-     * @return The supported rating type
-     */
-    public int getRatingType() {
-        return mProvider.getRatingType_impl();
-    }
-
-    /**
      * Get an intent for launching UI associated with this session if one exists.
      *
      * @return A {@link PendingIntent} to launch UI or null.
@@ -555,12 +583,72 @@
      * playback state.
      *
      * @return a playback state. Can be {@code null}
+     * @hide
      */
     public @Nullable PlaybackState2 getPlaybackState() {
         return mProvider.getPlaybackState_impl();
     }
 
     /**
+     * Get the lastly cached player state from {@link ControllerCallback#onPlayerStateChanged(int)}.
+     *
+     * @return player state
+     */
+    public int getPlayerState() {
+        return mProvider.getPlayerState_impl();
+    }
+
+    /**
+     * Get the lastly cached position from {@link ControllerCallback#onPositionChanged(long, long)}.
+     * <p>
+     * This returns the calculated value of the position, based on the difference between the
+     * update time and current time.
+     *
+     * @return position
+     */
+    public long getPosition() {
+        return mProvider.getPosition_impl();
+    }
+
+    /**
+     * Get the lastly cached playback speed from
+     * {@link ControllerCallback#onPlaybackSpeedChanged(float)}.
+     *
+     * @return speed
+     */
+    public float getPlaybackSpeed() {
+        return mProvider.getPlaybackSpeed_impl();
+    }
+
+    /**
+     * Set the playback speed.
+     */
+    public void setPlaybackSpeed(float speed) {
+        // TODO: implement this
+    }
+
+    /**
+     * Get the lastly cached buffered position from
+     * {@link ControllerCallback#onBufferedPositionChanged(long)}.
+     *
+     * @return buffering position in millis
+     */
+    public long getBufferedPosition() {
+        return mProvider.getBufferedPosition_impl();
+    }
+
+    /**
+     * Get the lastly cached current item from
+     * {@link ControllerCallback#onCurrentPlaylistItemChanged(MediaItem2)}.
+     *
+     * @return index of the current item
+     */
+    @Override
+    public MediaItem2 getCurrentPlaylistItem() {
+        return mProvider.getCurrentPlaylistItem_impl();
+    }
+
+    /**
      * Get the current playback info for this session.
      *
      * @return The current playback info or null.
@@ -571,7 +659,12 @@
 
     /**
      * Rate the media. This will cause the rating to be set for the current user.
-     * The Rating type must match the type returned by {@link #getRatingType()}.
+     * The rating style must follow the user rating style from the session.
+     * You can get the rating style from the session through the
+     * {@link MediaMetadata#getRating(String)} with the key
+     * {@link MediaMetadata#METADATA_KEY_USER_RATING}.
+     * <p>
+     * If the user rating was {@code null}, the media item does not accept setting user rating.
      *
      * @param mediaId The id of the media
      * @param rating The rating to set
@@ -597,6 +690,7 @@
      *
      * @return playlist. Can be {@code null} if the controller doesn't have enough permission.
      */
+    @Override
     public @Nullable List<MediaItem2> getPlaylist() {
         return mProvider.getPlaylist_impl();
     }
@@ -611,34 +705,39 @@
     }
 
     /**
-     * Removes the media item at index in the play list.
+     * Removes the media item at index in the playlist.
      *<p>
-     * If index is same as the current index of the playlist, current playback
+     * If the item is the currently playing item of the playlist, current playback
      * will be stopped and playback moves to next source in the list.
-     *
-     * @return the removed DataSourceDesc at index in the play list
-     * @throws IllegalArgumentException if the play list is null
-     * @throws IndexOutOfBoundsException if index is outside play list range
      */
-    // TODO(jaewan): Remove with index was previously rejected by council (b/36524925)
-    // TODO(jaewan): Should we also add movePlaylistItem from index to index?
-    public void removePlaylistItem(MediaItem2 item) {
+    @Override
+    public void removePlaylistItem(@NonNull MediaItem2 item) {
         mProvider.removePlaylistItem_impl(item);
     }
 
     /**
+     * Replace the media item at index in the playlist.
+     * @param index the index of the item to replace
+     * @param item the new item
+     */
+    @Override
+    public void replacePlaylistItem(int index, @NonNull MediaItem2 item) {
+        mProvider.replacePlaylistItem_impl(index, item);
+    }
+
+    /**
      * Inserts the media item to the play list at position index.
      * <p>
      * This will not change the currently playing media item.
      * If index is less than or equal to the current index of the play list,
      * the current index of the play list will be incremented correspondingly.
      *
-     * @param index the index you want to add dsd to the play list
-     * @param item the media item you want to add to the play list
+     * @param index the index you want to add
+     * @param item the media item you want to add
      * @throws IndexOutOfBoundsException if index is outside play list range
-     * @throws NullPointerException if dsd is null
      */
-    public void addPlaylistItem(int index, MediaItem2 item) {
+    @Override
+    public void addPlaylistItem(int index, @NonNull MediaItem2 item) {
         mProvider.addPlaylistItem_impl(index, item);
     }
 }
diff --git a/media/java/android/media/MediaItem2.java b/media/java/android/media/MediaItem2.java
index 667aac1..b7b75e4 100644
--- a/media/java/android/media/MediaItem2.java
+++ b/media/java/android/media/MediaItem2.java
@@ -19,7 +19,6 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SystemApi;
 import android.content.Context;
 import android.media.update.ApiLoader;
 import android.media.update.MediaItem2Provider;
@@ -35,7 +34,6 @@
  * When it's sent to a controller or browser, it's anonymized and data descriptor wouldn't be sent.
  * <p>
  * This object isn't a thread safe.
- * @hide
  */
 public class MediaItem2 {
     /** @hide */
@@ -64,7 +62,9 @@
      * @param mediaId id of this item. It must be unique whithin this app
      * @param metadata metadata with the media id.
      * @param flags The flags for this item.
+     * @hide
      */
+    // TODO(jaewan): Remove this
     public MediaItem2(@NonNull Context context, @NonNull String mediaId,
             @NonNull DataSourceDesc dsd, @Nullable MediaMetadata2 metadata,
             @Flags int flags) {
@@ -76,7 +76,6 @@
      * Create a new media item
      * @hide
      */
-    @SystemApi
     public MediaItem2(MediaItem2Provider provider) {
         mProvider = provider;
     }
@@ -156,4 +155,87 @@
     public @Nullable DataSourceDesc getDataSourceDesc() {
         return mProvider.getDataSourceDesc_impl();
     }
+
+    /**
+     * Build {@link MediaItem2}
+     */
+    // TODO(jaewan): Move it to updatable
+    public static final class Builder {
+        private Context mContext;
+        private @Flags int mFlags;
+        private String mMediaId;
+        private MediaMetadata2 mMetadata;
+        private DataSourceDesc mDataSourceDesc;
+
+        /**
+         * Constructor for {@link Builder}
+         *
+         * @param context
+         * @param flags
+         */
+        public Builder(@NonNull Context context, @Flags int flags) {
+            mContext = context;
+            mFlags = flags;
+        }
+
+        /**
+         * Set the media id of this instance. {@code null} for unset.
+         * <p>
+         * Media id is used to identify a media contents between session and controller.
+         * <p>
+         * If the metadata is set with the {@link #setMetadata(MediaMetadata2)} and it has
+         * media id, id from {@link #setMediaId(String)} will be ignored and metadata's id will be
+         * used instead. If the id isn't set neither by {@link #setMediaId(String)} nor
+         * {@link #setMetadata(MediaMetadata2)}, id will be automatically generated.
+         *
+         * @param mediaId media id
+         * @return this instance for chaining
+         */
+        public Builder setMediaId(@Nullable String mediaId) {
+            mMediaId = mediaId;
+            return this;
+        }
+
+        /**
+         * Set the metadata of this instance. {@code null} for unset.
+         * <p>
+         * If the metadata is set with the {@link #setMetadata(MediaMetadata2)} and it has
+         * media id, id from {@link #setMediaId(String)} will be ignored and metadata's id will be
+         * used instead. If the id isn't set neither by {@link #setMediaId(String)} nor
+         * {@link #setMetadata(MediaMetadata2)}, id will be automatically generated.
+         *
+         * @param metadata metadata
+         * @return this instance for chaining
+         */
+        public Builder setMetadata(@Nullable MediaMetadata2 metadata) {
+            mMetadata = metadata;
+            return this;
+        }
+
+        /**
+         * Set the data source descriptor for this instance. {@code null} for unset.
+         *
+         * @param dataSourceDesc data source descriptor
+         * @return this instance for chaining
+         */
+        public Builder setDataSourceDesc(@Nullable DataSourceDesc dataSourceDesc) {
+            mDataSourceDesc = dataSourceDesc;
+            return this;
+        }
+
+        /**
+         * Build {@link MediaItem2}.
+         *
+         * @return a new {@link MediaItem2}.
+         */
+        public MediaItem2 build() {
+            String id = (mMetadata != null)
+                    ? mMetadata.getString(MediaMetadata2.METADATA_KEY_MEDIA_ID) : null;
+            if (id == null) {
+                //  TODO(jaewan): Double check if its sufficient (e.g. Use UUID instead?)
+                id = (mMediaId != null) ? mMediaId : toString();
+            }
+            return new MediaItem2(mContext, id, mDataSourceDesc, mMetadata, mFlags);
+        }
+    }
 }
diff --git a/media/java/android/media/MediaLibraryService2.java b/media/java/android/media/MediaLibraryService2.java
index c984697..5917190 100644
--- a/media/java/android/media/MediaLibraryService2.java
+++ b/media/java/android/media/MediaLibraryService2.java
@@ -19,10 +19,10 @@
 import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SystemApi;
 import android.app.PendingIntent;
 import android.content.Context;
-import android.media.MediaSession2.BuilderBase;
+import android.media.MediaLibraryService2.MediaLibrarySession.Builder;
+import android.media.MediaLibraryService2.MediaLibrarySession.MediaLibrarySessionCallback;
 import android.media.MediaSession2.ControllerInfo;
 import android.media.update.ApiLoader;
 import android.media.update.MediaLibraryService2Provider.LibraryRootProvider;
@@ -40,7 +40,7 @@
  * and ask the application to start playing it. They may also be used to control content that
  * is already playing by way of a {@link MediaSession2}.
  * <p>
- * To extend this class, adding followings directly to your {@code AndroidManifest.xml}.
+ * When extending this class, also add the following to your {@code AndroidManifest.xml}.
  * <pre>
  * &lt;service android:name="component_name_of_your_implementation" &gt;
  *   &lt;intent-filter&gt;
@@ -48,11 +48,12 @@
  *   &lt;/intent-filter&gt;
  * &lt;/service&gt;</pre>
  * <p>
- * A {@link MediaLibraryService2} is extension of {@link MediaSessionService2}. IDs shouldn't
+ * The {@link MediaLibraryService2} class derives from {@link MediaSessionService2}. IDs shouldn't
  * be shared between the {@link MediaSessionService2} and {@link MediaSession2}. By
  * default, an empty string will be used for ID of the service. If you want to specify an ID,
  * declare metadata in the manifest as follows.
- * @hide
+ *
+ * @see MediaSessionService2
  */
 public abstract class MediaLibraryService2 extends MediaSessionService2 {
     /**
@@ -63,41 +64,223 @@
 
     /**
      * Session for the {@link MediaLibraryService2}. Build this object with
-     * {@link MediaLibrarySessionBuilder} and return in {@link #onCreateSession(String)}.
+     * {@link Builder} and return in {@link #onCreateSession(String)}.
      */
-    public static class MediaLibrarySession extends MediaSession2 {
+    public static final class MediaLibrarySession extends MediaSession2 {
         private final MediaLibrarySessionProvider mProvider;
 
         /**
+         * Callback for the {@link MediaLibrarySession}.
+         */
+        public static class MediaLibrarySessionCallback extends MediaSession2.SessionCallback {
+            public MediaLibrarySessionCallback(Context context) {
+                super(context);
+            }
+
+            /**
+             * Called to get the root information for browsing by a particular client.
+             * <p>
+             * The implementation should verify that the client package has permission
+             * to access browse media information before returning the root id; it
+             * should return null if the client is not allowed to access this
+             * information.
+             *
+             * @param controllerInfo information of the controller requesting access to browse media.
+             * @param rootHints An optional bundle of service-specific arguments to send
+             * to the media library service when connecting and retrieving the
+             * root id for browsing, or null if none. The contents of this
+             * bundle may affect the information returned when browsing.
+             * @return The {@link LibraryRoot} for accessing this app's content or null.
+             * @see LibraryRoot#EXTRA_RECENT
+             * @see LibraryRoot#EXTRA_OFFLINE
+             * @see LibraryRoot#EXTRA_SUGGESTED
+             */
+            public @Nullable LibraryRoot onGetLibraryRoot(@NonNull ControllerInfo controllerInfo,
+                    @Nullable Bundle rootHints) {
+                return null;
+            }
+
+            /**
+             * Called to get an item. Return result here for the browser.
+             * <p>
+             * Return {@code null} for no result or error.
+             *
+             * @param mediaId item id to get media item.
+             * @return a media item. {@code null} for no result or error.
+             */
+            public @Nullable MediaItem2 onGetItem(@NonNull ControllerInfo controllerInfo,
+                    @NonNull String mediaId) {
+                return null;
+            }
+
+            /**
+             * Called to get children of given parent id. Return the children here for the browser.
+             * <p>
+             * Return an empty list for no children, and return {@code null} for the error.
+             *
+             * @param parentId parent id to get children
+             * @param page number of page
+             * @param pageSize size of the page
+             * @param extras extra bundle
+             * @return list of children. Can be {@code null}.
+             */
+            public @Nullable List<MediaItem2> onGetChildren(@NonNull ControllerInfo controller,
+                    @NonNull String parentId, int page, int pageSize, @Nullable Bundle extras) {
+                return null;
+            }
+
+            /**
+             * Called when a controller subscribes to the parent.
+             * <p>
+             * It's your responsibility to keep subscriptions by your own and call
+             * {@link MediaLibrarySession#notifyChildrenChanged(ControllerInfo, String, int, Bundle)}
+             * when the parent is changed.
+             *
+             * @param controller controller
+             * @param parentId parent id
+             * @param extras extra bundle
+             */
+            public void onSubscribe(@NonNull ControllerInfo controller, @NonNull String parentId,
+                    @Nullable Bundle extras) {
+            }
+
+            /**
+             * Called when a controller unsubscribes to the parent.
+             *
+             * @param controller controller
+             * @param parentId parent id
+             */
+            public void onUnsubscribe(@NonNull ControllerInfo controller,
+                    @NonNull String parentId) {
+            }
+
+            /**
+             * Called when a controller requests search.
+             *
+             * @param query The search query sent from the media browser. It contains keywords
+             *              separated by space.
+             * @param extras The bundle of service-specific arguments sent from the media browser.
+             */
+            public void onSearch(@NonNull ControllerInfo controllerInfo, @NonNull String query,
+                    @Nullable Bundle extras) {
+            }
+
+            /**
+             * Called to get the search result. Return search result here for the browser which has
+             * requested search previously.
+             * <p>
+             * Return an empty list for no search result, and return {@code null} for the error.
+             *
+             * @param controllerInfo Information of the controller requesting the search result.
+             * @param query The search query which was previously sent through
+             *              {@link #onSearch(ControllerInfo, String, Bundle)} call.
+             * @param page page number. Starts from {@code 1}.
+             * @param pageSize page size. Should be greater or equal to {@code 1}.
+             * @param extras The bundle of service-specific arguments sent from the media browser.
+             * @return search result. {@code null} for error.
+             */
+            public @Nullable List<MediaItem2> onGetSearchResult(
+                    @NonNull ControllerInfo controllerInfo, @NonNull String query, int page,
+                    int pageSize, @Nullable Bundle extras) {
+                return null;
+            }
+        }
+
+        /**
+         * Builder for {@link MediaLibrarySession}.
+         */
+        // Override all methods just to show them with the type instead of generics in Javadoc.
+        // This workarounds javadoc issue described in the MediaSession2.BuilderBase.
+        public static final class Builder extends BuilderBase<MediaLibrarySession, Builder,
+                MediaLibrarySessionCallback> {
+            // Builder requires MediaLibraryService2 instead of Context just to ensure that the
+            // builder can be only instantiated within the MediaLibraryService2.
+            // Ideally it's better to make it inner class of service to enforce, it violates API
+            // guideline that Builders should be the inner class of the building target.
+            public Builder(@NonNull MediaLibraryService2 service,
+                    @NonNull @CallbackExecutor Executor callbackExecutor,
+                    @NonNull MediaLibrarySessionCallback callback) {
+                super((instance) -> ApiLoader.getProvider(service)
+                        .createMediaLibraryService2Builder(service, (Builder) instance,
+                                callbackExecutor, callback));
+            }
+
+            @Override
+            public Builder setPlayer(@NonNull MediaPlayerBase player) {
+                return super.setPlayer(player);
+            }
+
+            @Override
+            public Builder setPlaylistController(@NonNull MediaPlaylistController mplc) {
+                return super.setPlaylistController(mplc);
+            }
+
+            @Override
+            public Builder setVolumeProvider(@NonNull VolumeProvider2 volumeProvider) {
+                return super.setVolumeProvider(volumeProvider);
+            }
+
+            @Override
+            public Builder setSessionActivity(@Nullable PendingIntent pi) {
+                return super.setSessionActivity(pi);
+            }
+
+            @Override
+            public Builder setId(String id) {
+                return super.setId(id);
+            }
+
+            @Override
+            public Builder setSessionCallback(@NonNull Executor executor,
+                    @NonNull MediaLibrarySessionCallback callback) {
+                return super.setSessionCallback(executor, callback);
+            }
+
+            @Override
+            public MediaLibrarySession build() {
+                return super.build();
+            }
+        }
+
+        /**
          * @hide
          */
-        @SystemApi
         public MediaLibrarySession(MediaLibrarySessionProvider provider) {
             super(provider);
             mProvider = provider;
         }
 
         /**
-         * Notify subscribed controller about change in a parent's children.
+         * Notify the controller of the change in a parent's children.
+         * <p>
+         * If the controller hasn't subscribed to the parent, the API will do nothing.
+         * <p>
+         * Controllers will use {@link MediaBrowser2#getChildren(String, int, int, Bundle)} to get
+         * the list of children.
          *
          * @param controller controller to notify
-         * @param parentId
-         * @param extras
+         * @param parentId parent id with changes in its children
+         * @param itemCount number of children.
+         * @param extras extra information from session to controller
          */
         public void notifyChildrenChanged(@NonNull ControllerInfo controller,
-                @NonNull String parentId, @NonNull Bundle extras) {
-            mProvider.notifyChildrenChanged_impl(controller, parentId, extras);
+                @NonNull String parentId, int itemCount, @Nullable Bundle extras) {
+            mProvider.notifyChildrenChanged_impl(controller, parentId, itemCount, extras);
         }
 
         /**
-         * Notify subscribed controller about change in a parent's children.
+         * Notify all controllers that subscribed to the parent about change in the parent's
+         * children, regardless of the extra bundle supplied by
+         * {@link MediaBrowser2#subscribe(String, Bundle)}.
          *
          * @param parentId parent id
-         * @param extras extra bundle
+         * @param itemCount number of children
+         * @param extras extra information from session to controller
          */
         // This is for the backward compatibility.
-        public void notifyChildrenChanged(@NonNull String parentId, @Nullable Bundle extras) {
-            mProvider.notifyChildrenChanged_impl(parentId, extras);
+        public void notifyChildrenChanged(@NonNull String parentId, int itemCount,
+                @Nullable Bundle extras) {
+            mProvider.notifyChildrenChanged_impl(parentId, itemCount, extras);
         }
 
         /**
@@ -114,170 +297,6 @@
         }
     }
 
-    /**
-     * Callback for the {@link MediaLibrarySession}.
-     */
-    public static class MediaLibrarySessionCallback extends MediaSession2.SessionCallback {
-
-        public MediaLibrarySessionCallback(Context context) {
-            super(context);
-        }
-
-        /**
-         * Called to get the root information for browsing by a particular client.
-         * <p>
-         * The implementation should verify that the client package has permission
-         * to access browse media information before returning the root id; it
-         * should return null if the client is not allowed to access this
-         * information.
-         *
-         * @param controllerInfo information of the controller requesting access to browse media.
-         * @param rootHints An optional bundle of service-specific arguments to send
-         * to the media library service when connecting and retrieving the
-         * root id for browsing, or null if none. The contents of this
-         * bundle may affect the information returned when browsing.
-         * @return The {@link LibraryRoot} for accessing this app's content or null.
-         * @see LibraryRoot#EXTRA_RECENT
-         * @see LibraryRoot#EXTRA_OFFLINE
-         * @see LibraryRoot#EXTRA_SUGGESTED
-         */
-        public @Nullable LibraryRoot onGetRoot(@NonNull ControllerInfo controllerInfo,
-                @Nullable Bundle rootHints) {
-            return null;
-        }
-
-        /**
-         * Called to get an item. Return result here for the browser.
-         * <p>
-         * Return {@code null} for no result or error.
-         *
-         * @param itemId item id to get media item.
-         * @return a media item. {@code null} for no result or error.
-         */
-        public @Nullable MediaItem2 onLoadItem(@NonNull ControllerInfo controllerInfo,
-                @NonNull String itemId) {
-            return null;
-        }
-
-        /**
-         * Called to get children of given parent id. Return the children here for the browser.
-         * <p>
-         * Return an empty list for no children, and return {@code null} for the error.
-         *
-         * @param parentId parent id to get children
-         * @param page number of page
-         * @param pageSize size of the page
-         * @param extras extra bundle
-         * @return list of children. Can be {@code null}.
-         */
-        public @Nullable List<MediaItem2> onLoadChildren(@NonNull ControllerInfo controller,
-                @NonNull String parentId, int page, int pageSize, @Nullable Bundle extras) {
-            return null;
-        }
-
-        /**
-         * Called when a controller subscribes to the parent.
-         *
-         * @param controller controller
-         * @param parentId parent id
-         * @param extras extra bundle
-         */
-        public void onSubscribed(@NonNull ControllerInfo controller, String parentId,
-                @Nullable Bundle extras) {
-        }
-
-        /**
-         * Called when a controller unsubscribes to the parent.
-         *
-         * @param controller controller
-         * @param parentId parent id
-         * @param extras extra bundle
-         */
-        public void onUnsubscribed(@NonNull ControllerInfo controller, String parentId,
-                @Nullable Bundle extras) {
-        }
-
-        /**
-         * Called when a controller requests search.
-         *
-         * @param query The search query sent from the media browser. It contains keywords separated
-         *              by space.
-         * @param extras The bundle of service-specific arguments sent from the media browser.
-         */
-        public void onSearch(@NonNull ControllerInfo controllerInfo, @NonNull String query,
-                @Nullable Bundle extras) {
-
-        }
-
-        /**
-         * Called to get the search result. Return search result here for the browser which has
-         * requested search previously.
-         * <p>
-         * Return an empty list for no search result, and return {@code null} for the error.
-         *
-         * @param controllerInfo Information of the controller requesting the search result.
-         * @param query The search query which was previously sent through
-         *              {@link #onSearch(ControllerInfo, String, Bundle)} call.
-         * @param page page number. Starts from {@code 1}.
-         * @param pageSize page size. Should be greater or equal to {@code 1}.
-         * @param extras The bundle of service-specific arguments sent from the media browser.
-         * @return search result. {@code null} for error.
-         */
-        public @Nullable List<MediaItem2> onLoadSearchResult(@NonNull ControllerInfo controllerInfo,
-                @NonNull String query, int page, int pageSize, @Nullable Bundle extras) {
-            return null;
-        }
-    }
-
-    /**
-     * Builder for {@link MediaLibrarySession}.
-     */
-    // Override all methods just to show them with the type instead of generics in Javadoc.
-    // This workarounds javadoc issue described in the MediaSession2.BuilderBase.
-    public class MediaLibrarySessionBuilder extends BuilderBase<MediaLibrarySession,
-            MediaLibrarySessionBuilder, MediaLibrarySessionCallback> {
-        public MediaLibrarySessionBuilder(
-                @NonNull Context context, @NonNull MediaPlayerInterface player,
-                @NonNull @CallbackExecutor Executor callbackExecutor,
-                @NonNull MediaLibrarySessionCallback callback) {
-            super((instance) -> ApiLoader.getProvider(context).createMediaLibraryService2Builder(
-                    context, (MediaLibrarySessionBuilder) instance, player, callbackExecutor,
-                    callback));
-        }
-
-        @Override
-        public MediaLibrarySessionBuilder setVolumeProvider(
-                @Nullable VolumeProvider2 volumeProvider) {
-            return super.setVolumeProvider(volumeProvider);
-        }
-
-        @Override
-        public MediaLibrarySessionBuilder setRatingType(int type) {
-            return super.setRatingType(type);
-        }
-
-        @Override
-        public MediaLibrarySessionBuilder setSessionActivity(@Nullable PendingIntent pi) {
-            return super.setSessionActivity(pi);
-        }
-
-        @Override
-        public MediaLibrarySessionBuilder setId(String id) {
-            return super.setId(id);
-        }
-
-        @Override
-        public MediaLibrarySessionBuilder setSessionCallback(
-                @NonNull Executor executor, @NonNull MediaLibrarySessionCallback callback) {
-            return super.setSessionCallback(executor, callback);
-        }
-
-        @Override
-        public MediaLibrarySession build() {
-            return super.build();
-        }
-    }
-
     @Override
     MediaSessionService2Provider createProvider() {
         return ApiLoader.getProvider(this).createMediaLibraryService2(this);
@@ -296,7 +315,7 @@
      *
      * @param sessionId session id written in the AndroidManifest.xml.
      * @return a new library session
-     * @see MediaLibrarySessionBuilder
+     * @see Builder
      * @see #getSession()
      * @throws RuntimeException if returned session is invalid
      */
@@ -316,7 +335,8 @@
          * supplied as a root hint for retrieving media items that are recently played.
          * If the media library service can provide such media items, the implementation must return
          * the key in the root hint when
-         * {@link MediaLibrarySessionCallback#onGetRoot(ControllerInfo, Bundle)} is called back.
+         * {@link MediaLibrarySessionCallback#onGetLibraryRoot(ControllerInfo, Bundle)} is called
+         * back.
          *
          * <p>The root hint may contain multiple keys.
          *
@@ -334,7 +354,8 @@
          * internet connection.
          * If the media library service can provide such media items, the implementation must return
          * the key in the root hint when
-         * {@link MediaLibrarySessionCallback#onGetRoot(ControllerInfo, Bundle)} is called back.
+         * {@link MediaLibrarySessionCallback#onGetLibraryRoot(ControllerInfo, Bundle)} is called
+         * back.
          *
          * <p>The root hint may contain multiple keys.
          *
@@ -353,7 +374,8 @@
          * suggestion.
          * If the media library service can provide such media items, the implementation must return
          * the key in the root hint when
-         * {@link MediaLibrarySessionCallback#onGetRoot(ControllerInfo, Bundle)} is called back.
+         * {@link MediaLibrarySessionCallback#onGetLibraryRoot(ControllerInfo, Bundle)} is called
+         * back.
          *
          * <p>The root hint may contain multiple keys.
          *
diff --git a/media/java/android/media/MediaMetadata2.java b/media/java/android/media/MediaMetadata2.java
index 54a9057e..b363831 100644
--- a/media/java/android/media/MediaMetadata2.java
+++ b/media/java/android/media/MediaMetadata2.java
@@ -19,7 +19,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.StringDef;
-import android.annotation.SystemApi;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.media.update.ApiLoader;
@@ -33,15 +32,13 @@
 
 /**
  * Contains metadata about an item, such as the title, artist, etc.
- *
- * @hide
  */
+// New version of MediaMetadata with following changes
+//   - Don't implement Parcelable for updatable support.
+//   - Also support MediaDescription features. MediaDescription is deprecated instead because
+//     it was insufficient for controller to display media contents.
+// TODO(jaewan): Add @see for APIs from MediaDescription
 public final class MediaMetadata2 {
-    // New version of MediaMetadata that no longer implements Parcelable but added from/toBundle()
-    // for updatable.
-    // MediaDescription is deprecated because it was insufficient for controller to display media
-    // contents. Added getExtra() here to support all the features from the MediaDescription.
-
     /**
      * The title of the media.
      */
@@ -220,13 +217,25 @@
     /**
      * A Uri formatted String representing the content. This value is specific to the
      * service providing the content. It may be used with
-     * {@link MediaController2#playFromUri(String, Bundle)}
+     * {@link MediaController2#playFromUri(Uri, Bundle)}
      * to initiate playback when provided by a {@link MediaBrowser2} connected to
      * the same app.
      */
     public static final String METADATA_KEY_MEDIA_URI = "android.media.metadata.MEDIA_URI";
 
     /**
+     * The radio frequency in Float format if this metdata representing radio content.
+     */
+    public static final String METADATA_KEY_RADIO_FREQUENCY =
+            "android.media.metadata.RADIO_FREQUENCY";
+
+    /**
+     * The radio callsign in String format if this metdata representing radio content.
+     */
+    public static final String METADATA_KEY_RADIO_CALLSIGN =
+            "android.media.metadata.RADIO_CALLSIGN";
+
+    /**
      * The bluetooth folder type of the media specified in the section 6.10.2.2 of the Bluetooth
      * AVRCP 1.5. It should be one of the following:
      * <ul>
@@ -327,9 +336,8 @@
 
     /**
      * A {@link Bundle} extra.
-     * @hide
      */
-    public static final String METADATA_KEY_EXTRA = "android.media.metadata.EXTRA";
+    public static final String METADATA_KEY_EXTRAS = "android.media.metadata.EXTRAS";
 
     /**
      * @hide
@@ -339,7 +347,7 @@
             METADATA_KEY_DATE, METADATA_KEY_GENRE, METADATA_KEY_ALBUM_ARTIST, METADATA_KEY_ART_URI,
             METADATA_KEY_ALBUM_ART_URI, METADATA_KEY_DISPLAY_TITLE, METADATA_KEY_DISPLAY_SUBTITLE,
             METADATA_KEY_DISPLAY_DESCRIPTION, METADATA_KEY_DISPLAY_ICON_URI,
-            METADATA_KEY_MEDIA_ID, METADATA_KEY_MEDIA_URI})
+            METADATA_KEY_MEDIA_ID, METADATA_KEY_MEDIA_URI, METADATA_KEY_RADIO_CALLSIGN})
     @Retention(RetentionPolicy.SOURCE)
     public @interface TextKey {}
 
@@ -366,12 +374,18 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface RatingKey {}
 
+    /**
+     * @hide
+     */
+    @StringDef({METADATA_KEY_RADIO_FREQUENCY})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FloatKey {}
+
     private final MediaMetadata2Provider mProvider;
 
     /**
      * @hide
      */
-    @SystemApi
     public MediaMetadata2(MediaMetadata2Provider provider) {
         mProvider = provider;
     }
@@ -399,9 +413,9 @@
     }
 
     /**
-     * Returns the value associated with the given key, or null if no mapping of
-     * the desired type exists for the given key or a null value is explicitly
-     * associated with the key.
+     * Returns the media id, or {@code null} if the id doesn't exist.
+     *<p>
+     * This is equivalent to the {@link #getString(String)} with the {@link #METADATA_KEY_MEDIA_ID}.
      *
      * @return media id. Can be {@code null}
      * @see #METADATA_KEY_MEDIA_ID
@@ -436,6 +450,9 @@
     /**
      * Return a {@link Rating2} for the given key or null if no rating exists for
      * the given key.
+     * <p>
+     * For the {@link #METADATA_KEY_USER_RATING}, A {@code null} return value means that user rating
+     * cannot be set by {@link MediaController2}.
      *
      * @param key The key the value is stored under
      * @return A {@link Rating2} or {@code null}
@@ -456,12 +473,23 @@
     }
 
     /**
+     * Return the value associated with the given key, or 0.0f if no long exists
+     * for the given key.
+     *
+     * @param key The key the value is stored under
+     * @return a float value
+     */
+    public float getFloat(@NonNull @FloatKey String key) {
+        return mProvider.getFloat_impl(key);
+    }
+
+    /**
      * Get the extra {@link Bundle} from the metadata object.
      *
      * @return A {@link Bundle} or {@code null}
      */
-    public @Nullable Bundle getExtra() {
-        return mProvider.getExtra_impl();
+    public @Nullable Bundle getExtras() {
+        return mProvider.getExtras_impl();
     }
 
     /**
@@ -536,7 +564,6 @@
         /**
          * @hide
          */
-        @SystemApi
         public Builder(@NonNull MediaMetadata2Provider.BuilderProvider provider) {
             mProvider = provider;
         }
@@ -591,6 +618,7 @@
          * <li>{@link #METADATA_KEY_DISPLAY_SUBTITLE}</li>
          * <li>{@link #METADATA_KEY_DISPLAY_DESCRIPTION}</li>
          * <li>{@link #METADATA_KEY_DISPLAY_ICON_URI}</li>
+         * <li>{@link #METADATA_KEY_RADIO_CALLSIGN}</li>
          * </ul>
          *
          * @param key The key for referencing this value
@@ -664,10 +692,29 @@
         }
 
         /**
-         * Set an extra {@link Bundle} into the metadata.
+         * Put a float value into the metadata. Custom keys may be used, but if
+         * the METADATA_KEYs defined in this class are used they may only be one
+         * of the following:
+         * <ul>
+         * <li>{@link #METADATA_KEY_RADIO_FREQUENCY}</li>
+         * </ul>
+         *
+         * @param key The key for referencing this value
+         * @param value The float value to store
+         * @return The Builder to allow chaining
          */
-        public @NonNull Builder setExtra(@Nullable Bundle bundle) {
-            return mProvider.setExtra_impl(bundle);
+        public @NonNull Builder putFloat(@NonNull @LongKey String key, float value) {
+            return mProvider.putFloat_impl(key, value);
+        }
+
+        /**
+         * Set a bundle of extras.
+         *
+         * @param extras The extras to include with this description or null.
+         * @return The Builder to allow chaining
+         */
+        public Builder setExtras(@Nullable Bundle extras) {
+            return mProvider.setExtras_impl(extras);
         }
 
         /**
diff --git a/media/java/android/media/MediaMuxer.java b/media/java/android/media/MediaMuxer.java
index 02c71b2..205ce8d 100644
--- a/media/java/android/media/MediaMuxer.java
+++ b/media/java/android/media/MediaMuxer.java
@@ -328,6 +328,7 @@
         RandomAccessFile file = null;
         try {
             file = new RandomAccessFile(path, "rws");
+            file.setLength(0);
             FileDescriptor fd = file.getFD();
             setUpMediaMuxer(fd, format);
         } finally {
diff --git a/media/java/android/media/MediaPlayer2.java b/media/java/android/media/MediaPlayer2.java
index 2f3d972..e0047d6 100644
--- a/media/java/android/media/MediaPlayer2.java
+++ b/media/java/android/media/MediaPlayer2.java
@@ -22,15 +22,10 @@
 import android.annotation.Nullable;
 import android.content.Context;
 import android.graphics.SurfaceTexture;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Parcel;
-import android.os.PersistableBundle;
-import android.view.Surface;
-import android.view.SurfaceHolder;
 import android.media.MediaDrm;
 import android.media.MediaFormat;
 import android.media.MediaPlayer2Impl;
+import android.media.MediaPlayerBase;
 import android.media.MediaTimeProvider;
 import android.media.PlaybackParams;
 import android.media.SubtitleController;
@@ -38,6 +33,12 @@
 import android.media.SubtitleData;
 import android.media.SubtitleTrack.RenderingWidget;
 import android.media.SyncParams;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Parcel;
+import android.os.PersistableBundle;
+import android.view.Surface;
+import android.view.SurfaceHolder;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -45,7 +46,6 @@
 import java.lang.AutoCloseable;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.net.InetSocketAddress;
 import java.util.concurrent.Executor;
 import java.util.List;
 import java.util.Map;
@@ -91,7 +91,7 @@
  * <p>From this state diagram, one can see that a MediaPlayer2 object has the
  *    following states:</p>
  * <ul>
- *     <li>When a MediaPlayer2 object is just created using <code>new</code> or
+ *     <li>When a MediaPlayer2 object is just created using <code>create</code> or
  *         after {@link #reset()} is called, it is in the <em>Idle</em> state; and after
  *         {@link #close()} is called, it is in the <em>End</em> state. Between these
  *         two states is the life cycle of the MediaPlayer2 object.
@@ -100,9 +100,9 @@
  *         as {@link #getCurrentPosition()},
  *         {@link #getDuration()}, {@link #getVideoHeight()},
  *         {@link #getVideoWidth()}, {@link #setAudioAttributes(AudioAttributes)},
- *         {@link #setVolume(float, float)}, {@link #pause()}, {@link #play()},
+ *         {@link #setPlayerVolume(float)}, {@link #pause()}, {@link #play()},
  *         {@link #seekTo(long, int)} or
- *         {@link #prepareAsync()} in the <em>Idle</em> state.
+ *         {@link #prepare()} in the <em>Idle</em> state.
  *         <li>It is also recommended that once
  *         a MediaPlayer2 object is no longer being used, call {@link #close()} immediately
  *         so that resources used by the internal player engine associated with the
@@ -126,9 +126,9 @@
  *         these circumstances. Sometimes, due to programming errors, invoking a playback
  *         control operation in an invalid state may also occur. Under all these
  *         error conditions, the internal player engine invokes a user supplied
- *         EventCallback.onError() method if an EventCallback has been
+ *         MediaPlayer2EventCallback.onError() method if an MediaPlayer2EventCallback has been
  *         registered beforehand via
- *         {@link #registerEventCallback(Executor, EventCallback)}.
+ *         {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)}.
  *         <ul>
  *         <li>It is important to note that once an error occurs, the
  *         MediaPlayer2 object enters the <em>Error</em> state (except as noted
@@ -142,7 +142,7 @@
  *         the internal player engine.</li>
  *         <li>IllegalStateException is
  *         thrown to prevent programming errors such as calling
- *         {@link #prepareAsync()}, {@link #setDataSource(DataSourceDesc)}, or
+ *         {@link #prepare()}, {@link #setDataSource(DataSourceDesc)}, or
  *         {@code setPlaylist} methods in an invalid state. </li>
  *         </ul>
  *         </li>
@@ -164,21 +164,21 @@
  *         before playback can be started.
  *         <ul>
  *         <li>There are an asynchronous way that the <em>Prepared</em> state can be reached:
- *         a call to {@link #prepareAsync()} (asynchronous) which
+ *         a call to {@link #prepare()} (asynchronous) which
  *         first transfers the object to the <em>Preparing</em> state after the
  *         call returns (which occurs almost right way) while the internal
  *         player engine continues working on the rest of preparation work
  *         until the preparation work completes. When the preparation completes,
  *         the internal player engine then calls a user supplied callback method,
- *         onInfo() of the EventCallback interface with {@link #MEDIA_INFO_PREPARED}, if an
- *         EventCallback is registered beforehand via
- *         {@link #registerEventCallback(Executor, EventCallback)}.</li>
+ *         onInfo() of the MediaPlayer2EventCallback interface with {@link #MEDIA_INFO_PREPARED},
+ *         if an MediaPlayer2EventCallback is registered beforehand via
+ *         {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)}.</li>
  *         <li>It is important to note that
  *         the <em>Preparing</em> state is a transient state, and the behavior
  *         of calling any method with side effect while a MediaPlayer2 object is
  *         in the <em>Preparing</em> state is undefined.</li>
  *         <li>An IllegalStateException is
- *         thrown if {@link #prepareAsync()} is called in
+ *         thrown if {@link #prepare()} is called in
  *         any other state.</li>
  *         <li>While in the <em>Prepared</em> state, properties
  *         such as audio/sound volume, screenOnWhilePlaying, looping can be
@@ -187,13 +187,14 @@
  *         </li>
  *     <li>To start the playback, {@link #play()} must be called. After
  *         {@link #play()} returns successfully, the MediaPlayer2 object is in the
- *         <em>Started</em> state. {@link #isPlaying()} can be called to test
+ *         <em>Started</em> state. {@link #getPlayerState()} can be called to test
  *         whether the MediaPlayer2 object is in the <em>Started</em> state.
  *         <ul>
  *         <li>While in the <em>Started</em> state, the internal player engine calls
- *         a user supplied EventCallback.onBufferingUpdate() callback
- *         method if an EventCallback has been registered beforehand
- *         via {@link #registerEventCallback(Executor, EventCallback)}.
+ *         a user supplied callback method MediaPlayer2EventCallback.onInfo() with
+ *         {@link #MEDIA_INFO_BUFFERING_UPDATE} if an MediaPlayer2EventCallback has been
+ *         registered beforehand via
+ *         {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)}.
  *         This callback allows applications to keep track of the buffering status
  *         while streaming audio/video.</li>
  *         <li>Calling {@link #play()} has not effect
@@ -206,7 +207,7 @@
  *         <em>Paused</em> state. Note that the transition from the <em>Started</em>
  *         state to the <em>Paused</em> state and vice versa happens
  *         asynchronously in the player engine. It may take some time before
- *         the state is updated in calls to {@link #isPlaying()}, and it can be
+ *         the state is updated in calls to {@link #getPlayerState()}, and it can be
  *         a number of seconds in the case of streamed content.
  *         <ul>
  *         <li>Calling {@link #play()} to resume playback for a paused
@@ -225,9 +226,9 @@
  *         call returns right away, the actual seek operation may take a while to
  *         finish, especially for audio/video being streamed. When the actual
  *         seek operation completes, the internal player engine calls a user
- *         supplied EventCallback.onInfo() with {@link #MEDIA_INFO_COMPLETE_CALL_SEEK}
- *         if an EventCallback has been registered beforehand via
- *         {@link #registerEventCallback(Executor, EventCallback)}.</li>
+ *         supplied MediaPlayer2EventCallback.onCallComplete() with {@link #MEDIA_CALL_SEEK_TO}
+ *         if an MediaPlayer2EventCallback has been registered beforehand via
+ *         {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)}.</li>
  *         <li>Please
  *         note that {@link #seekTo(long, int)} can also be called in the other states,
  *         such as <em>Prepared</em>, <em>Paused</em> and <em>PlaybackCompleted
@@ -243,15 +244,13 @@
  *         </li>
  *     <li>When the playback reaches the end of stream, the playback completes.
  *         <ul>
- *         <li>If the looping mode was being set to one of the values of
- *         {@link #LOOPING_MODE_FULL}, {@link #LOOPING_MODE_SINGLE} or
- *         {@link #LOOPING_MODE_SHUFFLE} with
- *         {@link #setLoopingMode(int)}, the MediaPlayer2 object shall remain in
- *         the <em>Started</em> state.</li>
+ *         <li>If current source is set to loop by {@link #loopCurrent(boolean)},
+ *         the MediaPlayer2 object shall remain in the <em>Started</em> state.</li>
  *         <li>If the looping mode was set to <var>false
  *         </var>, the player engine calls a user supplied callback method,
- *         EventCallback.onCompletion(), if an EventCallback is registered
- *         beforehand via {@link #registerEventCallback(Executor, EventCallback)}.
+ *         MediaPlayer2EventCallback.onCompletion(), if an MediaPlayer2EventCallback is
+ *         registered beforehand via
+ *         {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)}.
  *         The invoke of the callback signals that the object is now in the <em>
  *         PlaybackCompleted</em> state.</li>
  *         <li>While in the <em>PlaybackCompleted</em>
@@ -305,7 +304,7 @@
  *     <td>Successful invoke of this method in a valid state does not change
  *         the state. Calling this method in an invalid state transfers the
  *         object to the <em>Error</em> state. </p></td></tr>
- * <tr><td>isPlaying </p></td>
+ * <tr><td>getPlayerState </p></td>
  *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
  *          PlaybackCompleted}</p></td>
  *     <td>{Error}</p></td>
@@ -318,7 +317,7 @@
  *     <td>Successful invoke of this method in a valid state transfers the
  *         object to the <em>Paused</em> state. Calling this method in an
  *         invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
- * <tr><td>prepareAsync </p></td>
+ * <tr><td>prepare </p></td>
  *     <td>{Initialized, Stopped} </p></td>
  *     <td>{Idle, Prepared, Started, Paused, PlaybackCompleted, Error} </p></td>
  *     <td>Successful invoke of this method in a valid state transfers the
@@ -345,7 +344,7 @@
  *     <td>{Error}</p></td>
  *     <td>Successful invoke of this method does not change the state. In order for the
  *         target audio attributes type to become effective, this method must be called before
- *         prepareAsync().</p></td></tr>
+ *         prepare().</p></td></tr>
  * <tr><td>setAudioSessionId </p></td>
  *     <td>{Idle} </p></td>
  *     <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted,
@@ -359,7 +358,7 @@
  *     <td>{Error}</p></td>
  *     <td>Successful invoke of this method does not change the state. In order for the
  *         target audio stream type to become effective, this method must be called before
- *         prepareAsync().</p></td></tr>
+ *         prepare().</p></td></tr>
  * <tr><td>setAuxEffectSendLevel </p></td>
  *     <td>any</p></td>
  *     <td>{} </p></td>
@@ -388,7 +387,7 @@
  *     <td>{} </p></td>
  *     <td>This method can be called in any state and calling it does not change
  *         the object state. </p></td></tr>
- * <tr><td>setLoopingMode </p></td>
+ * <tr><td>loopCurrent </p></td>
  *     <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
  *         PlaybackCompleted}</p></td>
  *     <td>{Error}</p></td>
@@ -400,12 +399,12 @@
  *     <td>{} </p></td>
  *     <td>This method can be called in any state and calling it does not change
  *         the object state. </p></td></tr>
- * <tr><td>registerDrmEventCallback </p></td>
+ * <tr><td>setDrmEventCallback </p></td>
  *     <td>any </p></td>
  *     <td>{} </p></td>
  *     <td>This method can be called in any state and calling it does not change
  *         the object state. </p></td></tr>
- * <tr><td>registerEventCallback </p></td>
+ * <tr><td>setMediaPlayer2EventCallback </p></td>
  *     <td>any </p></td>
  *     <td>{} </p></td>
  *     <td>This method can be called in any state and calling it does not change
@@ -415,7 +414,7 @@
  *     <td>{Idle, Stopped} </p></td>
  *     <td>This method will change state in some cases, depending on when it's called.
  *         </p></td></tr>
- * <tr><td>setVolume </p></td>
+ * <tr><td>setPlayerVolume </p></td>
  *     <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
  *          PlaybackCompleted}</p></td>
  *     <td>{Error}</p></td>
@@ -463,51 +462,17 @@
  * possible runtime errors during playback or streaming. Registration for
  * these events is done by properly setting the appropriate listeners (via calls
  * to
- * {@link #registerEventCallback(Executor, EventCallback)},
- * {@link #registerDrmEventCallback(Executor, DrmEventCallback)}).
+ * {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)},
+ * {@link #setDrmEventCallback(Executor, DrmEventCallback)}).
  * In order to receive the respective callback
  * associated with these listeners, applications are required to create
  * MediaPlayer2 objects on a thread with its own Looper running (main UI
  * thread by default has a Looper running).
  *
  */
-public abstract class MediaPlayer2 implements SubtitleController.Listener
-                                            , AudioRouting
-                                            , AutoCloseable
-{
-    /**
-       Constant to retrieve only the new metadata since the last
-       call.
-       // FIXME: unhide.
-       // FIXME: add link to getMetadata(boolean, boolean)
-       {@hide}
-     */
-    public static final boolean METADATA_UPDATE_ONLY = true;
-
-    /**
-       Constant to retrieve all the metadata.
-       // FIXME: unhide.
-       // FIXME: add link to getMetadata(boolean, boolean)
-       {@hide}
-     */
-    public static final boolean METADATA_ALL = false;
-
-    /**
-       Constant to enable the metadata filter during retrieval.
-       // FIXME: unhide.
-       // FIXME: add link to getMetadata(boolean, boolean)
-       {@hide}
-     */
-    public static final boolean APPLY_METADATA_FILTER = true;
-
-    /**
-       Constant to disable the metadata filter during retrieval.
-       // FIXME: unhide.
-       // FIXME: add link to getMetadata(boolean, boolean)
-       {@hide}
-     */
-    public static final boolean BYPASS_METADATA_FILTER = false;
-
+public abstract class MediaPlayer2 extends MediaPlayerBase
+                                   implements SubtitleController.Listener
+                                            , AudioRouting {
     /**
      * Create a MediaPlayer2 object.
      *
@@ -525,6 +490,256 @@
     public MediaPlayer2() { }
 
     /**
+     * Releases the resources held by this {@code MediaPlayer2} object.
+     *
+     * It is considered good practice to call this method when you're
+     * done using the MediaPlayer2. In particular, whenever an Activity
+     * of an application is paused (its onPause() method is called),
+     * or stopped (its onStop() method is called), this method should be
+     * invoked to release the MediaPlayer2 object, unless the application
+     * has a special need to keep the object around. In addition to
+     * unnecessary resources (such as memory and instances of codecs)
+     * being held, failure to call this method immediately if a
+     * MediaPlayer2 object is no longer needed may also lead to
+     * continuous battery consumption for mobile devices, and playback
+     * failure for other applications if no multiple instances of the
+     * same codec are supported on a device. Even if multiple instances
+     * of the same codec are supported, some performance degradation
+     * may be expected when unnecessary multiple instances are used
+     * at the same time.
+     *
+     * {@code close()} may be safely called after a prior {@code close()}.
+     * This class implements the Java {@code AutoCloseable} interface and
+     * may be used with try-with-resources.
+     */
+    @Override
+    public abstract void close();
+
+    /**
+     * Starts or resumes playback. If playback had previously been paused,
+     * playback will continue from where it was paused. If playback had
+     * reached end of stream and been paused, or never started before,
+     * playback will start at the beginning. If the source had not been
+     * prepared, the player will prepare the source and play.
+     *
+     */
+    @Override
+    public abstract void play();
+
+    /**
+     * Prepares the player for playback, asynchronously.
+     *
+     * After setting the datasource and the display surface, you need to
+     * call prepare().
+     *
+     */
+    @Override
+    public abstract void prepare();
+
+    /**
+     * Pauses playback. Call play() to resume.
+     */
+    @Override
+    public abstract void pause();
+
+    /**
+     * Tries to play next data source if applicable.
+     */
+    @Override
+    public abstract void skipToNext();
+
+    /**
+     * Moves the media to specified time position.
+     * Same as {@link #seekTo(long, int)} with {@code mode = SEEK_PREVIOUS_SYNC}.
+     *
+     * @param msec the offset in milliseconds from the start to seek to
+     */
+    @Override
+    public void seekTo(long msec) {
+        seekTo(msec, SEEK_PREVIOUS_SYNC /* mode */);
+    }
+
+    /**
+     * Gets the current playback position.
+     *
+     * @return the current position in milliseconds
+     */
+    @Override
+    public abstract long getCurrentPosition();
+
+    /**
+     * Gets the duration of the file.
+     *
+     * @return the duration in milliseconds, if no duration is available
+     *         (for example, if streaming live content), -1 is returned.
+     */
+    @Override
+    public abstract long getDuration();
+
+    /**
+     * Gets the current buffered media source position received through progressive downloading.
+     * The received buffering percentage indicates how much of the content has been buffered
+     * or played. For example a buffering update of 80 percent when half the content
+     * has already been played indicates that the next 30 percent of the
+     * content to play has been buffered.
+     *
+     * @return the current buffered media source position in milliseconds
+     */
+    @Override
+    public abstract long getBufferedPosition();
+
+    /**
+     * Gets the current player state.
+     *
+     * @return the current player state.
+     */
+    @Override
+    public abstract @PlayerState int getPlayerState();
+
+    /**
+     * Gets the current buffering state of the player.
+     * During buffering, see {@link #getBufferedPosition()} for the quantifying the amount already
+     * buffered.
+     * @return the buffering state, one of the following:
+     */
+    @Override
+    public abstract @BuffState int getBufferingState();
+
+    /**
+     * Sets the audio attributes for this MediaPlayer2.
+     * See {@link AudioAttributes} for how to build and configure an instance of this class.
+     * You must call this method before {@link #prepare()} in order
+     * for the audio attributes to become effective thereafter.
+     * @param attributes a non-null set of audio attributes
+     */
+    @Override
+    public abstract void setAudioAttributes(@NonNull AudioAttributes attributes);
+
+    /**
+     * Gets the audio attributes for this MediaPlayer2.
+     * @return attributes a set of audio attributes
+     */
+    @Override
+    public abstract @Nullable AudioAttributes getAudioAttributes();
+
+    /**
+     * Sets the data source as described by a DataSourceDesc.
+     *
+     * @param dsd the descriptor of data source you want to play
+     */
+    @Override
+    public abstract void setDataSource(@NonNull DataSourceDesc dsd);
+
+    /**
+     * Sets a single data source as described by a DataSourceDesc which will be played
+     * after current data source is finished.
+     *
+     * @param dsd the descriptor of data source you want to play after current one
+     */
+    @Override
+    public abstract void setNextDataSource(@NonNull DataSourceDesc dsd);
+
+    /**
+     * Sets a list of data sources to be played sequentially after current data source is done.
+     *
+     * @param dsds the list of data sources you want to play after current one
+     */
+    @Override
+    public abstract void setNextDataSources(@NonNull List<DataSourceDesc> dsds);
+
+    /**
+     * Gets the current data source as described by a DataSourceDesc.
+     *
+     * @return the current DataSourceDesc
+     */
+    @Override
+    public abstract @NonNull DataSourceDesc getCurrentDataSource();
+
+    /**
+     * Configures the player to loop on the current data source.
+     * @param loop true if the current data source is meant to loop.
+     */
+    @Override
+    public abstract void loopCurrent(boolean loop);
+
+    /**
+     * Sets the playback speed.
+     * A value of 1.0f is the default playback value.
+     * A negative value indicates reverse playback, check {@link #isReversePlaybackSupported()}
+     * before using negative values.<br>
+     * After changing the playback speed, it is recommended to query the actual speed supported
+     * by the player, see {@link #getPlaybackSpeed()}.
+     * @param speed the desired playback speed
+     */
+    @Override
+    public abstract void setPlaybackSpeed(float speed);
+
+    /**
+     * Returns the actual playback speed to be used by the player when playing.
+     * Note that it may differ from the speed set in {@link #setPlaybackSpeed(float)}.
+     * @return the actual playback speed
+     */
+    @Override
+    public float getPlaybackSpeed() {
+        return 1.0f;
+    }
+
+    /**
+     * Indicates whether reverse playback is supported.
+     * Reverse playback is indicated by negative playback speeds, see
+     * {@link #setPlaybackSpeed(float)}.
+     * @return true if reverse playback is supported.
+     */
+    @Override
+    public boolean isReversePlaybackSupported() {
+        return false;
+    }
+
+    /**
+     * Sets the volume of the audio of the media to play, expressed as a linear multiplier
+     * on the audio samples.
+     * Note that this volume is specific to the player, and is separate from stream volume
+     * used across the platform.<br>
+     * A value of 0.0f indicates muting, a value of 1.0f is the nominal unattenuated and unamplified
+     * gain. See {@link #getMaxPlayerVolume()} for the volume range supported by this player.
+     * @param volume a value between 0.0f and {@link #getMaxPlayerVolume()}.
+     */
+    @Override
+    public abstract void setPlayerVolume(float volume);
+
+    /**
+     * Returns the current volume of this player to this player.
+     * Note that it does not take into account the associated stream volume.
+     * @return the player volume.
+     */
+    @Override
+    public abstract float getPlayerVolume();
+
+    /**
+     * @return the maximum volume that can be used in {@link #setPlayerVolume(float)}.
+     */
+    @Override
+    public float getMaxPlayerVolume() {
+        return 1.0f;
+    }
+
+    /**
+     * Adds a callback to be notified of events for this player.
+     * @param e the {@link Executor} to be used for the events.
+     * @param cb the callback to receive the events.
+     */
+    @Override
+    public abstract void registerPlayerEventCallback(@NonNull Executor e,
+            @NonNull PlayerEventCallback cb);
+
+    /**
+     * Removes a previously registered callback for player events
+     * @param cb the callback to remove
+     */
+    @Override
+    public abstract void unregisterPlayerEventCallback(@NonNull PlayerEventCallback cb);
+
+    /**
      * Create a request parcel which can be routed to the native media
      * player using {@link #invoke(Parcel, Parcel)}. The Parcel
      * returned has the proper InterfaceToken set. The caller should
@@ -556,6 +771,19 @@
     public void invoke(Parcel request, Parcel reply) { }
 
     /**
+     * Insert a task in the command queue to help the client to identify whether a batch
+     * of commands has been finished. When this command is processed, a notification
+     * {@code MediaPlayer2EventCallback.onCommandLabelReached} will be fired with the
+     * given {@code label}.
+     *
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCommandLabelReached
+     *
+     * @param label An application specific Object used to help to identify the completeness
+     * of a batch of commands.
+     */
+    public void notifyWhenCommandLabelReached(Object label) { }
+
+    /**
      * Sets the {@link SurfaceHolder} to use for displaying the video
      * portion of the media.
      *
@@ -642,188 +870,6 @@
     public abstract void clearPendingCommands();
 
     /**
-     * Sets the data source as described by a DataSourceDesc.
-     *
-     * @param dsd the descriptor of data source you want to play
-     * @throws IllegalStateException if it is called in an invalid state
-     * @throws NullPointerException if dsd is null
-     */
-    public abstract void setDataSource(@NonNull DataSourceDesc dsd) throws IOException;
-
-    /**
-     * Gets the current data source as described by a DataSourceDesc.
-     *
-     * @return the current DataSourceDesc
-     */
-    public abstract DataSourceDesc getCurrentDataSource();
-
-    /**
-     * Sets the play list.
-     *
-     * If startIndex falls outside play list range, it will be clamped to the nearest index
-     * in the play list.
-     *
-     * @param pl the play list of data source you want to play
-     * @param startIndex the index of the DataSourceDesc in the play list you want to play first
-     * @throws IllegalStateException if it is called in an invalid state
-     * @throws IllegalArgumentException if pl is null or empty, or pl contains null DataSourceDesc
-     */
-    public abstract void setPlaylist(@NonNull List<DataSourceDesc> pl, int startIndex)
-            throws IOException;
-
-    /**
-     * Gets a copy of the play list.
-     *
-     * @return a copy of the play list used by {@link MediaPlayer2}
-     */
-    public abstract List<DataSourceDesc> getPlaylist();
-
-    /**
-     * Sets the index of current DataSourceDesc in the play list to be played.
-     *
-     * @param index the index of DataSourceDesc in the play list you want to play
-     * @throws IllegalArgumentException if the play list is null
-     * @throws NullPointerException if index is outside play list range
-     */
-    public abstract void setCurrentPlaylistItem(int index);
-
-    /**
-     * Sets the index of next-to-be-played DataSourceDesc in the play list.
-     *
-     * @param index the index of next-to-be-played DataSourceDesc in the play list
-     * @throws IllegalArgumentException if the play list is null
-     * @throws NullPointerException if index is outside play list range
-     */
-    public abstract void setNextPlaylistItem(int index);
-
-    /**
-     * Gets the current index of play list.
-     *
-     * @return the index of the current DataSourceDesc in the play list
-     */
-    public abstract int getCurrentPlaylistItemIndex();
-
-    /**
-     * Specifies a playback looping mode. The source will not be played in looping mode.
-     */
-    public static final int LOOPING_MODE_NONE = 0;
-    /**
-     * Specifies a playback looping mode. The full list of source will be played in looping mode,
-     * and in the order specified in the play list.
-     */
-    public static final int LOOPING_MODE_FULL = 1;
-    /**
-     * Specifies a playback looping mode. The current DataSourceDesc will be played in looping mode.
-     */
-    public static final int LOOPING_MODE_SINGLE = 2;
-    /**
-     * Specifies a playback looping mode. The full list of source will be played in looping mode,
-     * and in a random order.
-     */
-    public static final int LOOPING_MODE_SHUFFLE = 3;
-
-    /** @hide */
-    @IntDef(
-        value = {
-            LOOPING_MODE_NONE,
-            LOOPING_MODE_FULL,
-            LOOPING_MODE_SINGLE,
-            LOOPING_MODE_SHUFFLE,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface LoopingMode {}
-
-    /**
-     * Sets the looping mode of the play list.
-     * The mode shall be one of {@link #LOOPING_MODE_NONE}, {@link #LOOPING_MODE_FULL},
-     * {@link #LOOPING_MODE_SINGLE}, {@link #LOOPING_MODE_SHUFFLE}.
-     *
-     * @param mode the mode in which the play list will be played
-     * @throws IllegalArgumentException if mode is not supported
-     */
-    public abstract void setLoopingMode(@LoopingMode int mode);
-
-    /**
-     * Gets the looping mode of play list.
-     *
-     * @return the looping mode of the play list
-     */
-    public abstract int getLoopingMode();
-
-    /**
-     * Moves the DataSourceDesc at indexFrom in the play list to indexTo.
-     *
-     * @throws IllegalArgumentException if the play list is null
-     * @throws IndexOutOfBoundsException if indexFrom or indexTo is outside play list range
-     */
-    public abstract void movePlaylistItem(int indexFrom, int indexTo);
-
-    /**
-     * Removes the DataSourceDesc at index in the play list.
-     *
-     * If index is same as the current index of the play list, current DataSourceDesc
-     * will be stopped and playback moves to next source in the list.
-     *
-     * @return the removed DataSourceDesc at index in the play list
-     * @throws IllegalArgumentException if the play list is null
-     * @throws IndexOutOfBoundsException if index is outside play list range
-     */
-    public abstract DataSourceDesc removePlaylistItem(int index);
-
-    /**
-     * Inserts the DataSourceDesc to the play list at position index.
-     *
-     * This will not change the DataSourceDesc currently being played.
-     * If index is less than or equal to the current index of the play list,
-     * the current index of the play list will be incremented correspondingly.
-     *
-     * @param index the index you want to add dsd to the play list
-     * @param dsd the descriptor of data source you want to add to the play list
-     * @throws IndexOutOfBoundsException if index is outside play list range
-     * @throws NullPointerException if dsd is null
-     */
-    public abstract void addPlaylistItem(int index, DataSourceDesc dsd);
-
-    /**
-     * replaces the DataSourceDesc at index in the play list with given dsd.
-     *
-     * When index is same as the current index of the play list, the current source
-     * will be stopped and the new source will be played, except that if new
-     * and old source only differ on end position and current media position is
-     * smaller then the new end position.
-     *
-     * This will not change the DataSourceDesc currently being played.
-     * If index is less than or equal to the current index of the play list,
-     * the current index of the play list will be incremented correspondingly.
-     *
-     * @param index the index you want to add dsd to the play list
-     * @param dsd the descriptor of data source you want to add to the play list
-     * @throws IndexOutOfBoundsException if index is outside play list range
-     * @throws NullPointerException if dsd is null
-     */
-    public abstract DataSourceDesc editPlaylistItem(int index, DataSourceDesc dsd);
-
-    /**
-     * Prepares the player for playback, asynchronously.
-     *
-     * After setting the datasource and the display surface, you need to
-     * call prepareAsync().
-     *
-     * @throws IllegalStateException if it is called in an invalid state
-     */
-    public abstract void prepareAsync();
-
-    /**
-     * Starts or resumes playback. If playback had previously been paused,
-     * playback will continue from where it was paused. If playback had
-     * been stopped, or never started before, playback will start at the
-     * beginning.
-     *
-     * @throws IllegalStateException if it is called in an invalid state
-     */
-    public abstract void play();
-
-    /**
      * Stops playback after playback has been started or paused.
      *
      * @throws IllegalStateException if the internal player engine has not been
@@ -832,14 +878,6 @@
      */
     public void stop() { }
 
-    /**
-     * Pauses playback. Call play() to resume.
-     *
-     * @throws IllegalStateException if the internal player engine has not been
-     * initialized.
-     */
-    public abstract void pause();
-
     //--------------------------------------------------------------------------
     // Explicit Routing
     //--------------------
@@ -927,9 +965,10 @@
      *
      * @return the width of the video, or 0 if there is no video,
      * no display surface was set, or the width has not been determined
-     * yet. The {@code EventCallback} can be registered via
-     * {@link #registerEventCallback(Executor, EventCallback)} to provide a
-     * notification {@code EventCallback.onVideoSizeChanged} when the width is available.
+     * yet. The {@code MediaPlayer2EventCallback} can be registered via
+     * {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)} to provide a
+     * notification {@code MediaPlayer2EventCallback.onVideoSizeChanged} when the width
+     * is available.
      */
     public abstract int getVideoWidth();
 
@@ -938,9 +977,9 @@
      *
      * @return the height of the video, or 0 if there is no video,
      * no display surface was set, or the height has not been determined
-     * yet. The {@code EventCallback} can be registered via
-     * {@link #registerEventCallback(Executor, EventCallback)} to provide a
-     * notification {@code EventCallback.onVideoSizeChanged} when the height is available.
+     * yet. The {@code MediaPlayer2EventCallback} can be registered via
+     * {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)} to provide a
+     * notification {@code MediaPlayer2EventCallback.onVideoSizeChanged} when the height is available.
      */
     public abstract int getVideoHeight();
 
@@ -962,10 +1001,59 @@
      * @return true if currently playing, false otherwise
      * @throws IllegalStateException if the internal player engine has not been
      * initialized or has been released.
+     * @hide
      */
     public abstract boolean isPlaying();
 
     /**
+     * MediaPlayer2 has not been prepared or just has been reset.
+     * In this state, MediaPlayer2 doesn't fetch data.
+     */
+    public static final int MEDIAPLAYER2_STATE_IDLE = 1;
+
+    /**
+     * MediaPlayer2 has been just prepared.
+     * In this state, MediaPlayer2 just fetches data from media source,
+     * but doesn't actively render data.
+     */
+    public static final int MEDIAPLAYER2_STATE_PREPARED = 2;
+
+    /**
+     * MediaPlayer2 is paused.
+     * In this state, MediaPlayer2 doesn't actively render data.
+     */
+    public static final int MEDIAPLAYER2_STATE_PAUSED = 3;
+
+    /**
+     * MediaPlayer2 is actively playing back data.
+     */
+    public static final int MEDIAPLAYER2_STATE_PLAYING = 4;
+
+    /**
+     * MediaPlayer2 has hit some fatal error and cannot continue playback.
+     */
+    public static final int MEDIAPLAYER2_STATE_ERROR = 5;
+
+    /**
+     * @hide
+     */
+    @IntDef({
+        MEDIAPLAYER2_STATE_IDLE,
+        MEDIAPLAYER2_STATE_PREPARED,
+        MEDIAPLAYER2_STATE_PAUSED,
+        MEDIAPLAYER2_STATE_PLAYING,
+        MEDIAPLAYER2_STATE_ERROR })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface MediaPlayer2State {}
+
+    /**
+     * Gets the current MediaPlayer2 state.
+     *
+     * @return the current MediaPlayer2 state.
+     */
+    public abstract @MediaPlayer2State int getMediaPlayer2State();
+
+    /**
      * Gets the current buffering management params used by the source component.
      * Calling it only after {@code setDataSource} has been called.
      * Each type of data source might have different set of default params.
@@ -1075,10 +1163,6 @@
      * non-zero speed is equivalent to calling play().
      *
      * @param params the playback params.
-     *
-     * @throws IllegalStateException if the internal player engine has not been
-     * initialized or has been released.
-     * @throws IllegalArgumentException if params is not supported.
      */
     public abstract void setPlaybackParams(@NonNull PlaybackParams params);
 
@@ -1086,8 +1170,6 @@
      * Gets the playback params, containing the current playback rate.
      *
      * @return the playback params.
-     * @throws IllegalStateException if the internal player engine has not been
-     * initialized.
      */
     @NonNull
     public abstract PlaybackParams getPlaybackParams();
@@ -1096,10 +1178,6 @@
      * Sets A/V sync mode.
      *
      * @param params the A/V sync params to apply
-     *
-     * @throws IllegalStateException if the internal player engine has not been
-     * initialized.
-     * @throws IllegalArgumentException if params are not supported.
      */
     public abstract void setSyncParams(@NonNull SyncParams params);
 
@@ -1107,9 +1185,6 @@
      * Gets the A/V sync mode.
      *
      * @return the A/V sync params
-     *
-     * @throws IllegalStateException if the internal player engine has not been
-     * initialized.
      */
     @NonNull
     public abstract SyncParams getSyncParams();
@@ -1191,9 +1266,6 @@
      * or may not be a sync frame but is closest to or the same as msec.
      * {@link #SEEK_CLOSEST} often has larger performance overhead compared
      * to the other options if there is no sync frame located at msec.
-     * @throws IllegalStateException if the internal player engine has not been
-     * initialized
-     * @throws IllegalArgumentException if the mode is invalid.
      */
     public abstract void seekTo(long msec, @SeekMode int mode);
 
@@ -1219,21 +1291,6 @@
     public abstract MediaTimestamp getTimestamp();
 
     /**
-     * Gets the current playback position.
-     *
-     * @return the current position in milliseconds
-     */
-    public abstract int getCurrentPosition();
-
-    /**
-     * Gets the duration of the file.
-     *
-     * @return the duration in milliseconds, if no duration is available
-     *         (for example, if streaming live content), -1 is returned.
-     */
-    public abstract int getDuration();
-
-    /**
      * Gets the media metadata.
      *
      * @param update_only controls whether the full set of available
@@ -1278,30 +1335,9 @@
     }
 
     /**
-     * Set the MediaPlayer2 to start when this MediaPlayer2 finishes playback
-     * (i.e. reaches the end of the stream).
-     * The media framework will attempt to transition from this player to
-     * the next as seamlessly as possible. The next player can be set at
-     * any time before completion, but shall be after setDataSource has been
-     * called successfully. The next player must be prepared by the
-     * app, and the application should not call play() on it.
-     * The next MediaPlayer2 must be different from 'this'. An exception
-     * will be thrown if next == this.
-     * The application may call setNextMediaPlayer(null) to indicate no
-     * next player should be started at the end of playback.
-     * If the current player is looping, it will keep looping and the next
-     * player will not be started.
-     *
-     * @param next the player to start after this one completes playback.
-     *
-     * @hide
-     */
-    public void setNextMediaPlayer(MediaPlayer2 next) { }
-
-    /**
      * Resets the MediaPlayer2 to its uninitialized state. After calling
      * this method, you will have to initialize it again by setting the
-     * data source and calling prepareAsync().
+     * data source and calling prepare().
      */
     public abstract void reset();
 
@@ -1316,24 +1352,6 @@
     public void notifyAt(long mediaTimeUs) { }
 
     /**
-     * Sets the audio attributes for this MediaPlayer2.
-     * See {@link AudioAttributes} for how to build and configure an instance of this class.
-     * You must call this method before {@link #prepareAsync()} in order
-     * for the audio attributes to become effective thereafter.
-     * @param attributes a non-null set of audio attributes
-     * @throws IllegalArgumentException if the attributes are null or invalid.
-     */
-    public abstract void setAudioAttributes(AudioAttributes attributes);
-
-    /**
-     * Sets the player to be looping or non-looping.
-     *
-     * @param looping whether to loop or not
-     * @hide
-     */
-    public void setLooping(boolean looping) { }
-
-    /**
      * Checks whether the MediaPlayer2 is looping or non-looping.
      *
      * @return true if the MediaPlayer2 is currently looping, false otherwise
@@ -1344,31 +1362,6 @@
     }
 
     /**
-     * Sets the volume on this player.
-     * This API is recommended for balancing the output of audio streams
-     * within an application. Unless you are writing an application to
-     * control user settings, this API should be used in preference to
-     * {@link AudioManager#setStreamVolume(int, int, int)} which sets the volume of ALL streams of
-     * a particular type. Note that the passed volume values are raw scalars in range 0.0 to 1.0.
-     * UI controls should be scaled logarithmically.
-     *
-     * @param leftVolume left volume scalar
-     * @param rightVolume right volume scalar
-     */
-    /*
-     * FIXME: Merge this into javadoc comment above when setVolume(float) is not @hide.
-     * The single parameter form below is preferred if the channel volumes don't need
-     * to be set independently.
-     */
-    public abstract void setVolume(float leftVolume, float rightVolume);
-
-    /**
-     * Similar, excepts sets volume of all channels to same value.
-     * @hide
-     */
-    public void setVolume(float volume) { }
-
-    /**
      * Sets the audio session ID.
      *
      * @param sessionId the audio session ID.
@@ -1382,8 +1375,6 @@
      * However, it is possible to force this player to be part of an already existing audio session
      * by calling this method.
      * This method must be called before one of the overloaded <code> setDataSource </code> methods.
-     * @throws IllegalStateException if it is called in an invalid state
-     * @throws IllegalArgumentException if the sessionId is invalid.
      */
     public abstract void setAudioSessionId(int sessionId);
 
@@ -1472,7 +1463,6 @@
      * @return List of track info. The total number of tracks is the array length.
      * Must be called again if an external timed text source has been added after
      * addTimedTextSource method is called.
-     * @throws IllegalStateException if it is called in an invalid state.
      */
     public abstract List<TrackInfo> getTrackInfo();
 
@@ -1657,32 +1647,6 @@
      */
     public abstract void deselectTrack(int index);
 
-    /**
-     * Releases the resources held by this {@code MediaPlayer2} object.
-     *
-     * It is considered good practice to call this method when you're
-     * done using the MediaPlayer2. In particular, whenever an Activity
-     * of an application is paused (its onPause() method is called),
-     * or stopped (its onStop() method is called), this method should be
-     * invoked to release the MediaPlayer2 object, unless the application
-     * has a special need to keep the object around. In addition to
-     * unnecessary resources (such as memory and instances of codecs)
-     * being held, failure to call this method immediately if a
-     * MediaPlayer2 object is no longer needed may also lead to
-     * continuous battery consumption for mobile devices, and playback
-     * failure for other applications if no multiple instances of the
-     * same codec are supported on a device. Even if multiple instances
-     * of the same codec are supported, some performance degradation
-     * may be expected when unnecessary multiple instances are used
-     * at the same time.
-     *
-     * {@code close()} may be safely called after a prior {@code close()}.
-     * This class implements the Java {@code AutoCloseable} interface and
-     * may be used with try-with-resources.
-     */
-    @Override
-    public abstract void close();
-
     /** @hide */
     public MediaTimeProvider getMediaTimeProvider() {
         return null;
@@ -1692,22 +1656,7 @@
      * Interface definition for callbacks to be invoked when the player has the corresponding
      * events.
      */
-    public abstract static class EventCallback {
-        /**
-         * Called to update status in buffering a media source received through
-         * progressive downloading. The received buffering percentage
-         * indicates how much of the content has been buffered or played.
-         * For example a buffering update of 80 percent when half the content
-         * has already been played indicates that the next 30 percent of the
-         * content to play has been buffered.
-         *
-         * @param mp the MediaPlayer2 the update pertains to
-         * @param srcId the Id of this data source
-         * @param percent the percentage (0-100) of the content
-         *                that has been buffered or played thus far
-         */
-        public void onBufferingUpdate(MediaPlayer2 mp, long srcId, int percent) { }
-
+    public abstract static class MediaPlayer2EventCallback {
         /**
          * Called to indicate the video size
          *
@@ -1715,22 +1664,22 @@
          * no display surface was set, or the value was not determined yet.
          *
          * @param mp the MediaPlayer2 associated with this callback
-         * @param srcId the Id of this data source
+         * @param dsd the DataSourceDesc of this data source
          * @param width the width of the video
          * @param height the height of the video
          */
-        public void onVideoSizeChanged(MediaPlayer2 mp, long srcId, int width, int height) { }
+        public void onVideoSizeChanged(MediaPlayer2 mp, DataSourceDesc dsd, int width, int height) { }
 
         /**
          * Called to indicate an avaliable timed text
          *
          * @param mp the MediaPlayer2 associated with this callback
-         * @param srcId the Id of this data source
+         * @param dsd the DataSourceDesc of this data source
          * @param text the timed text sample which contains the text
          *             needed to be displayed and the display format.
          * @hide
          */
-        public void onTimedText(MediaPlayer2 mp, long srcId, TimedText text) { }
+        public void onTimedText(MediaPlayer2 mp, DataSourceDesc dsd, TimedText text) { }
 
         /**
          * Called to indicate avaliable timed metadata
@@ -1747,16 +1696,16 @@
          * @see TimedMetaData
          *
          * @param mp the MediaPlayer2 associated with this callback
-         * @param srcId the Id of this data source
+         * @param dsd the DataSourceDesc of this data source
          * @param data the timed metadata sample associated with this event
          */
-        public void onTimedMetaDataAvailable(MediaPlayer2 mp, long srcId, TimedMetaData data) { }
+        public void onTimedMetaDataAvailable(MediaPlayer2 mp, DataSourceDesc dsd, TimedMetaData data) { }
 
         /**
          * Called to indicate an error.
          *
          * @param mp the MediaPlayer2 the error pertains to
-         * @param srcId the Id of this data source
+         * @param dsd the DataSourceDesc of this data source
          * @param what the type of error that has occurred:
          * <ul>
          * <li>{@link #MEDIA_ERROR_UNKNOWN}
@@ -1771,13 +1720,13 @@
          * <li><code>MEDIA_ERROR_SYSTEM (-2147483648)</code> - low-level system error.
          * </ul>
          */
-        public void onError(MediaPlayer2 mp, long srcId, int what, int extra) { }
+        public void onError(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) { }
 
         /**
          * Called to indicate an info or a warning.
          *
          * @param mp the MediaPlayer2 the info pertains to.
-         * @param srcId the Id of this data source
+         * @param dsd the DataSourceDesc of this data source
          * @param what the type of info or warning.
          * <ul>
          * <li>{@link #MEDIA_INFO_UNKNOWN}
@@ -1787,9 +1736,6 @@
          * <li>{@link #MEDIA_INFO_PLAYBACK_COMPLETE}
          * <li>{@link #MEDIA_INFO_PLAYLIST_END}
          * <li>{@link #MEDIA_INFO_PREPARED}
-         * <li>{@link #MEDIA_INFO_COMPLETE_CALL_PLAY}
-         * <li>{@link #MEDIA_INFO_COMPLETE_CALL_PAUSE}
-         * <li>{@link #MEDIA_INFO_COMPLETE_CALL_SEEK}
          * <li>{@link #MEDIA_INFO_VIDEO_TRACK_LAGGING}
          * <li>{@link #MEDIA_INFO_BUFFERING_START}
          * <li>{@link #MEDIA_INFO_BUFFERING_END}
@@ -1804,25 +1750,78 @@
          * @param extra an extra code, specific to the info. Typically
          * implementation dependent.
          */
-        public void onInfo(MediaPlayer2 mp, long srcId, int what, int extra) { }
+        public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) { }
+
+        /**
+         * Called to acknowledge an API call.
+         *
+         * @param mp the MediaPlayer2 the call was made on.
+         * @param dsd the DataSourceDesc of this data source
+         * @param what the enum for the API call.
+         * <ul>
+         * <li>{@link #MEDIA_CALL_ATTACH_AUX_EFFECT}
+         * <li>{@link #MEDIA_CALL_DESELECT_TRACK}
+         * <li>{@link #MEDIA_CALL_LOOP_CURRENT}
+         * <li>{@link #MEDIA_CALL_PAUSE}
+         * <li>{@link #MEDIA_CALL_PLAY}
+         * <li>{@link #MEDIA_CALL_PREPARE}
+         * <li>{@link #MEDIA_CALL_PREPARE_DRM}
+         * <li>{@link #MEDIA_CALL_PROVIDE_DRM_KEY_RESPONSE}
+         * <li>{@link #MEDIA_CALL_RELEASE_DRM}
+         * <li>{@link #MEDIA_CALL_RESTORE_DRM_KEYS}
+         * <li>{@link #MEDIA_CALL_SEEK_TO}
+         * <li>{@link #MEDIA_CALL_SELECT_TRACK}
+         * <li>{@link #MEDIA_CALL_SET_AUDIO_ATTRIBUTES}
+         * <li>{@link #MEDIA_CALL_SET_AUDIO_SESSION_ID}
+         * <li>{@link #MEDIA_CALL_SET_AUX_EFFECT_SEND_LEVEL}
+         * <li>{@link #MEDIA_CALL_SET_DATA_SOURCE}
+         * <li>{@link #MEDIA_CALL_SET_DRM_CONFIG_HELPER}
+         * <li>{@link #MEDIA_CALL_SET_DRM_PROPERTY_STRING}
+         * <li>{@link #MEDIA_CALL_SET_NEXT_DATA_SOURCE}
+         * <li>{@link #MEDIA_CALL_SET_NEXT_DATA_SOURCES}
+         * <li>{@link #MEDIA_CALL_SET_PLAYBACK_PARAMS}
+         * <li>{@link #MEDIA_CALL_SET_PLAYBACK_SPEED}
+         * <li>{@link #MEDIA_CALL_SET_PLAYER_VOLUME}
+         * <li>{@link #MEDIA_CALL_SET_SURFACE}
+         * <li>{@link #MEDIA_CALL_SET_SYNC_PARAMS}
+         * <li>{@link #MEDIA_CALL_SKIP_TO_NEXT}
+         * </ul>
+         * @param status the returned status code for the call.
+         */
+        public void onCallComplete(MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) { }
+
+        /**
+         * Called to indicate media clock has changed.
+         *
+         * @param mp the MediaPlayer2 the media time pertains to.
+         * @param dsd the DataSourceDesc of this data source
+         * @param timestamp the new media clock.
+         */
+        public void onMediaTimeChanged(MediaPlayer2 mp, DataSourceDesc dsd, MediaTimestamp timestamp) { }
+
+        /**
+         * Called to indicate {@link #notifyWhenCommandLabelReached(Object)} has been processed.
+         *
+         * @param mp the MediaPlayer2 {@link #notifyWhenCommandLabelReached(Object)} was called on.
+         * @param label the application specific Object given by
+         *        {@link #notifyWhenCommandLabelReached(Object)}.
+         */
+        public void onCommandLabelReached(MediaPlayer2 mp, Object label) { }
     }
 
     /**
-     * Register a callback to be invoked when the media source is ready
-     * for playback.
+     * Sets the callback to be invoked when the media source is ready for playback.
      *
      * @param eventCallback the callback that will be run
      * @param executor the executor through which the callback should be invoked
      */
-    public abstract void registerEventCallback(@NonNull @CallbackExecutor Executor executor,
-            @NonNull EventCallback eventCallback);
+    public abstract void setMediaPlayer2EventCallback(@NonNull @CallbackExecutor Executor executor,
+            @NonNull MediaPlayer2EventCallback eventCallback);
 
     /**
-     * Unregisters an {@link EventCallback}.
-     *
-     * @param callback an {@link EventCallback} to unregister
+     * Clears the {@link MediaPlayer2EventCallback}.
      */
-    public abstract void unregisterEventCallback(EventCallback callback);
+    public abstract void clearMediaPlayer2EventCallback();
 
     /**
      * Interface definition of a callback to be invoked when a
@@ -1849,14 +1848,14 @@
      * in include/media/mediaplayer2.h!
      */
     /** Unspecified media player error.
-     * @see android.media.MediaPlayer2.EventCallback.onError
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onError
      */
     public static final int MEDIA_ERROR_UNKNOWN = 1;
 
     /** The video is streamed and its container is not valid for progressive
      * playback i.e the video's index (e.g moov atom) is not at the start of the
      * file.
-     * @see android.media.MediaPlayer2.EventCallback.onError
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onError
      */
     public static final int MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 200;
 
@@ -1872,7 +1871,7 @@
 
     /** Unspecified low-level system error. This value originated from UNKNOWN_ERROR in
      * system/core/include/utils/Errors.h
-     * @see android.media.MediaPlayer2.EventCallback.onError
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onError
      * @hide
      */
     public static final int MEDIA_ERROR_SYSTEM = -2147483648;
@@ -1882,96 +1881,93 @@
      * in include/media/mediaplayer2.h!
      */
     /** Unspecified media player info.
-     * @see android.media.MediaPlayer2.EventCallback.onInfo
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
      */
     public static final int MEDIA_INFO_UNKNOWN = 1;
 
     /** The player switched to this datas source because it is the
-     * next-to-be-played in the play list.
-     * @see android.media.MediaPlayer2.EventCallback.onInfo
+     * next-to-be-played in the playlist.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
      */
     public static final int MEDIA_INFO_STARTED_AS_NEXT = 2;
 
     /** The player just pushed the very first video frame for rendering.
-     * @see android.media.MediaPlayer2.EventCallback.onInfo
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
      */
     public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3;
 
     /** The player just rendered the very first audio sample.
-     * @see android.media.MediaPlayer2.EventCallback.onInfo
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
      */
     public static final int MEDIA_INFO_AUDIO_RENDERING_START = 4;
 
     /** The player just completed the playback of this data source.
-     * @see android.media.MediaPlayer2.EventCallback.onInfo
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
      */
     public static final int MEDIA_INFO_PLAYBACK_COMPLETE = 5;
 
-    /** The player just completed the playback of the full play list.
-     * @see android.media.MediaPlayer2.EventCallback.onInfo
+    /** The player just completed the playback of the full playlist.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
      */
     public static final int MEDIA_INFO_PLAYLIST_END = 6;
 
     /** The player just prepared a data source.
-     * This also serves as call completion notification for {@link #prepareAsync()}.
-     * @see android.media.MediaPlayer2.EventCallback.onInfo
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
      */
     public static final int MEDIA_INFO_PREPARED = 100;
 
-    /** The player just completed a call {@link #play()}.
-     * @see android.media.MediaPlayer2.EventCallback.onInfo
-     */
-    public static final int MEDIA_INFO_COMPLETE_CALL_PLAY = 101;
-
-    /** The player just completed a call {@link #pause()}.
-     * @see android.media.MediaPlayer2.EventCallback.onInfo
-     */
-    public static final int MEDIA_INFO_COMPLETE_CALL_PAUSE = 102;
-
-    /** The player just completed a call {@link #seekTo(long, int)}.
-     * @see android.media.MediaPlayer2.EventCallback.onInfo
-     */
-    public static final int MEDIA_INFO_COMPLETE_CALL_SEEK = 103;
-
     /** The video is too complex for the decoder: it can't decode frames fast
      *  enough. Possibly only the audio plays fine at this stage.
-     * @see android.media.MediaPlayer2.EventCallback.onInfo
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
      */
     public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700;
 
     /** MediaPlayer2 is temporarily pausing playback internally in order to
      * buffer more data.
-     * @see android.media.MediaPlayer2.EventCallback.onInfo
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
      */
     public static final int MEDIA_INFO_BUFFERING_START = 701;
 
     /** MediaPlayer2 is resuming playback after filling buffers.
-     * @see android.media.MediaPlayer2.EventCallback.onInfo
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
      */
     public static final int MEDIA_INFO_BUFFERING_END = 702;
 
     /** Estimated network bandwidth information (kbps) is available; currently this event fires
      * simultaneously as {@link #MEDIA_INFO_BUFFERING_START} and {@link #MEDIA_INFO_BUFFERING_END}
      * when playing network files.
-     * @see android.media.MediaPlayer2.EventCallback.onInfo
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
      * @hide
      */
     public static final int MEDIA_INFO_NETWORK_BANDWIDTH = 703;
 
+    /**
+     * Update status in buffering a media source received through progressive downloading.
+     * The received buffering percentage indicates how much of the content has been buffered
+     * or played. For example a buffering update of 80 percent when half the content
+     * has already been played indicates that the next 30 percent of the
+     * content to play has been buffered.
+     *
+     * The {@code extra} parameter in {@code MediaPlayer2EventCallback.onInfo} is the
+     * percentage (0-100) of the content that has been buffered or played thus far.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
+     */
+    public static final int MEDIA_INFO_BUFFERING_UPDATE = 704;
+
     /** Bad interleaving means that a media has been improperly interleaved or
      * not interleaved at all, e.g has all the video samples first then all the
      * audio ones. Video is playing but a lot of disk seeks may be happening.
-     * @see android.media.MediaPlayer2.EventCallback.onInfo
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
      */
     public static final int MEDIA_INFO_BAD_INTERLEAVING = 800;
 
     /** The media cannot be seeked (e.g live stream)
-     * @see android.media.MediaPlayer2.EventCallback.onInfo
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
      */
     public static final int MEDIA_INFO_NOT_SEEKABLE = 801;
 
     /** A new set of metadata is available.
-     * @see android.media.MediaPlayer2.EventCallback.onInfo
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
      */
     public static final int MEDIA_INFO_METADATA_UPDATE = 802;
 
@@ -1983,33 +1979,164 @@
 
     /** Informs that audio is not playing. Note that playback of the video
      * is not interrupted.
-     * @see android.media.MediaPlayer2.EventCallback.onInfo
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
      */
     public static final int MEDIA_INFO_AUDIO_NOT_PLAYING = 804;
 
     /** Informs that video is not playing. Note that playback of the audio
      * is not interrupted.
-     * @see android.media.MediaPlayer2.EventCallback.onInfo
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
      */
     public static final int MEDIA_INFO_VIDEO_NOT_PLAYING = 805;
 
     /** Failed to handle timed text track properly.
-     * @see android.media.MediaPlayer2.EventCallback.onInfo
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
      *
      * {@hide}
      */
     public static final int MEDIA_INFO_TIMED_TEXT_ERROR = 900;
 
     /** Subtitle track was not supported by the media framework.
-     * @see android.media.MediaPlayer2.EventCallback.onInfo
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
      */
     public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901;
 
     /** Reading the subtitle track takes too long.
-     * @see android.media.MediaPlayer2.EventCallback.onInfo
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onInfo
      */
     public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902;
 
+    //--------------------------------------------------------------------------
+    /** The player just completed a call {@code attachAuxEffect}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_ATTACH_AUX_EFFECT = 1;
+
+    /** The player just completed a call {@code deselectTrack}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_DESELECT_TRACK = 2;
+
+    /** The player just completed a call {@code loopCurrent}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback.CallComplete
+     */
+    public static final int MEDIA_CALL_LOOP_CURRENT = 3;
+
+    /** The player just completed a call {@code pause}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback.CallComplete
+     */
+    public static final int MEDIA_CALL_PAUSE = 4;
+
+    /** The player just completed a call {@code play}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_PLAY = 5;
+
+    /** The player just completed a call {@code prepare}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_PREPARE = 6;
+
+    /** The player just completed a call {@code prepareDrm}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_PREPARE_DRM = 7;
+
+    /** The player just completed a call {@code provideDrmKeyResponse}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_PROVIDE_DRM_KEY_RESPONSE = 8;
+
+    /** The player just completed a call {@code releaseDrm}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_RELEASE_DRM = 12;
+
+    /** The player just completed a call {@code restoreDrmKeys}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_RESTORE_DRM_KEYS = 13;
+
+    /** The player just completed a call {@code seekTo}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_SEEK_TO = 14;
+
+    /** The player just completed a call {@code selectTrack}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_SELECT_TRACK = 15;
+
+    /** The player just completed a call {@code setAudioAttributes}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_SET_AUDIO_ATTRIBUTES = 16;
+
+    /** The player just completed a call {@code setAudioSessionId}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_SET_AUDIO_SESSION_ID = 17;
+
+    /** The player just completed a call {@code setAuxEffectSendLevel}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_SET_AUX_EFFECT_SEND_LEVEL = 18;
+
+    /** The player just completed a call {@code setDataSource}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_SET_DATA_SOURCE = 19;
+
+    /** The player just completed a call {@code setOnDrmConfigHelper}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_SET_DRM_CONFIG_HELPER = 20;
+
+    /** The player just completed a call {@code setDrmPropertyString}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_SET_DRM_PROPERTY_STRING = 21;
+
+    /** The player just completed a call {@code setNextDataSource}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_SET_NEXT_DATA_SOURCE = 22;
+
+    /** The player just completed a call {@code setNextDataSources}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_SET_NEXT_DATA_SOURCES = 23;
+
+    /** The player just completed a call {@code setPlaybackParams}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_SET_PLAYBACK_PARAMS = 24;
+
+    /** The player just completed a call {@code setPlaybackSpeed}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_SET_PLAYBACK_SPEED = 25;
+
+    /** The player just completed a call {@code setPlayerVolume}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_SET_PLAYER_VOLUME = 26;
+
+    /** The player just completed a call {@code setSurface}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_SET_SURFACE = 27;
+
+    /** The player just completed a call {@code setSyncParams}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_SET_SYNC_PARAMS = 28;
+
+    /** The player just completed a call {@code skipToNext}.
+     * @see android.media.MediaPlayer2.MediaPlayer2EventCallback#onCallComplete
+     */
+    public static final int MEDIA_CALL_SKIP_TO_NEXT = 29;
+
 
     // Modular DRM begin
 
@@ -2029,8 +2156,9 @@
          * Called to give the app the opportunity to configure DRM before the session is created
          *
          * @param mp the {@code MediaPlayer2} associated with this callback
+         * @param dsd the DataSourceDesc of this data source
          */
-        public void onDrmConfig(MediaPlayer2 mp);
+        public void onDrmConfig(MediaPlayer2 mp, DataSourceDesc dsd);
     }
 
     /**
@@ -2051,42 +2179,41 @@
         /**
          * Called to indicate DRM info is available
          *
-         * @param mp       the {@code MediaPlayer2} associated with this callback
-         * @param drmInfo  DRM info of the source including PSSH, and subset
-         *                 of crypto schemes supported by this device
+         * @param mp the {@code MediaPlayer2} associated with this callback
+         * @param dsd the DataSourceDesc of this data source
+         * @param drmInfo DRM info of the source including PSSH, and subset
+         *                of crypto schemes supported by this device
          */
-        public void onDrmInfo(MediaPlayer2 mp, DrmInfo drmInfo) { }
+        public void onDrmInfo(MediaPlayer2 mp, DataSourceDesc dsd, DrmInfo drmInfo) { }
 
         /**
-         * Called to notify the client that {@code prepareDrm} is finished and ready for key request/response.
+         * Called to notify the client that {@code prepareDrm} is finished and ready for
+         * key request/response.
          *
-         * @param mp      the {@code MediaPlayer2} associated with this callback
-         * @param status  the result of DRM preparation which can be
+         * @param mp the {@code MediaPlayer2} associated with this callback
+         * @param dsd the DataSourceDesc of this data source
+         * @param status the result of DRM preparation which can be
          * {@link #PREPARE_DRM_STATUS_SUCCESS},
          * {@link #PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR},
          * {@link #PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR}, or
          * {@link #PREPARE_DRM_STATUS_PREPARATION_ERROR}.
          */
-        public void onDrmPrepared(MediaPlayer2 mp, @PrepareDrmStatusCode int status) { }
-
+        public void onDrmPrepared(MediaPlayer2 mp, DataSourceDesc dsd, @PrepareDrmStatusCode int status) { }
     }
 
     /**
-     * Register a callback to be invoked when the media source is ready
-     * for playback.
+     * Sets the callback to be invoked when the media source is ready for playback.
      *
      * @param eventCallback the callback that will be run
      * @param executor the executor through which the callback should be invoked
      */
-    public abstract void registerDrmEventCallback(@NonNull @CallbackExecutor Executor executor,
+    public abstract void setDrmEventCallback(@NonNull @CallbackExecutor Executor executor,
             @NonNull DrmEventCallback eventCallback);
 
     /**
-     * Unregisters a {@link DrmEventCallback}.
-     *
-     * @param callback a {@link DrmEventCallback} to unregister
+     * Clears the {@link DrmEventCallback}.
      */
-    public abstract void unregisterDrmEventCallback(DrmEventCallback callback);
+    public abstract void clearDrmEventCallback();
 
     /**
      * The status codes for {@link DrmEventCallback#onDrmPrepared} listener.
@@ -2184,14 +2311,14 @@
      * A key request/response exchange occurs between the app and a license server
      * to obtain or release keys used to decrypt encrypted content.
      * <p>
-     * getKeyRequest() is used to obtain an opaque key request byte array that is
+     * getDrmKeyRequest() is used to obtain an opaque key request byte array that is
      * delivered to the license server.  The opaque key request byte array is returned
      * in KeyRequest.data.  The recommended URL to deliver the key request to is
      * returned in KeyRequest.defaultUrl.
      * <p>
      * After the app has received the key request response from the server,
      * it should deliver to the response to the DRM engine plugin using the method
-     * {@link #provideKeyResponse}.
+     * {@link #provideDrmKeyResponse}.
      *
      * @param keySetId is the key-set identifier of the offline keys being released when keyType is
      * {@link MediaDrm#KEY_TYPE_RELEASE}. It should be set to null for other key requests, when
@@ -2218,22 +2345,23 @@
      * @throws NoDrmSchemeException if there is no active DRM session
      */
     @NonNull
-    public abstract MediaDrm.KeyRequest getKeyRequest(@Nullable byte[] keySetId, @Nullable byte[] initData,
+    public abstract MediaDrm.KeyRequest getDrmKeyRequest(
+            @Nullable byte[] keySetId, @Nullable byte[] initData,
             @Nullable String mimeType, @MediaDrm.KeyType int keyType,
             @Nullable Map<String, String> optionalParameters)
             throws NoDrmSchemeException;
 
     /**
      * A key response is received from the license server by the app, then it is
-     * provided to the DRM engine plugin using provideKeyResponse. When the
+     * provided to the DRM engine plugin using provideDrmKeyResponse. When the
      * response is for an offline key request, a key-set identifier is returned that
      * can be used to later restore the keys to a new session with the method
-     * {@ link # restoreKeys}.
+     * {@ link # restoreDrmKeys}.
      * When the response is for a streaming or release request, null is returned.
      *
      * @param keySetId When the response is for a release request, keySetId identifies
      * the saved key associated with the release request (i.e., the same keySetId
-     * passed to the earlier {@ link # getKeyRequest} call. It MUST be null when the
+     * passed to the earlier {@ link # getDrmKeyRequest} call. It MUST be null when the
      * response is for either streaming or offline key requests.
      *
      * @param response the byte array response from the server
@@ -2242,16 +2370,17 @@
      * @throws DeniedByServerException if the response indicates that the
      * server rejected the request
      */
-    public abstract byte[] provideKeyResponse(@Nullable byte[] keySetId, @NonNull byte[] response)
+    public abstract byte[] provideDrmKeyResponse(
+            @Nullable byte[] keySetId, @NonNull byte[] response)
             throws NoDrmSchemeException, DeniedByServerException;
 
     /**
      * Restore persisted offline keys into a new session.  keySetId identifies the
-     * keys to load, obtained from a prior call to {@link #provideKeyResponse}.
+     * keys to load, obtained from a prior call to {@link #provideDrmKeyResponse}.
      *
      * @param keySetId identifies the saved key set to restore
      */
-    public abstract void restoreKeys(@NonNull byte[] keySetId)
+    public abstract void restoreDrmKeys(@NonNull byte[] keySetId)
             throws NoDrmSchemeException;
 
     /**
@@ -2264,7 +2393,8 @@
      * {@link MediaDrm#PROPERTY_DESCRIPTION}, {@link MediaDrm#PROPERTY_ALGORITHMS}
      */
     @NonNull
-    public abstract String getDrmPropertyString(@NonNull @MediaDrm.StringProperty String propertyName)
+    public abstract String getDrmPropertyString(
+            @NonNull @MediaDrm.StringProperty String propertyName)
             throws NoDrmSchemeException;
 
     /**
@@ -2277,8 +2407,8 @@
      * {@link MediaDrm#PROPERTY_VENDOR}, {@link MediaDrm#PROPERTY_VERSION},
      * {@link MediaDrm#PROPERTY_DESCRIPTION}, {@link MediaDrm#PROPERTY_ALGORITHMS}
      */
-    public abstract void setDrmPropertyString(@NonNull @MediaDrm.StringProperty String propertyName,
-                                     @NonNull String value)
+    public abstract void setDrmPropertyString(
+            @NonNull @MediaDrm.StringProperty String propertyName, @NonNull String value)
             throws NoDrmSchemeException;
 
     /**
@@ -2422,4 +2552,38 @@
         public static final String ERROR_CODE = "android.media.mediaplayer.errcode";
 
     }
+
+    /**
+       Constant to retrieve only the new metadata since the last
+       call.
+       // FIXME: unhide.
+       // FIXME: add link to getMetadata(boolean, boolean)
+       {@hide}
+     */
+    public static final boolean METADATA_UPDATE_ONLY = true;
+
+    /**
+       Constant to retrieve all the metadata.
+       // FIXME: unhide.
+       // FIXME: add link to getMetadata(boolean, boolean)
+       {@hide}
+     */
+    public static final boolean METADATA_ALL = false;
+
+    /**
+       Constant to enable the metadata filter during retrieval.
+       // FIXME: unhide.
+       // FIXME: add link to getMetadata(boolean, boolean)
+       {@hide}
+     */
+    public static final boolean APPLY_METADATA_FILTER = true;
+
+    /**
+       Constant to disable the metadata filter during retrieval.
+       // FIXME: unhide.
+       // FIXME: add link to getMetadata(boolean, boolean)
+       {@hide}
+     */
+    public static final boolean BYPASS_METADATA_FILTER = false;
+
 }
diff --git a/media/java/android/media/MediaPlayer2Impl.java b/media/java/android/media/MediaPlayer2Impl.java
index 1b21b5b..50bf738 100644
--- a/media/java/android/media/MediaPlayer2Impl.java
+++ b/media/java/android/media/MediaPlayer2Impl.java
@@ -24,6 +24,9 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.res.AssetFileDescriptor;
+import android.graphics.SurfaceTexture;
+import android.media.SubtitleController.Anchor;
+import android.media.SubtitleTrack.RenderingWidget;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -45,9 +48,6 @@
 import android.view.Surface;
 import android.view.SurfaceHolder;
 import android.widget.VideoView;
-import android.graphics.SurfaceTexture;
-import android.media.SubtitleController.Anchor;
-import android.media.SubtitleTrack.RenderingWidget;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.Preconditions;
@@ -77,7 +77,6 @@
 import java.util.Collections;
 import java.util.concurrent.Executor;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Scanner;
@@ -87,453 +86,6 @@
 
 
 /**
- * MediaPlayer2 class can be used to control playback
- * of audio/video files and streams. An example on how to use the methods in
- * this class can be found in {@link android.widget.VideoView}.
- *
- * <p>Topics covered here are:
- * <ol>
- * <li><a href="#StateDiagram">State Diagram</a>
- * <li><a href="#Valid_and_Invalid_States">Valid and Invalid States</a>
- * <li><a href="#Permissions">Permissions</a>
- * <li><a href="#Callbacks">Register informational and error callbacks</a>
- * </ol>
- *
- * <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>For more information about how to use MediaPlayer2, read the
- * <a href="{@docRoot}guide/topics/media/mediaplayer.html">Media Playback</a> developer guide.</p>
- * </div>
- *
- * <a name="StateDiagram"></a>
- * <h3>State Diagram</h3>
- *
- * <p>Playback control of audio/video files and streams is managed as a state
- * machine. The following diagram shows the life cycle and the states of a
- * MediaPlayer2 object driven by the supported playback control operations.
- * The ovals represent the states a MediaPlayer2 object may reside
- * in. The arcs represent the playback control operations that drive the object
- * state transition. There are two types of arcs. The arcs with a single arrow
- * head represent synchronous method calls, while those with
- * a double arrow head represent asynchronous method calls.</p>
- *
- * <p><img src="../../../images/mediaplayer_state_diagram.gif"
- *         alt="MediaPlayer State diagram"
- *         border="0" /></p>
- *
- * <p>From this state diagram, one can see that a MediaPlayer2 object has the
- *    following states:</p>
- * <ul>
- *     <li>When a MediaPlayer2 object is just created using <code>new</code> or
- *         after {@link #reset()} is called, it is in the <em>Idle</em> state; and after
- *         {@link #close()} is called, it is in the <em>End</em> state. Between these
- *         two states is the life cycle of the MediaPlayer2 object.
- *         <ul>
- *         <li>There is a subtle but important difference between a newly constructed
- *         MediaPlayer2 object and the MediaPlayer2 object after {@link #reset()}
- *         is called. It is a programming error to invoke methods such
- *         as {@link #getCurrentPosition()},
- *         {@link #getDuration()}, {@link #getVideoHeight()},
- *         {@link #getVideoWidth()}, {@link #setAudioAttributes(AudioAttributes)},
- *         {@link #setLooping(boolean)},
- *         {@link #setVolume(float, float)}, {@link #pause()}, {@link #play()},
- *         {@link #seekTo(long, int)} or
- *         {@link #prepareAsync()} in the <em>Idle</em> state for both cases. If any of these
- *         methods is called right after a MediaPlayer2 object is constructed,
- *         the user supplied callback method OnErrorListener.onError() won't be
- *         called by the internal player engine and the object state remains
- *         unchanged; but if these methods are called right after {@link #reset()},
- *         the user supplied callback method OnErrorListener.onError() will be
- *         invoked by the internal player engine and the object will be
- *         transfered to the <em>Error</em> state. </li>
- *         <li>It is also recommended that once
- *         a MediaPlayer2 object is no longer being used, call {@link #close()} immediately
- *         so that resources used by the internal player engine associated with the
- *         MediaPlayer2 object can be released immediately. Resource may include
- *         singleton resources such as hardware acceleration components and
- *         failure to call {@link #close()} may cause subsequent instances of
- *         MediaPlayer2 objects to fallback to software implementations or fail
- *         altogether. Once the MediaPlayer2
- *         object is in the <em>End</em> state, it can no longer be used and
- *         there is no way to bring it back to any other state. </li>
- *         <li>Furthermore,
- *         the MediaPlayer2 objects created using <code>new</code> is in the
- *         <em>Idle</em> state.
- *         </li>
- *         </ul>
- *         </li>
- *     <li>In general, some playback control operation may fail due to various
- *         reasons, such as unsupported audio/video format, poorly interleaved
- *         audio/video, resolution too high, streaming timeout, and the like.
- *         Thus, error reporting and recovery is an important concern under
- *         these circumstances. Sometimes, due to programming errors, invoking a playback
- *         control operation in an invalid state may also occur. Under all these
- *         error conditions, the internal player engine invokes a user supplied
- *         EventCallback.onError() method if an EventCallback has been
- *         registered beforehand via
- *         {@link #registerEventCallback(Executor, EventCallback)}.
- *         <ul>
- *         <li>It is important to note that once an error occurs, the
- *         MediaPlayer2 object enters the <em>Error</em> state (except as noted
- *         above), even if an error listener has not been registered by the application.</li>
- *         <li>In order to reuse a MediaPlayer2 object that is in the <em>
- *         Error</em> state and recover from the error,
- *         {@link #reset()} can be called to restore the object to its <em>Idle</em>
- *         state.</li>
- *         <li>It is good programming practice to have your application
- *         register a OnErrorListener to look out for error notifications from
- *         the internal player engine.</li>
- *         <li>IllegalStateException is
- *         thrown to prevent programming errors such as calling
- *         {@link #prepareAsync()}, {@link #setDataSource(DataSourceDesc)}, or
- *         {@code setPlaylist} methods in an invalid state. </li>
- *         </ul>
- *         </li>
- *     <li>Calling
- *         {@link #setDataSource(DataSourceDesc)}, or
- *         {@code setPlaylist} transfers a
- *         MediaPlayer2 object in the <em>Idle</em> state to the
- *         <em>Initialized</em> state.
- *         <ul>
- *         <li>An IllegalStateException is thrown if
- *         setDataSource() or setPlaylist() is called in any other state.</li>
- *         <li>It is good programming
- *         practice to always look out for <code>IllegalArgumentException</code>
- *         and <code>IOException</code> that may be thrown from
- *         <code>setDataSource</code> and <code>setPlaylist</code> methods.</li>
- *         </ul>
- *         </li>
- *     <li>A MediaPlayer2 object must first enter the <em>Prepared</em> state
- *         before playback can be started.
- *         <ul>
- *         <li>{@link #prepareAsync()} first transfers the object to the
- *         <em>Preparing</em> state after the
- *         call returns (which occurs almost right way) while the internal
- *         player engine continues working on the rest of preparation work
- *         until the preparation work completes. When the preparation completes,
- *         the internal player engine then calls a user supplied callback method,
- *         onPrepared() of the EventCallback interface, if an
- *         EventCallback is registered beforehand via {@link
- *         #registerEventCallback(Executor, EventCallback)}.</li>
- *         <li>It is important to note that
- *         the <em>Preparing</em> state is a transient state, and the behavior
- *         of calling any method with side effect while a MediaPlayer2 object is
- *         in the <em>Preparing</em> state is undefined.</li>
- *         <li>An IllegalStateException is
- *         thrown if {@link #prepareAsync()} is called in
- *         any other state.</li>
- *         <li>While in the <em>Prepared</em> state, properties
- *         such as audio/sound volume, screenOnWhilePlaying, looping can be
- *         adjusted by invoking the corresponding set methods.</li>
- *         </ul>
- *         </li>
- *     <li>To start the playback, {@link #play()} must be called. After
- *         {@link #play()} returns successfully, the MediaPlayer2 object is in the
- *         <em>Started</em> state. {@link #isPlaying()} can be called to test
- *         whether the MediaPlayer2 object is in the <em>Started</em> state.
- *         <ul>
- *         <li>While in the <em>Started</em> state, the internal player engine calls
- *         a user supplied EventCallback.onBufferingUpdate() callback
- *         method if an EventCallback has been registered beforehand
- *         via {@link #registerEventCallback(Executor, EventCallback)}.
- *         This callback allows applications to keep track of the buffering status
- *         while streaming audio/video.</li>
- *         <li>Calling {@link #play()} has not effect
- *         on a MediaPlayer2 object that is already in the <em>Started</em> state.</li>
- *         </ul>
- *         </li>
- *     <li>Playback can be paused and stopped, and the current playback position
- *         can be adjusted. Playback can be paused via {@link #pause()}. When the call to
- *         {@link #pause()} returns, the MediaPlayer2 object enters the
- *         <em>Paused</em> state. Note that the transition from the <em>Started</em>
- *         state to the <em>Paused</em> state and vice versa happens
- *         asynchronously in the player engine. It may take some time before
- *         the state is updated in calls to {@link #isPlaying()}, and it can be
- *         a number of seconds in the case of streamed content.
- *         <ul>
- *         <li>Calling {@link #play()} to resume playback for a paused
- *         MediaPlayer2 object, and the resumed playback
- *         position is the same as where it was paused. When the call to
- *         {@link #play()} returns, the paused MediaPlayer2 object goes back to
- *         the <em>Started</em> state.</li>
- *         <li>Calling {@link #pause()} has no effect on
- *         a MediaPlayer2 object that is already in the <em>Paused</em> state.</li>
- *         </ul>
- *         </li>
- *     <li>The playback position can be adjusted with a call to
- *         {@link #seekTo(long, int)}.
- *         <ul>
- *         <li>Although the asynchronuous {@link #seekTo(long, int)}
- *         call returns right away, the actual seek operation may take a while to
- *         finish, especially for audio/video being streamed. When the actual
- *         seek operation completes, the internal player engine calls a user
- *         supplied EventCallback.onSeekComplete() if an EventCallback
- *         has been registered beforehand via
- *         {@link #registerEventCallback(Executor, EventCallback)}.</li>
- *         <li>Please
- *         note that {@link #seekTo(long, int)} can also be called in the other states,
- *         such as <em>Prepared</em>, <em>Paused</em> and <em>PlaybackCompleted
- *         </em> state. When {@link #seekTo(long, int)} is called in those states,
- *         one video frame will be displayed if the stream has video and the requested
- *         position is valid.
- *         </li>
- *         <li>Furthermore, the actual current playback position
- *         can be retrieved with a call to {@link #getCurrentPosition()}, which
- *         is helpful for applications such as a Music player that need to keep
- *         track of the playback progress.</li>
- *         </ul>
- *         </li>
- *     <li>When the playback reaches the end of stream, the playback completes.
- *         <ul>
- *         <li>If the looping mode was being set to <var>true</var>with
- *         {@link #setLooping(boolean)}, the MediaPlayer2 object shall remain in
- *         the <em>Started</em> state.</li>
- *         <li>If the looping mode was set to <var>false
- *         </var>, the player engine calls a user supplied callback method,
- *         EventCallback.onCompletion(), if an EventCallback is registered
- *         beforehand via {@link #registerEventCallback(Executor, EventCallback)}.
- *         The invoke of the callback signals that the object is now in the <em>
- *         PlaybackCompleted</em> state.</li>
- *         <li>While in the <em>PlaybackCompleted</em>
- *         state, calling {@link #play()} can restart the playback from the
- *         beginning of the audio/video source.</li>
- * </ul>
- *
- *
- * <a name="Valid_and_Invalid_States"></a>
- * <h3>Valid and invalid states</h3>
- *
- * <table border="0" cellspacing="0" cellpadding="0">
- * <tr><td>Method Name </p></td>
- *     <td>Valid Sates </p></td>
- *     <td>Invalid States </p></td>
- *     <td>Comments </p></td></tr>
- * <tr><td>attachAuxEffect </p></td>
- *     <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} </p></td>
- *     <td>{Idle, Error} </p></td>
- *     <td>This method must be called after setDataSource or setPlaylist.
- *     Calling it does not change the object state. </p></td></tr>
- * <tr><td>getAudioSessionId </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state. </p></td></tr>
- * <tr><td>getCurrentPosition </p></td>
- *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
- *         PlaybackCompleted} </p></td>
- *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method in a valid state does not change the
- *         state. Calling this method in an invalid state transfers the object
- *         to the <em>Error</em> state. </p></td></tr>
- * <tr><td>getDuration </p></td>
- *     <td>{Prepared, Started, Paused, Stopped, PlaybackCompleted} </p></td>
- *     <td>{Idle, Initialized, Error} </p></td>
- *     <td>Successful invoke of this method in a valid state does not change the
- *         state. Calling this method in an invalid state transfers the object
- *         to the <em>Error</em> state. </p></td></tr>
- * <tr><td>getVideoHeight </p></td>
- *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
- *         PlaybackCompleted}</p></td>
- *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method in a valid state does not change the
- *         state. Calling this method in an invalid state transfers the object
- *         to the <em>Error</em> state.  </p></td></tr>
- * <tr><td>getVideoWidth </p></td>
- *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
- *         PlaybackCompleted}</p></td>
- *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method in a valid state does not change
- *         the state. Calling this method in an invalid state transfers the
- *         object to the <em>Error</em> state. </p></td></tr>
- * <tr><td>isPlaying </p></td>
- *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
- *          PlaybackCompleted}</p></td>
- *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method in a valid state does not change
- *         the state. Calling this method in an invalid state transfers the
- *         object to the <em>Error</em> state. </p></td></tr>
- * <tr><td>pause </p></td>
- *     <td>{Started, Paused, PlaybackCompleted}</p></td>
- *     <td>{Idle, Initialized, Prepared, Stopped, Error}</p></td>
- *     <td>Successful invoke of this method in a valid state transfers the
- *         object to the <em>Paused</em> state. Calling this method in an
- *         invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
- * <tr><td>prepare </p></td>
- *     <td>{Initialized, Stopped} </p></td>
- *     <td>{Idle, Prepared, Started, Paused, PlaybackCompleted, Error} </p></td>
- *     <td>Successful invoke of this method in a valid state transfers the
- *         object to the <em>Prepared</em> state. Calling this method in an
- *         invalid state throws an IllegalStateException.</p></td></tr>
- * <tr><td>prepareAsync </p></td>
- *     <td>{Initialized, Stopped} </p></td>
- *     <td>{Idle, Prepared, Started, Paused, PlaybackCompleted, Error} </p></td>
- *     <td>Successful invoke of this method in a valid state transfers the
- *         object to the <em>Preparing</em> state. Calling this method in an
- *         invalid state throws an IllegalStateException.</p></td></tr>
- * <tr><td>release </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>After {@link #close()}, the object is no longer available. </p></td></tr>
- * <tr><td>reset </p></td>
- *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
- *         PlaybackCompleted, Error}</p></td>
- *     <td>{}</p></td>
- *     <td>After {@link #reset()}, the object is like being just created.</p></td></tr>
- * <tr><td>seekTo </p></td>
- *     <td>{Prepared, Started, Paused, PlaybackCompleted} </p></td>
- *     <td>{Idle, Initialized, Stopped, Error}</p></td>
- *     <td>Successful invoke of this method in a valid state does not change
- *         the state. Calling this method in an invalid state transfers the
- *         object to the <em>Error</em> state. </p></td></tr>
- * <tr><td>setAudioAttributes </p></td>
- *     <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
- *          PlaybackCompleted}</p></td>
- *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method does not change the state. In order for the
- *         target audio attributes type to become effective, this method must be called before
- *         prepareAsync().</p></td></tr>
- * <tr><td>setAudioSessionId </p></td>
- *     <td>{Idle} </p></td>
- *     <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted,
- *          Error} </p></td>
- *     <td>This method must be called in idle state as the audio session ID must be known before
- *         calling setDataSource or setPlaylist. Calling it does not change the object
- *         state. </p></td></tr>
- * <tr><td>setAudioStreamType (deprecated)</p></td>
- *     <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
- *          PlaybackCompleted}</p></td>
- *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method does not change the state. In order for the
- *         target audio stream type to become effective, this method must be called before
- *         prepareAsync().</p></td></tr>
- * <tr><td>setAuxEffectSendLevel </p></td>
- *     <td>any</p></td>
- *     <td>{} </p></td>
- *     <td>Calling this method does not change the object state. </p></td></tr>
- * <tr><td>setDataSource </p></td>
- *     <td>{Idle} </p></td>
- *     <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted,
- *          Error} </p></td>
- *     <td>Successful invoke of this method in a valid state transfers the
- *         object to the <em>Initialized</em> state. Calling this method in an
- *         invalid state throws an IllegalStateException.</p></td></tr>
- * <tr><td>setPlaylist </p></td>
- *     <td>{Idle} </p></td>
- *     <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted,
- *          Error} </p></td>
- *     <td>Successful invoke of this method in a valid state transfers the
- *         object to the <em>Initialized</em> state. Calling this method in an
- *         invalid state throws an IllegalStateException.</p></td></tr>
- * <tr><td>setDisplay </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state. </p></td></tr>
- * <tr><td>setSurface </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state. </p></td></tr>
- * <tr><td>setVideoScalingMode </p></td>
- *     <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} </p></td>
- *     <td>{Idle, Error}</p></td>
- *     <td>Successful invoke of this method does not change the state.</p></td></tr>
- * <tr><td>setLooping </p></td>
- *     <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
- *         PlaybackCompleted}</p></td>
- *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method in a valid state does not change
- *         the state. Calling this method in an
- *         invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
- * <tr><td>isLooping </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state. </p></td></tr>
- * <tr><td>registerDrmEventCallback </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state. </p></td></tr>
- * <tr><td>registerEventCallback </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state. </p></td></tr>
- * <tr><td>setPlaybackParams</p></td>
- *     <td>{Initialized, Prepared, Started, Paused, PlaybackCompleted, Error}</p></td>
- *     <td>{Idle, Stopped} </p></td>
- *     <td>This method will change state in some cases, depending on when it's called.
- *         </p></td></tr>
- * <tr><td>setScreenOnWhilePlaying</></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state.  </p></td></tr>
- * <tr><td>setVolume </p></td>
- *     <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
- *          PlaybackCompleted}</p></td>
- *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method does not change the state.
- * <tr><td>setWakeMode </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state.</p></td></tr>
- * <tr><td>start </p></td>
- *     <td>{Prepared, Started, Paused, PlaybackCompleted}</p></td>
- *     <td>{Idle, Initialized, Stopped, Error}</p></td>
- *     <td>Successful invoke of this method in a valid state transfers the
- *         object to the <em>Started</em> state. Calling this method in an
- *         invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
- * <tr><td>stop </p></td>
- *     <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
- *     <td>{Idle, Initialized, Error}</p></td>
- *     <td>Successful invoke of this method in a valid state transfers the
- *         object to the <em>Stopped</em> state. Calling this method in an
- *         invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
- * <tr><td>getTrackInfo </p></td>
- *     <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
- *     <td>{Idle, Initialized, Error}</p></td>
- *     <td>Successful invoke of this method does not change the state.</p></td></tr>
- * <tr><td>addTimedTextSource </p></td>
- *     <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
- *     <td>{Idle, Initialized, Error}</p></td>
- *     <td>Successful invoke of this method does not change the state.</p></td></tr>
- * <tr><td>selectTrack </p></td>
- *     <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
- *     <td>{Idle, Initialized, Error}</p></td>
- *     <td>Successful invoke of this method does not change the state.</p></td></tr>
- * <tr><td>deselectTrack </p></td>
- *     <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
- *     <td>{Idle, Initialized, Error}</p></td>
- *     <td>Successful invoke of this method does not change the state.</p></td></tr>
- *
- * </table>
- *
- * <a name="Permissions"></a>
- * <h3>Permissions</h3>
- * <p>One may need to declare a corresponding WAKE_LOCK permission {@link
- * android.R.styleable#AndroidManifestUsesPermission &lt;uses-permission&gt;}
- * element.
- *
- * <p>This class requires the {@link android.Manifest.permission#INTERNET} permission
- * when used with network-based content.
- *
- * <a name="Callbacks"></a>
- * <h3>Callbacks</h3>
- * <p>Applications may want to register for informational and error
- * events in order to be informed of some internal state update and
- * possible runtime errors during playback or streaming. Registration for
- * these events is done by properly setting the appropriate listeners (via calls
- * to
- * {@link #registerEventCallback(Executor, EventCallback)},
- * {@link #registerDrmEventCallback(Executor, DrmEventCallback)}).
- * In order to receive the respective callback
- * associated with these listeners, applications are required to create
- * MediaPlayer2 objects on a thread with its own Looper running (main UI
- * thread by default has a Looper running).
- *
  * @hide
  */
 public final class MediaPlayer2Impl extends MediaPlayer2 {
@@ -558,12 +110,13 @@
     private final CloseGuard mGuard = CloseGuard.get();
 
     private final Object mPlLock = new Object();
+    private DataSourceDesc mCurrentDSD;
+    private long mCurrentSrcId = 0;
     private List<DataSourceDesc> mPlaylist;
-    private int mPlCurrentIndex = 0;
+    private long mNextSrcId = mCurrentSrcId + 1;
     private int mPlNextIndex = -1;
     private int mPlNextSourceState = NEXT_SOURCE_STATE_INIT;
     private boolean mPlNextSourcePlayPending = false;
-    private int mLoopingMode = LOOPING_MODE_NONE;
 
     // Modular DRM
     private UUID mDrmUUID;
@@ -604,6 +157,381 @@
         native_setup(new WeakReference<MediaPlayer2Impl>(this));
     }
 
+    /**
+     * Releases the resources held by this {@code MediaPlayer2} object.
+     *
+     * It is considered good practice to call this method when you're
+     * done using the MediaPlayer2. In particular, whenever an Activity
+     * of an application is paused (its onPause() method is called),
+     * or stopped (its onStop() method is called), this method should be
+     * invoked to release the MediaPlayer2 object, unless the application
+     * has a special need to keep the object around. In addition to
+     * unnecessary resources (such as memory and instances of codecs)
+     * being held, failure to call this method immediately if a
+     * MediaPlayer2 object is no longer needed may also lead to
+     * continuous battery consumption for mobile devices, and playback
+     * failure for other applications if no multiple instances of the
+     * same codec are supported on a device. Even if multiple instances
+     * of the same codec are supported, some performance degradation
+     * may be expected when unnecessary multiple instances are used
+     * at the same time.
+     *
+     * {@code close()} may be safely called after a prior {@code close()}.
+     * This class implements the Java {@code AutoCloseable} interface and
+     * may be used with try-with-resources.
+     */
+    @Override
+    public void close() {
+        synchronized (mGuard) {
+            release();
+        }
+    }
+
+    /**
+     * Starts or resumes playback. If playback had previously been paused,
+     * playback will continue from where it was paused. If playback had
+     * been stopped, or never started before, playback will start at the
+     * beginning.
+     *
+     * @throws IllegalStateException if it is called in an invalid state
+     */
+    @Override
+    public void play() {
+        stayAwake(true);
+        _start();
+    }
+
+    private native void _start() throws IllegalStateException;
+
+    /**
+     * Prepares the player for playback, asynchronously.
+     *
+     * After setting the datasource and the display surface, you need to either
+     * call prepare(). For streams, you should call prepare(),
+     * which returns immediately, rather than blocking until enough data has been
+     * buffered.
+     *
+     * @throws IllegalStateException if it is called in an invalid state
+     */
+    @Override
+    public native void prepare();
+
+    /**
+     * Pauses playback. Call play() to resume.
+     *
+     * @throws IllegalStateException if the internal player engine has not been
+     * initialized.
+     */
+    @Override
+    public void pause() {
+        stayAwake(false);
+        _pause();
+    }
+
+    private native void _pause() throws IllegalStateException;
+
+    /**
+     * Tries to play next data source if applicable.
+     *
+     * @throws IllegalStateException if it is called in an invalid state
+     */
+    @Override
+    public void skipToNext() {
+        // TODO: switch to next data source and play
+    }
+
+    /**
+     * Gets the current playback position.
+     *
+     * @return the current position in milliseconds
+     */
+    @Override
+    public native long getCurrentPosition();
+
+    /**
+     * Gets the duration of the file.
+     *
+     * @return the duration in milliseconds, if no duration is available
+     *         (for example, if streaming live content), -1 is returned.
+     */
+    @Override
+    public native long getDuration();
+
+    /**
+     * Gets the current buffered media source position received through progressive downloading.
+     * The received buffering percentage indicates how much of the content has been buffered
+     * or played. For example a buffering update of 80 percent when half the content
+     * has already been played indicates that the next 30 percent of the
+     * content to play has been buffered.
+     *
+     * @return the current buffered media source position in milliseconds
+     */
+    @Override
+    public long getBufferedPosition() {
+        // TODO: either get buffered position from native code, or cache BUFFERING_UPDATE
+        // number and convert it to buffered position.
+        return 0;
+    }
+
+    /**
+     * Gets the current player state.
+     *
+     * @return the current player state, one of the following:
+     * <ul>
+     * <li>{@link #PLAYER_STATE_IDLE}
+     * <li>{@link #PLAYER_STATE_PAUSED}
+     * <li>{@link #PLAYER_STATE_PLAYING}
+     * <li>{@link #PLAYER_STATE_ERROR}
+     * </ul>
+     * @throws IllegalStateException if the internal player engine has not been
+     * initialized or has been released.
+     */
+    @Override
+    public @PlayerState int getPlayerState() {
+        // TODO: use cached state or call native function.
+        return PLAYER_STATE_IDLE;
+    }
+
+    /**
+     * Gets the current buffering state of the player.
+     * During buffering, see {@link #getBufferedPosition()} for the quantifying the amount already
+     * buffered.
+     * @return the buffering state, one of the following:
+     * <ul>
+     * <li>{@link #BUFFERING_STATE_UNKNOWN}
+     * <li>{@link #BUFFERING_STATE_BUFFERING_AND_PLAYABLE}
+     * <li>{@link #BUFFERING_STATE_BUFFERING_AND_STARVED}
+     * <li>{@link #BUFFERING_STATE_BUFFERING_COMPLETE}
+     * </ul>
+     * @throws IllegalStateException if the internal player engine has not been
+     * initialized or has been released.
+     */
+    @Override
+    public @BuffState int getBufferingState() {
+        // TODO: use cached state or call native function.
+        return BUFFERING_STATE_UNKNOWN;
+    }
+
+    /**
+     * Sets the audio attributes for this MediaPlayer2.
+     * See {@link AudioAttributes} for how to build and configure an instance of this class.
+     * You must call this method before {@link #prepare()} in order
+     * for the audio attributes to become effective thereafter.
+     * @param attributes a non-null set of audio attributes
+     * @throws IllegalArgumentException if the attributes are null or invalid.
+     */
+    @Override
+    public void setAudioAttributes(@NonNull AudioAttributes attributes) {
+        if (attributes == null) {
+            final String msg = "Cannot set AudioAttributes to null";
+            throw new IllegalArgumentException(msg);
+        }
+        mUsage = attributes.getUsage();
+        mBypassInterruptionPolicy = (attributes.getAllFlags()
+                & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0;
+        Parcel pattributes = Parcel.obtain();
+        attributes.writeToParcel(pattributes, AudioAttributes.FLATTEN_TAGS);
+        setParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES, pattributes);
+        pattributes.recycle();
+    }
+
+    @Override
+    public @NonNull AudioAttributes getAudioAttributes() {
+        Parcel pattributes = getParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES);
+        AudioAttributes attributes = AudioAttributes.CREATOR.createFromParcel(pattributes);
+        pattributes.recycle();
+        return attributes;
+    }
+
+    /**
+     * Sets the data source as described by a DataSourceDesc.
+     *
+     * @param dsd the descriptor of data source you want to play
+     * @throws IllegalStateException if it is called in an invalid state
+     * @throws NullPointerException if dsd is null
+     */
+    @Override
+    public void setDataSource(@NonNull DataSourceDesc dsd) {
+        Preconditions.checkNotNull(dsd, "the DataSourceDesc cannot be null");
+        synchronized (mPlLock) {
+            mCurrentDSD = dsd;
+            try {
+                handleDataSource(true /* isCurrent */, dsd);
+            } catch (IOException e) {
+            }
+        }
+    }
+
+    /**
+     * Sets a single data source as described by a DataSourceDesc which will be played
+     * after current data source is finished.
+     *
+     * @param dsd the descriptor of data source you want to play after current one
+     * @throws IllegalStateException if it is called in an invalid state
+     * @throws NullPointerException if dsd is null
+     */
+    @Override
+    public void setNextDataSource(@NonNull DataSourceDesc dsd) {
+        Preconditions.checkNotNull(dsd, "the DataSourceDesc cannot be null");
+
+        // TODO: save dsd in a list
+    }
+
+    /**
+     * Sets a list of data sources to be played sequentially after current data source is done.
+     *
+     * @param dsds the list of data sources you want to play after current one
+     * @throws IllegalStateException if it is called in an invalid state
+     * @throws IllegalArgumentException if dsds is null or empty, or contains null DataSourceDesc
+     */
+    @Override
+    public void setNextDataSources(@NonNull List<DataSourceDesc> dsds) {
+        // TODO: save the list.
+        /*
+        if (dsds == null || dsds.size() == 0) {
+            throw new IllegalArgumentException("data source list cannot be null or empty.");
+        }
+        HashSet ids = new HashSet(pl.size());
+        for (DataSourceDesc dsd : pl) {
+            if (dsd == null) {
+                throw new IllegalArgumentException("DataSourceDesc in playlist cannot be null.");
+            }
+            if (ids.add(dsd.getId()) == false) {
+                throw new IllegalArgumentException("DataSourceDesc Id in playlist should be unique.");
+            }
+        }
+
+        if (startIndex < 0) {
+            startIndex = 0;
+        } else if (startIndex >= pl.size()) {
+            startIndex = pl.size() - 1;
+        }
+
+        synchronized (mPlLock) {
+            mPlaylist = Collections.synchronizedList(new ArrayList(pl));
+            handleDataSource(true, mPlaylist.get(startIndex));
+            // TODO: handle the preparation of next source in the playlist.
+            // It should be processed after current source is prepared.
+            mPlNextIndex = getNextIndex_l();
+        }
+        */
+    }
+
+    /**
+     * Gets the current data source as described by a DataSourceDesc.
+     *
+     * @return the current DataSourceDesc
+     */
+    @Override
+    public @NonNull DataSourceDesc getCurrentDataSource() {
+        synchronized (mPlLock) {
+            return mCurrentDSD;
+        }
+    }
+
+    /**
+     * Configures the player to loop on the current data source.
+     * @param loop true if the current data source is meant to loop.
+     */
+    @Override
+    public void loopCurrent(boolean loop) {
+        // TODO: set the looping mode, send notification
+        setLooping(loop);
+    }
+
+    private native void setLooping(boolean looping);
+
+    /**
+     * Sets the playback speed.
+     * A value of 1.0f is the default playback value.
+     * A negative value indicates reverse playback, check {@link #isReversePlaybackSupported()}
+     * before using negative values.<br>
+     * After changing the playback speed, it is recommended to query the actual speed supported
+     * by the player, see {@link #getPlaybackSpeed()}.
+     * @param speed the desired playback speed
+     */
+    @Override
+    public void setPlaybackSpeed(float speed) {
+        // TODO: send notification
+        setPlaybackParams(getPlaybackParams().setSpeed(speed));
+    }
+
+    /**
+     * Returns the actual playback speed to be used by the player when playing.
+     * Note that it may differ from the speed set in {@link #setPlaybackSpeed(float)}.
+     * @return the actual playback speed
+     */
+    @Override
+    public float getPlaybackSpeed() {
+        return getPlaybackParams().getSpeed();
+    }
+
+    /**
+     * Indicates whether reverse playback is supported.
+     * Reverse playback is indicated by negative playback speeds, see
+     * {@link #setPlaybackSpeed(float)}.
+     * @return true if reverse playback is supported.
+     */
+    @Override
+    public boolean isReversePlaybackSupported() {
+        return false;
+    }
+
+    /**
+     * Sets the volume of the audio of the media to play, expressed as a linear multiplier
+     * on the audio samples.
+     * Note that this volume is specific to the player, and is separate from stream volume
+     * used across the platform.<br>
+     * A value of 0.0f indicates muting, a value of 1.0f is the nominal unattenuated and unamplified
+     * gain. See {@link #getMaxPlayerVolume()} for the volume range supported by this player.
+     * @param volume a value between 0.0f and {@link #getMaxPlayerVolume()}.
+     */
+    @Override
+    public void setPlayerVolume(float volume) {
+        // send notification
+        _setVolume(volume, volume);
+    }
+
+    private native void _setVolume(float leftVolume, float rightVolume);
+
+    /**
+     * Returns the current volume of this player to this player.
+     * Note that it does not take into account the associated stream volume.
+     * @return the player volume.
+     */
+    @Override
+    public float getPlayerVolume() {
+        // TODO: get real volume
+        return 1.0f;
+    }
+
+    /**
+     * @return the maximum volume that can be used in {@link #setPlayerVolume(float)}.
+     */
+    @Override
+    public float getMaxPlayerVolume() {
+        return 1.0f;
+    }
+
+    /**
+     * Adds a callback to be notified of events for this player.
+     * @param e the {@link Executor} to be used for the events.
+     * @param cb the callback to receive the events.
+     */
+    @Override
+    public void registerPlayerEventCallback(@NonNull Executor e,
+            @NonNull PlayerEventCallback cb) {
+    }
+
+    /**
+     * Removes a previously registered callback for player events
+     * @param cb the callback to remove
+     */
+    @Override
+    public void unregisterPlayerEventCallback(@NonNull PlayerEventCallback cb) {
+    }
+
+
     private static final int NEXT_SOURCE_STATE_ERROR = -1;
     private static final int NEXT_SOURCE_STATE_INIT = 0;
     private static final int NEXT_SOURCE_STATE_PREPARING = 1;
@@ -666,6 +594,11 @@
         }
     }
 
+    @Override
+    public void notifyWhenCommandLabelReached(Object label) {
+        // TODO: create an entry in command queue
+    }
+
     /**
      * Sets the {@link SurfaceHolder} to use for displaying the video
      * portion of the media.
@@ -768,335 +701,6 @@
     public void clearPendingCommands() {
     }
 
-    /**
-     * Sets the data source as described by a DataSourceDesc.
-     *
-     * @param dsd the descriptor of data source you want to play
-     * @throws IllegalStateException if it is called in an invalid state
-     * @throws NullPointerException if dsd is null
-     */
-    @Override
-    public void setDataSource(@NonNull DataSourceDesc dsd) throws IOException {
-        Preconditions.checkNotNull(dsd, "the DataSourceDesc cannot be null");
-        synchronized (mPlLock) {
-            mPlaylist = Collections.synchronizedList(new ArrayList<DataSourceDesc>(1));
-            mPlaylist.add(dsd);
-            mPlCurrentIndex = 0;
-            mPlNextIndex = -1;
-            handleDataSource(true /* isCurrent */, dsd);
-        }
-    }
-
-    /**
-     * Gets the current data source as described by a DataSourceDesc.
-     *
-     * @return the current DataSourceDesc
-     */
-    @Override
-    public DataSourceDesc getCurrentDataSource() {
-        synchronized (mPlLock) {
-            if (mPlaylist == null) {
-                return null;
-            }
-            return mPlaylist.get(mPlCurrentIndex);
-        }
-    }
-
-    /**
-     * Sets the play list.
-     *
-     * If startIndex falls outside play list range, it will be clamped to the nearest index
-     * in the play list.
-     *
-     * @param pl the play list of data source you want to play
-     * @param startIndex the index of the DataSourceDesc in the play list you want to play first
-     * @throws IllegalStateException if it is called in an invalid state
-     * @throws IllegalArgumentException if pl is null or empty, or pl contains null DataSourceDesc
-     */
-    @Override
-    public void setPlaylist(@NonNull List<DataSourceDesc> pl, int startIndex)
-            throws IOException {
-        if (pl == null || pl.size() == 0) {
-            throw new IllegalArgumentException("play list cannot be null or empty.");
-        }
-        HashSet ids = new HashSet(pl.size());
-        for (DataSourceDesc dsd : pl) {
-            if (dsd == null) {
-                throw new IllegalArgumentException("DataSourceDesc in play list cannot be null.");
-            }
-            if (ids.add(dsd.getId()) == false) {
-                throw new IllegalArgumentException("DataSourceDesc Id in play list should be unique.");
-            }
-        }
-
-        if (startIndex < 0) {
-            startIndex = 0;
-        } else if (startIndex >= pl.size()) {
-            startIndex = pl.size() - 1;
-        }
-
-        synchronized (mPlLock) {
-            mPlaylist = Collections.synchronizedList(new ArrayList(pl));
-            mPlCurrentIndex = startIndex;
-            handleDataSource(true /* isCurrent */, mPlaylist.get(startIndex));
-            // TODO: handle the preparation of next source in the play list.
-            // It should be processed after current source is prepared.
-            mPlNextIndex = getNextIndex_l();
-        }
-    }
-
-    /**
-     * Gets a copy of the play list.
-     *
-     * @return a copy of the play list used by {@link MediaPlayer2}
-     */
-    @Override
-    public List<DataSourceDesc> getPlaylist() {
-        synchronized (mPlLock) {
-            if (mPlaylist == null) {
-                return null;
-            }
-            return new ArrayList(mPlaylist);
-        }
-    }
-
-    /**
-     * Sets the index of current DataSourceDesc in the play list to be played.
-     *
-     * @param index the index of DataSourceDesc in the play list you want to play
-     * @throws IllegalArgumentException if the play list is null
-     * @throws NullPointerException if index is outside play list range
-     */
-    @Override
-    public void setCurrentPlaylistItem(int index) {
-        synchronized (mPlLock) {
-            if (mPlaylist == null) {
-                throw new IllegalArgumentException("play list has not been set yet.");
-            }
-            if (index < 0 || index >= mPlaylist.size()) {
-                throw new IndexOutOfBoundsException("index is out of play list range.");
-            }
-
-            if (index == mPlCurrentIndex) {
-                return;
-            }
-
-            // TODO: in playing state, stop current source and start to play source of index.
-            mPlCurrentIndex = index;
-        }
-    }
-
-    /**
-     * Sets the index of next-to-be-played DataSourceDesc in the play list.
-     *
-     * @param index the index of next-to-be-played DataSourceDesc in the play list
-     * @throws IllegalArgumentException if the play list is null
-     * @throws NullPointerException if index is outside play list range
-     */
-    @Override
-    public void setNextPlaylistItem(int index) {
-        synchronized (mPlLock) {
-            if (mPlaylist == null) {
-                throw new IllegalArgumentException("play list has not been set yet.");
-            }
-            if (index < 0 || index >= mPlaylist.size()) {
-                throw new IndexOutOfBoundsException("index is out of play list range.");
-            }
-
-            if (index == mPlNextIndex) {
-                return;
-            }
-
-            // TODO: prepare the new next-to-be-played DataSourceDesc
-            mPlNextIndex = index;
-        }
-    }
-
-    /**
-     * Gets the current index of play list.
-     *
-     * @return the index of the current DataSourceDesc in the play list
-     */
-    @Override
-    public int getCurrentPlaylistItemIndex() {
-        synchronized (mPlLock) {
-            return mPlCurrentIndex;
-        }
-    }
-
-    /**
-     * Sets the looping mode of the play list.
-     * The mode shall be one of {@link #LOOPING_MODE_NONE}, {@link #LOOPING_MODE_FULL},
-     * {@link #LOOPING_MODE_SINGLE}, {@link #LOOPING_MODE_SHUFFLE}.
-     *
-     * @param mode the mode in which the play list will be played
-     * @throws IllegalArgumentException if mode is not supported
-     */
-    @Override
-    public void setLoopingMode(@LoopingMode int mode) {
-        if (mode != LOOPING_MODE_NONE
-            && mode != LOOPING_MODE_FULL
-            && mode != LOOPING_MODE_SINGLE
-            && mode != LOOPING_MODE_SHUFFLE) {
-            throw new IllegalArgumentException("mode is not supported.");
-        }
-
-        synchronized (mPlLock) {
-            mLoopingMode = mode;
-            if (mPlaylist == null) {
-                return;
-            }
-
-            // TODO: handle the new mode if necessary.
-        }
-    }
-
-    /**
-     * Gets the looping mode of play list.
-     *
-     * @return the looping mode of the play list
-     */
-    @Override
-    public int getLoopingMode() {
-        synchronized (mPlLock) {
-            return mPlCurrentIndex;
-        }
-    }
-
-    /**
-     * Moves the DataSourceDesc at indexFrom in the play list to indexTo.
-     *
-     * @throws IllegalArgumentException if the play list is null
-     * @throws IndexOutOfBoundsException if indexFrom or indexTo is outside play list range
-     */
-    @Override
-    public void movePlaylistItem(int indexFrom, int indexTo) {
-        synchronized (mPlLock) {
-            if (mPlaylist == null) {
-                throw new IllegalArgumentException("play list has not been set yet.");
-            }
-            // TODO: move the DataSourceDesc from indexFrom to indexTo.
-        }
-    }
-
-    /**
-     * Removes the DataSourceDesc at index in the play list.
-     *
-     * If index is same as the current index of the play list, current DataSourceDesc
-     * will be stopped and playback moves to next source in the list.
-     *
-     * @return the removed DataSourceDesc at index in the play list
-     * @throws IllegalArgumentException if the play list is null
-     * @throws IndexOutOfBoundsException if index is outside play list range
-     */
-    @Override
-    public DataSourceDesc removePlaylistItem(int index) {
-        synchronized (mPlLock) {
-            if (mPlaylist == null) {
-                throw new IllegalArgumentException("play list has not been set yet.");
-            }
-
-            DataSourceDesc oldDsd = mPlaylist.remove(index);
-            // TODO: if index == mPlCurrentIndex, stop current source and move to next one.
-            // if index == mPlNextIndex, prepare the new next-to-be-played source.
-            return oldDsd;
-        }
-    }
-
-    /**
-     * Inserts the DataSourceDesc to the play list at position index.
-     *
-     * This will not change the DataSourceDesc currently being played.
-     * If index is less than or equal to the current index of the play list,
-     * the current index of the play list will be incremented correspondingly.
-     *
-     * @param index the index you want to add dsd to the play list
-     * @param dsd the descriptor of data source you want to add to the play list
-     * @throws IndexOutOfBoundsException if index is outside play list range
-     * @throws NullPointerException if dsd is null
-     */
-    @Override
-    public void addPlaylistItem(int index, DataSourceDesc dsd) {
-        Preconditions.checkNotNull(dsd, "the DataSourceDesc cannot be null");
-
-        synchronized (mPlLock) {
-            if (mPlaylist == null) {
-                if (index == 0) {
-                    mPlaylist = Collections.synchronizedList(new ArrayList<DataSourceDesc>());
-                    mPlaylist.add(dsd);
-                    mPlCurrentIndex = 0;
-                    return;
-                }
-                throw new IllegalArgumentException("index should be 0 for first DataSourceDesc.");
-            }
-
-            long id = dsd.getId();
-            for (DataSourceDesc pldsd : mPlaylist) {
-                if (id == pldsd.getId()) {
-                    throw new IllegalArgumentException("Id of dsd already exists in the play list.");
-                }
-            }
-
-            mPlaylist.add(index, dsd);
-            if (index <= mPlCurrentIndex) {
-                ++mPlCurrentIndex;
-            }
-        }
-    }
-
-    /**
-     * replaces the DataSourceDesc at index in the play list with given dsd.
-     *
-     * When index is same as the current index of the play list, the current source
-     * will be stopped and the new source will be played, except that if new
-     * and old source only differ on end position and current media position is
-     * smaller then the new end position.
-     *
-     * This will not change the DataSourceDesc currently being played.
-     * If index is less than or equal to the current index of the play list,
-     * the current index of the play list will be incremented correspondingly.
-     *
-     * @param index the index you want to add dsd to the play list
-     * @param dsd the descriptor of data source you want to add to the play list
-     * @throws IndexOutOfBoundsException if index is outside play list range
-     * @throws NullPointerException if dsd is null
-     */
-    @Override
-    public DataSourceDesc editPlaylistItem(int index, DataSourceDesc dsd) {
-        Preconditions.checkNotNull(dsd, "the DataSourceDesc cannot be null");
-        Preconditions.checkNotNull(mPlaylist, "the play list cannot be null");
-
-        long id = dsd.getId();
-        synchronized (mPlLock) {
-            for (int i = 0; i < mPlaylist.size(); ++i) {
-                if (i == index) {
-                    continue;
-                }
-                if (id == mPlaylist.get(i).getId()) {
-                    throw new IllegalArgumentException(
-                            "Id of dsd already exists in the play list.");
-                }
-            }
-
-            // TODO: if needed, stop playback of current source, and start new dsd.
-            DataSourceDesc oldDsd = mPlaylist.set(index, dsd);
-            return mPlaylist.set(index, dsd);
-        }
-    }
-
-    // Called with mPlLock acquired.
-    // TODO: support all looping modes
-    private int getNextIndex_l() {
-        if (mPlaylist.size() <= 1) {
-            return -1;
-        }
-        int index = mPlCurrentIndex + 1;
-        if (index >= mPlaylist.size()) {
-            index = 0;
-        }
-        return index;
-    }
-
     private void handleDataSource(boolean isCurrent, @NonNull DataSourceDesc dsd)
             throws IOException {
         Preconditions.checkNotNull(dsd, "the DataSourceDesc cannot be null");
@@ -1104,13 +708,13 @@
         switch (dsd.getType()) {
             case DataSourceDesc.TYPE_CALLBACK:
                 handleDataSource(isCurrent,
-                                 dsd.getId(),
+                                 0,  // TODO: get mapped Id
                                  dsd.getMedia2DataSource());
                 break;
 
             case DataSourceDesc.TYPE_FD:
                 handleDataSource(isCurrent,
-                                 dsd.getId(),
+                                 0,  // TODO: get mapped Id
                                  dsd.getFileDescriptor(),
                                  dsd.getFileDescriptorOffset(),
                                  dsd.getFileDescriptorLength());
@@ -1118,7 +722,7 @@
 
             case DataSourceDesc.TYPE_URI:
                 handleDataSource(isCurrent,
-                                 dsd.getId(),
+                                 0,  // TODO: get mapped Id
                                  dsd.getUriContext(),
                                  dsd.getUri(),
                                  dsd.getUriHeaders(),
@@ -1304,11 +908,11 @@
 
         try {
             mPlNextSourceState = NEXT_SOURCE_STATE_PREPARING;
-            handleDataSource(false /* isCurrent */, mPlaylist.get(mPlNextIndex));
+            handleDataSource(false /* isCurrent */, mPlaylist.get(0));
         } catch (Exception e) {
             Message msg2 = mEventHandler.obtainMessage(
                     MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNSUPPORTED, null);
-            final long nextSrcId = mPlaylist.get(mPlNextIndex).getId();
+            final long nextSrcId = mNextSrcId;
             mEventHandler.post(new Runnable() {
                 @Override
                 public void run() {
@@ -1326,12 +930,12 @@
 
         if (mPlNextSourceState == NEXT_SOURCE_STATE_PREPARED) {
             // Switch to next source only when it's in prepared state.
-            mPlCurrentIndex = mPlNextIndex;
-            mPlNextIndex = getNextIndex_l();
+            mCurrentSrcId = mNextSrcId;
+            mNextSrcId = 0; // TODO; fix it
             mPlNextSourceState = NEXT_SOURCE_STATE_INIT;
             mPlNextSourcePlayPending = false;
 
-            long srcId = mPlaylist.get(mPlCurrentIndex).getId();
+            long srcId = mCurrentSrcId;
             try {
                 nativePlayNextDataSource(srcId);
             } catch (Exception e) {
@@ -1356,35 +960,6 @@
 
     private native void nativePlayNextDataSource(long srcId);
 
-    /**
-     * Prepares the player for playback, asynchronously.
-     *
-     * After setting the datasource and the display surface, you need to either
-     * call prepareAsync(). For streams, you should call prepareAsync(),
-     * which returns immediately, rather than blocking until enough data has been
-     * buffered.
-     *
-     * @throws IllegalStateException if it is called in an invalid state
-     */
-    @Override
-    public native void prepareAsync();
-
-    /**
-     * Starts or resumes playback. If playback had previously been paused,
-     * playback will continue from where it was paused. If playback had
-     * been stopped, or never started before, playback will start at the
-     * beginning.
-     *
-     * @throws IllegalStateException if it is called in an invalid state
-     */
-    @Override
-    public void play() {
-        stayAwake(true);
-        _start();
-    }
-
-    private native void _start() throws IllegalStateException;
-
 
     private int getAudioStreamType() {
         if (mStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
@@ -1410,20 +985,6 @@
 
     private native void _stop() throws IllegalStateException;
 
-    /**
-     * Pauses playback. Call play() to resume.
-     *
-     * @throws IllegalStateException if the internal player engine has not been
-     * initialized.
-     */
-    @Override
-    public void pause() {
-        stayAwake(false);
-        _pause();
-    }
-
-    private native void _pause() throws IllegalStateException;
-
     //--------------------------------------------------------------------------
     // Explicit Routing
     //--------------------
@@ -1634,9 +1195,10 @@
      *
      * @return the width of the video, or 0 if there is no video,
      * no display surface was set, or the width has not been determined
-     * yet. The {@code EventCallback} can be registered via
-     * {@link #registerEventCallback(Executor, EventCallback)} to provide a
-     * notification {@code EventCallback.onVideoSizeChanged} when the width is available.
+     * yet. The {@code MediaPlayer2EventCallback} can be registered via
+     * {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)} to provide a
+     * notification {@code MediaPlayer2EventCallback.onVideoSizeChanged} when the width
+     * is available.
      */
     @Override
     public native int getVideoWidth();
@@ -1646,9 +1208,10 @@
      *
      * @return the height of the video, or 0 if there is no video,
      * no display surface was set, or the height has not been determined
-     * yet. The {@code EventCallback} can be registered via
-     * {@link #registerEventCallback(Executor, EventCallback)} to provide a
-     * notification {@code EventCallback.onVideoSizeChanged} when the height is available.
+     * yet. The {@code MediaPlayer2EventCallback} can be registered via
+     * {@link #setMediaPlayer2EventCallback(Executor, MediaPlayer2EventCallback)} to provide a
+     * notification {@code MediaPlayer2EventCallback.onVideoSizeChanged} when the height
+     * is available.
      */
     @Override
     public native int getVideoHeight();
@@ -1677,11 +1240,32 @@
      * @return true if currently playing, false otherwise
      * @throws IllegalStateException if the internal player engine has not been
      * initialized or has been released.
+     * @hide
      */
     @Override
     public native boolean isPlaying();
 
     /**
+     * Gets the current MediaPlayer2 state.
+     *
+     * @return the current MediaPlayer2 state, one of the following:
+     * <ul>
+     * <li>{@link #MEDIAPLAYER2_STATE_IDLE}
+     * <li>{@link #MEDIAPLAYER2_STATE_PREPARED}
+     * <li>{@link #MEDIAPLAYER2_STATE_PAUSED}
+     * <li>{@link #MEDIAPLAYER2_STATE_PLAYING}
+     * <li>{@link #MEDIAPLAYER2_STATE_ERROR}
+     * </ul>
+     * @throws IllegalStateException if the internal player engine has not been
+     * initialized or has been released.
+     */
+    @Override
+    public @MediaPlayer2State int getMediaPlayer2State() {
+        // TODO: get state from native layer or cached value.
+        return MEDIAPLAYER2_STATE_IDLE;
+    }
+
+    /**
      * Gets the current buffering management params used by the source component.
      * Calling it only after {@code setDataSource} has been called.
      * Each type of data source might have different set of default params.
@@ -1801,8 +1385,6 @@
     @NonNull
     public native SyncParams getSyncParams();
 
-    private native final void _seekTo(long msec, int mode);
-
     /**
      * Moves the media to specified time position by considering the given mode.
      * <p>
@@ -1850,6 +1432,8 @@
         _seekTo(msec, mode);
     }
 
+    private native final void _seekTo(long msec, int mode);
+
     /**
      * Get current playback position as a {@link MediaTimestamp}.
      * <p>
@@ -1884,23 +1468,6 @@
     }
 
     /**
-     * Gets the current playback position.
-     *
-     * @return the current position in milliseconds
-     */
-    @Override
-    public native int getCurrentPosition();
-
-    /**
-     * Gets the duration of the file.
-     *
-     * @return the duration in milliseconds, if no duration is available
-     *         (for example, if streaming live content), -1 is returned.
-     */
-    @Override
-    public native int getDuration();
-
-    /**
      * Gets the media metadata.
      *
      * @param update_only controls whether the full set of available
@@ -1986,31 +1553,9 @@
     }
 
     /**
-     * Set the MediaPlayer2 to start when this MediaPlayer2 finishes playback
-     * (i.e. reaches the end of the stream).
-     * The media framework will attempt to transition from this player to
-     * the next as seamlessly as possible. The next player can be set at
-     * any time before completion, but shall be after setDataSource has been
-     * called successfully. The next player must be prepared by the
-     * app, and the application should not call play() on it.
-     * The next MediaPlayer2 must be different from 'this'. An exception
-     * will be thrown if next == this.
-     * The application may call setNextMediaPlayer(null) to indicate no
-     * next player should be started at the end of playback.
-     * If the current player is looping, it will keep looping and the next
-     * player will not be started.
-     *
-     * @param next the player to start after this one completes playback.
-     *
-     * @hide
-     */
-    @Override
-    public native void setNextMediaPlayer(MediaPlayer2 next);
-
-    /**
      * Resets the MediaPlayer2 to its uninitialized state. After calling
      * this method, you will have to initialize it again by setting the
-     * data source and calling prepareAsync().
+     * data source and calling prepare().
      */
     @Override
     public void reset() {
@@ -2078,41 +1623,11 @@
      * @param key key indicates the parameter to be set.
      * @param value value of the parameter to be set.
      * @return true if the parameter is set successfully, false otherwise
-     * {@hide}
      */
     private native boolean setParameter(int key, Parcel value);
 
-    /**
-     * Sets the audio attributes for this MediaPlayer2.
-     * See {@link AudioAttributes} for how to build and configure an instance of this class.
-     * You must call this method before {@link #prepareAsync()} in order
-     * for the audio attributes to become effective thereafter.
-     * @param attributes a non-null set of audio attributes
-     * @throws IllegalArgumentException if the attributes are null or invalid.
-     */
-    @Override
-    public void setAudioAttributes(AudioAttributes attributes) {
-        if (attributes == null) {
-            final String msg = "Cannot set AudioAttributes to null";
-            throw new IllegalArgumentException(msg);
-        }
-        mUsage = attributes.getUsage();
-        mBypassInterruptionPolicy = (attributes.getAllFlags()
-                & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0;
-        Parcel pattributes = Parcel.obtain();
-        attributes.writeToParcel(pattributes, AudioAttributes.FLATTEN_TAGS);
-        setParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES, pattributes);
-        pattributes.recycle();
-    }
+    private native Parcel getParameter(int key);
 
-    /**
-     * Sets the player to be looping or non-looping.
-     *
-     * @param looping whether to loop or not
-     * @hide
-     */
-    @Override
-    public native void setLooping(boolean looping);
 
     /**
      * Checks whether the MediaPlayer2 is looping or non-looping.
@@ -2124,39 +1639,6 @@
     public native boolean isLooping();
 
     /**
-     * Sets the volume on this player.
-     * This API is recommended for balancing the output of audio streams
-     * within an application. Unless you are writing an application to
-     * control user settings, this API should be used in preference to
-     * {@link AudioManager#setStreamVolume(int, int, int)} which sets the volume of ALL streams of
-     * a particular type. Note that the passed volume values are raw scalars in range 0.0 to 1.0.
-     * UI controls should be scaled logarithmically.
-     *
-     * @param leftVolume left volume scalar
-     * @param rightVolume right volume scalar
-     */
-    /*
-     * FIXME: Merge this into javadoc comment above when setVolume(float) is not @hide.
-     * The single parameter form below is preferred if the channel volumes don't need
-     * to be set independently.
-     */
-    @Override
-    public void setVolume(float leftVolume, float rightVolume) {
-        _setVolume(leftVolume, rightVolume);
-    }
-
-    private native void _setVolume(float leftVolume, float rightVolume);
-
-    /**
-     * Similar, excepts sets volume of all channels to same value.
-     * @hide
-     */
-    @Override
-    public void setVolume(float volume) {
-        setVolume(volume, volume);
-    }
-
-    /**
      * Sets the audio session ID.
      *
      * @param sessionId the audio session ID.
@@ -2202,7 +1684,6 @@
     @Override
     public native void attachAuxEffect(int effectId);
 
-
     /**
      * Sets the send level of the player to the attached auxiliary effect.
      * See {@link #attachAuxEffect(int)}. The level value range is 0 to 1.0.
@@ -3042,36 +2523,6 @@
         }
     }
 
-    /**
-     * Releases the resources held by this {@code MediaPlayer2} object.
-     *
-     * It is considered good practice to call this method when you're
-     * done using the MediaPlayer2. In particular, whenever an Activity
-     * of an application is paused (its onPause() method is called),
-     * or stopped (its onStop() method is called), this method should be
-     * invoked to release the MediaPlayer2 object, unless the application
-     * has a special need to keep the object around. In addition to
-     * unnecessary resources (such as memory and instances of codecs)
-     * being held, failure to call this method immediately if a
-     * MediaPlayer2 object is no longer needed may also lead to
-     * continuous battery consumption for mobile devices, and playback
-     * failure for other applications if no multiple instances of the
-     * same codec are supported on a device. Even if multiple instances
-     * of the same codec are supported, some performance degradation
-     * may be expected when unnecessary multiple instances are used
-     * at the same time.
-     *
-     * {@code close()} may be safely called after a prior {@code close()}.
-     * This class implements the Java {@code AutoCloseable} interface and
-     * may be used with try-with-resources.
-     */
-    @Override
-    public void close() {
-        synchronized (mGuard) {
-            release();
-        }
-    }
-
     // Have to declare protected for finalize() since it is protected
     // in the base class Object.
     @Override
@@ -3174,23 +2625,28 @@
                     sendMessage(msg2);
                 }
 
+                final DataSourceDesc dsd;
                 synchronized (mPlLock) {
                     Log.i(TAG, "MEDIA_PREPARED: srcId=" + srcId
-                            + ", currentIndex=" + mPlCurrentIndex + ", nextIndex=" + mPlNextIndex);
-                    if (mPlCurrentIndex >= 0 && srcId == mPlaylist.get(mPlCurrentIndex).getId()) {
+                            + ", currentSrcId=" + mCurrentSrcId + ", nextSrcId=" + mNextSrcId);
+                    if (srcId == mCurrentSrcId) {
                         prepareNextDataSource_l();
-                    } else if (mPlNextIndex >= 0 && srcId == mPlaylist.get(mPlNextIndex).getId()) {
+                        dsd = mCurrentDSD;
+                    } else if (mPlNextIndex >= 0 && srcId == mNextSrcId) {
                         mPlNextSourceState = NEXT_SOURCE_STATE_PREPARED;
                         if (mPlNextSourcePlayPending) {
                             playNextDataSource_l();
                         }
+                        dsd = mPlaylist.get(0);
+                    } else {
+                        dsd = null;
                     }
                 }
 
                 synchronized (mEventCbLock) {
-                    for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
+                    for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
                         cb.first.execute(() -> cb.second.onInfo(
-                                mMediaPlayer, srcId, MEDIA_INFO_PREPARED, 0));
+                                mMediaPlayer, dsd, MEDIA_INFO_PREPARED, 0));
                     }
                 }
                 return;
@@ -3215,7 +2671,7 @@
                         synchronized (mEventCbLock) {
                             for (Pair<Executor, DrmEventCallback> cb : mDrmEventCallbackRecords) {
                                 cb.first.execute(() -> cb.second.onDrmInfo(
-                                        mMediaPlayer, drmInfo));
+                                        mMediaPlayer, mCurrentDSD, drmInfo));
                             }
                         }
                     }
@@ -3226,17 +2682,17 @@
 
             case MEDIA_PLAYBACK_COMPLETE:
                 synchronized (mPlLock) {
-                    if (mPlCurrentIndex >= 0 && srcId == mPlaylist.get(mPlCurrentIndex).getId()) {
+                    if (srcId == mCurrentSrcId) {
                         Log.i(TAG, "MEDIA_PLAYBACK_COMPLETE: srcId=" + srcId
-                                + ", currentIndex=" + mPlCurrentIndex + ", nextIndex=" + mPlNextIndex);
+                                + ", currentSrcId=" + mCurrentSrcId + ", nextSrcId=" + mNextSrcId);
                         playNextDataSource_l();
                     }
                 }
 
                 synchronized (mEventCbLock) {
-                    for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
+                    for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
                         cb.first.execute(() -> cb.second.onInfo(
-                                mMediaPlayer, srcId, MEDIA_INFO_PLAYBACK_COMPLETE, 0));
+                                mMediaPlayer, mCurrentDSD, MEDIA_INFO_PLAYBACK_COMPLETE, 0));
                     }
                 }
                 stayAwake(false);
@@ -3264,18 +2720,18 @@
             case MEDIA_BUFFERING_UPDATE:
                 final int percent = msg.arg1;
                 synchronized (mEventCbLock) {
-                    for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
-                        cb.first.execute(() -> cb.second.onBufferingUpdate(
-                                mMediaPlayer, srcId, percent));
+                    for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
+                        cb.first.execute(() -> cb.second.onInfo(
+                                mMediaPlayer, mCurrentDSD, MEDIA_INFO_BUFFERING_UPDATE, percent));
                     }
                 }
                 return;
 
             case MEDIA_SEEK_COMPLETE:
                 synchronized (mEventCbLock) {
-                    for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
-                        cb.first.execute(() -> cb.second.onInfo(
-                                mMediaPlayer, srcId, MEDIA_INFO_COMPLETE_CALL_SEEK, 0));
+                    for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
+                        cb.first.execute(() -> cb.second.onCallComplete(
+                                mMediaPlayer, mCurrentDSD, MEDIA_CALL_SEEK_TO, 0));
                     }
                 }
                 // fall through
@@ -3293,9 +2749,9 @@
                 final int width = msg.arg1;
                 final int height = msg.arg2;
                 synchronized (mEventCbLock) {
-                    for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
+                    for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
                         cb.first.execute(() -> cb.second.onVideoSizeChanged(
-                                mMediaPlayer, srcId, width, height));
+                                mMediaPlayer, mCurrentDSD, width, height));
                     }
                 }
                 return;
@@ -3303,11 +2759,11 @@
             case MEDIA_ERROR:
                 Log.e(TAG, "Error (" + msg.arg1 + "," + msg.arg2 + ")");
                 synchronized (mEventCbLock) {
-                    for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
+                    for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
                         cb.first.execute(() -> cb.second.onError(
-                                mMediaPlayer, srcId, what, extra));
+                                mMediaPlayer, mCurrentDSD, what, extra));
                         cb.first.execute(() -> cb.second.onInfo(
-                                mMediaPlayer, srcId, MEDIA_INFO_PLAYBACK_COMPLETE, 0));
+                                mMediaPlayer, mCurrentDSD, MEDIA_INFO_PLAYBACK_COMPLETE, 0));
                     }
                 }
                 stayAwake(false);
@@ -3316,7 +2772,7 @@
             case MEDIA_INFO:
                 switch (msg.arg1) {
                     case MEDIA_INFO_STARTED_AS_NEXT:
-                        if (mPlCurrentIndex >= 0 && srcId == mPlaylist.get(mPlCurrentIndex).getId()) {
+                        if (srcId == mCurrentSrcId) {
                             prepareNextDataSource_l();
                         }
                         break;
@@ -3354,9 +2810,9 @@
                 }
 
                 synchronized (mEventCbLock) {
-                    for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
+                    for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
                         cb.first.execute(() -> cb.second.onInfo(
-                                mMediaPlayer, srcId, what, extra));
+                                mMediaPlayer, mCurrentDSD, what, extra));
                     }
                 }
                 // No real default action so far.
@@ -3380,8 +2836,8 @@
                 }
 
                 synchronized (mEventCbLock) {
-                    for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
-                        cb.first.execute(() -> cb.second.onTimedText(mMediaPlayer, srcId, text));
+                    for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
+                        cb.first.execute(() -> cb.second.onTimedText(mMediaPlayer, mCurrentDSD, text));
                     }
                 }
                 return;
@@ -3410,9 +2866,9 @@
                 }
 
                 synchronized (mEventCbLock) {
-                    for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
+                    for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
                         cb.first.execute(() -> cb.second.onTimedMetaDataAvailable(
-                                mMediaPlayer, srcId, data));
+                                mMediaPlayer, mCurrentDSD, data));
                     }
                 }
                 return;
@@ -3485,7 +2941,7 @@
 
         case MEDIA_PREPARED:
             // By this time, we've learned about DrmInfo's presence or absence. This is meant
-            // mainly for prepareAsync() use case. For prepare(), this still can run to a race
+            // mainly for prepare() use case. For prepare(), this still can run to a race
             // condition b/c MediaPlayerNative releases the prepare() lock before calling notify
             // so we also set mDrmInfoResolved in prepare().
             synchronized (mp.mDrmLock) {
@@ -3508,8 +2964,8 @@
     }
 
     private final Object mEventCbLock = new Object();
-    private ArrayList<Pair<Executor, EventCallback> > mEventCallbackRecords
-        = new ArrayList<Pair<Executor, EventCallback> >();
+    private ArrayList<Pair<Executor, MediaPlayer2EventCallback> > mEventCallbackRecords
+        = new ArrayList<Pair<Executor, MediaPlayer2EventCallback> >();
 
     /**
      * Register a callback to be invoked when the media source is ready
@@ -3519,13 +2975,14 @@
      * @param executor the executor through which the callback should be invoked
      */
     @Override
-    public void registerEventCallback(@NonNull @CallbackExecutor Executor executor,
-            @NonNull EventCallback eventCallback) {
+    public void setMediaPlayer2EventCallback(@NonNull @CallbackExecutor Executor executor,
+            @NonNull MediaPlayer2EventCallback eventCallback) {
         if (eventCallback == null) {
-            throw new IllegalArgumentException("Illegal null EventCallback");
+            throw new IllegalArgumentException("Illegal null MediaPlayer2EventCallback");
         }
         if (executor == null) {
-            throw new IllegalArgumentException("Illegal null Executor for the EventCallback");
+            throw new IllegalArgumentException(
+                    "Illegal null Executor for the MediaPlayer2EventCallback");
         }
         synchronized (mEventCbLock) {
             mEventCallbackRecords.add(new Pair(executor, eventCallback));
@@ -3533,17 +2990,13 @@
     }
 
     /**
-     * Unregisters an {@link EventCallback}.
-     *
-     * @param callback an {@link EventCallback} to unregister
+     * Clears the {@link MediaPlayer2EventCallback}.
      */
     @Override
-    public void unregisterEventCallback(EventCallback callback) {
+    public void clearMediaPlayer2EventCallback() {
         synchronized (mEventCbLock) {
-            for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
-                if (cb.second == callback) {
-                    mEventCallbackRecords.remove(cb);
-                }
+            for (Pair<Executor, MediaPlayer2EventCallback> cb : mEventCallbackRecords) {
+                mEventCallbackRecords.remove(cb);
             }
         }
     }
@@ -3595,13 +3048,14 @@
      * @param executor the executor through which the callback should be invoked
      */
     @Override
-    public void registerDrmEventCallback(@NonNull @CallbackExecutor Executor executor,
+    public void setDrmEventCallback(@NonNull @CallbackExecutor Executor executor,
             @NonNull DrmEventCallback eventCallback) {
         if (eventCallback == null) {
-            throw new IllegalArgumentException("Illegal null EventCallback");
+            throw new IllegalArgumentException("Illegal null MediaPlayer2EventCallback");
         }
         if (executor == null) {
-            throw new IllegalArgumentException("Illegal null Executor for the EventCallback");
+            throw new IllegalArgumentException(
+                    "Illegal null Executor for the MediaPlayer2EventCallback");
         }
         synchronized (mDrmEventCbLock) {
             mDrmEventCallbackRecords.add(new Pair(executor, eventCallback));
@@ -3609,18 +3063,13 @@
     }
 
     /**
-     * Unregisters a {@link DrmEventCallback}.
-     *
-     * @param callback a {@link DrmEventCallback} to unregister
+     * Clears the {@link DrmEventCallback}.
      */
     @Override
-    public void unregisterDrmEventCallback(DrmEventCallback callback) {
+    public void clearDrmEventCallback() {
         synchronized (mDrmEventCbLock) {
             for (Pair<Executor, DrmEventCallback> cb : mDrmEventCallbackRecords) {
-                if (cb.second == callback) {
-                    mDrmEventCallbackRecords.remove(cb);
-                    break;
-                }
+                mDrmEventCallbackRecords.remove(cb);
             }
         }
     }
@@ -3629,7 +3078,7 @@
     /**
      * Retrieves the DRM Info associated with the current source
      *
-     * @throws IllegalStateException if called before prepareAsync()
+     * @throws IllegalStateException if called before prepare()
      */
     @Override
     public DrmInfo getDrmInfo() {
@@ -3680,7 +3129,7 @@
      * @param uuid The UUID of the crypto scheme. If not known beforehand, it can be retrieved
      * from the source through {@code getDrmInfo} or registering a {@code onDrmInfoListener}.
      *
-     * @throws IllegalStateException              if called before prepareAsync(), or the DRM was
+     * @throws IllegalStateException              if called before prepare(), or the DRM was
      *                                            prepared already
      * @throws UnsupportedSchemeException         if the crypto scheme is not supported
      * @throws ResourceBusyException              if required DRM resources are in use
@@ -3735,7 +3184,7 @@
 
             try {
                 // only creating the DRM object to allow pre-openSession configuration
-                prepareDrm_createDrmStep(uuid);
+                prepareDrm(uuid);
             } catch (Exception e) {
                 Log.w(TAG, "prepareDrm(): Exception ", e);
                 mPrepareDrmInProgress = false;
@@ -3748,7 +3197,7 @@
 
         // call the callback outside the lock
         if (mOnDrmConfigHelper != null)  {
-            mOnDrmConfigHelper.onDrmConfig(this);
+            mOnDrmConfigHelper.onDrmConfig(this, mCurrentDSD);
         }
 
         synchronized (mDrmLock) {
@@ -3822,7 +3271,7 @@
             synchronized (mDrmEventCbLock) {
                 for (Pair<Executor, DrmEventCallback> cb : mDrmEventCallbackRecords) {
                     cb.first.execute(() -> cb.second.onDrmPrepared(
-                            this, PREPARE_DRM_STATUS_SUCCESS));
+                            this, mCurrentDSD, PREPARE_DRM_STATUS_SUCCESS));
                 }
             }
         }
@@ -3878,14 +3327,14 @@
      * A key request/response exchange occurs between the app and a license server
      * to obtain or release keys used to decrypt encrypted content.
      * <p>
-     * getKeyRequest() is used to obtain an opaque key request byte array that is
+     * getDrmKeyRequest() is used to obtain an opaque key request byte array that is
      * delivered to the license server.  The opaque key request byte array is returned
      * in KeyRequest.data.  The recommended URL to deliver the key request to is
      * returned in KeyRequest.defaultUrl.
      * <p>
      * After the app has received the key request response from the server,
      * it should deliver to the response to the DRM engine plugin using the method
-     * {@link #provideKeyResponse}.
+     * {@link #provideDrmKeyResponse}.
      *
      * @param keySetId is the key-set identifier of the offline keys being released when keyType is
      * {@link MediaDrm#KEY_TYPE_RELEASE}. It should be set to null for other key requests, when
@@ -3913,19 +3362,19 @@
      */
     @Override
     @NonNull
-    public MediaDrm.KeyRequest getKeyRequest(@Nullable byte[] keySetId, @Nullable byte[] initData,
+    public MediaDrm.KeyRequest getDrmKeyRequest(@Nullable byte[] keySetId, @Nullable byte[] initData,
             @Nullable String mimeType, @MediaDrm.KeyType int keyType,
             @Nullable Map<String, String> optionalParameters)
             throws NoDrmSchemeException
     {
-        Log.v(TAG, "getKeyRequest: " +
+        Log.v(TAG, "getDrmKeyRequest: " +
                 " keySetId: " + keySetId + " initData:" + initData + " mimeType: " + mimeType +
                 " keyType: " + keyType + " optionalParameters: " + optionalParameters);
 
         synchronized (mDrmLock) {
             if (!mActiveDrmScheme) {
-                Log.e(TAG, "getKeyRequest NoDrmSchemeException");
-                throw new NoDrmSchemeExceptionImpl("getKeyRequest: Has to set a DRM scheme first.");
+                Log.e(TAG, "getDrmKeyRequest NoDrmSchemeException");
+                throw new NoDrmSchemeExceptionImpl("getDrmKeyRequest: Has to set a DRM scheme first.");
             }
 
             try {
@@ -3940,16 +3389,16 @@
 
                 MediaDrm.KeyRequest request = mDrmObj.getKeyRequest(scope, initData, mimeType,
                                                               keyType, hmapOptionalParameters);
-                Log.v(TAG, "getKeyRequest:   --> request: " + request);
+                Log.v(TAG, "getDrmKeyRequest:   --> request: " + request);
 
                 return request;
 
             } catch (NotProvisionedException e) {
-                Log.w(TAG, "getKeyRequest NotProvisionedException: " +
+                Log.w(TAG, "getDrmKeyRequest NotProvisionedException: " +
                         "Unexpected. Shouldn't have reached here.");
-                throw new IllegalStateException("getKeyRequest: Unexpected provisioning error.");
+                throw new IllegalStateException("getDrmKeyRequest: Unexpected provisioning error.");
             } catch (Exception e) {
-                Log.w(TAG, "getKeyRequest Exception " + e);
+                Log.w(TAG, "getDrmKeyRequest Exception " + e);
                 throw e;
             }
 
@@ -3959,15 +3408,15 @@
 
     /**
      * A key response is received from the license server by the app, then it is
-     * provided to the DRM engine plugin using provideKeyResponse. When the
+     * provided to the DRM engine plugin using provideDrmKeyResponse. When the
      * response is for an offline key request, a key-set identifier is returned that
      * can be used to later restore the keys to a new session with the method
-     * {@ link # restoreKeys}.
+     * {@ link # restoreDrmKeys}.
      * When the response is for a streaming or release request, null is returned.
      *
      * @param keySetId When the response is for a release request, keySetId identifies
      * the saved key associated with the release request (i.e., the same keySetId
-     * passed to the earlier {@ link # getKeyRequest} call. It MUST be null when the
+     * passed to the earlier {@ link #getDrmKeyRequest} call. It MUST be null when the
      * response is for either streaming or offline key requests.
      *
      * @param response the byte array response from the server
@@ -3977,16 +3426,16 @@
      * server rejected the request
      */
     @Override
-    public byte[] provideKeyResponse(@Nullable byte[] keySetId, @NonNull byte[] response)
+    public byte[] provideDrmKeyResponse(@Nullable byte[] keySetId, @NonNull byte[] response)
             throws NoDrmSchemeException, DeniedByServerException
     {
-        Log.v(TAG, "provideKeyResponse: keySetId: " + keySetId + " response: " + response);
+        Log.v(TAG, "provideDrmKeyResponse: keySetId: " + keySetId + " response: " + response);
 
         synchronized (mDrmLock) {
 
             if (!mActiveDrmScheme) {
-                Log.e(TAG, "getKeyRequest NoDrmSchemeException");
-                throw new NoDrmSchemeExceptionImpl("getKeyRequest: Has to set a DRM scheme first.");
+                Log.e(TAG, "getDrmKeyRequest NoDrmSchemeException");
+                throw new NoDrmSchemeExceptionImpl("getDrmKeyRequest: Has to set a DRM scheme first.");
             }
 
             try {
@@ -3996,19 +3445,19 @@
 
                 byte[] keySetResult = mDrmObj.provideKeyResponse(scope, response);
 
-                Log.v(TAG, "provideKeyResponse: keySetId: " + keySetId + " response: " + response +
+                Log.v(TAG, "provideDrmKeyResponse: keySetId: " + keySetId + " response: " + response +
                         " --> " + keySetResult);
 
 
                 return keySetResult;
 
             } catch (NotProvisionedException e) {
-                Log.w(TAG, "provideKeyResponse NotProvisionedException: " +
+                Log.w(TAG, "provideDrmKeyResponse NotProvisionedException: " +
                         "Unexpected. Shouldn't have reached here.");
-                throw new IllegalStateException("provideKeyResponse: " +
+                throw new IllegalStateException("provideDrmKeyResponse: " +
                         "Unexpected provisioning error.");
             } catch (Exception e) {
-                Log.w(TAG, "provideKeyResponse Exception " + e);
+                Log.w(TAG, "provideDrmKeyResponse Exception " + e);
                 throw e;
             }
         }   // synchronized
@@ -4017,21 +3466,21 @@
 
     /**
      * Restore persisted offline keys into a new session.  keySetId identifies the
-     * keys to load, obtained from a prior call to {@link #provideKeyResponse}.
+     * keys to load, obtained from a prior call to {@link #provideDrmKeyResponse}.
      *
      * @param keySetId identifies the saved key set to restore
      */
     @Override
-    public void restoreKeys(@NonNull byte[] keySetId)
+    public void restoreDrmKeys(@NonNull byte[] keySetId)
             throws NoDrmSchemeException
     {
-        Log.v(TAG, "restoreKeys: keySetId: " + keySetId);
+        Log.v(TAG, "restoreDrmKeys: keySetId: " + keySetId);
 
         synchronized (mDrmLock) {
 
             if (!mActiveDrmScheme) {
-                Log.w(TAG, "restoreKeys NoDrmSchemeException");
-                throw new NoDrmSchemeExceptionImpl("restoreKeys: Has to set a DRM scheme first.");
+                Log.w(TAG, "restoreDrmKeys NoDrmSchemeException");
+                throw new NoDrmSchemeExceptionImpl("restoreDrmKeys: Has to set a DRM scheme first.");
             }
 
             try {
@@ -4315,7 +3764,7 @@
 
         // TODO: don't need an open session for a future specialKeyReleaseDrm mode but we should do
         // it anyway so it raises provisioning error if needed. We'd rather handle provisioning
-        // at prepareDrm/openSession rather than getKeyRequest/provideKeyResponse
+        // at prepareDrm/openSession rather than getDrmKeyRequest/provideDrmKeyResponse
         try {
             mDrmSessionId = mDrmObj.openSession();
             Log.v(TAG, "prepareDrm_openSessionStep: mDrmSessionId=" + mDrmSessionId);
@@ -4490,7 +3939,8 @@
                 // calling the callback outside the lock
                 synchronized (mDrmEventCbLock) {
                     for (Pair<Executor, DrmEventCallback> cb : mDrmEventCallbackRecords) {
-                        cb.first.execute(() -> cb.second.onDrmPrepared(mediaPlayer, status));
+                        cb.first.execute(() -> cb.second.onDrmPrepared(
+                                mediaPlayer, mCurrentDSD, status));
                     }
                 }
             } else {   // blocking mode already has the lock
diff --git a/media/java/android/media/MediaPlayerBase.java b/media/java/android/media/MediaPlayerBase.java
new file mode 100644
index 0000000..3739847
--- /dev/null
+++ b/media/java/android/media/MediaPlayerBase.java
@@ -0,0 +1,308 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+/**
+ * Base class for all media players that want media session.
+ */
+public abstract class MediaPlayerBase implements AutoCloseable {
+    /**
+     * @hide
+     */
+    @IntDef({
+        PLAYER_STATE_IDLE,
+        PLAYER_STATE_PAUSED,
+        PLAYER_STATE_PLAYING,
+        PLAYER_STATE_ERROR })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PlayerState {}
+
+    /**
+     * @hide
+     */
+    @IntDef({
+        BUFFERING_STATE_UNKNOWN,
+        BUFFERING_STATE_BUFFERING_AND_PLAYABLE,
+        BUFFERING_STATE_BUFFERING_AND_STARVED,
+        BUFFERING_STATE_BUFFERING_COMPLETE })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface BuffState {}
+
+    /**
+     * State when the player is idle, and needs configuration to start playback.
+     */
+    public static final int PLAYER_STATE_IDLE = 0;
+
+    /**
+     * State when the player's playback is paused
+     */
+    public static final int PLAYER_STATE_PAUSED = 1;
+
+    /**
+     * State when the player's playback is ongoing
+     */
+    public static final int PLAYER_STATE_PLAYING = 2;
+
+    /**
+     * State when the player is in error state and cannot be recovered self.
+     */
+    public static final int PLAYER_STATE_ERROR = 3;
+
+    /**
+     * Buffering state is unknown.
+     */
+    public static final int BUFFERING_STATE_UNKNOWN = 0;
+
+    /**
+     * Buffering state indicating the player is buffering but enough has been buffered
+     * for this player to be able to play the content.
+     * See {@link #getBufferedPosition()} for how far is buffered already.
+     */
+    public static final int BUFFERING_STATE_BUFFERING_AND_PLAYABLE = 1;
+
+    /**
+     * Buffering state indicating the player is buffering, but the player is currently starved
+     * for data, and cannot play.
+     */
+    public static final int BUFFERING_STATE_BUFFERING_AND_STARVED = 2;
+
+    /**
+     * Buffering state indicating the player is done buffering, and the remainder of the content is
+     * available for playback.
+     */
+    public static final int BUFFERING_STATE_BUFFERING_COMPLETE = 3;
+
+    /**
+     * Starts or resumes playback.
+     */
+    public abstract void play();
+
+    /**
+     * Prepares the player for playback.
+     * See {@link PlayerEventCallback#onMediaPrepared(MediaPlayerBase, DataSourceDesc)} for being
+     * notified when the preparation phase completed. During this time, the player may allocate
+     * resources required to play, such as audio and video decoders.
+     */
+    public abstract void prepare();
+
+    /**
+     * Pauses playback.
+     */
+    public abstract void pause();
+
+    /**
+     *
+     */
+    public abstract void skipToNext();
+
+    /**
+     * Moves the playback head to the specified position
+     * @param pos the new playback position expressed in ms.
+     */
+    public abstract void seekTo(long pos);
+
+    public static final long UNKNOWN_TIME = -1;
+
+    /**
+     * Returns the current playback head position.
+     * @return the current play position in ms, or {@link #UNKNOWN_TIME} if unknown.
+     */
+    public long getCurrentPosition() { return UNKNOWN_TIME; }
+
+    /**
+     * Returns the duration of the current data source, or {@link #UNKNOWN_TIME} if unknown.
+     * @return the duration in ms, or {@link #UNKNOWN_TIME}.
+     */
+    public long getDuration() { return UNKNOWN_TIME; }
+
+    /**
+     * Returns the duration of the current data source, or {@link #UNKNOWN_TIME} if unknown.
+     * @return the duration in ms, or {@link #UNKNOWN_TIME}.
+     */
+    public long getBufferedPosition() { return UNKNOWN_TIME; }
+
+    /**
+     * Returns the current player state.
+     * See also {@link PlayerEventCallback#onPlayerStateChanged(MediaPlayerBase, int)} for
+     * notification of changes.
+     * @return the current player state
+     */
+    public abstract @PlayerState int getPlayerState();
+
+    /**
+     * Returns the current buffering state of the player.
+     * During buffering, see {@link #getBufferedPosition()} for the quantifying the amount already
+     * buffered.
+     * @return the buffering state.
+     */
+    public abstract @BuffState int getBufferingState();
+
+    /**
+     * Sets the {@link AudioAttributes} to be used during the playback of the media.
+     *
+     * @param attributes non-null <code>AudioAttributes</code>.
+     */
+    public abstract void setAudioAttributes(@NonNull AudioAttributes attributes);
+
+    /**
+     * Returns AudioAttributes that media player has.
+     */
+    public abstract @Nullable AudioAttributes getAudioAttributes();
+
+    /**
+     * Sets the data source to be played.
+     * @param dsd
+     */
+    public abstract void setDataSource(@NonNull DataSourceDesc dsd);
+
+    /**
+     * Sets the data source that will be played immediately after the current one is done playing.
+     * @param dsd
+     */
+    public abstract void setNextDataSource(@NonNull DataSourceDesc dsd);
+
+    /**
+     * Sets the list of data sources that will be sequentially played after the current one. Each
+     * data source is played immediately after the previous one is done playing.
+     * @param dsds
+     */
+    public abstract void setNextDataSources(@NonNull List<DataSourceDesc> dsds);
+
+    /**
+     * Returns the current data source.
+     * @return the current data source, or null if none is set, or none available to play.
+     */
+    public abstract @Nullable DataSourceDesc getCurrentDataSource();
+
+    /**
+     * Configures the player to loop on the current data source.
+     * @param loop true if the current data source is meant to loop.
+     */
+    public abstract void loopCurrent(boolean loop);
+
+    /**
+     * Sets the playback speed.
+     * A value of 1.0f is the default playback value.
+     * A negative value indicates reverse playback, check {@link #isReversePlaybackSupported()}
+     * before using negative values.<br>
+     * After changing the playback speed, it is recommended to query the actual speed supported
+     * by the player, see {@link #getPlaybackSpeed()}.
+     * @param speed
+     */
+    public abstract void setPlaybackSpeed(float speed);
+
+    /**
+     * Returns the actual playback speed to be used by the player when playing.
+     * Note that it may differ from the speed set in {@link #setPlaybackSpeed(float)}.
+     * @return the actual playback speed
+     */
+    public float getPlaybackSpeed() { return 1.0f; }
+
+    /**
+     * Indicates whether reverse playback is supported.
+     * Reverse playback is indicated by negative playback speeds, see
+     * {@link #setPlaybackSpeed(float)}.
+     * @return true if reverse playback is supported.
+     */
+    public boolean isReversePlaybackSupported() { return false; }
+
+    /**
+     * Sets the volume of the audio of the media to play, expressed as a linear multiplier
+     * on the audio samples.
+     * Note that this volume is specific to the player, and is separate from stream volume
+     * used across the platform.<br>
+     * A value of 0.0f indicates muting, a value of 1.0f is the nominal unattenuated and unamplified
+     * gain. See {@link #getMaxPlayerVolume()} for the volume range supported by this player.
+     * @param volume a value between 0.0f and {@link #getMaxPlayerVolume()}.
+     */
+    public abstract void setPlayerVolume(float volume);
+
+    /**
+     * Returns the current volume of this player to this player.
+     * Note that it does not take into account the associated stream volume.
+     * @return the player volume.
+     */
+    public abstract float getPlayerVolume();
+
+    /**
+     * @return the maximum volume that can be used in {@link #setPlayerVolume(float)}.
+     */
+    public float getMaxPlayerVolume() { return 1.0f; }
+
+    /**
+     * Adds a callback to be notified of events for this player.
+     * @param e the {@link Executor} to be used for the events.
+     * @param cb the callback to receive the events.
+     */
+    public abstract void registerPlayerEventCallback(@NonNull Executor e,
+            @NonNull PlayerEventCallback cb);
+
+    /**
+     * Removes a previously registered callback for player events
+     * @param cb the callback to remove
+     */
+    public abstract void unregisterPlayerEventCallback(@NonNull PlayerEventCallback cb);
+
+    /**
+     * A callback class to receive notifications for events on the media player.
+     * See {@link MediaPlayerBase#registerPlayerEventCallback(Executor, PlayerEventCallback)} to
+     * register this callback.
+     */
+    public static abstract class PlayerEventCallback {
+        /**
+         * Called when the player's curretn data source has changed.
+         * @param mpb the player whose data source changed.
+         * @param dsd the new current data source.
+         */
+        public void onCurrentDataSourceChanged(@NonNull MediaPlayerBase mpb,
+                @Nullable DataSourceDesc dsd) { }
+        /**
+         * Called when the player is <i>prepared</i>, i.e. it is ready to play the content
+         * referenced by the given data source.
+         * @param mpb the player that is prepared.
+         * @param dsd the data source that the player is prepared to play.
+         */
+        public void onMediaPrepared(@NonNull MediaPlayerBase mpb, @NonNull DataSourceDesc dsd) { }
+
+        /**
+         * Called to indicate that the state of the player has changed.
+         * See {@link MediaPlayerBase#getPlayerState()} for polling the player state.
+         * @param mpb the player whose state has changed.
+         * @param state the new state of the player.
+         */
+        public void onPlayerStateChanged(@NonNull MediaPlayerBase mpb, @PlayerState int state) { }
+
+        /**
+         * Called to report buffering events for a data source.
+         * @param mpb the player that is buffering
+         * @param dsd the data source for which buffering is happening.
+         * @param state the new buffering state.
+         */
+        public void onBufferingStateChanged(@NonNull MediaPlayerBase mpb,
+                @NonNull DataSourceDesc dsd, @BuffState int state) { }
+    }
+
+}
diff --git a/media/java/android/media/MediaPlayerInterface.java b/media/java/android/media/MediaPlayerInterface.java
deleted file mode 100644
index 78e2391..0000000
--- a/media/java/android/media/MediaPlayerInterface.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.media.MediaSession2.PlaylistParams;
-
-import java.util.List;
-import java.util.concurrent.Executor;
-
-/**
- * Base interfaces for all media players that want media session.
- * @hide
- */
-public interface MediaPlayerInterface {
-    /**
-     * Listens change in {@link PlaybackState2}.
-     */
-    interface PlaybackListener {
-        /**
-         * Called when {@link PlaybackState2} for this player is changed.
-         */
-        void onPlaybackChanged(PlaybackState2 state);
-    }
-
-    // Transport controls that session will send command directly to this player.
-    void play();
-    void prepare();
-    void pause();
-    void stop();
-    void skipToPrevious();
-    void skipToNext();
-    void seekTo(long pos);
-    void fastForward();
-    void rewind();
-
-    PlaybackState2 getPlaybackState();
-
-    /**
-     * Sets the {@link AudioAttributes} to be used during the playback of the media.
-     *
-     * @param attributes non-null <code>AudioAttributes</code>.
-     */
-    void setAudioAttributes(@NonNull AudioAttributes attributes);
-
-    /**
-     * Returns AudioAttributes that media player has.
-     */
-    @Nullable
-    AudioAttributes getAudioAttributes();
-
-    void addPlaylistItem(int index, MediaItem2 item);
-    void removePlaylistItem(MediaItem2 item);
-
-    void setPlaylist(List<MediaItem2> playlist);
-    List<MediaItem2> getPlaylist();
-
-    void setCurrentPlaylistItem(int index);
-    void setPlaylistParams(PlaylistParams params);
-    PlaylistParams getPlaylistParams();
-
-    /**
-     * Add a {@link PlaybackListener} to be invoked when the playback state is changed.
-     *
-     * @param executor the Handler that will receive the listener
-     * @param listener the listener that will be run
-     */
-    void addPlaybackListener(Executor executor, PlaybackListener listener);
-
-    /**
-     * Remove previously added {@link PlaybackListener}.
-     *
-     * @param listener the listener to be removed
-     */
-    void removePlaybackListener(PlaybackListener listener);
-}
diff --git a/media/java/android/media/MediaPlaylistController.java b/media/java/android/media/MediaPlaylistController.java
new file mode 100644
index 0000000..c98d50e
--- /dev/null
+++ b/media/java/android/media/MediaPlaylistController.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import android.annotation.NonNull;
+
+import java.util.List;
+
+/**
+ * Controller interface for playlist management.
+ * Playlists are composed of one or multiple {@link MediaItem2} instances, which combine metadata
+ * and data sources (as {@link DataSourceDesc})
+ * Used by {@link MediaSession2} and {@link MediaController2}.
+ */
+ // This class only includes methods that contain {@link MediaItem2}.
+ // Note that setPlaylist() isn't added on purpose because it's considered session-specific.
+
+public interface MediaPlaylistController {
+    void addPlaylistItem(int index, @NonNull MediaItem2 item);
+    void removePlaylistItem(@NonNull MediaItem2 item);
+    MediaItem2 getCurrentPlaylistItem();
+    void skipToPlaylistItem(@NonNull MediaItem2 item);
+    void replacePlaylistItem(int index, @NonNull MediaItem2 item);
+    List<MediaItem2> getPlaylist();
+}
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 9ad5cd9..90b6bff 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -29,6 +29,7 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
+import android.util.Pair;
 import android.view.Surface;
 
 import java.io.File;
@@ -105,6 +106,8 @@
     private OnErrorListener mOnErrorListener;
     private OnInfoListener mOnInfoListener;
 
+    private int mChannelCount;
+
     /**
      * Default constructor.
      */
@@ -119,6 +122,7 @@
             mEventHandler = null;
         }
 
+        mChannelCount = 1;
         String packageName = ActivityThread.currentPackageName();
         /* Native setup requires a weak reference to our object.
          * It's easier to create it here than in C++.
@@ -755,6 +759,7 @@
         if (numChannels <= 0) {
             throw new IllegalArgumentException("Number of channels is not positive");
         }
+        mChannelCount = numChannels;
         setParameter("audio-param-number-of-channels=" + numChannels);
     }
 
@@ -1432,6 +1437,20 @@
             return new ArrayList<MicrophoneInfo>();
         }
         AudioManager.setPortIdForMicrophones(activeMicrophones);
+
+        // Use routed device when there is not information returned by hal.
+        if (activeMicrophones.size() == 0) {
+            AudioDeviceInfo device = getRoutedDevice();
+            if (device != null) {
+                MicrophoneInfo microphone = AudioManager.microphoneInfoFromAudioDeviceInfo(device);
+                ArrayList<Pair<Integer, Integer>> channelMapping = new ArrayList<>();
+                for (int i = 0; i < mChannelCount; i++) {
+                    channelMapping.add(new Pair(i, MicrophoneInfo.CHANNEL_MAPPING_DIRECT));
+                }
+                microphone.setChannelMapping(channelMapping);
+                activeMicrophones.add(microphone);
+            }
+        }
         return activeMicrophones;
     }
 
diff --git a/media/java/android/media/MediaSession2.java b/media/java/android/media/MediaSession2.java
index 0258dca..ae5a8c6 100644
--- a/media/java/android/media/MediaSession2.java
+++ b/media/java/android/media/MediaSession2.java
@@ -20,11 +20,11 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SystemApi;
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
-import android.media.MediaPlayerInterface.PlaybackListener;
+import android.media.MediaPlayerBase.PlayerEventCallback;
+import android.media.MediaPlaylistController;
 import android.media.session.MediaSession;
 import android.media.session.MediaSession.Callback;
 import android.media.session.PlaybackState;
@@ -41,7 +41,6 @@
 import android.os.Handler;
 import android.os.IInterface;
 import android.os.ResultReceiver;
-import android.text.TextUtils;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -71,7 +70,7 @@
  * <p>
  * When a session receive transport control commands, the session sends the commands directly to
  * the the underlying media player set by {@link Builder} or
- * {@link #setPlayer(MediaPlayerInterface)}.
+ * {@link #updatePlayer}.
  * <p>
  * When an app is finished performing playback it must call {@link #close()} to clean up the session
  * and notify any controllers.
@@ -79,16 +78,14 @@
  * {@link MediaSession2} objects should be used on the thread on the looper.
  *
  * @see MediaSessionService2
- * @hide
  */
-public class MediaSession2 implements AutoCloseable {
+public class MediaSession2 implements AutoCloseable, MediaPlaylistController {
     private final MediaSession2Provider mProvider;
 
     // TODO(jaewan): Should we define IntDef? Currently we don't have to allow subclass to add more.
     // TODO(jaewan): Shouldn't we pull out?
     // TODO(jaewan): Should we also protect getters not related with metadata?
-    //               Getters are getRatingType(), getPlaybackState(), getSessionActivity(),
-    //               getPlaylistParams())
+    //               Getters are getPlaybackState(), getSessionActivity(), getPlaylistParams()
     // Next ID: 23
     /**
      * Command code for the custom command which can be defined by string action in the
@@ -121,7 +118,7 @@
     public static final int COMMAND_CODE_PLAYBACK_STOP = 3;
 
     /**
-     * Command code for {@link MediaController2#skipToNext()} ()}.
+     * Command code for {@link MediaController2#skipToNext()}.
      * <p>
      * Command would be sent directly to the player if the session doesn't reject the request
      * through the {@link SessionCallback#onCommandRequest(ControllerInfo, Command)}.
@@ -129,7 +126,7 @@
     public static final int COMMAND_CODE_PLAYBACK_SKIP_NEXT_ITEM = 4;
 
     /**
-     * Command code for {@link MediaController2#skipToPrevious()} ()}.
+     * Command code for {@link MediaController2#skipToPrevious()}.
      * <p>
      * Command would be sent directly to the player if the session doesn't reject the request
      * through the {@link SessionCallback#onCommandRequest(ControllerInfo, Command)}.
@@ -145,7 +142,7 @@
     public static final int COMMAND_CODE_PLAYBACK_PREPARE = 6;
 
     /**
-     * Command code for {@link MediaController2#fastForward()} ()}.
+     * Command code for {@link MediaController2#fastForward()}.
      * <p>
      * This is transport control command. Command would be sent directly to the player if the
      * session doesn't reject the request through the
@@ -162,22 +159,22 @@
     public static final int COMMAND_CODE_PLAYBACK_REWIND = 8;
 
     /**
-     * Command code for {@link MediaController2#seekTo(long)} ()}.
+     * Command code for {@link MediaController2#seekTo(long)}.
      * <p>
      * Command would be sent directly to the player if the session doesn't reject the request
      * through the {@link SessionCallback#onCommandRequest(ControllerInfo, Command)}.
      */
     public static final int COMMAND_CODE_PLAYBACK_SEEK_TO = 9;
     /**
-     * Command code for {@link MediaController2#setCurrentPlaylistItem(int)} ()}.
+     * Command code for {@link MediaController2#skipToPlaylistItem(MediaItem2)}.
      * <p>
      * Command would be sent directly to the player if the session doesn't reject the request
      * through the {@link SessionCallback#onCommandRequest(ControllerInfo, Command)}.
      */
-    public static final int COMMAND_CODE_PLAYBACK_SET_CURRENT_PLAYLIST_ITEM = 10;
+    public static final int COMMAND_CODE_PLAYBACK_SKIP_TO_PLAYLIST_ITEM = 10;
 
     /**
-     * Command code for {@link MediaController2#setPlaylistParams(PlaylistParams)} ()}.
+     * Command code for {@link MediaController2#setPlaylistParams(PlaylistParams)}.
      * <p>
      * Command would be sent directly to the player if the session doesn't reject the request
      * through the {@link SessionCallback#onCommandRequest(ControllerInfo, Command)}.
@@ -224,7 +221,7 @@
     public static final int COMMAND_CODE_PLAY_FROM_MEDIA_ID = 16;
 
     /**
-     * Command code for {@link MediaController2#playFromUri(String, Bundle)}.
+     * Command code for {@link MediaController2#playFromUri(Uri, Bundle)}.
      */
     public static final int COMMAND_CODE_PLAY_FROM_URI = 17;
 
@@ -258,6 +255,84 @@
     public static final int COMMAND_CODE_BROWSER = 22;
 
     /**
+     * @hide
+     */
+    @IntDef({ERROR_CODE_UNKNOWN_ERROR, ERROR_CODE_APP_ERROR, ERROR_CODE_NOT_SUPPORTED,
+            ERROR_CODE_AUTHENTICATION_EXPIRED, ERROR_CODE_PREMIUM_ACCOUNT_REQUIRED,
+            ERROR_CODE_CONCURRENT_STREAM_LIMIT, ERROR_CODE_PARENTAL_CONTROL_RESTRICTED,
+            ERROR_CODE_NOT_AVAILABLE_IN_REGION, ERROR_CODE_CONTENT_ALREADY_PLAYING,
+            ERROR_CODE_SKIP_LIMIT_REACHED, ERROR_CODE_ACTION_ABORTED, ERROR_CODE_END_OF_QUEUE,
+            ERROR_CODE_SETUP_REQUIRED})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ErrorCode {}
+
+    /**
+     * This is the default error code and indicates that none of the other error codes applies.
+     */
+    public static final int ERROR_CODE_UNKNOWN_ERROR = 0;
+
+    /**
+     * Error code when the application state is invalid to fulfill the request.
+     */
+    public static final int ERROR_CODE_APP_ERROR = 1;
+
+    /**
+     * Error code when the request is not supported by the application.
+     */
+    public static final int ERROR_CODE_NOT_SUPPORTED = 2;
+
+    /**
+     * Error code when the request cannot be performed because authentication has expired.
+     */
+    public static final int ERROR_CODE_AUTHENTICATION_EXPIRED = 3;
+
+    /**
+     * Error code when a premium account is required for the request to succeed.
+     */
+    public static final int ERROR_CODE_PREMIUM_ACCOUNT_REQUIRED = 4;
+
+    /**
+     * Error code when too many concurrent streams are detected.
+     */
+    public static final int ERROR_CODE_CONCURRENT_STREAM_LIMIT = 5;
+
+    /**
+     * Error code when the content is blocked due to parental controls.
+     */
+    public static final int ERROR_CODE_PARENTAL_CONTROL_RESTRICTED = 6;
+
+    /**
+     * Error code when the content is blocked due to being regionally unavailable.
+     */
+    public static final int ERROR_CODE_NOT_AVAILABLE_IN_REGION = 7;
+
+    /**
+     * Error code when the requested content is already playing.
+     */
+    public static final int ERROR_CODE_CONTENT_ALREADY_PLAYING = 8;
+
+    /**
+     * Error code when the application cannot skip any more songs because skip limit is reached.
+     */
+    public static final int ERROR_CODE_SKIP_LIMIT_REACHED = 9;
+
+    /**
+     * Error code when the action is interrupted due to some external event.
+     */
+    public static final int ERROR_CODE_ACTION_ABORTED = 10;
+
+    /**
+     * Error code when the playback navigation (previous, next) is not possible because the queue
+     * was exhausted.
+     */
+    public static final int ERROR_CODE_END_OF_QUEUE = 11;
+
+    /**
+     * Error code when the session needs user's manual intervention.
+     */
+    public static final int ERROR_CODE_SETUP_REQUIRED = 12;
+
+    /**
      * Define a command that a {@link MediaController2} can send to a {@link MediaSession2}.
      * <p>
      * If {@link #getCommandCode()} isn't {@link #COMMAND_CODE_CUSTOM}), it's predefined command.
@@ -273,12 +348,12 @@
                     .createMediaSession2Command(this, commandCode, null, null);
         }
 
-        public Command(@NonNull Context context, @NonNull String action, @Nullable Bundle extra) {
+        public Command(@NonNull Context context, @NonNull String action, @Nullable Bundle extras) {
             if (action == null) {
                 throw new IllegalArgumentException("action shouldn't be null");
             }
             mProvider = ApiLoader.getProvider(context)
-                    .createMediaSession2Command(this, COMMAND_CODE_CUSTOM, action, extra);
+                    .createMediaSession2Command(this, COMMAND_CODE_CUSTOM, action, extras);
         }
 
         public int getCommandCode() {
@@ -289,8 +364,8 @@
             return mProvider.getCustomCommand_impl();
         }
 
-        public @Nullable Bundle getExtra() {
-            return mProvider.getExtra_impl();
+        public @Nullable Bundle getExtras() {
+            return mProvider.getExtras_impl();
         }
 
         /**
@@ -326,7 +401,7 @@
     /**
      * Represent set of {@link Command}.
      */
-    public static class CommandGroup {
+    public static final class CommandGroup {
         private final CommandGroupProvider mProvider;
 
         public CommandGroup(Context context) {
@@ -359,10 +434,14 @@
             return mProvider.hasCommand_impl(code);
         }
 
+        public List<Command> getCommands() {
+            // TODO: implement this
+            return null;
+        }
+
         /**
          * @hide
          */
-        @SystemApi
         public CommandGroupProvider getProvider() {
             return mProvider;
         }
@@ -392,7 +471,7 @@
      * default.
      */
     // TODO(jaewan): Can we move this inside of the updatable for default implementation.
-    public static class SessionCallback {
+    public static abstract class SessionCallback {
         private final Context mContext;
 
         public SessionCallback(Context context) {
@@ -439,7 +518,7 @@
          * @see #COMMAND_CODE_PLAYBACK_FAST_FORWARD
          * @see #COMMAND_CODE_PLAYBACK_REWIND
          * @see #COMMAND_CODE_PLAYBACK_SEEK_TO
-         * @see #COMMAND_CODE_PLAYBACK_SET_CURRENT_PLAYLIST_ITEM
+         * @see #COMMAND_CODE_PLAYBACK_SKIP_TO_PLAYLIST_ITEM
          * @see #COMMAND_CODE_PLAYBACK_SET_PLAYLIST_PARAMS
          * @see #COMMAND_CODE_PLAYLIST_ADD
          * @see #COMMAND_CODE_PLAYLIST_REMOVE
@@ -454,6 +533,11 @@
         /**
          * Called when a controller set rating of a media item through
          * {@link MediaController2#setRating(String, Rating2)}.
+         * <p>
+         * To allow setting user rating for a {@link MediaItem2}, the media item's metadata
+         * should have {@link Rating2} with the key {@link MediaMetadata#METADATA_KEY_USER_RATING},
+         * in order to provide possible rating style for controller. Controller will follow the
+         * rating style.
          *
          * @param controller controller information
          * @param mediaId media id from the controller
@@ -584,7 +668,7 @@
     /**
      * Base builder class for MediaSession2 and its subclass. Any change in this class should be
      * also applied to the subclasses {@link MediaSession2.Builder} and
-     * {@link MediaLibraryService2.MediaLibrarySessionBuilder}.
+     * {@link MediaLibraryService2.MediaLibrarySession.Builder}.
      * <p>
      * APIs here should be package private, but should have documentations for developers.
      * Otherwise, javadoc will generate documentation with the generic types such as follows.
@@ -607,34 +691,38 @@
         }
 
         /**
-         * Set volume provider to configure this session to use remote volume handling.
-         * This must be called to receive volume button events, otherwise the system
-         * will adjust the appropriate stream volume for this session's player.
+         * Set the underlying {@link MediaPlayerBase} for this session to dispatch incoming event
+         * to.
          * <p>
-         * Set {@code null} to reset.
          *
-         * @param volumeProvider The provider that will handle volume changes. Can be {@code null}.
+         * @param player a {@link MediaPlayerBase} that handles actual media playback in your app.
          */
-        U setVolumeProvider(@Nullable VolumeProvider2 volumeProvider) {
-            mProvider.setVolumeProvider_impl(volumeProvider);
+        U setPlayer(@NonNull MediaPlayerBase player) {
+            // TODO: Change the provider properly
+            mProvider.setPlayer_impl(player, null, null);
             return (U) this;
         }
 
         /**
-         * Set the style of rating used by this session. Apps trying to set the
-         * rating should use this style. Must be one of the following:
-         * <ul>
-         * <li>{@link Rating2#RATING_NONE}</li>
-         * <li>{@link Rating2#RATING_3_STARS}</li>
-         * <li>{@link Rating2#RATING_4_STARS}</li>
-         * <li>{@link Rating2#RATING_5_STARS}</li>
-         * <li>{@link Rating2#RATING_HEART}</li>
-         * <li>{@link Rating2#RATING_PERCENTAGE}</li>
-         * <li>{@link Rating2#RATING_THUMB_UP_DOWN}</li>
-         * </ul>
+         * Set the {@link MediaPlaylistController} for this session to manages playlist of the
+         * underlying {@link MediaPlayerBase player}.
+         *
+         * @param mplc a {@link MediaPlaylistController} that manages playlist of the
+         * {@code player.}
          */
-        U setRatingType(@Rating2.Style int type) {
-            mProvider.setRatingType_impl(type);
+        U setPlaylistController(@NonNull MediaPlaylistController mplc) {
+            // TODO: implement this
+            return (U) this;
+        }
+
+        /**
+         * Set the {@link VolumeProvider2} for this session to receive volume button events. If not
+         * set, system will adjust the appropriate stream volume for this session's player.
+         *
+         * @param volumeProvider The provider that will receive volume button events.
+         */
+        U setVolumeProvider(@NonNull VolumeProvider2 volumeProvider) {
+            // TODO: implement this
             return (U) this;
         }
 
@@ -699,22 +787,36 @@
     // Override all methods just to show them with the type instead of generics in Javadoc.
     // This workarounds javadoc issue described in the MediaSession2.BuilderBase.
     public static final class Builder extends BuilderBase<MediaSession2, Builder, SessionCallback> {
-        public Builder(Context context, @NonNull MediaPlayerInterface player) {
+        public Builder(Context context) {
             super((instance) -> ApiLoader.getProvider(context).createMediaSession2Builder(
-                    context, (Builder) instance, player));
+                    context, (Builder) instance));
         }
 
         @Override
-        public Builder setVolumeProvider(@Nullable VolumeProvider2 volumeProvider) {
+        public Builder setPlayer(@NonNull MediaPlayerBase player) {
+            if (player == null) {
+                throw new IllegalArgumentException("Illegal null MediaPlayerBase");
+            }
+            return super.setPlayer(player);
+        }
+
+        @Override
+        public Builder setPlaylistController(@NonNull MediaPlaylistController mplc) {
+            if (mplc == null) {
+                throw new IllegalArgumentException("Illegal null MediaPlaylistController");
+            }
+            return super.setPlaylistController(mplc);
+        }
+
+        @Override
+        public Builder setVolumeProvider(@NonNull VolumeProvider2 volumeProvider) {
+            if (volumeProvider == null) {
+                throw new IllegalArgumentException("Illegal null VolumeProvider2");
+            }
             return super.setVolumeProvider(volumeProvider);
         }
 
         @Override
-        public Builder setRatingType(@Rating2.Style int type) {
-            return super.setRatingType(type);
-        }
-
-        @Override
         public Builder setSessionActivity(@Nullable PendingIntent pi) {
             return super.setSessionActivity(pi);
         }
@@ -745,7 +847,6 @@
         /**
          * @hide
          */
-        // TODO(jaewan): SystemApi
         // TODO(jaewan): Also accept componentName to check notificaiton listener.
         public ControllerInfo(Context context, int uid, int pid, String packageName,
                 IInterface callback) {
@@ -782,7 +883,6 @@
         /**
          * @hide
          */
-        @SystemApi
         public ControllerInfoProvider getProvider() {
             return mProvider;
         }
@@ -814,13 +914,12 @@
      * <p>
      * It's up to the controller's decision to respect or ignore this customization request.
      */
-    public static class CommandButton {
+    public static final class CommandButton {
         private final CommandButtonProvider mProvider;
 
         /**
          * @hide
          */
-        @SystemApi
         public CommandButton(CommandButtonProvider provider) {
             mProvider = provider;
         }
@@ -860,8 +959,8 @@
          *
          * @return
          */
-        public @Nullable Bundle getExtra() {
-            return mProvider.getExtra_impl();
+        public @Nullable Bundle getExtras() {
+            return mProvider.getExtras_impl();
         }
 
         /**
@@ -876,7 +975,6 @@
         /**
          * @hide
          */
-        @SystemApi
         public CommandButtonProvider getProvider() {
             return mProvider;
         }
@@ -884,7 +982,7 @@
         /**
          * Builder for {@link CommandButton}.
          */
-        public static class Builder {
+        public static final class Builder {
             private final CommandButtonProvider.BuilderProvider mProvider;
 
             public Builder(@NonNull Context context) {
@@ -908,8 +1006,8 @@
                 return mProvider.setEnabled_impl(enabled);
             }
 
-            public Builder setExtra(Bundle extra) {
-                return mProvider.setExtra_impl(extra);
+            public Builder setExtras(Bundle extras) {
+                return mProvider.setExtras_impl(extras);
             }
 
             public CommandButton build() {
@@ -1058,7 +1156,6 @@
      *       framework had to add heuristics to figure out if an app is
      * @hide
      */
-    @SystemApi
     public MediaSession2(MediaSession2Provider provider) {
         super();
         mProvider = provider;
@@ -1067,40 +1164,25 @@
     /**
      * @hide
      */
-    @SystemApi
     public MediaSession2Provider getProvider() {
         return mProvider;
     }
 
     /**
-     * Set the underlying {@link MediaPlayerInterface} for this session to dispatch incoming event
+     * Set the underlying {@link MediaPlayerBase} for this session to dispatch incoming event
      * to. Events from the {@link MediaController2} will be sent directly to the underlying
      * player on the {@link Handler} where the session is created on.
-     * <p>
-     * If the new player is successfully set, {@link PlaybackListener}
-     * will be called to tell the current playback state of the new player.
-     * <p>
-     * For the remote playback case which you want to handle volume by yourself, use
-     * {@link #setPlayer(MediaPlayerInterface, VolumeProvider2)}.
      *
-     * @param player a {@link MediaPlayerInterface} that handles actual media playback in your app.
-     * @throws IllegalArgumentException if the player is {@code null}.
+     * @param player a {@link MediaPlayerBase} that handles actual media playback in your app.
+     * @param mplc a {@link MediaPlaylistController} that manages playlist of the
+     * {@code player.}
+     * @param volumeProvider The provider that will receive volume button events. If
+     * {@code null}, system will adjust the appropriate stream volume for this session's player.
      */
-    public void setPlayer(@NonNull MediaPlayerInterface player) {
-        mProvider.setPlayer_impl(player);
-    }
-
-    /**
-     * Set the underlying {@link MediaPlayerInterface} with the volume provider for remote playback.
-     *
-     * @param player a {@link MediaPlayerInterface} that handles actual media playback in your app.
-     * @param volumeProvider a volume provider
-     * @see #setPlayer(MediaPlayerInterface)
-     * @see Builder#setVolumeProvider(VolumeProvider2)
-     */
-    public void setPlayer(@NonNull MediaPlayerInterface player,
-            @NonNull VolumeProvider2 volumeProvider) {
-        mProvider.setPlayer_impl(player, volumeProvider);
+    public void updatePlayer(@NonNull MediaPlayerBase player,
+            @Nullable MediaPlaylistController mplc, @NonNull VolumeProvider2 volumeProvider) {
+        // TODO: rename setPlayer_impl to updatePlayer_impl
+        mProvider.setPlayer_impl(player, mplc, volumeProvider);
     }
 
     @Override
@@ -1112,11 +1194,29 @@
      * @return player
      */
     public @Nullable
-    MediaPlayerInterface getPlayer() {
+    MediaPlayerBase getPlayer() {
         return mProvider.getPlayer_impl();
     }
 
     /**
+     * @return playlist controller
+     */
+    public @Nullable
+    MediaPlaylistController getMediaPlaylistController() {
+        // TODO: implement this
+        return null;
+    }
+
+    /**
+     * @return volume provider
+     */
+    public @Nullable
+    VolumeProvider2 getVolumeProvider() {
+     // TODO: implement this
+        return null;
+    }
+
+    /**
      * Returns the {@link SessionToken2} for creating {@link MediaController2}.
      */
     public @NonNull
@@ -1129,22 +1229,13 @@
     }
 
     /**
-     * Sets which type of audio focus will be requested during the playback, or configures playback
-     * to not request audio focus. Valid values for focus requests are
-     * {@link AudioManager#AUDIOFOCUS_GAIN}, {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT},
-     * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK}, and
-     * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}. Or use
-     * {@link AudioManager#AUDIOFOCUS_NONE} to express that audio focus should not be
-     * requested when playback starts. You can for instance use this when playing a silent animation
-     * through this class, and you don't want to affect other audio applications playing in the
-     * background.
+     * Set the {@link AudioFocusRequest} to obtain the audio focus
      *
-     * @param focusGain the type of audio focus gain that will be requested, or
-     *                  {@link AudioManager#AUDIOFOCUS_NONE} to disable the use audio focus during
-     *                  playback.
+     * @param afr the full request parameters
      */
-    public void setAudioFocusRequest(int focusGain) {
-        mProvider.setAudioFocusRequest_impl(focusGain);
+    public void setAudioFocusRequest(AudioFocusRequest afr) {
+        // TODO: implement this
+        // mProvider.setAudioFocusRequest_impl(focusGain);
     }
 
     /**
@@ -1183,14 +1274,6 @@
     }
 
     /**
-     * Notify changes in metadata of previously set playlist. Controller will get the whole set of
-     * playlist again.
-     */
-    public void notifyMetadataChanged() {
-        mProvider.notifyMetadataChanged_impl();
-    }
-
-    /**
      * Send custom command to all connected controllers.
      *
      * @param command a command
@@ -1283,14 +1366,14 @@
     }
 
     /**
-     * Sets the index of current DataSourceDesc in the play list to be played.
+     * Skip to the item in the play list.
      *
-     * @param index the index of DataSourceDesc in the play list you want to play
+     * @param item item in the play list you want to play
      * @throws IllegalArgumentException if the play list is null
      * @throws NullPointerException if index is outside play list range
      */
-    public void setCurrentPlaylistItem(int index) {
-        mProvider.setCurrentPlaylistItem_impl(index);
+    public void skipToPlaylistItem(MediaItem2 item) {
+        mProvider.skipToPlaylistItem_impl(item);
     }
 
     /**
@@ -1308,7 +1391,7 @@
     }
 
     /**
-     * Sets a list of {@link MediaItem2} as the current play list.
+     * Set a list of {@link MediaItem2} as the current play list.
      *
      * @param playlist A list of {@link MediaItem2} objects to set as a play list.
      * @throws IllegalArgumentException if given {@param playlist} is null.
@@ -1318,13 +1401,66 @@
     }
 
     /**
-     * Returns the playlist which is lastly set.
+     * Remove the media item in the play list.
+     * <p>
+     * If the item is the currently playing item of the playlist, current playback
+     * will be stopped and playback moves to next source in the list.
+     *
+     * @throws IllegalArgumentException if the play list is null
      */
+    // TODO(jaewan): Remove with index was previously rejected by council (b/36524925)
+    // TODO(jaewan): Should we also add movePlaylistItem from index to index?
+    public void removePlaylistItem(MediaItem2 item) {
+        mProvider.removePlaylistItem_impl(item);
+    }
+
+    /**
+     * Add the media item to the play list at position index.
+     * <p>
+     * This will not change the currently playing media item.
+     * If index is less than or equal to the current index of the play list,
+     * the current index of the play list will be incremented correspondingly.
+     *
+     * @param index the index you want to add
+     * @param item the media item you want to add
+     * @throws IndexOutOfBoundsException if index is outside play list range
+     */
+    @Override
+    public void addPlaylistItem(int index, @NonNull MediaItem2 item) {
+        mProvider.addPlaylistItem_impl(index, item);
+    }
+
+    /**
+     * Replace the media item at index in the playlist.
+     * @param index the index of the item to replace
+     * @param item the new item
+     */
+    @Override
+    public void replacePlaylistItem(int index, @NonNull MediaItem2 item) {
+        mProvider.replacePlaylistItem_impl(index, item);
+    }
+
+    /**
+     * Return the playlist which is lastly set.
+     *
+     * @return playlist
+     */
+    @Override
     public List<MediaItem2> getPlaylist() {
         return mProvider.getPlaylist_impl();
     }
 
     /**
+     * Return currently playing media item.
+     *
+     * @return currently playing media item
+     */
+    @Override
+    public MediaItem2 getCurrentPlaylistItem() {
+        return mProvider.getCurrentPlaylistItem_impl();
+    }
+
+    /**
      * Sets the {@link PlaylistParams} for the current play list. Repeat/shuffle mode and metadata
      * for the list can be set by calling this method.
      *
@@ -1343,37 +1479,69 @@
         return mProvider.getPlaylistParams_impl();
     }
 
-    /*
-     * Add a {@link PlaybackListener} to listen changes in the underlying
-     * {@link MediaPlayerInterface}. Listener will be called immediately to tell the current value.
-     * <p>
-     * Added listeners will be also called when the underlying player is changed.
+    /**
+     * Notify errors to the connected controllers
      *
-     * @param executor the call listener
-     * @param listener the listener that will be run
-     * @throws IllegalArgumentException when either the listener or handler is {@code null}.
+     * @param errorCode error code
+     * @param extras extras
      */
-    public void addPlaybackListener(@NonNull @CallbackExecutor Executor executor,
-            @NonNull PlaybackListener listener) {
-        mProvider.addPlaybackListener_impl(executor, listener);
+    public void notifyError(@ErrorCode int errorCode, @Nullable Bundle extras) {
+        mProvider.notifyError_impl(errorCode, extras);
     }
 
     /**
-     * Remove previously added {@link PlaybackListener}.
+     * Register {@link EventCallback} to listen changes in the underlying
+     * {@link MediaPlayerBase}, regardless of the change in the underlying player.
+     * <p>
+     * Registered callbacks will be also called when the underlying player is changed.
      *
-     * @param listener the listener to be removed
-     * @throws IllegalArgumentException if the listener is {@code null}.
+     * @param executor a callback Executor
+     * @param callback a EventCallback
+     * @throws IllegalArgumentException if executor or callback is {@code null}.
+     * @hide
      */
-    public void removePlaybackListener(@NonNull PlaybackListener listener) {
-        mProvider.removePlaybackListener_impl(listener);
+    // TODO(jaewan): Unhide or remove
+    public void registerPlayerEventCallback(@NonNull @CallbackExecutor Executor executor,
+            @NonNull PlayerEventCallback callback) {
+        mProvider.registerPlayerEventCallback_impl(executor, callback);
+    }
+
+    /**
+     * Unregister the previously registered {@link EventCallback}.
+     *
+     * @param callback the callback to be removed
+     * @throws IllegalArgumentException if the callback is {@code null}.
+     * @hide
+     */
+    // TODO(jaewan): Unhide or remove
+    public void unregisterPlayerEventCallback(@NonNull PlayerEventCallback callback) {
+        mProvider.unregisterPlayerEventCallback_impl(callback);
     }
 
     /**
      * Return the {@link PlaybackState2} from the player.
      *
      * @return playback state
+     * @hide
      */
     public PlaybackState2 getPlaybackState() {
         return mProvider.getPlaybackState_impl();
     }
+
+    /**
+     * Get the playback speed.
+     *
+     * @return speed
+     */
+    public float getPlaybackSpeed() {
+        // TODO: implement this
+        return -1;
+    }
+
+    /**
+     * Set the playback speed.
+     */
+    public void setPlaybackSpeed(float speed) {
+        // TODO: implement this
+    }
 }
diff --git a/media/java/android/media/MediaSessionService2.java b/media/java/android/media/MediaSessionService2.java
index 0b5dddf..56e8e5d 100644
--- a/media/java/android/media/MediaSessionService2.java
+++ b/media/java/android/media/MediaSessionService2.java
@@ -90,7 +90,7 @@
  * rejected, the controller will unbind. If it's accepted, the controller will be available to use
  * and keep binding.
  * <p>
- * When playback is started for this session service, {@link #onUpdateNotification(PlaybackState2)}
+ * When playback is started for this session service, {@link #onUpdateNotification()}
  * is called and service would become a foreground service. It's needed to keep playback after the
  * controller is destroyed. The session service becomes background service when the playback is
  * stopped.
@@ -100,7 +100,6 @@
  * Any app can bind to the session service with controller, but the controller can be used only if
  * the session service accepted the connection request through
  * {@link MediaSession2.SessionCallback#onConnect(ControllerInfo)}.
- * @hide
  */
 public abstract class MediaSessionService2 extends Service {
     private final MediaSessionService2Provider mProvider;
@@ -158,17 +157,16 @@
     public @NonNull abstract MediaSession2 onCreateSession(String sessionId);
 
     /**
-     * Called when the playback state of this session is changed, and notification needs update.
-     * Override this method to show your own notification UI.
+     * Called when the playback state of this session is changed so notification needs update.
+     * Override this method to show or cancel your own notification UI.
      * <p>
      * With the notification returned here, the service become foreground service when the playback
      * is started. It becomes background service after the playback is stopped.
      *
-     * @param state playback state
      * @return a {@link MediaNotification}. If it's {@code null}, notification wouldn't be shown.
      */
-    public MediaNotification onUpdateNotification(PlaybackState2 state) {
-        return mProvider.onUpdateNotification_impl(state);
+    public MediaNotification onUpdateNotification() {
+        return mProvider.onUpdateNotification_impl();
     }
 
     /**
@@ -201,9 +199,9 @@
     }
 
     /**
-     * Returned by {@link #onUpdateNotification(PlaybackState2)} for making session service
-     * foreground service to keep playback running in the background. It's highly recommended to
-     * show media style notification here.
+     * Returned by {@link #onUpdateNotification()} for making session service forground service
+     * to keep playback running in the background. It's highly recommended to show media style
+     * notification here.
      */
     public static class MediaNotification {
         private final MediaNotificationProvider mProvider;
diff --git a/media/java/android/media/MicrophoneInfo.java b/media/java/android/media/MicrophoneInfo.java
index 131e37b..004efea 100644
--- a/media/java/android/media/MicrophoneInfo.java
+++ b/media/java/android/media/MicrophoneInfo.java
@@ -92,6 +92,38 @@
      */
     public static final int CHANNEL_MAPPING_PROCESSED = 2;
 
+    /**
+     * Value used for when the group of the microphone is unknown.
+     */
+    public static final int GROUP_UNKNOWN = -1;
+
+    /**
+     * Value used for when the index in the group of the microphone is unknown.
+     */
+    public static final int INDEX_IN_THE_GROUP_UNKNOWN = -1;
+
+    /**
+     * Value used for when the position of the microphone is unknown.
+     */
+    public static final Coordinate3F POSITION_UNKNOWN = new Coordinate3F(
+            -Float.MAX_VALUE, -Float.MAX_VALUE, -Float.MAX_VALUE);
+
+    /**
+     * Value used for when the orientation of the microphone is unknown.
+     */
+    public static final Coordinate3F ORIENTATION_UNKNOWN = new Coordinate3F(0.0f, 0.0f, 0.0f);
+
+    /**
+     * Value used for when the sensitivity of the microphone is unknown.
+     */
+    public static final float SENSITIVITY_UNKNOWN = -Float.MAX_VALUE;
+
+    /**
+     * Value used for when the SPL of the microphone is unknown. This value could be used when
+     * maximum SPL or minimum SPL is unknown.
+     */
+    public static final float SPL_UNKNOWN = -Float.MAX_VALUE;
+
     /** @hide */
     @IntDef(flag = true, prefix = { "LOCATION_" }, value = {
             LOCATION_UNKNOWN,
@@ -216,7 +248,7 @@
      * Returns A device group id that can be used to group together microphones on the same
      * peripheral, attachments or logical groups. Main body is usually group 0.
      *
-     * @return the group of the microphone
+     * @return the group of the microphone or {@link #GROUP_UNKNOWN} if the group is unknown
      */
     public int getGroup() {
         return mGroup;
@@ -225,7 +257,8 @@
     /**
      * Returns unique index for device within its group.
      *
-     * @return the microphone's index in its group
+     * @return the microphone's index in its group or {@link #INDEX_IN_THE_GROUP_UNKNOWN} if the
+     * index in the group is unknown
      */
     public int getIndexInTheGroup() {
         return mIndexInTheGroup;
@@ -233,10 +266,11 @@
 
     /**
      * Returns A {@link Coordinate3F} object that represents the geometric location of microphone
-     * in meters, from botton-left-back corner of appliance. X-axis, Y-axis and Z-axis show
+     * in meters, from bottom-left-back corner of appliance. X-axis, Y-axis and Z-axis show
      * as the x, y, z values.
      *
-     * @return the geometric location of the microphone
+     * @return the geometric location of the microphone or {@link #POSITION_UNKNOWN} if the
+     * geometric location is unknown
      */
     public Coordinate3F getPosition() {
         return mPosition;
@@ -247,7 +281,8 @@
      * X-axis, Y-axis and Z-axis show as the x, y, z value. The orientation will be normalized
      * such as sqrt(x^2 + y^2 + z^2) equals 1.
      *
-     * @return the orientation of the microphone
+     * @return the orientation of the microphone or {@link #ORIENTATION_UNKNOWN} if orientation
+     * is unknown
      */
     public Coordinate3F getOrientation() {
         return mOrientation;
@@ -283,7 +318,8 @@
     /**
      * Returns the level in dBFS produced by a 1000Hz tone at 94 dB SPL.
      *
-     * @return the sensitivity of the microphone
+     * @return the sensitivity of the microphone or {@link #SENSITIVITY_UNKNOWN} if the sensitivity
+     * is unknown
      */
     public float getSensitivity() {
         return mSensitivity;
@@ -292,7 +328,7 @@
     /**
      * Returns the level in dB of the maximum SPL supported by the device at 1000Hz.
      *
-     * @return the maximum level in dB
+     * @return the maximum level in dB or {@link #SPL_UNKNOWN} if maximum SPL is unknown
      */
     public float getMaxSpl() {
         return mMaxSpl;
@@ -301,7 +337,7 @@
     /**
      * Returns the level in dB of the minimum SPL that can be registered by the device at 1000Hz.
      *
-     * @return the minimum level in dB
+     * @return the minimum level in dB or {@link #SPL_UNKNOWN} if minimum SPL is unknown
      */
     public float getMinSpl() {
         return mMinSpl;
@@ -327,8 +363,16 @@
         mPortId = portId;
     }
 
+    /**
+     * Set the channel mapping for the device.
+     * @hide
+     */
+    public void setChannelMapping(List<Pair<Integer, Integer>> channelMapping) {
+        mChannelMapping = channelMapping;
+    }
+
     /* A class containing three float value to represent a 3D coordinate */
-    public class Coordinate3F {
+    public static final class Coordinate3F {
         public final float x;
         public final float y;
         public final float z;
@@ -338,5 +382,17 @@
             this.y = y;
             this.z = z;
         }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (!(obj instanceof Coordinate3F)) {
+                return false;
+            }
+            Coordinate3F other = (Coordinate3F) obj;
+            return this.x == other.x && this.y == other.y && this.z == other.z;
+        }
     }
 }
diff --git a/media/java/android/media/PlaybackState2.java b/media/java/android/media/PlaybackState2.java
index 627974a..7afb579 100644
--- a/media/java/android/media/PlaybackState2.java
+++ b/media/java/android/media/PlaybackState2.java
@@ -28,13 +28,14 @@
 import java.lang.annotation.RetentionPolicy;
 
 /**
- * Playback state for a {@link MediaPlayerInterface}, to be shared between {@link MediaSession2} and
+ * Playback state for a {@link MediaPlayerBase}, to be shared between {@link MediaSession2} and
  * {@link MediaController2}. This includes a playback state {@link #STATE_PLAYING},
  * the current playback position and extra.
  * @hide
  */
+// TODO(jaewan): Remove this.
 public final class PlaybackState2 {
-    // Similar to the PlaybackState2 with following changes
+    // Similar to the PlaybackState with following changes
     //    - Not implement Parcelable and added from/toBundle()
     //    - Removed playback state that doesn't match with the MediaPlayer2
     //      Full list should be finalized when the MediaPlayer2 has getter for the playback state.
@@ -73,6 +74,7 @@
     //         |    EventCallback.onBufferingUpdate()   |                                        |
     //         +----------------------------------------+----------------------------------------+
     //    - Removed actions and custom actions.
+    //    - Removed error string
     //    - Repeat mode / shuffle mode is now in the PlaylistParams
     // TODO(jaewan): Replace states from MediaPlayer2
     /**
@@ -110,8 +112,7 @@
     public final static int STATE_BUFFERING = 4;
 
     /**
-     * State indicating this item is currently in an error state. The error
-     * message should also be set when entering this state.
+     * State indicating this item is currently in an error state.
      */
     public final static int STATE_ERROR = 5;
 
@@ -122,13 +123,10 @@
 
     private final PlaybackState2Provider mProvider;
 
-    // TODO(jaewan): Better error handling?
-    //               E.g. media item at #2 has issue, but continue playing #3
-    //                    login error. fire intent xxx to login
     public PlaybackState2(@NonNull Context context, int state, long position, long updateTime,
-            float speed, long bufferedPosition, long activeItemId, CharSequence error) {
+            float speed, long bufferedPosition, long activeItemId) {
         mProvider = ApiLoader.getProvider(context).createPlaybackState2(context, this, state,
-                position, updateTime, speed, bufferedPosition, activeItemId, error);
+                position, updateTime, speed, bufferedPosition, activeItemId);
     }
 
     @Override
@@ -141,10 +139,8 @@
      * <ul>
      * <li> {@link PlaybackState2#STATE_NONE}</li>
      * <li> {@link PlaybackState2#STATE_STOPPED}</li>
-     * <li> {@link PlaybackState2#STATE_PREPARED}</li>
      * <li> {@link PlaybackState2#STATE_PAUSED}</li>
      * <li> {@link PlaybackState2#STATE_PLAYING}</li>
-     * <li> {@link PlaybackState2#STATE_FINISH}</li>
      * <li> {@link PlaybackState2#STATE_BUFFERING}</li>
      * <li> {@link PlaybackState2#STATE_ERROR}</li>
      * </ul>
@@ -182,14 +178,6 @@
     }
 
     /**
-     * Get a user readable error message. This should be set when the state is
-     * {@link PlaybackState2#STATE_ERROR}.
-     */
-    public CharSequence getErrorMessage() {
-        return mProvider.getErrorMessage_impl();
-    }
-
-    /**
      * Get the elapsed real time at which position was last updated. If the
      * position has never been set this will return 0;
      *
@@ -227,4 +215,4 @@
             @Nullable Bundle bundle) {
         return ApiLoader.getProvider(context).fromBundle_PlaybackState2(context, bundle);
     }
-}
\ No newline at end of file
+}
diff --git a/media/java/android/media/Rating2.java b/media/java/android/media/Rating2.java
index 4f77ecd..e5b05fb 100644
--- a/media/java/android/media/Rating2.java
+++ b/media/java/android/media/Rating2.java
@@ -19,7 +19,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.IntDef;
-import android.annotation.SystemApi;
 import android.content.Context;
 import android.media.update.ApiLoader;
 import android.media.update.Rating2Provider;
@@ -36,12 +35,10 @@
  * {@link #RATING_5_STARS} or {@link #RATING_PERCENTAGE}) and the actual rating value (which may
  * be defined as "unrated"), both of which are defined when the rating instance is constructed
  * through one of the factory methods.
- * @hide
  */
+// New version of Rating with following change
+//   - Don't implement Parcelable for updatable support.
 public final class Rating2 {
-    // Mostly same as the android.media.Rating, but it's no longer implements Parcelable for
-    // updatable support.
-
     /**
      * @hide
      */
@@ -100,7 +97,6 @@
     /**
      * @hide
      */
-    @SystemApi
     public Rating2(@NonNull Rating2Provider provider) {
         mProvider = provider;
     }
@@ -113,7 +109,6 @@
     /**
      * @hide
      */
-    @SystemApi
     public Rating2Provider getProvider() {
         return mProvider;
     }
diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java
index 209ec42..c0468dc9 100644
--- a/media/java/android/media/Ringtone.java
+++ b/media/java/android/media/Ringtone.java
@@ -40,7 +40,7 @@
  * <p>
  * For ways of retrieving {@link Ringtone} objects or to show a ringtone
  * picker, see {@link RingtoneManager}.
- * 
+ *
  * @see RingtoneManager
  */
 public class Ringtone {
@@ -97,7 +97,7 @@
 
     /**
      * Sets the stream type where this ringtone will be played.
-     * 
+     *
      * @param streamType The stream, see {@link AudioManager}.
      * @deprecated use {@link #setAudioAttributes(AudioAttributes)}
      */
@@ -111,7 +111,7 @@
 
     /**
      * Gets the stream type where this ringtone will be played.
-     * 
+     *
      * @return The stream type, see {@link AudioManager}.
      * @deprecated use of stream types is deprecated, see
      *     {@link #setAudioAttributes(AudioAttributes)}
@@ -146,9 +146,8 @@
     }
 
     /**
-     * @hide
      * Sets the player to be looping or non-looping.
-     * @param looping whether to loop or not
+     * @param looping whether to loop or not.
      */
     public void setLooping(boolean looping) {
         synchronized (mPlaybackSettingsLock) {
@@ -158,7 +157,16 @@
     }
 
     /**
-     * @hide
+     * Returns whether the looping mode was enabled on this player.
+     * @return true if this player loops when playing.
+     */
+    public boolean isLooping() {
+        synchronized (mPlaybackSettingsLock) {
+            return mIsLooping;
+        }
+    }
+
+    /**
      * Sets the volume on this player.
      * @param volume a raw scalar in range 0.0 to 1.0, where 0.0 mutes this player, and 1.0
      *   corresponds to no attenuation being applied.
@@ -173,6 +181,16 @@
     }
 
     /**
+     * Returns the volume scalar set on this player.
+     * @return a value between 0.0f and 1.0f.
+     */
+    public float getVolume() {
+        synchronized (mPlaybackSettingsLock) {
+            return mVolume;
+        }
+    }
+
+    /**
      * Must be called synchronized on mPlaybackSettingsLock
      */
     private void applyPlaybackProperties_sync() {
@@ -194,8 +212,8 @@
     /**
      * Returns a human-presentable title for ringtone. Looks in media
      * content provider. If not in either, uses the filename
-     * 
-     * @param context A context used for querying. 
+     *
+     * @param context A context used for querying.
      */
     public String getTitle(Context context) {
         if (mTitle != null) return mTitle;
@@ -265,12 +283,11 @@
 
         if (title == null) {
             title = context.getString(com.android.internal.R.string.ringtone_unknown);
-            
             if (title == null) {
                 title = "";
             }
         }
-        
+
         return title;
     }
 
@@ -395,7 +412,7 @@
 
     /**
      * Whether this ringtone is currently playing.
-     * 
+     *
      * @return True if playing, false otherwise.
      */
     public boolean isPlaying() {
diff --git a/media/java/android/media/SessionPlayer2.java b/media/java/android/media/SessionPlayer2.java
deleted file mode 100644
index 60acf16..0000000
--- a/media/java/android/media/SessionPlayer2.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import android.annotation.SystemApi;
-import android.content.Context;
-import android.media.MediaSession2.PlaylistParams;
-import android.media.update.ApiLoader;
-import android.media.update.SessionPlayer2Provider;
-
-import java.util.List;
-import java.util.concurrent.Executor;
-
-/**
- * Implementation of the {@link MediaPlayerInterface} which is backed by the {@link MediaPlayer2}
- * @hide
- */
-public class SessionPlayer2 implements MediaPlayerInterface {
-    private final SessionPlayer2Provider mProvider;
-
-    public SessionPlayer2(Context context) {
-        mProvider = ApiLoader.getProvider(context).createSessionPlayer2(context, this);
-    }
-
-    @Override
-    public void play() {
-        mProvider.play_impl();
-    }
-
-    @Override
-    public void prepare() {
-        mProvider.prepare_impl();
-    }
-
-    @Override
-    public void pause() {
-        mProvider.pause_impl();
-    }
-
-    @Override
-    public void stop() {
-        mProvider.stop_impl();
-    }
-
-    @Override
-    public void skipToPrevious() {
-        mProvider.skipToPrevious_impl();
-    }
-
-    @Override
-    public void skipToNext() {
-        mProvider.skipToNext_impl();
-    }
-
-    @Override
-    public void seekTo(long pos) {
-        mProvider.seekTo_impl(pos);
-    }
-
-    @Override
-    public void fastForward() {
-        mProvider.fastForward_impl();
-    }
-
-    @Override
-    public void rewind() {
-        mProvider.rewind_impl();
-    }
-
-    @Override
-    public PlaybackState2 getPlaybackState() {
-        return mProvider.getPlaybackState_impl();
-    }
-
-    @Override
-    public void setAudioAttributes(AudioAttributes attributes) {
-        mProvider.setAudioAttributes_impl(attributes);
-    }
-
-    @Override
-    public AudioAttributes getAudioAttributes() {
-        return mProvider.getAudioAttributes_impl();
-    }
-
-    @Override
-    public void setPlaylist(List<MediaItem2> playlist) {
-        mProvider.setPlaylist_impl(playlist);
-    }
-
-    @Override
-    public List<MediaItem2> getPlaylist() {
-        return mProvider.getPlaylist_impl();
-    }
-
-    @Override
-    public void setCurrentPlaylistItem(int index) {
-        mProvider.setCurrentPlaylistItem_impl(index);
-    }
-
-    @Override
-    public void setPlaylistParams(PlaylistParams params) {
-        mProvider.setPlaylistParams_impl(params);
-    }
-
-    @Override
-    public void addPlaylistItem(int index, MediaItem2 item) {
-        mProvider.addPlaylistItem_impl(index, item);
-    }
-
-    @Override
-    public void removePlaylistItem(MediaItem2 item) {
-        mProvider.removePlaylistItem_impl(item);
-    }
-
-    @Override
-    public PlaylistParams getPlaylistParams() {
-        return mProvider.getPlaylistParams_impl();
-    }
-
-    @Override
-    public void addPlaybackListener(Executor executor, PlaybackListener listener) {
-        mProvider.addPlaybackListener_impl(executor, listener);
-    }
-
-    @Override
-    public void removePlaybackListener(PlaybackListener listener) {
-        mProvider.removePlaybackListener_impl(listener);
-    }
-
-    public MediaPlayer2 getPlayer() {
-        return mProvider.getPlayer_impl();
-    }
-
-    @SystemApi
-    public SessionPlayer2Provider getProvider() {
-        return mProvider;
-    }
-}
diff --git a/media/java/android/media/SessionToken2.java b/media/java/android/media/SessionToken2.java
index 2c2090c..fdfa43a 100644
--- a/media/java/android/media/SessionToken2.java
+++ b/media/java/android/media/SessionToken2.java
@@ -18,7 +18,6 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.annotation.SystemApi;
 import android.content.Context;
 import android.media.session.MediaSessionManager;
 import android.media.update.ApiLoader;
@@ -36,8 +35,11 @@
  * {@link MediaController2} to communicate with the session.
  * <p>
  * It can be also obtained by {@link MediaSessionManager}.
- * @hide
  */
+// New version of MediaSession.Token for following reasons
+//   - Stop implementing Parcelable for updatable support
+//   - Represent session and library service (formerly browser service) in one class.
+//     Previously MediaSession.Token was for session and ComponentName was for service.
 public final class SessionToken2 {
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(value = {TYPE_SESSION, TYPE_SESSION_SERVICE, TYPE_LIBRARY_SERVICE})
@@ -86,7 +88,6 @@
      * Constructor for the token.
      * @hide
      */
-    @SystemApi
     public SessionToken2(@NonNull SessionToken2Provider provider) {
         mProvider = provider;
     }
@@ -106,7 +107,9 @@
         return mProvider.toString_impl();
     }
 
-    @SystemApi
+    /**
+     * @hide
+     */
     public SessionToken2Provider getProvider() {
         return mProvider;
     }
@@ -147,7 +150,7 @@
      * @return
      */
     public static SessionToken2 fromBundle(@NonNull Context context, @NonNull Bundle bundle) {
-        return ApiLoader.getProvider(context).SessionToken2_fromBundle(context, bundle);
+        return ApiLoader.getProvider(context).fromBundle_SessionToken2(context, bundle);
     }
 
     /**
diff --git a/media/java/android/media/VolumeProvider2.java b/media/java/android/media/VolumeProvider2.java
index 53ba466..711f51f 100644
--- a/media/java/android/media/VolumeProvider2.java
+++ b/media/java/android/media/VolumeProvider2.java
@@ -18,7 +18,6 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.annotation.SystemApi;
 import android.content.Context;
 import android.media.update.ApiLoader;
 import android.media.update.VolumeProvider2Provider;
@@ -32,12 +31,11 @@
  * {@link #setCurrentVolume(int)} each time the volume being provided changes.
  * <p>
  * You can set a volume provider on a session by calling
- * {@link MediaSession2#setPlayer(MediaPlayerInterface, VolumeProvider2)}.
- *
- * @hide
+ * {@link MediaSession2#updatePlayer}.
  */
+// New version of VolumeProvider with following changes
+//   - Don't implement Parcelable for updatable support.
 public abstract class VolumeProvider2 {
-
     /**
      * @hide
      */
@@ -85,7 +83,6 @@
     /**
      * @hide
      */
-    @SystemApi
     public VolumeProvider2Provider getProvider() {
         return mProvider;
     }
diff --git a/media/java/android/media/audiofx/AudioEffect.java b/media/java/android/media/audiofx/AudioEffect.java
index 7dbca3b..21d6873 100644
--- a/media/java/android/media/audiofx/AudioEffect.java
+++ b/media/java/android/media/audiofx/AudioEffect.java
@@ -39,6 +39,7 @@
  *   <li> {@link android.media.audiofx.BassBoost}</li>
  *   <li> {@link android.media.audiofx.PresetReverb}</li>
  *   <li> {@link android.media.audiofx.EnvironmentalReverb}</li>
+ *   <li> {@link android.media.audiofx.DynamicsProcessing}</li>
  * </ul>
  * <p>To apply the audio effect to a specific AudioTrack or MediaPlayer instance,
  * the application must specify the audio session ID of that instance when creating the AudioEffect.
@@ -126,6 +127,12 @@
               .fromString("fe3199be-aed0-413f-87bb-11260eb63cf1");
 
     /**
+     * UUID for Dynamics Processing
+     */
+    public static final UUID EFFECT_TYPE_DYNAMICS_PROCESSING = UUID
+              .fromString("7261676f-6d75-7369-6364-28e2fd3ac39e");
+
+    /**
      * Null effect UUID. Used when the UUID for effect type of
      * @hide
      */
@@ -203,7 +210,8 @@
      * {@link AudioEffect#EFFECT_TYPE_AEC}, {@link AudioEffect#EFFECT_TYPE_AGC},
      * {@link AudioEffect#EFFECT_TYPE_BASS_BOOST}, {@link AudioEffect#EFFECT_TYPE_ENV_REVERB},
      * {@link AudioEffect#EFFECT_TYPE_EQUALIZER}, {@link AudioEffect#EFFECT_TYPE_NS},
-     * {@link AudioEffect#EFFECT_TYPE_PRESET_REVERB}, {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER}.
+     * {@link AudioEffect#EFFECT_TYPE_PRESET_REVERB}, {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER},
+     * {@link AudioEffect#EFFECT_TYPE_DYNAMICS_PROCESSING}.
      *  </li>
      *  <li>uuid: UUID for this particular implementation</li>
      *  <li>connectMode: {@link #EFFECT_INSERT} or {@link #EFFECT_AUXILIARY}</li>
@@ -224,7 +232,8 @@
          * {@link AudioEffect#EFFECT_TYPE_BASS_BOOST}, {@link AudioEffect#EFFECT_TYPE_ENV_REVERB},
          * {@link AudioEffect#EFFECT_TYPE_EQUALIZER}, {@link AudioEffect#EFFECT_TYPE_NS},
          * {@link AudioEffect#EFFECT_TYPE_PRESET_REVERB},
-         * {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER}.
+         * {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER},
+         * {@link AudioEffect#EFFECT_TYPE_DYNAMICS_PROCESSING}.
          * @param uuid         UUID for this particular implementation
          * @param connectMode  {@link #EFFECT_INSERT} or {@link #EFFECT_AUXILIARY}
          * @param name         human readable effect name
@@ -246,7 +255,8 @@
          *  {@link AudioEffect#EFFECT_TYPE_AGC}, {@link AudioEffect#EFFECT_TYPE_BASS_BOOST},
          *  {@link AudioEffect#EFFECT_TYPE_ENV_REVERB}, {@link AudioEffect#EFFECT_TYPE_EQUALIZER},
          *  {@link AudioEffect#EFFECT_TYPE_NS}, {@link AudioEffect#EFFECT_TYPE_PRESET_REVERB}
-         *   or {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER}.<br>
+         *  {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER}
+         *   or {@link AudioEffect#EFFECT_TYPE_DYNAMICS_PROCESSING}.<br>
          *  For reverberation, bass boost, EQ and virtualizer, the UUID
          *  corresponds to the OpenSL ES Interface ID.
          */
@@ -1344,6 +1354,34 @@
     /**
      * @hide
      */
+    public static float byteArrayToFloat(byte[] valueBuf) {
+        return byteArrayToFloat(valueBuf, 0);
+
+    }
+
+    /**
+     * @hide
+     */
+    public static float byteArrayToFloat(byte[] valueBuf, int offset) {
+        ByteBuffer converter = ByteBuffer.wrap(valueBuf);
+        converter.order(ByteOrder.nativeOrder());
+        return converter.getFloat(offset);
+
+    }
+
+    /**
+     * @hide
+     */
+    public static byte[] floatToByteArray(float value) {
+        ByteBuffer converter = ByteBuffer.allocate(4);
+        converter.order(ByteOrder.nativeOrder());
+        converter.putFloat(value);
+        return converter.array();
+    }
+
+    /**
+     * @hide
+     */
     public static byte[] concatArrays(byte[]... arrays) {
         int len = 0;
         for (byte[] a : arrays) {
diff --git a/media/java/android/media/audiofx/DynamicsProcessing.java b/media/java/android/media/audiofx/DynamicsProcessing.java
new file mode 100644
index 0000000..d09c9a8
--- /dev/null
+++ b/media/java/android/media/audiofx/DynamicsProcessing.java
@@ -0,0 +1,2257 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.audiofx;
+
+import android.media.AudioTrack;
+import android.media.MediaPlayer;
+import android.media.audiofx.AudioEffect;
+import android.media.audiofx.DynamicsProcessing.Settings;
+import android.util.Log;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.StringTokenizer;
+
+/**
+ * DynamicsProcessing is an audio effect for equalizing and changing dynamic range properties of the
+ * sound. It is composed of multiple stages including equalization, multi-band compression and
+ * limiter.
+ * <p>The number of bands and active stages is configurable, and most parameters can be controlled
+ * in realtime, such as gains, attack/release times, thresholds, etc.
+ * <p>The effect is instantiated and controlled by channels. Each channel has the same basic
+ * architecture, but all of their parameters are independent from other channels.
+ * <p>The basic channel configuration is:
+ * <pre>
+ *
+ *    Channel 0          Channel 1       ....       Channel N-1
+ *      Input              Input                       Input
+ *        |                  |                           |
+ *   +----v----+        +----v----+                 +----v----+
+ *   |inputGain|        |inputGain|                 |inputGain|
+ *   +---------+        +---------+                 +---------+
+ *        |                  |                           |
+ *  +-----v-----+      +-----v-----+               +-----v-----+
+ *  |   PreEQ   |      |   PreEQ   |               |   PreEQ   |
+ *  +-----------+      +-----------+               +-----------+
+ *        |                  |                           |
+ *  +-----v-----+      +-----v-----+               +-----v-----+
+ *  |    MBC    |      |    MBC    |               |    MBC    |
+ *  +-----------+      +-----------+               +-----------+
+ *        |                  |                           |
+ *  +-----v-----+      +-----v-----+               +-----v-----+
+ *  |  PostEQ   |      |  PostEQ   |               |  PostEQ   |
+ *  +-----------+      +-----------+               +-----------+
+ *        |                  |                           |
+ *  +-----v-----+      +-----v-----+               +-----v-----+
+ *  |  Limiter  |      |  Limiter  |               |  Limiter  |
+ *  +-----------+      +-----------+               +-----------+
+ *        |                  |                           |
+ *     Output             Output                      Output
+ * </pre>
+ *
+ * <p>Where the stages are:
+ * inputGain: input gain factor in decibels (dB). 0 dB means no change in level.
+ * PreEQ:  Multi-band Equalizer.
+ * MBC:    Multi-band Compressor
+ * PostEQ: Multi-band Equalizer
+ * Limiter: Single band compressor/limiter.
+ *
+ * <p>An application creates a DynamicsProcessing object to instantiate and control this audio
+ * effect in the audio framework. A DynamicsProcessor.Config and DynamicsProcessor.Config.Builder
+ * are available to help configure the multiple stages and each band parameters if desired.
+ * <p>See each stage documentation for further details.
+ * <p>If no Config is specified during creation, a default configuration is chosen.
+ * <p>To attach the DynamicsProcessing to a particular AudioTrack or MediaPlayer,
+ * specify the audio session ID of this AudioTrack or MediaPlayer when constructing the effect
+ * (see {@link AudioTrack#getAudioSessionId()} and {@link MediaPlayer#getAudioSessionId()}).
+ *
+ * <p>To attach the DynamicsProcessing to a particular AudioTrack or MediaPlayer, specify the audio
+ * session ID of this AudioTrack or MediaPlayer when constructing the DynamicsProcessing.
+ * <p>See {@link android.media.MediaPlayer#getAudioSessionId()} for details on audio sessions.
+ * <p>See {@link android.media.audiofx.AudioEffect} class for more details on controlling audio
+ * effects.
+ */
+
+public final class DynamicsProcessing extends AudioEffect {
+
+    private final static String TAG = "DynamicsProcessing";
+
+    /**
+     * Config object used to initialize and change effect parameters at runtime.
+     */
+    private Config mConfig = null;
+
+
+    // These parameter constants must be synchronized with those in
+    // /system/media/audio_effects/include/audio_effects/effect_dynamicsprocessing.h
+
+    private static final int PARAM_GET_CHANNEL_COUNT = 0x0;
+    private static final int PARAM_EQ_BAND_COUNT = 0x1;
+    private static final int PARAM_MBC_BAND_COUNT = 0x2;
+    private static final int PARAM_INPUT_GAIN = 0x3;
+    private static final int PARAM_PRE_EQ_ENABLED = 0x10;
+    private static final int PARAM_PRE_EQ_BAND_ENABLED = 0x11;
+    private static final int PARAM_PRE_EQ_BAND_FREQUENCY = 0x12;
+    private static final int PARAM_PRE_EQ_BAND_GAIN = 0x13;
+    private static final int PARAM_EQ_FREQUENCY_RANGE = 0x22;
+    private static final int PARAM_EQ_GAIN_RANGE = 0x23;
+    private static final int PARAM_MBC_ENABLED = 0x30;
+    private static final int PARAM_MBC_BAND_ENABLED = 0x31;
+    private static final int PARAM_MBC_BAND_FREQUENCY = 0x32;
+    private static final int PARAM_MBC_BAND_ATTACK_TIME = 0x33;
+    private static final int PARAM_MBC_BAND_RELEASE_TIME = 0x34;
+    private static final int PARAM_MBC_BAND_RATIO = 0x35;
+    private static final int PARAM_MBC_BAND_THRESHOLD = 0x36;
+    private static final int PARAM_MBC_BAND_KNEE_WIDTH = 0x37;
+    private static final int PARAM_MBC_BAND_NOISE_GATE_THRESHOLD = 0x38;
+    private static final int PARAM_MBC_BAND_EXPANDER_RATIO = 0x39;
+    private static final int PARAM_MBC_BAND_GAIN_PRE = 0x3A;
+    private static final int PARAM_MBC_BAND_GAIN_POST = 0x3B;
+    private static final int PARAM_MBC_FREQUENCY_RANGE = 0x42;
+    private static final int PARAM_MBC_ATTACK_TIME_RANGE = 0x43;
+    private static final int PARAM_MBC_RELEASE_TIME_RANGE = 0x44;
+    private static final int PARAM_MBC_RATIO_RANGE = 0x45;
+    private static final int PARAM_MBC_THRESHOLD_RANGE = 0x46;
+    private static final int PARAM_MBC_KNEE_WIDTH_RANGE = 0x47;
+    private static final int PARAM_MBC_NOISE_GATE_THRESHOLD_RANGE = 0x48;
+    private static final int PARAM_MBC_EXPANDER_RATIO_RANGE = 0x49;
+    private static final int PARAM_MBC_GAIN_RANGE = 0x4A;
+    private static final int PARAM_POST_EQ_ENABLED = 0x50;
+    private static final int PARAM_POST_EQ_BAND_ENABLED = 0x51;
+    private static final int PARAM_POST_EQ_BAND_FREQUENCY = 0x52;
+    private static final int PARAM_POST_EQ_BAND_GAIN = 0x53;
+    private static final int PARAM_LIMITER_ENABLED = 0x60;
+    private static final int PARAM_LIMITER_LINK_GROUP = 0x61;
+    private static final int PARAM_LIMITER_ATTACK_TIME = 0x62;
+    private static final int PARAM_LIMITER_RELEASE_TIME = 0x63;
+    private static final int PARAM_LIMITER_RATIO = 0x64;
+    private static final int PARAM_LIMITER_THRESHOLD = 0x65;
+    private static final int PARAM_LIMITER_GAIN_POST = 0x66;
+    private static final int PARAM_LIMITER_ATTACK_TIME_RANGE = 0x72;
+    private static final int PARAM_LIMITER_RELEASE_TIME_RANGE = 0x73;
+    private static final int PARAM_LIMITER_RATIO_RANGE = 0x74;
+    private static final int PARAM_LIMITER_THRESHOLD_RANGE = 0x75;
+    private static final int PARAM_LIMITER_GAIN_RANGE = 0x76;
+    private static final int PARAM_VARIANT = 0x100;
+    private static final int PARAM_VARIANT_DESCRIPTION = 0x101;
+    private static final int PARAM_VARIANT_COUNT = 0x102;
+    private static final int PARAM_SET_ENGINE_ARCHITECTURE = 0x200;
+
+    /**
+     * Index of variant that favors frequency resolution. Frequency domain based implementation.
+     */
+    public static final int VARIANT_FAVOR_FREQUENCY_RESOLUTION  = 0;
+
+    /**
+     * Index of variant that favors time resolution resolution. Time domain based implementation.
+     */
+    public static final int VARIANT_FAVOR_TIME_RESOLUTION       = 1;
+
+    /**
+     * Maximum expected channels to be reported by effect
+     */
+    private static final int CHANNEL_COUNT_MAX = 32;
+
+    /**
+     * Number of channels in effect architecture
+     */
+    private int mChannelCount = 0;
+
+    /**
+     * Registered listener for parameter changes.
+     */
+    private OnParameterChangeListener mParamListener = null;
+
+    /**
+     * Listener used internally to to receive raw parameter change events
+     * from AudioEffect super class
+     */
+    private BaseParameterListener mBaseParamListener = null;
+
+    /**
+     * Lock for access to mParamListener
+     */
+    private final Object mParamListenerLock = new Object();
+
+    /**
+     * Class constructor.
+     * @param audioSession system-wide unique audio session identifier. The DynamicsProcessing
+     * will be attached to the MediaPlayer or AudioTrack in the same audio session.
+     */
+    public DynamicsProcessing(int audioSession) {
+        this(0 /*priority*/, audioSession);
+    }
+
+    /**
+     * @hide
+     * Class constructor for the DynamicsProcessing audio effect.
+     * @param priority the priority level requested by the application for controlling the
+     * DynamicsProcessing engine. As the same engine can be shared by several applications,
+     * this parameter indicates how much the requesting application needs control of effect
+     * parameters. The normal priority is 0, above normal is a positive number, below normal a
+     * negative number.
+     * @param audioSession system-wide unique audio session identifier. The DynamicsProcessing
+     * will be attached to the MediaPlayer or AudioTrack in the same audio session.
+     */
+    public DynamicsProcessing(int priority, int audioSession) {
+        this(priority, audioSession, null);
+    }
+
+    /**
+     * Class constructor for the DynamicsProcessing audio effect
+     * @param priority the priority level requested by the application for controlling the
+     * DynamicsProcessing engine. As the same engine can be shared by several applications,
+     * this parameter indicates how much the requesting application needs control of effect
+     * parameters. The normal priority is 0, above normal is a positive number, below normal a
+     * negative number.
+     * @param audioSession system-wide unique audio session identifier. The DynamicsProcessing
+     * will be attached to the MediaPlayer or AudioTrack in the same audio session.
+     * @param cfg Config object used to setup the audio effect, including bands per stage, and
+     * specific parameters for each stage/band. Use
+     * {@link android.media.audiofx.DynamicsProcessing.Config.Builder} to create a
+     * Config object that suits your needs. A null cfg parameter will create and use a default
+     * configuration for the effect
+     */
+    public DynamicsProcessing(int priority, int audioSession, Config cfg) {
+        super(EFFECT_TYPE_DYNAMICS_PROCESSING, EFFECT_TYPE_NULL, priority, audioSession);
+        if (audioSession == 0) {
+            Log.w(TAG, "WARNING: attaching a DynamicsProcessing to global output mix is"
+                    + "deprecated!");
+        }
+        mChannelCount = getChannelCount();
+        if (cfg == null) {
+            //create a default configuration and effect, with the number of channels this effect has
+            DynamicsProcessing.Config.Builder builder =
+                    new DynamicsProcessing.Config.Builder(
+                            CONFIG_DEFAULT_VARIANT,
+                            mChannelCount,
+                            true /*use preEQ*/, 6 /*pre eq bands*/,
+                            true /*use mbc*/, 6 /*mbc bands*/,
+                            true /*use postEQ*/, 6 /*postEq bands*/,
+                            true /*use Limiter*/);
+            mConfig = builder.build();
+        } else {
+            //validate channels are ok. decide what to do: replicate channels if more, or fail, or
+            mConfig = new DynamicsProcessing.Config(mChannelCount, cfg);
+        }
+
+        setEngineArchitecture(mConfig.getVariant(),
+                mConfig.isPreEqInUse(), mConfig.getPreEqBandCount(),
+                mConfig.isMbcInUse(), mConfig.getMbcBandCount(),
+                mConfig.isPostEqInUse(), mConfig.getPostEqBandCount(),
+                mConfig.isLimiterInUse());
+    }
+
+    /**
+     * Returns the Config object used to setup this effect.
+     * @return Config Current Config object used to setup this DynamicsProcessing effect.
+     */
+    public Config getConfig() {
+        return mConfig;
+    }
+
+
+    private static final int CONFIG_DEFAULT_VARIANT = 0; //favor frequency
+    private static final float CHANNEL_DEFAULT_INPUT_GAIN = 0; // dB
+    private static final float CONFIG_PREFERRED_FRAME_DURATION_MS = 10.0f; //milliseconds
+
+    private static final float EQ_DEFAULT_GAIN = 0; // dB
+    private static final boolean PREEQ_DEFAULT_ENABLED = true;
+    private static final boolean POSTEQ_DEFAULT_ENABLED = true;
+
+
+    private static final boolean MBC_DEFAULT_ENABLED = true;
+    private static final float MBC_DEFAULT_ATTACK_TIME = 50; // ms
+    private static final float MBC_DEFAULT_RELEASE_TIME = 120; // ms
+    private static final float MBC_DEFAULT_RATIO = 2; // 1:N
+    private static final float MBC_DEFAULT_THRESHOLD = -30; // dB
+    private static final float MBC_DEFAULT_KNEE_WIDTH = 0; // dB
+    private static final float MBC_DEFAULT_NOISE_GATE_THRESHOLD = -80; // dB
+    private static final float MBC_DEFAULT_EXPANDER_RATIO = 1.5f; // N:1
+    private static final float MBC_DEFAULT_PRE_GAIN = 0; // dB
+    private static final float MBC_DEFAULT_POST_GAIN = 10; // dB
+
+    private static final boolean LIMITER_DEFAULT_ENABLED = true;
+    private static final int LIMITER_DEFAULT_LINK_GROUP = 0;//;
+    private static final float LIMITER_DEFAULT_ATTACK_TIME = 50; // ms
+    private static final float LIMITER_DEFAULT_RELEASE_TIME = 120; // ms
+    private static final float LIMITER_DEFAULT_RATIO = 2; // 1:N
+    private static final float LIMITER_DEFAULT_THRESHOLD = -30; // dB
+    private static final float LIMITER_DEFAULT_POST_GAIN = 10; // dB
+
+    private static final float DEFAULT_MIN_FREQUENCY = 220; // Hz
+    private static final float DEFAULT_MAX_FREQUENCY = 20000; // Hz
+    private static final float mMinFreqLog = (float)Math.log10(DEFAULT_MIN_FREQUENCY);
+    private static final float mMaxFreqLog = (float)Math.log10(DEFAULT_MAX_FREQUENCY);
+
+    /**
+     * base class for the different stages.
+     */
+    public static class Stage {
+        private boolean mInUse;
+        private boolean mEnabled;
+        /**
+         * Class constructor for stage
+         * @param inUse true if this stage is set to be used. False otherwise. Stages that are not
+         * set "inUse" at initialization time are not available to be used at any time.
+         * @param enabled true if this stage is currently used to process sound. When disabled,
+         * the stage is bypassed and the sound is copied unaltered from input to output.
+         */
+        public Stage(boolean inUse, boolean enabled) {
+            mInUse = inUse;
+            mEnabled = enabled;
+        }
+
+        /**
+         * returns enabled state of the stage
+         * @return true if stage is enabled for processing, false otherwise
+         */
+        public boolean isEnabled() {
+            return mEnabled;
+        }
+        /**
+         * sets enabled state of the stage
+         * @param enabled true for enabled, false otherwise
+         */
+        public void setEnabled(boolean enabled) {
+            mEnabled = enabled;
+        }
+
+        /**
+         * returns inUse state of the stage.
+         * @return inUse state of the stage. True if this stage is currently used to process sound.
+         * When false, the stage is bypassed and the sound is copied unaltered from input to output.
+         */
+        public boolean isInUse() {
+            return mInUse;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(String.format(" Stage InUse: %b\n", isInUse()));
+            if (isInUse()) {
+                sb.append(String.format(" Stage Enabled: %b\n", mEnabled));
+            }
+            return sb.toString();
+        }
+    }
+
+    /**
+     * Base class for stages that hold bands
+     */
+    public static class BandStage extends Stage{
+        private int mBandCount;
+        /**
+         * Class constructor for BandStage
+         * @param inUse true if this stage is set to be used. False otherwise. Stages that are not
+         * set "inUse" at initialization time are not available to be used at any time.
+         * @param enabled true if this stage is currently used to process sound. When disabled,
+         * the stage is bypassed and the sound is copied unaltered from input to output.
+         * @param bandCount number of bands this stage will handle. If stage is not inUse, bandcount
+         * is set to 0
+         */
+        public BandStage(boolean inUse, boolean enabled, int bandCount) {
+            super(inUse, enabled);
+            mBandCount = isInUse() ? bandCount : 0;
+        }
+
+        /**
+         * gets number of bands held in this stage
+         * @return number of bands held in this stage
+         */
+        public int getBandCount() {
+            return mBandCount;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(super.toString());
+            if (isInUse()) {
+                sb.append(String.format(" Band Count: %d\n", mBandCount));
+            }
+            return sb.toString();
+        }
+    }
+
+    /**
+     * Base class for bands
+     */
+    public static class BandBase {
+        private boolean mEnabled;
+        private float mCutoffFrequency;
+        /**
+         * Class constructor for BandBase
+         * @param enabled true if this band is currently used to process sound. When false,
+         * the band is effectively muted and sound set to zero.
+         * @param cutoffFrequency topmost frequency number (in Hz) this band will process. The
+         * effective bandwidth for the band is then computed using this and the previous band
+         * topmost frequency (or 0 Hz for band number 0). Frequencies are expected to increase with
+         * band number, thus band 0 cutoffFrequency <= band 1 cutoffFrequency, and so on.
+         */
+        public BandBase(boolean enabled, float cutoffFrequency) {
+            mEnabled = enabled;
+            mCutoffFrequency = cutoffFrequency;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(String.format(" Enabled: %b\n", mEnabled));
+            sb.append(String.format(" CutoffFrequency: %f\n", mCutoffFrequency));
+            return sb.toString();
+        }
+
+        /**
+         * returns enabled state of the band
+         * @return true if bands is enabled for processing, false otherwise
+         */
+        public boolean isEnabled() {
+            return mEnabled;
+        }
+        /**
+         * sets enabled state of the band
+         * @param enabled true for enabled, false otherwise
+         */
+        public void setEnabled(boolean enabled) {
+            mEnabled = enabled;
+        }
+
+        /**
+         * gets cutoffFrequency for this band in Hertz (Hz)
+         * @return cutoffFrequency for this band in Hertz (Hz)
+         */
+        public float getCutoffFrequency() {
+            return mCutoffFrequency;
+        }
+
+        /**
+         * sets topmost frequency number (in Hz) this band will process. The
+         * effective bandwidth for the band is then computed using this and the previous band
+         * topmost frequency (or 0 Hz for band number 0). Frequencies are expected to increase with
+         * band number, thus band 0 cutoffFrequency <= band 1 cutoffFrequency, and so on.
+         * @param frequency
+         */
+        public void setCutoffFrequency(float frequency) {
+            mCutoffFrequency = frequency;
+        }
+    }
+
+    /**
+     * Class for Equalizer Bands
+     * Equalizer bands have three controllable parameters: enabled/disabled, cutoffFrequency and
+     * gain
+     */
+    public final static class EqBand extends BandBase {
+        private float mGain;
+        /**
+         * Class constructor for EqBand
+         * @param enabled true if this band is currently used to process sound. When false,
+         * the band is effectively muted and sound set to zero.
+         * @param cutoffFrequency topmost frequency number (in Hz) this band will process. The
+         * effective bandwidth for the band is then computed using this and the previous band
+         * topmost frequency (or 0 Hz for band number 0). Frequencies are expected to increase with
+         * band number, thus band 0 cutoffFrequency <= band 1 cutoffFrequency, and so on.
+         * @param gain of equalizer band in decibels (dB). A gain of 0 dB means no change in level.
+         */
+        public EqBand(boolean enabled, float cutoffFrequency, float gain) {
+            super(enabled, cutoffFrequency);
+            mGain = gain;
+        }
+
+        /**
+         * Class constructor for EqBand
+         * @param cfg copy constructor
+         */
+        public EqBand(EqBand cfg) {
+            super(cfg.isEnabled(), cfg.getCutoffFrequency());
+            mGain = cfg.mGain;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(super.toString());
+            sb.append(String.format(" Gain: %f\n", mGain));
+            return sb.toString();
+        }
+
+        /**
+         * gets current gain of band in decibels (dB)
+         * @return current gain of band in decibels (dB)
+         */
+        public float getGain() {
+            return mGain;
+        }
+
+        /**
+         * sets current gain of band in decibels (dB)
+         * @param gain desired in decibels (db)
+         */
+        public void setGain(float gain) {
+            mGain = gain;
+        }
+    }
+
+    /**
+     * Class for Multi-Band compressor bands
+     * MBC bands have multiple controllable parameters: enabled/disabled, cutoffFrequency,
+     * attackTime, releaseTime, ratio, threshold, kneeWidth, noiseGateThreshold, expanderRatio,
+     * preGain and postGain.
+     */
+    public final static class MbcBand extends BandBase{
+        private float mAttackTime;
+        private float mReleaseTime;
+        private float mRatio;
+        private float mThreshold;
+        private float mKneeWidth;
+        private float mNoiseGateThreshold;
+        private float mExpanderRatio;
+        private float mPreGain;
+        private float mPostGain;
+        /**
+         * Class constructor for MbcBand
+         * @param enabled true if this band is currently used to process sound. When false,
+         * the band is effectively muted and sound set to zero.
+         * @param cutoffFrequency topmost frequency number (in Hz) this band will process. The
+         * effective bandwidth for the band is then computed using this and the previous band
+         * topmost frequency (or 0 Hz for band number 0). Frequencies are expected to increase with
+         * band number, thus band 0 cutoffFrequency <= band 1 cutoffFrequency, and so on.
+         * @param attackTime Attack Time for compressor in milliseconds (ms)
+         * @param releaseTime Release Time for compressor in milliseconds (ms)
+         * @param ratio Compressor ratio (1:N)
+         * @param threshold Compressor threshold measured in decibels (dB) from 0 dB Full Scale
+         * (dBFS).
+         * @param kneeWidth Width in decibels (dB) around compressor threshold point.
+         * @param noiseGateThreshold Noise gate threshold in decibels (dB) from 0 dB Full Scale
+         * (dBFS).
+         * @param expanderRatio Expander ratio (N:1) for signals below the Noise Gate Threshold.
+         * @param preGain Gain applied to the signal BEFORE the compression.
+         * @param postGain Gain applied to the signal AFTER compression.
+         */
+        public MbcBand(boolean enabled, float cutoffFrequency, float attackTime, float releaseTime,
+                float ratio, float threshold, float kneeWidth, float noiseGateThreshold,
+                float expanderRatio, float preGain, float postGain) {
+            super(enabled, cutoffFrequency);
+            mAttackTime = attackTime;
+            mReleaseTime = releaseTime;
+            mRatio = ratio;
+            mThreshold = threshold;
+            mKneeWidth = kneeWidth;
+            mNoiseGateThreshold = noiseGateThreshold;
+            mExpanderRatio = expanderRatio;
+            mPreGain = preGain;
+            mPostGain = postGain;
+        }
+
+        /**
+         * Class constructor for MbcBand
+         * @param cfg copy constructor
+         */
+        public MbcBand(MbcBand cfg) {
+            super(cfg.isEnabled(), cfg.getCutoffFrequency());
+            mAttackTime = cfg.mAttackTime;
+            mReleaseTime = cfg.mReleaseTime;
+            mRatio = cfg.mRatio;
+            mThreshold = cfg.mThreshold;
+            mKneeWidth = cfg.mKneeWidth;
+            mNoiseGateThreshold = cfg.mNoiseGateThreshold;
+            mExpanderRatio = cfg.mExpanderRatio;
+            mPreGain = cfg.mPreGain;
+            mPostGain = cfg.mPostGain;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(super.toString());
+            sb.append(String.format(" AttackTime: %f (ms)\n", mAttackTime));
+            sb.append(String.format(" ReleaseTime: %f (ms)\n", mReleaseTime));
+            sb.append(String.format(" Ratio: 1:%f\n", mRatio));
+            sb.append(String.format(" Threshold: %f (dB)\n", mThreshold));
+            sb.append(String.format(" NoiseGateThreshold: %f(dB)\n", mNoiseGateThreshold));
+            sb.append(String.format(" ExpanderRatio: %f:1\n", mExpanderRatio));
+            sb.append(String.format(" PreGain: %f (dB)\n", mPreGain));
+            sb.append(String.format(" PostGain: %f (dB)\n", mPostGain));
+            return sb.toString();
+        }
+
+        /**
+         * gets attack time for compressor in milliseconds (ms)
+         * @return attack time for compressor in milliseconds (ms)
+         */
+        public float getAttackTime() { return mAttackTime; }
+        /**
+         * sets attack time for compressor in milliseconds (ms)
+         * @param attackTime desired for compressor in milliseconds (ms)
+         */
+        public void setAttackTime(float attackTime) { mAttackTime = attackTime; }
+        /**
+         * gets release time for compressor in milliseconds (ms)
+         * @return release time for compressor in milliseconds (ms)
+         */
+        public float getReleaseTime() { return mReleaseTime; }
+        /**
+         * sets release time for compressor in milliseconds (ms)
+         * @param releaseTime desired for compressor in milliseconds (ms)
+         */
+        public void setReleaseTime(float releaseTime) { mReleaseTime = releaseTime; }
+        /**
+         * gets the compressor ratio (1:N)
+         * @return compressor ratio (1:N)
+         */
+        public float getRatio() { return mRatio; }
+        /**
+         * sets compressor ratio (1:N)
+         * @param ratio desired for the compressor (1:N)
+         */
+        public void setRatio(float ratio) { mRatio = ratio; }
+        /**
+         * gets the compressor threshold measured in decibels (dB) from 0 dB Full Scale (dBFS).
+         * Thresholds are negative. A threshold of 0 dB means no compression will take place.
+         * @return compressor threshold in decibels (dB)
+         */
+        public float getThreshold() { return mThreshold; }
+        /**
+         * sets the compressor threshold measured in decibels (dB) from 0 dB Full Scale (dBFS).
+         * Thresholds are negative. A threshold of 0 dB means no compression will take place.
+         * @param threshold desired for compressor in decibels(dB)
+         */
+        public void setThreshold(float threshold) { mThreshold = threshold; }
+        /**
+         * get Knee Width in decibels (dB) around compressor threshold point. Widths are always
+         * positive, with higher values representing a wider area of transition from the linear zone
+         * to the compression zone. A knee of 0 dB means a more abrupt transition.
+         * @return Knee Width in decibels (dB)
+         */
+        public float getKneeWidth() { return mKneeWidth; }
+        /**
+         * sets knee width in decibels (dB). See
+         * {@link android.media.audiofx.DynamicsProcessing.MbcBand#getKneeWidth} for more
+         * information.
+         * @param kneeWidth desired in decibels (dB)
+         */
+        public void setKneeWidth(float kneeWidth) { mKneeWidth = kneeWidth; }
+        /**
+         * gets the noise gate threshold in decibels (dB) from 0 dB Full Scale (dBFS). Noise gate
+         * thresholds are negative. Signals below this level will be expanded according the
+         * expanderRatio parameter. A Noise Gate Threshold of -75 dB means very quiet signals might
+         * be effectively removed from the signal.
+         * @return Noise Gate Threshold in decibels (dB)
+         */
+        public float getNoiseGateThreshold() { return mNoiseGateThreshold; }
+        /**
+         * sets noise gate threshod in decibels (dB). See
+         * {@link android.media.audiofx.DynamicsProcessing.MbcBand#getNoiseGateThreshold} for more
+         * information.
+         * @param noiseGateThreshold desired in decibels (dB)
+         */
+        public void setNoiseGateThreshold(float noiseGateThreshold) {
+            mNoiseGateThreshold = noiseGateThreshold; }
+        /**
+         * gets Expander ratio (N:1) for signals below the Noise Gate Threshold.
+         * @return Expander ratio (N:1)
+         */
+        public float getExpanderRatio() { return mExpanderRatio; }
+        /**
+         * sets Expander ratio (N:1) for signals below the Noise Gate Threshold.
+         * @param expanderRatio desired expander ratio (N:1)
+         */
+        public void setExpanderRatio(float expanderRatio) { mExpanderRatio = expanderRatio; }
+        /**
+         * gets the gain applied to the signal BEFORE the compression. Measured in decibels (dB)
+         * where 0 dB means no level change.
+         * @return preGain value in decibels (dB)
+         */
+        public float getPreGain() { return mPreGain; }
+        /**
+         * sets the gain to be applied to the signal BEFORE the compression, measured in decibels
+         * (dB), where 0 dB means no level change.
+         * @param preGain desired in decibels (dB)
+         */
+        public void setPreGain(float preGain) { mPreGain = preGain; }
+        /**
+         * gets the gain applied to the signal AFTER compression. Measured in decibels (dB) where 0
+         * dB means no level change
+         * @return postGain value in decibels (dB)
+         */
+        public float getPostGain() { return mPostGain; }
+        /**
+         * sets the gain to be applied to the siganl AFTER the compression. Measured in decibels
+         * (dB), where 0 dB means no level change.
+         * @param postGain desired value in decibels (dB)
+         */
+        public void setPostGain(float postGain) { mPostGain = postGain; }
+    }
+
+    /**
+     * Class for Equalizer stage
+     */
+    public final static class Eq extends BandStage {
+        private final EqBand[] mBands;
+        /**
+         * Class constructor for Equalizer (Eq) stage
+         * @param inUse true if Eq stage will be used, false otherwise.
+         * @param enabled true if Eq stage is enabled/disabled. This can be changed while effect is
+         * running
+         * @param bandCount number of bands for this Equalizer stage. Can't be changed while effect
+         * is running
+         */
+        public Eq(boolean inUse, boolean enabled, int bandCount) {
+            super(inUse, enabled, bandCount);
+            if (isInUse()) {
+                mBands = new EqBand[bandCount];
+                for (int b = 0; b < bandCount; b++) {
+                    float freq = DEFAULT_MAX_FREQUENCY;
+                    if (bandCount > 1) {
+                        freq = (float)Math.pow(10, mMinFreqLog +
+                                b * (mMaxFreqLog - mMinFreqLog)/(bandCount -1));
+                    }
+                    mBands[b] = new EqBand(true, freq, EQ_DEFAULT_GAIN);
+                }
+            } else {
+                mBands = null;
+            }
+        }
+        /**
+         * Class constructor for Eq stage
+         * @param cfg copy constructor
+         */
+        public Eq(Eq cfg) {
+            super(cfg.isInUse(), cfg.isEnabled(), cfg.getBandCount());
+            if (isInUse()) {
+                mBands = new EqBand[cfg.mBands.length];
+                for (int b = 0; b < mBands.length; b++) {
+                    mBands[b] = new EqBand(cfg.mBands[b]);
+                }
+            } else {
+                mBands = null;
+            }
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(super.toString());
+            if (isInUse()) {
+                sb.append("--->EqBands: " + mBands.length + "\n");
+                for (int b = 0; b < mBands.length; b++) {
+                    sb.append(String.format("  Band %d\n", b));
+                    sb.append(mBands[b].toString());
+                }
+            }
+            return sb.toString();
+        }
+        /**
+         * Helper function to check if band index is within range
+         * @param band index to check
+         */
+        private void checkBand(int band) {
+            if (mBands == null || band < 0 || band >= mBands.length) {
+                throw new IllegalArgumentException("band index " + band +" out of bounds");
+            }
+        }
+        /**
+         * Sets EqBand object for given band index
+         * @param band index of band to be modified
+         * @param bandCfg EqBand object.
+         */
+        public void setBand(int band, EqBand bandCfg) {
+            checkBand(band);
+            mBands[band] = new EqBand(bandCfg);
+        }
+        /**
+         * Gets EqBand object for band of interest.
+         * @param band index of band of interest
+         * @return EqBand Object
+         */
+        public EqBand getBand(int band) {
+            checkBand(band);
+            return mBands[band];
+        }
+    }
+
+    /**
+     * Class for Multi-Band Compressor (MBC) stage
+     */
+    public final static class Mbc extends BandStage {
+        private final MbcBand[] mBands;
+        /**
+         * Constructor for Multi-Band Compressor (MBC) stage
+         * @param inUse true if MBC stage will be used, false otherwise.
+         * @param enabled true if MBC stage is enabled/disabled. This can be changed while effect
+         * is running
+         * @param bandCount number of bands for this MBC stage. Can't be changed while effect is
+         * running
+         */
+        public Mbc(boolean inUse, boolean enabled, int bandCount) {
+            super(inUse, enabled, bandCount);
+            if (isInUse()) {
+                mBands = new MbcBand[bandCount];
+                for (int b = 0; b < bandCount; b++) {
+                    float freq = DEFAULT_MAX_FREQUENCY;
+                    if (bandCount > 1) {
+                        freq = (float)Math.pow(10, mMinFreqLog +
+                                b * (mMaxFreqLog - mMinFreqLog)/(bandCount -1));
+                    }
+                    mBands[b] = new MbcBand(true, freq, MBC_DEFAULT_ATTACK_TIME,
+                            MBC_DEFAULT_RELEASE_TIME, MBC_DEFAULT_RATIO,
+                            MBC_DEFAULT_THRESHOLD, MBC_DEFAULT_KNEE_WIDTH,
+                            MBC_DEFAULT_NOISE_GATE_THRESHOLD, MBC_DEFAULT_EXPANDER_RATIO,
+                            MBC_DEFAULT_PRE_GAIN, MBC_DEFAULT_POST_GAIN);
+                }
+            } else {
+                mBands = null;
+            }
+        }
+        /**
+         * Class constructor for MBC stage
+         * @param cfg copy constructor
+         */
+        public Mbc(Mbc cfg) {
+            super(cfg.isInUse(), cfg.isEnabled(), cfg.getBandCount());
+            if (isInUse()) {
+                mBands = new MbcBand[cfg.mBands.length];
+                for (int b = 0; b < mBands.length; b++) {
+                    mBands[b] = new MbcBand(cfg.mBands[b]);
+                }
+            } else {
+                mBands = null;
+            }
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(super.toString());
+            if (isInUse()) {
+                sb.append("--->MbcBands: " + mBands.length + "\n");
+                for (int b = 0; b < mBands.length; b++) {
+                    sb.append(String.format("  Band %d\n", b));
+                    sb.append(mBands[b].toString());
+                }
+            }
+            return sb.toString();
+        }
+        /**
+         * Helper function to check if band index is within range
+         * @param band index to check
+         */
+        private void checkBand(int band) {
+            if (mBands == null || band < 0 || band >= mBands.length) {
+                throw new IllegalArgumentException("band index " + band +" out of bounds");
+            }
+        }
+        /**
+         * Sets MbcBand object for given band index
+         * @param band index of band to be modified
+         * @param bandCfg MbcBand object.
+         */
+        public void setBand(int band, MbcBand bandCfg) {
+            checkBand(band);
+            mBands[band] = new MbcBand(bandCfg);
+        }
+        /**
+         * Gets MbcBand object for band of interest.
+         * @param band index of band of interest
+         * @return MbcBand Object
+         */
+        public MbcBand getBand(int band) {
+            checkBand(band);
+            return mBands[band];
+        }
+    }
+
+    /**
+     * Class for Limiter Stage
+     * Limiter is a single band compressor at the end of the processing chain, commonly used to
+     * protect the signal from overloading and distortion. Limiters have multiple controllable
+     * parameters: enabled/disabled, linkGroup, attackTime, releaseTime, ratio, threshold, and
+     * postGain.
+     * <p>Limiters can be linked in groups across multiple channels. Linked limiters will trigger
+     * the same limiting if any of the linked limiters starts compressing.
+     */
+    public final static class Limiter extends Stage {
+        private int mLinkGroup;
+        private float mAttackTime;
+        private float mReleaseTime;
+        private float mRatio;
+        private float mThreshold;
+        private float mPostGain;
+
+        /**
+         * Class constructor for Limiter Stage
+         * @param inUse true if MBC stage will be used, false otherwise.
+         * @param enabled true if MBC stage is enabled/disabled. This can be changed while effect
+         * is running
+         * @param linkGroup index of group assigned to this Limiter. Only limiters that share the
+         * same linkGroup index will react together.
+         * @param attackTime Attack Time for limiter compressor in milliseconds (ms)
+         * @param releaseTime Release Time for limiter compressor in milliseconds (ms)
+         * @param ratio Limiter Compressor ratio (1:N)
+         * @param threshold Limiter Compressor threshold measured in decibels (dB) from 0 dB Full
+         * Scale (dBFS).
+         * @param postGain Gain applied to the signal AFTER compression.
+         */
+        public Limiter(boolean inUse, boolean enabled, int linkGroup, float attackTime,
+                float releaseTime, float ratio, float threshold, float postGain) {
+            super(inUse, enabled);
+            mLinkGroup = linkGroup;
+            mAttackTime = attackTime;
+            mReleaseTime = releaseTime;
+            mRatio = ratio;
+            mThreshold = threshold;
+            mPostGain = postGain;
+        }
+
+        /**
+         * Class Constructor for Limiter
+         * @param cfg copy constructor
+         */
+        public Limiter(Limiter cfg) {
+            super(cfg.isInUse(), cfg.isEnabled());
+            mLinkGroup = cfg.mLinkGroup;
+            mAttackTime = cfg.mAttackTime;
+            mReleaseTime = cfg.mReleaseTime;
+            mRatio = cfg.mRatio;
+            mThreshold = cfg.mThreshold;
+            mPostGain = cfg.mPostGain;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(super.toString());
+            if (isInUse()) {
+                sb.append(String.format(" LinkGroup: %d (group)\n", mLinkGroup));
+                sb.append(String.format(" AttackTime: %f (ms)\n", mAttackTime));
+                sb.append(String.format(" ReleaseTime: %f (ms)\n", mReleaseTime));
+                sb.append(String.format(" Ratio: 1:%f\n", mRatio));
+                sb.append(String.format(" Threshold: %f (dB)\n", mThreshold));
+                sb.append(String.format(" PostGain: %f (dB)\n", mPostGain));
+            }
+            return sb.toString();
+        }
+        /**
+         * Gets the linkGroup index for this Limiter Stage. Only limiters that share the same
+         * linkGroup index will react together.
+         * @return linkGroup index.
+         */
+        public int getLinkGroup() { return mLinkGroup; }
+        /**
+         * Sets the linkGroup index for this limiter Stage.
+         * @param linkGroup desired linkGroup index
+         */
+        public void setLinkGroup(int linkGroup) { mLinkGroup = linkGroup; }
+        /**
+         * gets attack time for limiter compressor in milliseconds (ms)
+         * @return attack time for limiter compressor in milliseconds (ms)
+         */
+        public float getAttackTime() { return mAttackTime; }
+        /**
+         * sets attack time for limiter compressor in milliseconds (ms)
+         * @param attackTime desired for limiter compressor in milliseconds (ms)
+         */
+        public void setAttackTime(float attackTime) { mAttackTime = attackTime; }
+        /**
+         * gets release time for limiter compressor in milliseconds (ms)
+         * @return release time for limiter compressor in milliseconds (ms)
+         */
+        public float getReleaseTime() { return mReleaseTime; }
+        /**
+         * sets release time for limiter compressor in milliseconds (ms)
+         * @param releaseTime desired for limiter compressor in milliseconds (ms)
+         */
+        public void setReleaseTime(float releaseTime) { mReleaseTime = releaseTime; }
+        /**
+         * gets the limiter compressor ratio (1:N)
+         * @return limiter compressor ratio (1:N)
+         */
+        public float getRatio() { return mRatio; }
+        /**
+         * sets limiter compressor ratio (1:N)
+         * @param ratio desired for the limiter compressor (1:N)
+         */
+        public void setRatio(float ratio) { mRatio = ratio; }
+        /**
+         * gets the limiter compressor threshold measured in decibels (dB) from 0 dB Full Scale
+         * (dBFS). Thresholds are negative. A threshold of 0 dB means no limiting will take place.
+         * @return limiter compressor threshold in decibels (dB)
+         */
+        public float getThreshold() { return mThreshold; }
+        /**
+         * sets the limiter compressor threshold measured in decibels (dB) from 0 dB Full Scale
+         * (dBFS). Thresholds are negative. A threshold of 0 dB means no limiting will take place.
+         * @param threshold desired for limiter compressor in decibels(dB)
+         */
+        public void setThreshold(float threshold) { mThreshold = threshold; }
+        /**
+         * gets the gain applied to the signal AFTER limiting. Measured in decibels (dB) where 0
+         * dB means no level change
+         * @return postGain value in decibels (dB)
+         */
+        public float getPostGain() { return mPostGain; }
+        /**
+         * sets the gain to be applied to the siganl AFTER the limiter. Measured in decibels
+         * (dB), where 0 dB means no level change.
+         * @param postGain desired value in decibels (dB)
+         */
+        public void setPostGain(float postGain) { mPostGain = postGain; }
+    }
+
+    /**
+     * Class for Channel configuration parameters. It is composed of multiple stages, which can be
+     * used/enabled independently. Stages not used or disabled will be bypassed and the sound would
+     * be unaffected by them.
+     */
+    public final static class Channel {
+        private float   mInputGain;
+        private Eq      mPreEq;
+        private Mbc     mMbc;
+        private Eq      mPostEq;
+        private Limiter mLimiter;
+
+        /**
+         * Class constructor for Channel configuration.
+         * @param inputGain value in decibels (dB) of level change applied to the audio before
+         * processing. A value of 0 dB means no change.
+         * @param preEqInUse true if PreEq stage will be used, false otherwise. This can't be
+         * changed later.
+         * @param preEqBandCount number of bands for PreEq stage. This can't be changed later.
+         * @param mbcInUse true if Mbc stage will be used, false otherwise. This can't be changed
+         * later.
+         * @param mbcBandCount number of bands for Mbc stage. This can't be changed later.
+         * @param postEqInUse true if PostEq stage will be used, false otherwise. This can't be
+         * changed later.
+         * @param postEqBandCount number of bands for PostEq stage. This can't be changed later.
+         * @param limiterInUse true if Limiter stage will be used, false otherwise. This can't be
+         * changed later.
+         */
+        public Channel (float inputGain,
+                boolean preEqInUse, int preEqBandCount,
+                boolean mbcInUse, int mbcBandCount,
+                boolean postEqInUse, int postEqBandCount,
+                boolean limiterInUse) {
+            mInputGain = inputGain;
+            mPreEq = new Eq(preEqInUse, PREEQ_DEFAULT_ENABLED, preEqBandCount);
+            mMbc = new Mbc(mbcInUse, MBC_DEFAULT_ENABLED, mbcBandCount);
+            mPostEq = new Eq(postEqInUse, POSTEQ_DEFAULT_ENABLED,
+                    postEqBandCount);
+            mLimiter = new Limiter(limiterInUse,
+                    LIMITER_DEFAULT_ENABLED, LIMITER_DEFAULT_LINK_GROUP,
+                    LIMITER_DEFAULT_ATTACK_TIME, LIMITER_DEFAULT_RELEASE_TIME,
+                    LIMITER_DEFAULT_RATIO, LIMITER_DEFAULT_THRESHOLD, LIMITER_DEFAULT_POST_GAIN);
+        }
+
+        /**
+         * Class constructor for Channel configuration
+         * @param cfg copy constructor
+         */
+        public Channel(Channel cfg) {
+            mInputGain = cfg.mInputGain;
+            mPreEq = new Eq(cfg.mPreEq);
+            mMbc = new Mbc(cfg.mMbc);
+            mPostEq = new Eq(cfg.mPostEq);
+            mLimiter = new Limiter(cfg.mLimiter);
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(String.format(" InputGain: %f\n", mInputGain));
+            sb.append("-->PreEq\n");
+            sb.append(mPreEq.toString());
+            sb.append("-->MBC\n");
+            sb.append(mMbc.toString());
+            sb.append("-->PostEq\n");
+            sb.append(mPostEq.toString());
+            sb.append("-->Limiter\n");
+            sb.append(mLimiter.toString());
+            return sb.toString();
+        }
+        /**
+         * Gets inputGain value in decibels (dB). 0 dB means no change;
+         * @return gain value in decibels (dB)
+         */
+        public float getInputGain() {
+            return mInputGain;
+        }
+        /**
+         * Sets inputGain value in decibels (dB). 0 dB means no change;
+         * @param inputGain desired gain value in decibels (dB)
+         */
+        public void setInputGain(float inputGain) {
+            mInputGain = inputGain;
+        }
+
+        /**
+         * Gets PreEq configuration stage
+         * @return PreEq configuration stage
+         */
+        public Eq getPreEq() {
+            return mPreEq;
+        }
+        /**
+         * Sets PreEq configuration stage. New PreEq stage must have the same number of bands than
+         * original PreEq stage.
+         * @param preEq configuration
+         */
+        public void setPreEq(Eq preEq) {
+            if (preEq.getBandCount() != mPreEq.getBandCount()) {
+                throw new IllegalArgumentException("PreEqBandCount changed from " +
+                        mPreEq.getBandCount() + " to " + preEq.getBandCount());
+            }
+            mPreEq = new Eq(preEq);
+        }
+        /**
+         * Gets EqBand for PreEq stage for given band index.
+         * @param band index of band of interest from PreEq stage
+         * @return EqBand configuration
+         */
+        public EqBand getPreEqBand(int band) {
+            return mPreEq.getBand(band);
+        }
+        /**
+         * Sets EqBand for PreEq stage for given band index
+         * @param band index of band of interest from PreEq stage
+         * @param preEqBand configuration to be set.
+         */
+        public void setPreEqBand(int band, EqBand preEqBand) {
+            mPreEq.setBand(band, preEqBand);
+        }
+
+        /**
+         * Gets Mbc configuration stage
+         * @return Mbc configuration stage
+         */
+        public Mbc getMbc() {
+            return mMbc;
+        }
+        /**
+         * Sets Mbc configuration stage. New Mbc stage must have the same number of bands than
+         * original Mbc stage.
+         * @param mbc
+         */
+        public void setMbc(Mbc mbc) {
+            if (mbc.getBandCount() != mMbc.getBandCount()) {
+                throw new IllegalArgumentException("MbcBandCount changed from " +
+                        mMbc.getBandCount() + " to " + mbc.getBandCount());
+            }
+            mMbc = new Mbc(mbc);
+        }
+        /**
+         * Gets MbcBand configuration for Mbc stage, for given band index.
+         * @param band index of band of interest from Mbc stage
+         * @return MbcBand configuration
+         */
+        public MbcBand getMbcBand(int band) {
+            return mMbc.getBand(band);
+        }
+        /**
+         * Sets MbcBand for Mbc stage for given band index
+         * @param band index of band of interest from Mbc Stage
+         * @param mbcBand configuration to be set
+         */
+        public void setMbcBand(int band, MbcBand mbcBand) {
+            mMbc.setBand(band, mbcBand);
+        }
+
+        /**
+         * Gets PostEq configuration stage
+         * @return PostEq configuration stage
+         */
+        public Eq getPostEq() {
+            return mPostEq;
+        }
+        /**
+         * Sets PostEq configuration stage. New PostEq stage must have the same number of bands than
+         * original PostEq stage.
+         * @param postEq configuration
+         */
+        public void setPostEq(Eq postEq) {
+            if (postEq.getBandCount() != mPostEq.getBandCount()) {
+                throw new IllegalArgumentException("PostEqBandCount changed from " +
+                        mPostEq.getBandCount() + " to " + postEq.getBandCount());
+            }
+            mPostEq = new Eq(postEq);
+        }
+        /**
+         * Gets EqBand for PostEq stage for given band index.
+         * @param band index of band of interest from PostEq stage
+         * @return EqBand configuration
+         */
+        public EqBand getPostEqBand(int band) {
+            return mPostEq.getBand(band);
+        }
+        /**
+         * Sets EqBand for PostEq stage for given band index
+         * @param band index of band of interest from PostEq stage
+         * @param postEqBand configuration to be set.
+         */
+        public void setPostEqBand(int band, EqBand postEqBand) {
+            mPostEq.setBand(band, postEqBand);
+        }
+
+        /**
+         * Gets Limiter configuration stage
+         * @return Limiter configuration stage
+         */
+        public Limiter getLimiter() {
+            return mLimiter;
+        }
+        /**
+         * Sets Limiter configuration stage.
+         * @param limiter configuration stage.
+         */
+        public void setLimiter(Limiter limiter) {
+            mLimiter = new Limiter(limiter);
+        }
+    }
+
+    /**
+     * Class for Config object, used by DynamicsProcessing to configure and update the audio effect.
+     * use Builder to instantiate objects of this type.
+     */
+    public final static class Config {
+        private final int mVariant;
+        private final int mChannelCount;
+        private final boolean mPreEqInUse;
+        private final int mPreEqBandCount;
+        private final boolean mMbcInUse;
+        private final int mMbcBandCount;
+        private final boolean mPostEqInUse;
+        private final int mPostEqBandCount;
+        private final boolean mLimiterInUse;
+        private final float mPreferredFrameDuration;
+        private final Channel[] mChannel;
+
+        /**
+         * @hide
+         * Class constructor for config. None of these parameters can be changed later.
+         * @param variant index of variant used for effect engine. See
+         * {@link #VARIANT_FAVOR_FREQUENCY_RESOLUTION} and {@link #VARIANT_FAVOR_TIME_RESOLUTION}.
+         * @param frameDurationMs preferred frame duration in milliseconds (ms).
+         * @param channelCount Number of channels to be configured.
+         * @param preEqInUse true if PreEq stage will be used, false otherwise.
+         * @param preEqBandCount number of bands for PreEq stage.
+         * @param mbcInUse true if Mbc stage will be used, false otherwise.
+         * @param mbcBandCount number of bands for Mbc stage.
+         * @param postEqInUse true if PostEq stage will be used, false otherwise.
+         * @param postEqBandCount number of bands for PostEq stage.
+         * @param limiterInUse true if Limiter stage will be used, false otherwise.
+         * @param channel array of Channel objects to be used for this configuration.
+         */
+        public Config(int variant, float frameDurationMs, int channelCount,
+                boolean preEqInUse, int preEqBandCount,
+                boolean mbcInUse, int mbcBandCount,
+                boolean postEqInUse, int postEqBandCount,
+                boolean limiterInUse,
+                Channel[] channel) {
+            mVariant = variant;
+            mPreferredFrameDuration = frameDurationMs;
+            mChannelCount = channelCount;
+            mPreEqInUse = preEqInUse;
+            mPreEqBandCount = preEqBandCount;
+            mMbcInUse = mbcInUse;
+            mMbcBandCount = mbcBandCount;
+            mPostEqInUse = postEqInUse;
+            mPostEqBandCount = postEqBandCount;
+            mLimiterInUse = limiterInUse;
+
+            mChannel = new Channel[mChannelCount];
+            //check if channelconfig is null or has less channels than channel count.
+            //options: fill the missing with default options.
+            //  or fail?
+            for (int ch = 0; ch < mChannelCount; ch++) {
+                if (ch < channel.length) {
+                    mChannel[ch] = new Channel(channel[ch]); //copy create
+                } else {
+                    //create a new one from scratch? //fail?
+                }
+            }
+        }
+        //a version that will scale to necessary number of channels
+        /**
+         * @hide
+         * Class constructor for Configuration.
+         * @param channelCount limit configuration to this number of channels. if channelCount is
+         * greater than number of channels in cfg, the constructor will duplicate the last channel
+         * found as many times as necessary to create a Config with channelCount number of channels.
+         * If channelCount is less than channels in cfg, the extra channels in cfg will be ignored.
+         * @param cfg copy constructor paremter.
+         */
+        public Config(int channelCount, Config cfg) {
+            mVariant = cfg.mVariant;
+            mPreferredFrameDuration = cfg.mPreferredFrameDuration;
+            mChannelCount = cfg.mChannelCount;
+            mPreEqInUse = cfg.mPreEqInUse;
+            mPreEqBandCount = cfg.mPreEqBandCount;
+            mMbcInUse = cfg.mMbcInUse;
+            mMbcBandCount = cfg.mMbcBandCount;
+            mPostEqInUse = cfg.mPostEqInUse;
+            mPostEqBandCount = cfg.mPostEqBandCount;
+            mLimiterInUse = cfg.mLimiterInUse;
+
+            if (mChannelCount != cfg.mChannel.length) {
+                throw new IllegalArgumentException("configuration channel counts differ " +
+                        mChannelCount + " !=" + cfg.mChannel.length);
+            }
+            if (channelCount < 1) {
+                throw new IllegalArgumentException("channel resizing less than 1 not allowed");
+            }
+
+            mChannel = new Channel[channelCount];
+            for (int ch = 0; ch < channelCount; ch++) {
+                if (ch < mChannelCount) {
+                    mChannel[ch] = new Channel(cfg.mChannel[ch]);
+                } else {
+                    //duplicate last
+                    mChannel[ch] = new Channel(cfg.mChannel[mChannelCount-1]);
+                }
+            }
+        }
+
+        /**
+         * @hide
+         * Class constructor for Config
+         * @param cfg Configuration object copy constructor
+         */
+        public Config(Config cfg) {
+            this(cfg.mChannelCount, cfg);
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(String.format("Variant: %d\n", mVariant));
+            sb.append(String.format("PreferredFrameDuration: %f\n", mPreferredFrameDuration));
+            sb.append(String.format("ChannelCount: %d\n", mChannelCount));
+            sb.append(String.format("PreEq inUse: %b, bandCount:%d\n",mPreEqInUse,
+                    mPreEqBandCount));
+            sb.append(String.format("Mbc inUse: %b, bandCount: %d\n",mMbcInUse, mMbcBandCount));
+            sb.append(String.format("PostEq inUse: %b, bandCount: %d\n", mPostEqInUse,
+                    mPostEqBandCount));
+            sb.append(String.format("Limiter inUse: %b\n", mLimiterInUse));
+            for (int ch = 0; ch < mChannel.length; ch++) {
+                sb.append(String.format("==Channel %d\n", ch));
+                sb.append(mChannel[ch].toString());
+            }
+            return sb.toString();
+        }
+        private void checkChannel(int channelIndex) {
+            if (channelIndex < 0 || channelIndex >= mChannel.length) {
+                throw new IllegalArgumentException("ChannelIndex out of bounds");
+            }
+        }
+
+        //getters and setters
+        /**
+         * Gets variant for effect engine See {@link #VARIANT_FAVOR_FREQUENCY_RESOLUTION} and
+         * {@link #VARIANT_FAVOR_TIME_RESOLUTION}.
+         * @return variant of effect engine
+         */
+        public int getVariant() {
+            return mVariant;
+        }
+        /**
+         * Gets preferred frame duration in milliseconds (ms).
+         * @return preferred frame duration in milliseconds (ms)
+         */
+        public float getPreferredFrameDuration() {
+            return mPreferredFrameDuration;
+        }
+        /**
+         * Gets if preEq stage is in use
+         * @return true if preEq stage is in use;
+         */
+        public boolean isPreEqInUse() {
+            return mPreEqInUse;
+        }
+        /**
+         * Gets number of bands configured for the PreEq stage.
+         * @return number of bands configured for the PreEq stage.
+         */
+        public int getPreEqBandCount() {
+            return mPreEqBandCount;
+        }
+        /**
+         * Gets if Mbc stage is in use
+         * @return true if Mbc stage is in use;
+         */
+        public boolean isMbcInUse() {
+            return mMbcInUse;
+        }
+        /**
+         * Gets number of bands configured for the Mbc stage.
+         * @return number of bands configured for the Mbc stage.
+         */
+        public int getMbcBandCount() {
+            return mMbcBandCount;
+        }
+        /**
+         * Gets if PostEq stage is in use
+         * @return true if PostEq stage is in use;
+         */
+        public boolean isPostEqInUse() {
+            return mPostEqInUse;
+        }
+        /**
+         * Gets number of bands configured for the PostEq stage.
+         * @return number of bands configured for the PostEq stage.
+         */
+        public int getPostEqBandCount() {
+            return mPostEqBandCount;
+        }
+        /**
+         * Gets if Limiter stage is in use
+         * @return true if Limiter stage is in use;
+         */
+        public boolean isLimiterInUse() {
+            return mLimiterInUse;
+        }
+
+        //channel
+        /**
+         * Gets the Channel configuration object by using the channel index
+         * @param channelIndex of desired Channel object
+         * @return Channel configuration object
+         */
+        public Channel getChannelByChannelIndex(int channelIndex) {
+            checkChannel(channelIndex);
+            return mChannel[channelIndex];
+        }
+
+        /**
+         * Sets the chosen Channel object in the selected channelIndex
+         * Note that all the stages should have the same number of bands than the existing Channel
+         * object.
+         * @param channelIndex index of channel to be replaced
+         * @param channel Channel configuration object to be set
+         */
+        public void setChannelTo(int channelIndex, Channel channel) {
+            checkChannel(channelIndex);
+            //check all things are compatible
+            if (mMbcBandCount != channel.getMbc().getBandCount()) {
+                throw new IllegalArgumentException("MbcBandCount changed from " +
+                        mMbcBandCount + " to " + channel.getPreEq().getBandCount());
+            }
+            if (mPreEqBandCount != channel.getPreEq().getBandCount()) {
+                throw new IllegalArgumentException("PreEqBandCount changed from " +
+                        mPreEqBandCount + " to " + channel.getPreEq().getBandCount());
+            }
+            if (mPostEqBandCount != channel.getPostEq().getBandCount()) {
+                throw new IllegalArgumentException("PostEqBandCount changed from " +
+                        mPostEqBandCount + " to " + channel.getPostEq().getBandCount());
+            }
+            mChannel[channelIndex] = new Channel(channel);
+        }
+
+        /**
+         * Sets ALL channels to the chosen Channel object. Note that all the stages should have the
+         * same number of bands than the existing ones.
+         * @param channel Channel configuration object to be set.
+         */
+        public void setAllChannelsTo(Channel channel) {
+            for (int ch = 0; ch < mChannel.length; ch++) {
+                setChannelTo(ch, channel);
+            }
+        }
+
+        //===channel params
+        /**
+         * Gets inputGain value in decibels (dB) for channel indicated by channelIndex
+         * @param channelIndex index of channel of interest
+         * @return inputGain value in decibels (dB). 0 dB means no change.
+         */
+        public float getInputGainByChannelIndex(int channelIndex) {
+            checkChannel(channelIndex);
+            return mChannel[channelIndex].getInputGain();
+        }
+        /**
+         * Sets the inputGain value in decibels (dB) for the channel indicated by channelIndex.
+         * @param channelIndex index of channel of interest
+         * @param inputGain desired value in decibels (dB).
+         */
+        public void setInputGainByChannelIndex(int channelIndex, float inputGain) {
+            checkChannel(channelIndex);
+            mChannel[channelIndex].setInputGain(inputGain);
+        }
+        /**
+         * Sets the inputGain value in decibels (dB) for ALL channels
+         * @param inputGain desired value in decibels (dB)
+         */
+        public void setInputGainAllChannelsTo(float inputGain) {
+            for (int ch = 0; ch < mChannel.length; ch++) {
+                mChannel[ch].setInputGain(inputGain);
+            }
+        }
+
+        //=== PreEQ
+        /**
+         * Gets PreEq stage from channel indicated by channelIndex
+         * @param channelIndex index of channel of interest
+         * @return PreEq stage configuration object
+         */
+        public Eq getPreEqByChannelIndex(int channelIndex) {
+            checkChannel(channelIndex);
+            return mChannel[channelIndex].getPreEq();
+        }
+        /**
+         * Sets the PreEq stage configuration for the channel indicated by channelIndex. Note that
+         * new preEq stage must have the same number of bands than original preEq stage
+         * @param channelIndex index of channel to be set
+         * @param preEq desired PreEq configuration to be set
+         */
+        public void setPreEqByChannelIndex(int channelIndex, Eq preEq) {
+            checkChannel(channelIndex);
+            mChannel[channelIndex].setPreEq(preEq);
+        }
+        /**
+         * Sets the PreEq stage configuration for ALL channels. Note that new preEq stage must have
+         * the same number of bands than original preEq stages.
+         * @param preEq desired PreEq configuration to be set
+         */
+        public void setPreEqAllChannelsTo(Eq preEq) {
+            for (int ch = 0; ch < mChannel.length; ch++) {
+                mChannel[ch].setPreEq(preEq);
+            }
+        }
+        public EqBand getPreEqBandByChannelIndex(int channelIndex, int band) {
+            checkChannel(channelIndex);
+            return mChannel[channelIndex].getPreEqBand(band);
+        }
+        public void setPreEqBandByChannelIndex(int channelIndex, int band, EqBand preEqBand) {
+            checkChannel(channelIndex);
+            mChannel[channelIndex].setPreEqBand(band, preEqBand);
+        }
+        public void setPreEqBandAllChannelsTo(int band, EqBand preEqBand) {
+            for (int ch = 0; ch < mChannel.length; ch++) {
+                mChannel[ch].setPreEqBand(band, preEqBand);
+            }
+        }
+
+        //=== MBC
+        public Mbc getMbcByChannelIndex(int channelIndex) {
+            checkChannel(channelIndex);
+            return mChannel[channelIndex].getMbc();
+        }
+        public void setMbcByChannelIndex(int channelIndex, Mbc mbc) {
+            checkChannel(channelIndex);
+            mChannel[channelIndex].setMbc(mbc);
+        }
+        public void setMbcAllChannelsTo(Mbc mbc) {
+            for (int ch = 0; ch < mChannel.length; ch++) {
+                mChannel[ch].setMbc(mbc);
+            }
+        }
+        public MbcBand getMbcBandByChannelIndex(int channelIndex, int band) {
+            checkChannel(channelIndex);
+            return mChannel[channelIndex].getMbcBand(band);
+        }
+        public void setMbcBandByChannelIndex(int channelIndex, int band, MbcBand mbcBand) {
+            checkChannel(channelIndex);
+            mChannel[channelIndex].setMbcBand(band, mbcBand);
+        }
+        public void setMbcBandAllChannelsTo(int band, MbcBand mbcBand) {
+            for (int ch = 0; ch < mChannel.length; ch++) {
+                mChannel[ch].setMbcBand(band, mbcBand);
+            }
+        }
+
+        //=== PostEQ
+        public Eq getPostEqByChannelIndex(int channelIndex) {
+            checkChannel(channelIndex);
+            return mChannel[channelIndex].getPostEq();
+        }
+        public void setPostEqByChannelIndex(int channelIndex, Eq postEq) {
+            checkChannel(channelIndex);
+            mChannel[channelIndex].setPostEq(postEq);
+        }
+        public void setPostEqAllChannelsTo(Eq postEq) {
+            for (int ch = 0; ch < mChannel.length; ch++) {
+                mChannel[ch].setPostEq(postEq);
+            }
+        }
+        public EqBand getPostEqBandByChannelIndex(int channelIndex, int band) {
+            checkChannel(channelIndex);
+            return mChannel[channelIndex].getPostEqBand(band);
+        }
+        public void setPostEqBandByChannelIndex(int channelIndex, int band, EqBand postEqBand) {
+            checkChannel(channelIndex);
+            mChannel[channelIndex].setPostEqBand(band, postEqBand);
+        }
+        public void setPostEqBandAllChannelsTo(int band, EqBand postEqBand) {
+            for (int ch = 0; ch < mChannel.length; ch++) {
+                mChannel[ch].setPostEqBand(band, postEqBand);
+            }
+        }
+
+        //Limiter
+        public Limiter getLimiterByChannelIndex(int channelIndex) {
+            checkChannel(channelIndex);
+            return mChannel[channelIndex].getLimiter();
+        }
+        public void setLimiterByChannelIndex(int channelIndex, Limiter limiter) {
+            checkChannel(channelIndex);
+            mChannel[channelIndex].setLimiter(limiter);
+        }
+        public void setLimiterAllChannelsTo(Limiter limiter) {
+            for (int ch = 0; ch < mChannel.length; ch++) {
+                mChannel[ch].setLimiter(limiter);
+            }
+        }
+
+        public final static class Builder {
+            private int mVariant;
+            private int mChannelCount;
+            private boolean mPreEqInUse;
+            private int mPreEqBandCount;
+            private boolean mMbcInUse;
+            private int mMbcBandCount;
+            private boolean mPostEqInUse;
+            private int mPostEqBandCount;
+            private boolean mLimiterInUse;
+            private float mPreferredFrameDuration = CONFIG_PREFERRED_FRAME_DURATION_MS;
+            private Channel[] mChannel;
+
+            public Builder(int variant, int channelCount,
+                    boolean preEqInUse, int preEqBandCount,
+                    boolean mbcInUse, int mbcBandCount,
+                    boolean postEqInUse, int postEqBandCount,
+                    boolean limiterInUse) {
+                mVariant = variant;
+                mChannelCount = channelCount;
+                mPreEqInUse = preEqInUse;
+                mPreEqBandCount = preEqBandCount;
+                mMbcInUse = mbcInUse;
+                mMbcBandCount = mbcBandCount;
+                mPostEqInUse = postEqInUse;
+                mPostEqBandCount = postEqBandCount;
+                mLimiterInUse = limiterInUse;
+                mChannel = new Channel[mChannelCount];
+                for (int ch = 0; ch < mChannelCount; ch++) {
+                    this.mChannel[ch] = new Channel(CHANNEL_DEFAULT_INPUT_GAIN,
+                            this.mPreEqInUse, this.mPreEqBandCount,
+                            this.mMbcInUse, this.mMbcBandCount,
+                            this.mPostEqInUse, this.mPostEqBandCount,
+                            this.mLimiterInUse);
+                }
+            }
+
+            private void checkChannel(int channelIndex) {
+                if (channelIndex < 0 || channelIndex >= mChannel.length) {
+                    throw new IllegalArgumentException("ChannelIndex out of bounds");
+                }
+            }
+
+            public Builder setPreferredFrameDuration(float frameDuration) {
+                if (frameDuration < 0) {
+                    throw new IllegalArgumentException("Expected positive frameDuration");
+                }
+                mPreferredFrameDuration = frameDuration;
+                return this;
+            }
+
+            public Builder setInputGainByChannelIndex(int channelIndex, float inputGain) {
+                checkChannel(channelIndex);
+                mChannel[channelIndex].setInputGain(inputGain);
+                return this;
+            }
+            public Builder setInputGainAllChannelsTo(float inputGain) {
+                for (int ch = 0; ch < mChannel.length; ch++) {
+                    mChannel[ch].setInputGain(inputGain);
+                }
+                return this;
+            }
+
+            public Builder setChannelTo(int channelIndex, Channel channel) {
+                checkChannel(channelIndex);
+                //check all things are compatible
+                if (mMbcBandCount != channel.getMbc().getBandCount()) {
+                    throw new IllegalArgumentException("MbcBandCount changed from " +
+                            mMbcBandCount + " to " + channel.getPreEq().getBandCount());
+                }
+                if (mPreEqBandCount != channel.getPreEq().getBandCount()) {
+                    throw new IllegalArgumentException("PreEqBandCount changed from " +
+                            mPreEqBandCount + " to " + channel.getPreEq().getBandCount());
+                }
+                if (mPostEqBandCount != channel.getPostEq().getBandCount()) {
+                    throw new IllegalArgumentException("PostEqBandCount changed from " +
+                            mPostEqBandCount + " to " + channel.getPostEq().getBandCount());
+                }
+                mChannel[channelIndex] = new Channel(channel);
+                return this;
+            }
+            public Builder setAllChannelsTo(Channel channel) {
+                for (int ch = 0; ch < mChannel.length; ch++) {
+                    setChannelTo(ch, channel);
+                }
+                return this;
+            }
+
+            public Builder setPreEqByChannelIndex(int channelIndex, Eq preEq) {
+                checkChannel(channelIndex);
+                mChannel[channelIndex].setPreEq(preEq);
+                return this;
+            }
+            public Builder setPreEqAllChannelsTo(Eq preEq) {
+                for (int ch = 0; ch < mChannel.length; ch++) {
+                    setPreEqByChannelIndex(ch, preEq);
+                }
+                return this;
+            }
+
+            public Builder setMbcByChannelIndex(int channelIndex, Mbc mbc) {
+                checkChannel(channelIndex);
+                mChannel[channelIndex].setMbc(mbc);
+                return this;
+            }
+            public Builder setMbcAllChannelsTo(Mbc mbc) {
+                for (int ch = 0; ch < mChannel.length; ch++) {
+                    setMbcByChannelIndex(ch, mbc);
+                }
+                return this;
+            }
+
+            public Builder setPostEqByChannelIndex(int channelIndex, Eq postEq) {
+                checkChannel(channelIndex);
+                mChannel[channelIndex].setPostEq(postEq);
+                return this;
+            }
+            public Builder setPostEqAllChannelsTo(Eq postEq) {
+                for (int ch = 0; ch < mChannel.length; ch++) {
+                    setPostEqByChannelIndex(ch, postEq);
+                }
+                return this;
+            }
+
+            public Builder setLimiterByChannelIndex(int channelIndex, Limiter limiter) {
+                checkChannel(channelIndex);
+                mChannel[channelIndex].setLimiter(limiter);
+                return this;
+            }
+            public Builder setLimiterAllChannelsTo(Limiter limiter) {
+                for (int ch = 0; ch < mChannel.length; ch++) {
+                    setLimiterByChannelIndex(ch, limiter);
+                }
+                return this;
+            }
+
+            public Config build() {
+                return new Config(mVariant, mPreferredFrameDuration, mChannelCount,
+                        mPreEqInUse, mPreEqBandCount,
+                        mMbcInUse, mMbcBandCount,
+                        mPostEqInUse, mPostEqBandCount,
+                        mLimiterInUse, mChannel);
+            }
+        }
+    }
+    //=== CHANNEL
+    public Channel getChannelByChannelIndex(int channelIndex) {
+        return mConfig.getChannelByChannelIndex(channelIndex);
+    }
+
+    public void setChannelTo(int channelIndex, Channel channel) {
+        mConfig.setChannelTo(channelIndex, channel);
+    }
+
+    public void setAllChannelsTo(Channel channel) {
+        mConfig.setAllChannelsTo(channel);
+    }
+
+    //=== channel params
+    public float getInputGainByChannelIndex(int channelIndex) {
+        //TODO: return info from engine instead of cached config
+        return mConfig.getInputGainByChannelIndex(channelIndex);
+    }
+    public void setInputGainbyChannel(int channelIndex, float inputGain) {
+        mConfig.setInputGainByChannelIndex(channelIndex, inputGain);
+        //TODO: communicate change to engine
+    }
+    public void setInputGainAllChannelsTo(float inputGain) {
+        mConfig.setInputGainAllChannelsTo(inputGain);
+        //TODO: communicate change to engine
+    }
+
+    //=== PreEQ
+    public Eq getPreEqByChannelIndex(int channelIndex) {
+        //TODO: return info from engine instead of cached config
+        return mConfig.getPreEqByChannelIndex(channelIndex);
+    }
+
+    public void setPreEqByChannelIndex(int channelIndex, Eq preEq) {
+        mConfig.setPreEqByChannelIndex(channelIndex, preEq);
+        //TODO: communicate change to engine
+    }
+
+    public void setPreEqAllChannelsTo(Eq preEq) {
+        mConfig.setPreEqAllChannelsTo(preEq);
+        //TODO: communicate change to engine
+    }
+
+    public EqBand getPreEqBandByChannelIndex(int channelIndex, int band) {
+        //TODO: return info from engine instead of cached config
+        return mConfig.getPreEqBandByChannelIndex(channelIndex, band);
+    }
+
+    public void setPreEqBandByChannelIndex(int channelIndex, int band, EqBand preEqBand) {
+        mConfig.setPreEqBandByChannelIndex(channelIndex, band, preEqBand);
+        //TODO: communicate change to engine
+    }
+
+    public void setPreEqBandAllChannelsTo(int band, EqBand preEqBand) {
+        mConfig.setPreEqBandAllChannelsTo(band, preEqBand);
+        //TODO: communicate change to engine
+    }
+
+    //=== MBC
+    public Mbc getMbcByChannelIndex(int channelIndex) {
+        //TODO: return info from engine instead of cached config
+        return mConfig.getMbcByChannelIndex(channelIndex);
+    }
+
+    public void setMbcByChannelIndex(int channelIndex, Mbc mbc) {
+        mConfig.setMbcByChannelIndex(channelIndex, mbc);
+        //TODO: communicate change to engine
+    }
+
+    public void setMbcAllChannelsTo(Mbc mbc) {
+        mConfig.setMbcAllChannelsTo(mbc);
+        //TODO: communicate change to engine
+    }
+
+    public MbcBand getMbcBandByChannelIndex(int channelIndex, int band) {
+        //TODO: return info from engine instead of cached config
+        return mConfig.getMbcBandByChannelIndex(channelIndex, band);
+    }
+
+    public void setMbcBandByChannelIndex(int channelIndex, int band, MbcBand mbcBand) {
+        mConfig.setMbcBandByChannelIndex(channelIndex, band, mbcBand);
+        //TODO: communicate change to engine
+    }
+
+    public void setMbcBandAllChannelsTo(int band, MbcBand mbcBand) {
+        mConfig.setMbcBandAllChannelsTo(band, mbcBand);
+        //TODO: communicate change to engine
+    }
+
+    //== PostEq
+    public Eq getPostEqByChannelIndex(int channelIndex) {
+        //TODO: return info from engine instead of cached config
+        return mConfig.getPostEqByChannelIndex(channelIndex);
+    }
+
+    public void setPostEqByChannelIndex(int channelIndex, Eq postEq) {
+        mConfig.setPostEqByChannelIndex(channelIndex, postEq);
+        //TODO: communicate change to engine
+    }
+
+    public void setPostEqAllChannelsTo(Eq postEq) {
+        mConfig.setPostEqAllChannelsTo(postEq);
+        //TODO: communicate change to engine
+    }
+
+    public EqBand getPostEqBandByChannelIndex(int channelIndex, int band) {
+        //TODO: return info from engine instead of cached config
+        return mConfig.getPostEqBandByChannelIndex(channelIndex, band);
+    }
+
+    public void setPostEqBandByChannelIndex(int channelIndex, int band, EqBand postEqBand) {
+        mConfig.setPostEqBandByChannelIndex(channelIndex, band, postEqBand);
+        //TODO: communicate change to engine
+    }
+
+    public void setPostEqBandAllChannelsTo(int band, EqBand postEqBand) {
+        mConfig.setPostEqBandAllChannelsTo(band, postEqBand);
+        //TODO: communicate change to engine
+    }
+
+    //==== Limiter
+    public Limiter getLimiterByChannelIndex(int channelIndex) {
+        //TODO: return info from engine instead of cached config
+        return mConfig.getLimiterByChannelIndex(channelIndex);
+    }
+
+    public void setLimiterByChannelIndex(int channelIndex, Limiter limiter) {
+        mConfig.setLimiterByChannelIndex(channelIndex, limiter);
+        //TODO: communicate change to engine
+    }
+
+    public void setLimiterAllChannelsTo(Limiter limiter) {
+        mConfig.setLimiterAllChannelsTo(limiter);
+        //TODO: communicate change to engine
+    }
+
+    /**
+     * Gets the number of channels in the effect engine
+     * @return number of channels currently in use by the effect engine
+     */
+    public int getChannelCount() {
+        return getOneInt(PARAM_GET_CHANNEL_COUNT);
+    }
+
+    private void setEngineArchitecture(int variant, boolean preEqInUse, int preEqBandCount,
+            boolean mbcInUse, int mbcBandCount, boolean postEqInUse, int postEqBandCount,
+            boolean limiterInUse) {
+        int[] values = { variant, (preEqInUse ? 1 : 0), preEqBandCount,
+                (mbcInUse ? 1 : 0), mbcBandCount, (postEqInUse ? 1 : 0), postEqBandCount,
+                (limiterInUse ? 1 : 0)};
+        //TODO: enable later setIntArray(PARAM_SET_ENGINE_ARCHITECTURE, values);
+    }
+
+    //****** convenience methods:
+    //
+    private int getOneInt(int paramGet) {
+        int[] param = new int[1];
+        int[] result = new int[1];
+
+        param[0] = paramGet;
+        checkStatus(getParameter(param, result));
+        return result[0];
+    }
+
+    private int getTwoInt(int paramGet, int paramA) {
+        int[] param = new int[2];
+        int[] result = new int[1];
+
+        param[0] = paramGet;
+        param[1] = paramA;
+        checkStatus(getParameter(param, result));
+        return result[0];
+    }
+
+    private int getThreeInt(int paramGet, int paramA, int paramB) {
+        //have to use bytearrays, with more than 2 parameters.
+        byte[] paramBytes = concatArrays(intToByteArray(paramGet),
+                intToByteArray(paramA),
+                intToByteArray(paramB));
+        byte[] resultBytes = new byte[4]; //single int
+
+        checkStatus(getParameter(paramBytes, resultBytes));
+
+        return byteArrayToInt(resultBytes);
+    }
+
+    private void setOneInt(int paramSet, int valueSet) {
+        int[] param = new int[1];
+        int[] value = new int[1];
+
+        param[0] = paramSet;
+        value[0] = valueSet;
+        checkStatus(setParameter(param, value));
+    }
+
+    private void setTwoInt(int paramSet, int paramA, int valueSet) {
+        int[] param = new int[2];
+        int[] value = new int[1];
+
+        param[0] = paramSet;
+        param[1] = paramA;
+        value[0] = valueSet;
+        checkStatus(setParameter(param, value));
+    }
+
+    private void setThreeInt(int paramSet, int paramA, int paramB, int valueSet) {
+        //have to use bytearrays, with more than 2 parameters.
+        byte[] paramBytes = concatArrays(intToByteArray(paramSet),
+                intToByteArray(paramA),
+                intToByteArray(paramB));
+        byte[] valueBytes = intToByteArray(valueSet);
+
+        checkStatus(setParameter(paramBytes, valueBytes));
+    }
+
+    private void setOneFloat(int paramSet, float valueSet) {
+        int[] param = new int[1];
+        byte[] value;
+
+        param[0] = paramSet;
+        value = floatToByteArray(valueSet);
+        checkStatus(setParameter(param, value));
+    }
+
+    private void setTwoFloat(int paramSet, int paramA, float valueSet) {
+        int[] param = new int[2];
+        byte[] value;
+
+        param[0] = paramSet;
+        param[1] = paramA;
+        value = floatToByteArray(valueSet);
+        checkStatus(setParameter(param, value));
+    }
+
+    private void setThreeFloat(int paramSet, int paramA, int paramB, float valueSet) {
+        //have to use bytearrays, with more than 2 parameters.
+        byte[] paramBytes = concatArrays(intToByteArray(paramSet),
+                intToByteArray(paramA),
+                intToByteArray(paramB));
+        byte[] valueBytes = floatToByteArray(valueSet);
+
+        checkStatus(setParameter(paramBytes, valueBytes));
+    }
+    private byte[] intArrayToByteArray(int[] values) {
+        int expectedBytes = values.length * 4;
+        ByteBuffer converter = ByteBuffer.allocate(expectedBytes);
+        converter.order(ByteOrder.nativeOrder());
+        for (int k = 0; k < values.length; k++) {
+            converter.putFloat(values[k]);
+        }
+        return converter.array();
+    }
+    private void setIntArray(int paramSet, int[] paramArray) {
+        //have to use bytearrays, with more than 2 parameters.
+        byte[] paramBytes = intToByteArray(paramSet);
+        byte[] valueBytes = intArrayToByteArray(paramArray);
+
+        checkStatus(setParameter(paramBytes, valueBytes));
+    }
+
+    private float getOneFloat(int paramGet) {
+        int[] param = new int[1];
+        byte[] result = new byte[4];
+
+        param[0] = paramGet;
+        checkStatus(getParameter(param, result));
+        return byteArrayToFloat(result);
+    }
+
+    private float getTwoFloat(int paramGet, int paramA) {
+        int[] param = new int[2];
+        byte[] result = new byte[4];
+
+        param[0] = paramGet;
+        param[1] = paramA;
+        checkStatus(getParameter(param, result));
+        return byteArrayToFloat(result);
+    }
+
+    private float getThreeFloat(int paramGet, int paramA, int paramB) {
+        //have to use bytearrays, with more than 2 parameters.
+        byte[] paramBytes = concatArrays(intToByteArray(paramGet),
+                intToByteArray(paramA),
+                intToByteArray(paramB));
+        byte[] resultBytes = new byte[4]; //single float
+
+        checkStatus(getParameter(paramBytes, resultBytes));
+
+        return byteArrayToFloat(resultBytes);
+    }
+
+    private float[] getOneFloatArray(int paramGet, int expectedSize) {
+        int[] param = new int[1];
+        byte[] result = new byte[4 * expectedSize];
+
+        param[0] = paramGet;
+        checkStatus(getParameter(param, result));
+        float[] returnArray = new float[expectedSize];
+        for (int k = 0; k < expectedSize; k++) {
+            returnArray[k] = byteArrayToFloat(result, 4 * k);
+        }
+        return returnArray;
+    }
+    /**
+     * @hide
+     * The OnParameterChangeListener interface defines a method called by the DynamicsProcessing
+     * when a parameter value has changed.
+     */
+    public interface OnParameterChangeListener {
+        /**
+         * Method called when a parameter value has changed. The method is called only if the
+         * parameter was changed by another application having the control of the same
+         * DynamicsProcessing engine.
+         * @param effect the DynamicsProcessing on which the interface is registered.
+         * @param param ID of the modified parameter. See {@link #PARAM_GENERIC_PARAM1} ...
+         * @param value the new parameter value.
+         */
+        void onParameterChange(DynamicsProcessing effect, int param, int value);
+    }
+
+    /**
+     * helper method to update effect architecture parameters
+     */
+    private void updateEffectArchitecture() {
+        mChannelCount = getChannelCount();
+    }
+
+    /**
+     * Listener used internally to receive unformatted parameter change events from AudioEffect
+     * super class.
+     */
+    private class BaseParameterListener implements AudioEffect.OnParameterChangeListener {
+        private BaseParameterListener() {
+
+        }
+        public void onParameterChange(AudioEffect effect, int status, byte[] param, byte[] value) {
+            // only notify when the parameter was successfully change
+            if (status != AudioEffect.SUCCESS) {
+                return;
+            }
+            OnParameterChangeListener l = null;
+            synchronized (mParamListenerLock) {
+                if (mParamListener != null) {
+                    l = mParamListener;
+                }
+            }
+            if (l != null) {
+                int p = -1;
+                int v = Integer.MIN_VALUE;
+
+                if (param.length == 4) {
+                    p = byteArrayToInt(param, 0);
+                }
+                if (value.length == 4) {
+                    v = byteArrayToInt(value, 0);
+                }
+                if (p != -1 && v != Integer.MIN_VALUE) {
+                    l.onParameterChange(DynamicsProcessing.this, p, v);
+                }
+            }
+        }
+    }
+
+    /**
+     * @hide
+     * Registers an OnParameterChangeListener interface.
+     * @param listener OnParameterChangeListener interface registered
+     */
+    public void setParameterListener(OnParameterChangeListener listener) {
+        synchronized (mParamListenerLock) {
+            if (mParamListener == null) {
+                mBaseParamListener = new BaseParameterListener();
+                super.setParameterListener(mBaseParamListener);
+            }
+            mParamListener = listener;
+        }
+    }
+
+    /**
+     * @hide
+     * The Settings class regroups the DynamicsProcessing parameters. It is used in
+     * conjunction with the getProperties() and setProperties() methods to backup and restore
+     * all parameters in a single call.
+     */
+
+    public static class Settings {
+        public int channelCount;
+        public float[] inputGain;
+
+        public Settings() {
+        }
+
+        /**
+         * Settings class constructor from a key=value; pairs formatted string. The string is
+         * typically returned by Settings.toString() method.
+         * @throws IllegalArgumentException if the string is not correctly formatted.
+         */
+        public Settings(String settings) {
+            StringTokenizer st = new StringTokenizer(settings, "=;");
+            //int tokens = st.countTokens();
+            if (st.countTokens() != 3) {
+                throw new IllegalArgumentException("settings: " + settings);
+            }
+            String key = st.nextToken();
+            if (!key.equals("DynamicsProcessing")) {
+                throw new IllegalArgumentException(
+                        "invalid settings for DynamicsProcessing: " + key);
+            }
+            try {
+                key = st.nextToken();
+                if (!key.equals("channelCount")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                channelCount = Short.parseShort(st.nextToken());
+                if (channelCount > CHANNEL_COUNT_MAX) {
+                    throw new IllegalArgumentException("too many channels Settings:" + settings);
+                }
+                if (st.countTokens() != channelCount*1) { //check expected parameters.
+                    throw new IllegalArgumentException("settings: " + settings);
+                }
+                //check to see it is ok the size
+                inputGain = new float[channelCount];
+                for (int ch = 0; ch < channelCount; ch++) {
+                    key = st.nextToken();
+                    if (!key.equals(ch +"_inputGain")) {
+                        throw new IllegalArgumentException("invalid key name: " + key);
+                    }
+                    inputGain[ch] = Float.parseFloat(st.nextToken());
+                }
+             } catch (NumberFormatException nfe) {
+                throw new IllegalArgumentException("invalid value for key: " + key);
+            }
+        }
+
+        @Override
+        public String toString() {
+            String str = new String (
+                    "DynamicsProcessing"+
+                    ";channelCount="+Integer.toString(channelCount));
+                    for (int ch = 0; ch < channelCount; ch++) {
+                        str = str.concat(";"+ch+"_inputGain="+Float.toString(inputGain[ch]));
+                    }
+            return str;
+        }
+    };
+
+
+    /**
+     * @hide
+     * Gets the DynamicsProcessing properties. This method is useful when a snapshot of current
+     * effect settings must be saved by the application.
+     * @return a DynamicsProcessing.Settings object containing all current parameters values
+     */
+    public DynamicsProcessing.Settings getProperties() {
+        Settings settings = new Settings();
+
+        //TODO: just for testing, we are calling the getters one by one, this is
+        // supposed to be done in a single (or few calls) and get all the parameters at once.
+
+        settings.channelCount = getChannelCount();
+
+        if (settings.channelCount > CHANNEL_COUNT_MAX) {
+            throw new IllegalArgumentException("too many channels Settings:" + settings);
+        }
+
+        { // get inputGainmB per channel
+            settings.inputGain = new float [settings.channelCount];
+            for (int ch = 0; ch < settings.channelCount; ch++) {
+//TODO:with config                settings.inputGain[ch] = getInputGain(ch);
+            }
+        }
+        return settings;
+    }
+
+    /**
+     * @hide
+     * Sets the DynamicsProcessing properties. This method is useful when bass boost settings
+     * have to be applied from a previous backup.
+     * @param settings a DynamicsProcessing.Settings object containing the properties to apply
+     */
+    public void setProperties(DynamicsProcessing.Settings settings) {
+
+        if (settings.channelCount != settings.inputGain.length ||
+                settings.channelCount != mChannelCount) {
+                throw new IllegalArgumentException("settings invalid channel count: "
+                + settings.channelCount);
+            }
+
+        //TODO: for now calling multiple times.
+        for (int ch = 0; ch < mChannelCount; ch++) {
+//TODO: use config            setInputGain(ch, settings.inputGain[ch]);
+        }
+    }
+}
diff --git a/media/java/android/media/audiopolicy/AudioMix.java b/media/java/android/media/audiopolicy/AudioMix.java
index adeb834..39cdcf0 100644
--- a/media/java/android/media/audiopolicy/AudioMix.java
+++ b/media/java/android/media/audiopolicy/AudioMix.java
@@ -163,6 +163,19 @@
 
     /** @hide */
     @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        final AudioMix that = (AudioMix) o;
+        return (this.mRouteFlags == that.mRouteFlags)
+                && (this.mRule == that.mRule)
+                && (this.mMixType == that.mMixType)
+                && (this.mFormat == that.mFormat);
+    }
+
+    /** @hide */
+    @Override
     public int hashCode() {
         return Objects.hash(mRouteFlags, mRule, mMixType, mFormat);
     }
diff --git a/media/java/android/media/audiopolicy/AudioMixingRule.java b/media/java/android/media/audiopolicy/AudioMixingRule.java
index 5f12742..866b574 100644
--- a/media/java/android/media/audiopolicy/AudioMixingRule.java
+++ b/media/java/android/media/audiopolicy/AudioMixingRule.java
@@ -135,11 +135,31 @@
         }
     }
 
+    private static boolean areCriteriaEquivalent(ArrayList<AudioMixMatchCriterion> cr1,
+            ArrayList<AudioMixMatchCriterion> cr2) {
+        if (cr1 == null || cr2 == null) return false;
+        if (cr1 == cr2) return true;
+        if (cr1.size() != cr2.size()) return false;
+        //TODO iterate over rules to check they contain the same criterion
+        return (cr1.hashCode() == cr2.hashCode());
+    }
+
     private final int mTargetMixType;
     int getTargetMixType() { return mTargetMixType; }
     private final ArrayList<AudioMixMatchCriterion> mCriteria;
     ArrayList<AudioMixMatchCriterion> getCriteria() { return mCriteria; }
 
+    /** @hide */
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        final AudioMixingRule that = (AudioMixingRule) o;
+        return (this.mTargetMixType == that.mTargetMixType)
+                && (areCriteriaEquivalent(this.mCriteria, that.mCriteria));
+    }
+
     @Override
     public int hashCode() {
         return Objects.hash(mTargetMixType, mCriteria);
diff --git a/media/java/android/media/audiopolicy/AudioPolicy.java b/media/java/android/media/audiopolicy/AudioPolicy.java
index 343bbda..11107e2 100644
--- a/media/java/android/media/audiopolicy/AudioPolicy.java
+++ b/media/java/android/media/audiopolicy/AudioPolicy.java
@@ -42,6 +42,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
+import java.util.List;
 
 /**
  * @hide
@@ -256,6 +257,89 @@
         }
     }
 
+    /**
+     * @hide
+     * Update the current configuration of the set of audio mixes by adding new ones, while
+     * keeping the policy registered.
+     * This method can only be called on a registered policy.
+     * @param mixes the list of {@link AudioMix} to add
+     * @return {@link AudioManager#SUCCESS} if the change was successful, {@link AudioManager#ERROR}
+     *    otherwise.
+     */
+    @SystemApi
+    public int attachMixes(@NonNull List<AudioMix> mixes) {
+        if (mixes == null) {
+            throw new IllegalArgumentException("Illegal null list of AudioMix");
+        }
+        synchronized (mLock) {
+            if (mStatus != POLICY_STATUS_REGISTERED) {
+                throw new IllegalStateException("Cannot alter unregistered AudioPolicy");
+            }
+            final ArrayList<AudioMix> zeMixes = new ArrayList<AudioMix>(mixes.size());
+            for (AudioMix mix : mixes) {
+                if (mix == null) {
+                    throw new IllegalArgumentException("Illegal null AudioMix in attachMixes");
+                } else {
+                    zeMixes.add(mix);
+                }
+            }
+            final AudioPolicyConfig cfg = new AudioPolicyConfig(zeMixes);
+            IAudioService service = getService();
+            try {
+                final int status = service.addMixForPolicy(cfg, this.cb());
+                if (status == AudioManager.SUCCESS) {
+                    mConfig.add(zeMixes);
+                }
+                return status;
+            } catch (RemoteException e) {
+                Log.e(TAG, "Dead object in attachMixes", e);
+                return AudioManager.ERROR;
+            }
+        }
+    }
+
+    /**
+     * @hide
+     * Update the current configuration of the set of audio mixes by removing some, while
+     * keeping the policy registered.
+     * This method can only be called on a registered policy.
+     * @param mixes the list of {@link AudioMix} to remove
+     * @return {@link AudioManager#SUCCESS} if the change was successful, {@link AudioManager#ERROR}
+     *    otherwise.
+     */
+    @SystemApi
+    public int detachMixes(@NonNull List<AudioMix> mixes) {
+        if (mixes == null) {
+            throw new IllegalArgumentException("Illegal null list of AudioMix");
+        }
+        synchronized (mLock) {
+            if (mStatus != POLICY_STATUS_REGISTERED) {
+                throw new IllegalStateException("Cannot alter unregistered AudioPolicy");
+            }
+            final ArrayList<AudioMix> zeMixes = new ArrayList<AudioMix>(mixes.size());
+            for (AudioMix mix : mixes) {
+                if (mix == null) {
+                    throw new IllegalArgumentException("Illegal null AudioMix in detachMixes");
+                    // TODO also check mix is currently contained in list of mixes
+                } else {
+                    zeMixes.add(mix);
+                }
+            }
+            final AudioPolicyConfig cfg = new AudioPolicyConfig(zeMixes);
+            IAudioService service = getService();
+            try {
+                final int status = service.removeMixForPolicy(cfg, this.cb());
+                if (status == AudioManager.SUCCESS) {
+                    mConfig.remove(zeMixes);
+                }
+                return status;
+            } catch (RemoteException e) {
+                Log.e(TAG, "Dead object in detachMixes", e);
+                return AudioManager.ERROR;
+            }
+        }
+    }
+
     public void setRegistration(String regId) {
         synchronized (mLock) {
             mRegistrationId = regId;
diff --git a/media/java/android/media/audiopolicy/AudioPolicyConfig.java b/media/java/android/media/audiopolicy/AudioPolicyConfig.java
index cafa5a8..f725cac 100644
--- a/media/java/android/media/audiopolicy/AudioPolicyConfig.java
+++ b/media/java/android/media/audiopolicy/AudioPolicyConfig.java
@@ -16,6 +16,7 @@
 
 package android.media.audiopolicy;
 
+import android.annotation.NonNull;
 import android.media.AudioFormat;
 import android.media.AudioManager;
 import android.media.AudioPatch;
@@ -24,6 +25,8 @@
 import android.os.Parcelable;
 import android.util.Log;
 
+import com.android.internal.annotations.GuardedBy;
+
 import java.util.ArrayList;
 import java.util.Objects;
 
@@ -35,11 +38,16 @@
 
     private static final String TAG = "AudioPolicyConfig";
 
-    protected ArrayList<AudioMix> mMixes;
+    protected final ArrayList<AudioMix> mMixes;
     protected int mDuckingPolicy = AudioPolicy.FOCUS_POLICY_DUCKING_IN_APP;
 
     private String mRegistrationId = null;
 
+    /** counter for the mixes that are / have been in the list of AudioMix
+     *  e.g. register 4 mixes (counter is 3), remove 1 (counter is 3), add 1 (counter is 4)
+     */
+    private int mMixCounter = 0;
+
     protected AudioPolicyConfig(AudioPolicyConfig conf) {
         mMixes = conf.mMixes;
     }
@@ -201,20 +209,39 @@
             return;
         }
         mRegistrationId = regId == null ? "" : regId;
-        int mixIndex = 0;
         for (AudioMix mix : mMixes) {
-            if (!mRegistrationId.isEmpty()) {
-                if ((mix.getRouteFlags() & AudioMix.ROUTE_FLAG_LOOP_BACK) ==
-                        AudioMix.ROUTE_FLAG_LOOP_BACK) {
-                    mix.setRegistration(mRegistrationId + "mix" + mixTypeId(mix.getMixType()) + ":"
-                            + mixIndex++);
-                } else if ((mix.getRouteFlags() & AudioMix.ROUTE_FLAG_RENDER) ==
-                        AudioMix.ROUTE_FLAG_RENDER) {
-                    mix.setRegistration(mix.mDeviceAddress);
-                }
-            } else {
-                mix.setRegistration("");
+            setMixRegistration(mix);
+        }
+    }
+
+    private void setMixRegistration(@NonNull final AudioMix mix) {
+        if (!mRegistrationId.isEmpty()) {
+            if ((mix.getRouteFlags() & AudioMix.ROUTE_FLAG_LOOP_BACK) ==
+                    AudioMix.ROUTE_FLAG_LOOP_BACK) {
+                mix.setRegistration(mRegistrationId + "mix" + mixTypeId(mix.getMixType()) + ":"
+                        + mMixCounter);
+            } else if ((mix.getRouteFlags() & AudioMix.ROUTE_FLAG_RENDER) ==
+                    AudioMix.ROUTE_FLAG_RENDER) {
+                mix.setRegistration(mix.mDeviceAddress);
             }
+        } else {
+            mix.setRegistration("");
+        }
+        mMixCounter++;
+    }
+
+    @GuardedBy("mMixes")
+    protected void add(@NonNull ArrayList<AudioMix> mixes) {
+        for (AudioMix mix : mixes) {
+            setMixRegistration(mix);
+            mMixes.add(mix);
+        }
+    }
+
+    @GuardedBy("mMixes")
+    protected void remove(@NonNull ArrayList<AudioMix> mixes) {
+        for (AudioMix mix : mixes) {
+            mMixes.remove(mix);
         }
     }
 
diff --git a/media/java/android/media/session/ISessionManager.aidl b/media/java/android/media/session/ISessionManager.aidl
index 2d365d0..50b4acb 100644
--- a/media/java/android/media/session/ISessionManager.aidl
+++ b/media/java/android/media/session/ISessionManager.aidl
@@ -52,8 +52,8 @@
     void setOnMediaKeyListener(in IOnMediaKeyListener listener);
 
     // MediaSession2
-    boolean onSessionCreated(in Bundle sessionToken);
-    void onSessionDestroyed(in Bundle sessionToken);
+    boolean createSession2(in Bundle sessionToken);
+    void destroySession2(in Bundle sessionToken);
     List<Bundle> getSessionTokens(boolean activeSessionOnly, boolean sessionServiceOnly);
 
     void addSessionTokensListener(in ISessionTokensListener listener, int userId,
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index 454113c..d079b7a 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -343,29 +343,28 @@
      * Called when a {@link MediaSession2} is created.
      * @hide
      */
-    // TODO(jaewan): System API
-    public boolean onSessionCreated(@NonNull SessionToken2 token) {
+    public boolean createSession2(@NonNull SessionToken2 token) {
         if (token == null) {
             return false;
         }
         try {
-            return mService.onSessionCreated(token.toBundle());
+            return mService.createSession2(token.toBundle());
         } catch (RemoteException e) {
             Log.wtf(TAG, "Cannot communicate with the service.", e);
         }
         return false;
     }
 
-    /** Called when a {@link MediaSession2} is destroyed.
+    /**
+     * Called when a {@link MediaSession2} is destroyed.
      * @hide
      */
-    // TODO(jaewan): System API
-    public void onSessionDestroyed(@NonNull SessionToken2 token) {
+    public void destroySession2(@NonNull SessionToken2 token) {
         if (token == null) {
             return;
         }
         try {
-            mService.onSessionDestroyed(token.toBundle());
+            mService.destroySession2(token.toBundle());
         } catch (RemoteException e) {
             Log.wtf(TAG, "Cannot communicate with the service.", e);
         }
@@ -381,9 +380,7 @@
      * using the {@link NotificationListenerService} APIs.
      *
      * @return list of tokens
-     * @hide
      */
-    // TODO(jaewan): Unhide
     public List<SessionToken2> getActiveSessionTokens() {
         try {
             List<Bundle> bundles = mService.getSessionTokens(
@@ -404,9 +401,7 @@
      * using the {@link NotificationListenerService} APIs.
      *
      * @return list of tokens
-     * @hide
      */
-    // TODO(jaewan): Unhide
     public List<SessionToken2> getSessionServiceTokens() {
         try {
             List<Bundle> bundles = mService.getSessionTokens(
@@ -429,9 +424,7 @@
      * @return list of tokens
      * @see #getActiveSessionTokens
      * @see #getSessionServiceTokens
-     * @hide
      */
-    // TODO(jaewan): Unhide
     public List<SessionToken2> getAllSessionTokens() {
         try {
             List<Bundle> bundles = mService.getSessionTokens(
@@ -452,9 +445,7 @@
      *
      * @param executor executor to run this command
      * @param listener The listener to add.
-     * @hide
      */
-    // TODO(jaewan): Unhide
     public void addOnSessionTokensChangedListener(@NonNull @CallbackExecutor Executor executor,
             @NonNull OnSessionTokensChangedListener listener) {
         addOnSessionTokensChangedListener(UserHandle.myUserId(), executor, listener);
@@ -501,9 +492,7 @@
      * Stop receiving session token updates on the specified listener.
      *
      * @param listener The listener to remove.
-     * @hide
      */
-    // TODO(jaewan): Unhide
     public void removeOnSessionTokensChangedListener(
             @NonNull OnSessionTokensChangedListener listener) {
         if (listener == null) {
@@ -660,9 +649,7 @@
     /**
      * Listens for changes to the {@link #getAllSessionTokens()}. This can be added
      * using {@link #addOnActiveSessionsChangedListener}.
-     * @hide
      */
-    // TODO(jaewan): Unhide
     public interface OnSessionTokensChangedListener {
         void onSessionTokensChanged(@NonNull List<SessionToken2> tokens);
     }
diff --git a/media/java/android/media/update/MediaBrowser2Provider.java b/media/java/android/media/update/MediaBrowser2Provider.java
index eda4c7c..a18701e 100644
--- a/media/java/android/media/update/MediaBrowser2Provider.java
+++ b/media/java/android/media/update/MediaBrowser2Provider.java
@@ -25,7 +25,7 @@
     void getLibraryRoot_impl(Bundle rootHints);
 
     void subscribe_impl(String parentId, Bundle extras);
-    void unsubscribe_impl(String parentId, Bundle extras);
+    void unsubscribe_impl(String parentId);
 
     void getItem_impl(String mediaId);
     void getChildren_impl(String parentId, int page, int pageSize, Bundle extras);
diff --git a/media/java/android/media/update/MediaControlView2Provider.java b/media/java/android/media/update/MediaControlView2Provider.java
index ebde3fef..8e69653 100644
--- a/media/java/android/media/update/MediaControlView2Provider.java
+++ b/media/java/android/media/update/MediaControlView2Provider.java
@@ -16,10 +16,10 @@
 
 package android.media.update;
 
-import android.annotation.SystemApi;
+import android.media.SessionToken2;
 import android.media.session.MediaController;
 import android.util.AttributeSet;
-import android.view.View;
+import android.widget.MediaControlView2;
 
 /**
  * Interface for connecting the public API to an updatable implementation.
@@ -34,11 +34,19 @@
  *
  * @hide
  */
-// TODO @SystemApi
+// TODO: @SystemApi
 public interface MediaControlView2Provider extends ViewGroupProvider {
     void initialize(AttributeSet attrs, int defStyleAttr, int defStyleRes);
 
+    void setMediaSessionToken_impl(SessionToken2 token);
+    void setOnFullScreenListener_impl(MediaControlView2.OnFullScreenListener l);
+    /**
+     * @hide TODO: remove
+     */
     void setController_impl(MediaController controller);
+    /**
+     * @hide
+     */
     void setButtonVisibility_impl(int button, int visibility);
     void requestPlayButtonFocus_impl();
 }
diff --git a/media/java/android/media/update/MediaController2Provider.java b/media/java/android/media/update/MediaController2Provider.java
index 738bd0c..8d036be 100644
--- a/media/java/android/media/update/MediaController2Provider.java
+++ b/media/java/android/media/update/MediaController2Provider.java
@@ -16,7 +16,7 @@
 
 package android.media.update;
 
-import android.annotation.SystemApi;
+import android.annotation.NonNull;
 import android.app.PendingIntent;
 import android.media.AudioAttributes;
 import android.media.MediaController2.PlaybackInfo;
@@ -43,7 +43,6 @@
     boolean isConnected_impl();
 
     PendingIntent getSessionActivity_impl();
-    int getRatingType_impl();
 
     void setVolumeTo_impl(int value, int flags);
     void adjustVolume_impl(int direction, int flags);
@@ -60,12 +59,18 @@
     void sendCustomCommand_impl(Command command, Bundle args, ResultReceiver cb);
     List<MediaItem2> getPlaylist_impl();
 
-    void removePlaylistItem_impl(MediaItem2 index);
     void addPlaylistItem_impl(int index, MediaItem2 item);
+    void replacePlaylistItem_impl(int index, MediaItem2 item);
+    void removePlaylistItem_impl(MediaItem2 item);
 
     PlaylistParams getPlaylistParams_impl();
     void setPlaylistParams_impl(PlaylistParams params);
     PlaybackState2 getPlaybackState_impl();
+    int getPlayerState_impl();
+    long getPosition_impl();
+    float getPlaybackSpeed_impl();
+    long getBufferedPosition_impl();
+    MediaItem2 getCurrentPlaylistItem_impl();
 
     interface PlaybackInfoProvider {
         int getPlaybackType_impl();
diff --git a/media/java/android/media/update/MediaItem2Provider.java b/media/java/android/media/update/MediaItem2Provider.java
index 2970f0e..1d5b414 100644
--- a/media/java/android/media/update/MediaItem2Provider.java
+++ b/media/java/android/media/update/MediaItem2Provider.java
@@ -23,7 +23,6 @@
 /**
  * @hide
  */
-// TODO(jaewan): SystemApi
 public interface MediaItem2Provider {
     Bundle toBundle_impl();
     String toString_impl();
diff --git a/media/java/android/media/update/MediaLibraryService2Provider.java b/media/java/android/media/update/MediaLibraryService2Provider.java
index 17eea84..9a0d693 100644
--- a/media/java/android/media/update/MediaLibraryService2Provider.java
+++ b/media/java/android/media/update/MediaLibraryService2Provider.java
@@ -16,22 +16,19 @@
 
 package android.media.update;
 
-import android.annotation.SystemApi;
-import android.media.MediaLibraryService2.MediaLibrarySession;
-import android.media.MediaLibraryService2.MediaLibrarySessionCallback;
 import android.media.MediaSession2.ControllerInfo;
 import android.os.Bundle;
 
 /**
  * @hide
  */
-// TODO: @SystemApi
 public interface MediaLibraryService2Provider extends MediaSessionService2Provider {
     // Nothing new for now
 
     interface MediaLibrarySessionProvider extends MediaSession2Provider {
-        void notifyChildrenChanged_impl(ControllerInfo controller, String parentId, Bundle extras);
-        void notifyChildrenChanged_impl(String parentId, Bundle extras);
+        void notifyChildrenChanged_impl(ControllerInfo controller, String parentId,
+                int itemCount, Bundle extras);
+        void notifyChildrenChanged_impl(String parentId, int itemCount, Bundle extras);
         void notifySearchResultChanged_impl(ControllerInfo controller, String query, int itemCount,
                 Bundle extras);
     }
diff --git a/media/java/android/media/update/MediaMetadata2Provider.java b/media/java/android/media/update/MediaMetadata2Provider.java
index 55ac43d..22463e9 100644
--- a/media/java/android/media/update/MediaMetadata2Provider.java
+++ b/media/java/android/media/update/MediaMetadata2Provider.java
@@ -11,7 +11,6 @@
 /**
  * @hide
  */
-// TODO(jaewan): SystemApi
 public interface MediaMetadata2Provider {
     boolean containsKey_impl(String key);
     CharSequence getText_impl(String key);
@@ -23,7 +22,8 @@
     Set<String> keySet_impl();
     int size_impl();
     Bitmap getBitmap_impl(String key);
-    Bundle getExtra_impl();
+    float getFloat_impl(String key);
+    Bundle getExtras_impl();
 
     interface BuilderProvider {
         Builder putText_impl(String key, CharSequence value);
@@ -31,7 +31,8 @@
         Builder putLong_impl(String key, long value);
         Builder putRating_impl(String key, Rating2 value);
         Builder putBitmap_impl(String key, Bitmap value);
-        Builder setExtra_impl(Bundle bundle);
+        Builder putFloat_impl(String key, float value);
+        Builder setExtras_impl(Bundle bundle);
         MediaMetadata2 build_impl();
     }
 }
diff --git a/media/java/android/media/update/MediaSession2Provider.java b/media/java/android/media/update/MediaSession2Provider.java
index 41162e0..d0ec104 100644
--- a/media/java/android/media/update/MediaSession2Provider.java
+++ b/media/java/android/media/update/MediaSession2Provider.java
@@ -16,11 +16,13 @@
 
 package android.media.update;
 
+import android.annotation.NonNull;
 import android.app.PendingIntent;
 import android.media.MediaItem2;
 import android.media.MediaMetadata2;
-import android.media.MediaPlayerInterface;
-import android.media.MediaPlayerInterface.PlaybackListener;
+import android.media.MediaPlayerBase;
+import android.media.MediaPlayerBase.PlayerEventCallback;
+import android.media.MediaPlaylistController;
 import android.media.MediaSession2;
 import android.media.MediaSession2.Command;
 import android.media.MediaSession2.CommandButton;
@@ -40,34 +42,36 @@
 /**
  * @hide
  */
-// TODO: @SystemApi
 public interface MediaSession2Provider extends TransportControlProvider {
     void close_impl();
-    void setPlayer_impl(MediaPlayerInterface player);
-    void setPlayer_impl(MediaPlayerInterface player, VolumeProvider2 volumeProvider);
-    MediaPlayerInterface getPlayer_impl();
+    void setPlayer_impl(MediaPlayerBase player, MediaPlaylistController mplc,
+            VolumeProvider2 volumeProvider);
+    MediaPlayerBase getPlayer_impl();
     SessionToken2 getToken_impl();
     List<ControllerInfo> getConnectedControllers_impl();
     void setCustomLayout_impl(ControllerInfo controller, List<CommandButton> layout);
     void setAudioFocusRequest_impl(int focusGain);
-
     void setAllowedCommands_impl(ControllerInfo controller, CommandGroup commands);
-    void notifyMetadataChanged_impl();
     void sendCustomCommand_impl(ControllerInfo controller, Command command, Bundle args,
             ResultReceiver receiver);
     void sendCustomCommand_impl(Command command, Bundle args);
     void setPlaylist_impl(List<MediaItem2> playlist);
+    void addPlaylistItem_impl(int index, MediaItem2 item);
+    void removePlaylistItem_impl(MediaItem2 item);
+    void editPlaylistItem_impl(MediaItem2 item);
+    void replacePlaylistItem_impl(int index, MediaItem2 item);
     List<MediaItem2> getPlaylist_impl();
+    MediaItem2 getCurrentPlaylistItem_impl();
     void setPlaylistParams_impl(PlaylistParams params);
     PlaylistParams getPlaylistParams_impl();
-
-    void addPlaybackListener_impl(Executor executor, PlaybackListener listener);
-    void removePlaybackListener_impl(PlaybackListener listener);
+    void notifyError_impl(int errorCode, Bundle extras);
+    void registerPlayerEventCallback_impl(Executor executor, PlayerEventCallback callback);
+    void unregisterPlayerEventCallback_impl(PlayerEventCallback callback);
 
     interface CommandProvider {
         int getCommandCode_impl();
         String getCustomCommand_impl();
-        Bundle getExtra_impl();
+        Bundle getExtras_impl();
         Bundle toBundle_impl();
 
         boolean equals_impl(Object ob);
@@ -87,7 +91,7 @@
         Command getCommand_impl();
         int getIconResId_impl();
         String getDisplayName_impl();
-        Bundle getExtra_impl();
+        Bundle getExtras_impl();
         boolean isEnabled_impl();
 
         interface BuilderProvider {
@@ -95,7 +99,7 @@
             Builder setIconResId_impl(int resId);
             Builder setDisplayName_impl(String displayName);
             Builder setEnabled_impl(boolean enabled);
-            Builder setExtra_impl(Bundle extra);
+            Builder setExtras_impl(Bundle extras);
             CommandButton build_impl();
         }
     }
@@ -116,8 +120,8 @@
     }
 
     interface BuilderBaseProvider<T extends MediaSession2, C extends SessionCallback> {
-        void setVolumeProvider_impl(VolumeProvider2 volumeProvider);
-        void setRatingType_impl(int type);
+        void setPlayer_impl(MediaPlayerBase player, MediaPlaylistController mplc,
+                VolumeProvider2 volumeProvider);
         void setSessionActivity_impl(PendingIntent pi);
         void setId_impl(String id);
         void setSessionCallback_impl(Executor executor, C callback);
diff --git a/media/java/android/media/update/MediaSessionService2Provider.java b/media/java/android/media/update/MediaSessionService2Provider.java
index 42e7587..8697e70 100644
--- a/media/java/android/media/update/MediaSessionService2Provider.java
+++ b/media/java/android/media/update/MediaSessionService2Provider.java
@@ -16,7 +16,6 @@
 
 package android.media.update;
 
-import android.annotation.SystemApi;
 import android.app.Notification;
 import android.content.Intent;
 import android.media.MediaSession2;
@@ -29,7 +28,7 @@
  */
 public interface MediaSessionService2Provider {
     MediaSession2 getSession_impl();
-    MediaNotification onUpdateNotification_impl(PlaybackState2 state);
+    MediaNotification onUpdateNotification_impl();
 
     // Service
     void onCreate_impl();
diff --git a/media/java/android/media/update/PlaybackState2Provider.java b/media/java/android/media/update/PlaybackState2Provider.java
index 2875e98..66b8fa5 100644
--- a/media/java/android/media/update/PlaybackState2Provider.java
+++ b/media/java/android/media/update/PlaybackState2Provider.java
@@ -21,7 +21,6 @@
 /**
  * @hide
  */
-// TODO(jaewan): @SystemApi
 public interface PlaybackState2Provider {
     String toString_impl();
 
@@ -33,8 +32,6 @@
 
     float getPlaybackSpeed_impl();
 
-    CharSequence getErrorMessage_impl();
-
     long getLastPositionUpdateTime_impl();
 
     long getCurrentPlaylistItemIndex_impl();
diff --git a/media/java/android/media/update/Rating2Provider.java b/media/java/android/media/update/Rating2Provider.java
index 8966196..28ad273 100644
--- a/media/java/android/media/update/Rating2Provider.java
+++ b/media/java/android/media/update/Rating2Provider.java
@@ -22,7 +22,6 @@
 /**
  * @hide
  */
-// TODO(jaewan): @SystemApi
 public interface Rating2Provider {
     String toString_impl();
     boolean equals_impl(Object obj);
@@ -34,4 +33,4 @@
     boolean isThumbUp_impl();
     float getStarRating_impl();
     float getPercentRating_impl();
-}
\ No newline at end of file
+}
diff --git a/media/java/android/media/update/SessionPlayer2Provider.java b/media/java/android/media/update/SessionPlayer2Provider.java
deleted file mode 100644
index e068c21..0000000
--- a/media/java/android/media/update/SessionPlayer2Provider.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.update;
-
-import android.media.AudioAttributes;
-import android.media.MediaItem2;
-import android.media.MediaPlayer2;
-import android.media.MediaPlayerInterface.PlaybackListener;
-import android.media.MediaSession2.PlaylistParams;
-import android.media.PlaybackState2;
-
-import java.util.List;
-import java.util.concurrent.Executor;
-
-/**
- * @hide
- */
-public interface SessionPlayer2Provider {
-    void play_impl();
-    void prepare_impl();
-    void pause_impl();
-    void stop_impl();
-    void skipToPrevious_impl();
-    void skipToNext_impl();
-    void seekTo_impl(long pos);
-    void fastForward_impl();
-    void rewind_impl();
-    PlaybackState2 getPlaybackState_impl();
-    void setAudioAttributes_impl(AudioAttributes attributes);
-    AudioAttributes getAudioAttributes_impl();
-    void addPlaylistItem_impl(int index, MediaItem2 item);
-    void removePlaylistItem_impl(MediaItem2 item);
-    void setPlaylist_impl(List<MediaItem2> playlist);
-    List<MediaItem2> getPlaylist_impl();
-    void setCurrentPlaylistItem_impl(int index);
-    void setPlaylistParams_impl(PlaylistParams params);
-    PlaylistParams getPlaylistParams_impl();
-    void addPlaybackListener_impl(Executor executor, PlaybackListener listener);
-    void removePlaybackListener_impl(PlaybackListener listener);
-    MediaPlayer2 getPlayer_impl();
-}
diff --git a/media/java/android/media/update/StaticProvider.java b/media/java/android/media/update/StaticProvider.java
index 57f04cc..47f5ed3 100644
--- a/media/java/android/media/update/StaticProvider.java
+++ b/media/java/android/media/update/StaticProvider.java
@@ -28,10 +28,8 @@
 import android.media.MediaLibraryService2;
 import android.media.MediaLibraryService2.LibraryRoot;
 import android.media.MediaLibraryService2.MediaLibrarySession;
-import android.media.MediaLibraryService2.MediaLibrarySessionBuilder;
-import android.media.MediaLibraryService2.MediaLibrarySessionCallback;
+import android.media.MediaLibraryService2.MediaLibrarySession.MediaLibrarySessionCallback;
 import android.media.MediaMetadata2;
-import android.media.MediaPlayerInterface;
 import android.media.MediaSession2;
 import android.media.MediaSession2.CommandButton.Builder;
 import android.media.MediaSession2.PlaylistParams;
@@ -40,12 +38,11 @@
 import android.media.MediaSessionService2.MediaNotification;
 import android.media.PlaybackState2;
 import android.media.Rating2;
-import android.media.SessionPlayer2;
 import android.media.SessionToken2;
 import android.media.VolumeProvider2;
 import android.media.update.MediaLibraryService2Provider.LibraryRootProvider;
 import android.media.update.MediaSession2Provider.BuilderBaseProvider;
-import android.media.update.MediaSession2Provider.CommandButtonProvider.BuilderProvider;
+import android.media.update.MediaSession2Provider.CommandButtonProvider;
 import android.media.update.MediaSession2Provider.CommandGroupProvider;
 import android.media.update.MediaSession2Provider.CommandProvider;
 import android.media.update.MediaSession2Provider.ControllerInfoProvider;
@@ -87,9 +84,10 @@
             PlaylistParams playlistParams, int repeatMode, int shuffleMode,
             MediaMetadata2 playlistMetadata);
     PlaylistParams fromBundle_PlaylistParams(Context context, Bundle bundle);
-    BuilderProvider createMediaSession2CommandButtonBuilder(Context context, Builder builder);
+    CommandButtonProvider.BuilderProvider createMediaSession2CommandButtonBuilder(Context context,
+            MediaSession2.CommandButton.Builder builder);
     BuilderBaseProvider<MediaSession2, SessionCallback> createMediaSession2Builder(
-            Context context, MediaSession2.Builder instance, MediaPlayerInterface player);
+            Context context, MediaSession2.Builder instance);
 
     MediaController2Provider createMediaController2(Context context, MediaController2 instance,
             SessionToken2 token, Executor executor, ControllerCallback callback);
@@ -104,16 +102,14 @@
     MediaSessionService2Provider createMediaLibraryService2(MediaLibraryService2 instance);
     BuilderBaseProvider<MediaLibrarySession, MediaLibrarySessionCallback>
         createMediaLibraryService2Builder(
-            Context context, MediaLibrarySessionBuilder instance, MediaPlayerInterface player,
+            MediaLibraryService2 service, MediaLibrarySession.Builder instance,
             Executor callbackExecutor, MediaLibrarySessionCallback callback);
     LibraryRootProvider createMediaLibraryService2LibraryRoot(Context context, LibraryRoot instance,
             String rootId, Bundle extras);
 
     SessionToken2Provider createSessionToken2(Context context, SessionToken2 instance,
             String packageName, String serviceName, int uid);
-    SessionToken2 SessionToken2_fromBundle(Context context, Bundle bundle);
-
-    SessionPlayer2Provider createSessionPlayer2(Context context, SessionPlayer2 instance);
+    SessionToken2 fromBundle_SessionToken2(Context context, Bundle bundle);
 
     MediaItem2Provider createMediaItem2(Context context, MediaItem2 mediaItem2,
             String mediaId, DataSourceDesc dsd, MediaMetadata2 metadata, int flags);
@@ -136,7 +132,6 @@
     Rating2 newPercentageRating_Rating2(Context context, float percent);
 
     PlaybackState2Provider createPlaybackState2(Context context, PlaybackState2 instance, int state,
-            long position, long updateTime, float speed, long bufferedPosition, long activeItemId,
-            CharSequence error);
+            long position, long updateTime, float speed, long bufferedPosition, long activeItemId);
     PlaybackState2 fromBundle_PlaybackState2(Context context, Bundle bundle);
 }
diff --git a/media/java/android/media/update/TransportControlProvider.java b/media/java/android/media/update/TransportControlProvider.java
index 44f82b29..9af8ada 100644
--- a/media/java/android/media/update/TransportControlProvider.java
+++ b/media/java/android/media/update/TransportControlProvider.java
@@ -16,6 +16,7 @@
 
 package android.media.update;
 
+import android.media.MediaItem2;
 import android.media.PlaybackState2;
 
 /**
@@ -32,7 +33,7 @@
     void fastForward_impl();
     void rewind_impl();
     void seekTo_impl(long pos);
-    void setCurrentPlaylistItem_impl(int index);
+    void skipToPlaylistItem_impl(MediaItem2 item);
 
     PlaybackState2 getPlaybackState_impl();
 }
diff --git a/media/java/android/media/update/VideoView2Provider.java b/media/java/android/media/update/VideoView2Provider.java
index 21cc61f..11b3560 100644
--- a/media/java/android/media/update/VideoView2Provider.java
+++ b/media/java/android/media/update/VideoView2Provider.java
@@ -18,7 +18,11 @@
 
 import android.annotation.SystemApi;
 import android.media.AudioAttributes;
-import android.media.MediaPlayerInterface;
+import android.media.DataSourceDesc;
+import android.media.MediaItem2;
+import android.media.MediaMetadata2;
+import android.media.MediaPlayerBase;
+import android.media.SessionToken2;
 import android.media.session.MediaController;
 import android.media.session.PlaybackState;
 import android.media.session.MediaSession;
@@ -51,8 +55,14 @@
     void initialize(AttributeSet attrs, int defStyleAttr, int defStyleRes);
 
     void setMediaControlView2_impl(MediaControlView2 mediaControlView, long intervalMs);
+    void setMediaMetadata_impl(MediaMetadata2 metadata);
+    /**
+     * @hide TODO: remove
+     */
     MediaController getMediaController_impl();
+    SessionToken2 getMediaSessionToken_impl();
     MediaControlView2 getMediaControlView2_impl();
+    MediaMetadata2 getMediaMetadata_impl();
     void setSubtitleEnabled_impl(boolean enable);
     boolean isSubtitleEnabled_impl();
     // TODO: remove setSpeed_impl once MediaController2 is ready.
@@ -62,14 +72,32 @@
     /**
      * @hide
      */
-    void setRouteAttributes_impl(List<String> routeCategories, MediaPlayerInterface player);
+    void setRouteAttributes_impl(List<String> routeCategories, MediaPlayerBase player);
+    /**
+     * @hide
+     */
     // TODO: remove setRouteAttributes_impl with MediaSession.Callback once MediaSession2 is ready.
     void setRouteAttributes_impl(List<String> routeCategories, MediaSession.Callback sessionPlayer);
+
+    /**
+     * @hide TODO: remove
+     */
     void setVideoPath_impl(String path);
+    /**
+     * @hide TODO: remove
+     */
     void setVideoUri_impl(Uri uri);
+    /**
+     * @hide TODO: remove
+     */
     void setVideoUri_impl(Uri uri, Map<String, String> headers);
+    void setMediaItem_impl(MediaItem2 mediaItem);
+    void setDataSource_impl(DataSourceDesc dsd);
     void setViewType_impl(int viewType);
     int getViewType_impl();
+    /**
+     * @hide TODO: remove
+     */
     void setCustomActions_impl(List<PlaybackState.CustomAction> actionList,
             Executor executor, VideoView2.OnCustomActionListener listener);
     /**
@@ -77,5 +105,8 @@
      */
     @VisibleForTesting
     void setOnViewTypeChangedListener_impl(VideoView2.OnViewTypeChangedListener l);
+    /**
+     * @hide TODO: remove
+     */
     void setFullScreenRequestListener_impl(VideoView2.OnFullScreenRequestListener l);
 }
diff --git a/media/java/android/media/update/VolumeProvider2Provider.java b/media/java/android/media/update/VolumeProvider2Provider.java
index 5657af6..5b5cfd3 100644
--- a/media/java/android/media/update/VolumeProvider2Provider.java
+++ b/media/java/android/media/update/VolumeProvider2Provider.java
@@ -18,7 +18,6 @@
 /**
  * @hide
  */
-// TODO(jaewan): @SystemApi
 public interface VolumeProvider2Provider {
     int getControlType_impl();
     int getMaxVolume_impl();
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index fe2f64f..44e5d61 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -31,6 +31,7 @@
     shared_libs: [
         "libandroid_runtime",
         "libnativehelper",
+        "libnativewindow",
         "libutils",
         "libbinder",
         "libmedia",
@@ -51,6 +52,7 @@
         "libexif",
         "libpiex",
         "libandroidfw",
+        "libhidlallocatorutils",
         "libhidlbase",
         "libhidltransport",
         "android.hardware.cas@1.0",
@@ -106,6 +108,7 @@
         "liblog",  // NDK
         "libdrmframework",  // for FileSource, MediaHTTP
         "libgui",  // for VideoFrameScheduler
+        "libhidlallocatorutils",
         "libhidlbase",  // VNDK???
         "libmediandk",  // NDK
         "libpowermanager",  // for JWakeLock. to be removed
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index 885bf03..f5311764 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -33,11 +33,14 @@
 #include <android_runtime/android_hardware_HardwareBuffer.h>
 #include <grallocusage/GrallocUsageConversion.h>
 
+#include <private/android/AHardwareBufferHelpers.h>
+
 #include <jni.h>
 #include <nativehelper/JNIHelp.h>
 
 #include <stdint.h>
 #include <inttypes.h>
+#include <android/hardware_buffer_jni.h>
 
 #define ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID       "mNativeContext"
 #define ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID   "mNativeBuffer"
@@ -797,6 +800,14 @@
     }
 }
 
+static jobject Image_getHardwareBuffer(JNIEnv* env, jobject thiz) {
+    BufferItem* buffer = Image_getBufferItem(env, thiz);
+    AHardwareBuffer* b = AHardwareBuffer_from_GraphicBuffer(buffer->mGraphicBuffer.get());
+    // don't user the public AHardwareBuffer_toHardwareBuffer() because this would force us
+    // to link against libandroid.so
+    return android_hardware_HardwareBuffer_createFromAHardwareBuffer(env, b);
+}
+
 } // extern "C"
 
 // ----------------------------------------------------------------------------
@@ -814,10 +825,12 @@
 
 static const JNINativeMethod gImageMethods[] = {
     {"nativeCreatePlanes",      "(II)[Landroid/media/ImageReader$SurfaceImage$SurfacePlane;",
-                                                              (void*)Image_createSurfacePlanes },
-    {"nativeGetWidth",         "()I",                        (void*)Image_getWidth },
-    {"nativeGetHeight",        "()I",                        (void*)Image_getHeight },
-    {"nativeGetFormat",        "(I)I",                        (void*)Image_getFormat },
+                                                             (void*)Image_createSurfacePlanes },
+    {"nativeGetWidth",          "()I",                       (void*)Image_getWidth },
+    {"nativeGetHeight",         "()I",                       (void*)Image_getHeight },
+    {"nativeGetFormat",         "(I)I",                      (void*)Image_getFormat },
+    {"nativeGetHardwareBuffer", "()Landroid/hardware/HardwareBuffer;",
+                                                             (void*)Image_getHardwareBuffer },
 };
 
 int register_android_media_ImageReader(JNIEnv *env) {
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 022198b..62030bb 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -36,7 +36,6 @@
 
 #include <gui/Surface.h>
 
-#include <media/ICrypto.h>
 #include <media/MediaCodecBuffer.h>
 #include <media/stagefright/MediaCodec.h>
 #include <media/stagefright/foundation/ABuffer.h>
@@ -46,6 +45,7 @@
 #include <media/stagefright/foundation/AString.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/PersistentSurface.h>
+#include <mediadrm/ICrypto.h>
 #include <nativehelper/ScopedLocalRef.h>
 
 #include <system/window.h>
diff --git a/media/jni/android_media_MediaCrypto.cpp b/media/jni/android_media_MediaCrypto.cpp
index 1b3c24f..2d9051f 100644
--- a/media/jni/android_media_MediaCrypto.cpp
+++ b/media/jni/android_media_MediaCrypto.cpp
@@ -26,9 +26,9 @@
 
 #include <binder/IServiceManager.h>
 #include <cutils/properties.h>
-#include <media/ICrypto.h>
-#include <media/IMediaDrmService.h>
 #include <media/stagefright/foundation/ADebug.h>
+#include <mediadrm/ICrypto.h>
+#include <mediadrm/IMediaDrmService.h>
 
 namespace android {
 
diff --git a/media/jni/android_media_MediaDescrambler.cpp b/media/jni/android_media_MediaDescrambler.cpp
index e77e855..add47463 100644
--- a/media/jni/android_media_MediaDescrambler.cpp
+++ b/media/jni/android_media_MediaDescrambler.cpp
@@ -27,12 +27,13 @@
 #include <android/hardware/cas/native/1.0/BnHwDescrambler.h>
 #include <binder/MemoryDealer.h>
 #include <hidl/HidlSupport.h>
+#include <hidlmemory/FrameworkUtils.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <nativehelper/ScopedLocalRef.h>
 
 namespace android {
 
-using hardware::hidl_handle;
+using hardware::fromHeap;
 
 struct fields_t {
     jfieldID context;
@@ -146,14 +147,8 @@
         return false;
     }
 
-    native_handle_t* nativeHandle = native_handle_create(1, 0);
-    if (!nativeHandle) {
-        ALOGE("ensureBufferCapacity: failed to create native handle");
-        return false;
-    }
-    nativeHandle->data[0] = heap->getHeapID();
-    mDescramblerSrcBuffer.heapBase = hidl_memory("ashmem",
-            hidl_handle(nativeHandle), heap->getSize());
+    mHidlMemory = fromHeap(heap);
+    mDescramblerSrcBuffer.heapBase = *mHidlMemory;
     mDescramblerSrcBuffer.offset = (uint64_t) offset;
     mDescramblerSrcBuffer.size = (uint64_t) size;
     return true;
diff --git a/media/jni/android_media_MediaDescrambler.h b/media/jni/android_media_MediaDescrambler.h
index 015fad2..2354dc2 100644
--- a/media/jni/android_media_MediaDescrambler.h
+++ b/media/jni/android_media_MediaDescrambler.h
@@ -28,7 +28,10 @@
 class IMemory;
 class MemoryDealer;
 
-using hardware::hidl_memory;
+namespace hardware {
+class HidlMemory;
+};
+using hardware::HidlMemory;
 using hardware::hidl_string;
 using hardware::hidl_vec;
 using namespace hardware::cas::V1_0;
@@ -58,6 +61,7 @@
     sp<IDescrambler> mDescrambler;
     sp<IMemory> mMem;
     sp<MemoryDealer> mDealer;
+    sp<HidlMemory> mHidlMemory;
     SharedBuffer mDescramblerSrcBuffer;
 
     Mutex mSharedMemLock;
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index 3518392..4c20f05 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -31,10 +31,10 @@
 #include <binder/Parcel.h>
 #include <binder/PersistableBundle.h>
 #include <cutils/properties.h>
-#include <media/IDrm.h>
-#include <media/IMediaDrmService.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/MediaErrors.h>
+#include <mediadrm/IDrm.h>
+#include <mediadrm/IMediaDrmService.h>
 
 using ::android::os::PersistableBundle;
 
diff --git a/media/jni/android_media_MediaPlayer2.cpp b/media/jni/android_media_MediaPlayer2.cpp
index cf115a4..b0936fb 100644
--- a/media/jni/android_media_MediaPlayer2.cpp
+++ b/media/jni/android_media_MediaPlayer2.cpp
@@ -471,7 +471,7 @@
     // This will fail if the media player has not been initialized yet. This
     // can be the case if setDisplay() on MediaPlayer2Impl.java has been called
     // before setDataSource(). The redundant call to setVideoSurfaceTexture()
-    // in prepare/prepareAsync covers for this case.
+    // in prepare/prepare covers for this case.
     mp->setVideoSurfaceTexture(new ANativeWindowWrapper(anw));
 }
 
@@ -536,7 +536,7 @@
 }
 
 static void
-android_media_MediaPlayer2_prepareAsync(JNIEnv *env, jobject thiz)
+android_media_MediaPlayer2_prepare(JNIEnv *env, jobject thiz)
 {
     sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
     if (mp == NULL ) {
@@ -760,7 +760,8 @@
         return;
     }
     ALOGV("seekTo: %lld(msec), mode=%d", (long long)msec, mode);
-    process_media_player_call( env, thiz, mp->seekTo((int)msec, (MediaPlayer2SeekMode)mode), NULL, NULL );
+    process_media_player_call(env, thiz, mp->seekTo((int64_t)msec, (MediaPlayer2SeekMode)mode),
+                              NULL, NULL);
 }
 
 static void
@@ -838,7 +839,7 @@
     return mybundle;
 }
 
-static jint
+static jlong
 android_media_MediaPlayer2_getCurrentPosition(JNIEnv *env, jobject thiz)
 {
     sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
@@ -846,13 +847,13 @@
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
         return 0;
     }
-    int msec;
+    int64_t msec;
     process_media_player_call( env, thiz, mp->getCurrentPosition(&msec), NULL, NULL );
-    ALOGV("getCurrentPosition: %d (msec)", msec);
-    return (jint) msec;
+    ALOGV("getCurrentPosition: %lld (msec)", (long long)msec);
+    return (jlong) msec;
 }
 
-static jint
+static jlong
 android_media_MediaPlayer2_getDuration(JNIEnv *env, jobject thiz)
 {
     sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
@@ -860,10 +861,10 @@
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
         return 0;
     }
-    int msec;
+    int64_t msec;
     process_media_player_call( env, thiz, mp->getDuration(&msec), NULL, NULL );
-    ALOGV("getDuration: %d (msec)", msec);
-    return (jint) msec;
+    ALOGV("getDuration: %lld (msec)", (long long)msec);
+    return (jlong) msec;
 }
 
 static void
@@ -911,6 +912,28 @@
     }
 }
 
+static jobject
+android_media_MediaPlayer2_getParameter(JNIEnv *env, jobject thiz, jint key)
+{
+    ALOGV("getParameter: key %d", key);
+    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
+    if (mp == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException", NULL);
+        return NULL;
+    }
+
+    jobject jParcel = createJavaParcelObject(env);
+    if (jParcel != NULL) {
+        Parcel* nativeParcel = parcelForJavaObject(env, jParcel);
+        status_t err = mp->getParameter(key, nativeParcel);
+        if (err != OK) {
+            env->DeleteLocalRef(jParcel);
+            return NULL;
+        }
+    }
+    return jParcel;
+}
+
 static void
 android_media_MediaPlayer2_setLooping(JNIEnv *env, jobject thiz, jboolean looping)
 {
@@ -1171,33 +1194,6 @@
     process_media_player_call( env, thiz, mp->attachAuxEffect(effectId), NULL, NULL );
 }
 
-static void
-android_media_MediaPlayer2_setNextMediaPlayer(JNIEnv *env, jobject thiz, jobject java_player)
-{
-    ALOGV("setNextMediaPlayer");
-    sp<MediaPlayer2> thisplayer = getMediaPlayer(env, thiz);
-    if (thisplayer == NULL) {
-        jniThrowException(env, "java/lang/IllegalStateException", "This player not initialized");
-        return;
-    }
-    sp<MediaPlayer2> nextplayer = (java_player == NULL) ? NULL : getMediaPlayer(env, java_player);
-    if (nextplayer == NULL && java_player != NULL) {
-        jniThrowException(env, "java/lang/IllegalStateException", "That player not initialized");
-        return;
-    }
-
-    if (nextplayer == thisplayer) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", "Next player can't be self");
-        return;
-    }
-    // tie the two players together
-    process_media_player_call(
-            env, thiz, thisplayer->setNextMediaPlayer(nextplayer),
-            "java/lang/IllegalArgumentException",
-            "setNextMediaPlayer failed." );
-    ;
-}
-
 /////////////////////////////////////////////////////////////////////////////////////
 // Modular DRM begin
 
@@ -1484,7 +1480,7 @@
     {"_setVideoSurface",    "(Landroid/view/Surface;)V",        (void *)android_media_MediaPlayer2_setVideoSurface},
     {"getBufferingParams", "()Landroid/media/BufferingParams;", (void *)android_media_MediaPlayer2_getBufferingParams},
     {"setBufferingParams", "(Landroid/media/BufferingParams;)V", (void *)android_media_MediaPlayer2_setBufferingParams},
-    {"prepareAsync",        "()V",                              (void *)android_media_MediaPlayer2_prepareAsync},
+    {"prepare",            "()V",                              (void *)android_media_MediaPlayer2_prepare},
     {"_start",              "()V",                              (void *)android_media_MediaPlayer2_start},
     {"_stop",               "()V",                              (void *)android_media_MediaPlayer2_stop},
     {"getVideoWidth",       "()I",                              (void *)android_media_MediaPlayer2_getVideoWidth},
@@ -1498,12 +1494,13 @@
     {"_notifyAt",           "(J)V",                             (void *)android_media_MediaPlayer2_notifyAt},
     {"_pause",              "()V",                              (void *)android_media_MediaPlayer2_pause},
     {"isPlaying",           "()Z",                              (void *)android_media_MediaPlayer2_isPlaying},
-    {"getCurrentPosition",  "()I",                              (void *)android_media_MediaPlayer2_getCurrentPosition},
-    {"getDuration",         "()I",                              (void *)android_media_MediaPlayer2_getDuration},
+    {"getCurrentPosition",  "()J",                              (void *)android_media_MediaPlayer2_getCurrentPosition},
+    {"getDuration",         "()J",                              (void *)android_media_MediaPlayer2_getDuration},
     {"_release",            "()V",                              (void *)android_media_MediaPlayer2_release},
     {"_reset",              "()V",                              (void *)android_media_MediaPlayer2_reset},
     {"_getAudioStreamType", "()I",                              (void *)android_media_MediaPlayer2_getAudioStreamType},
     {"setParameter",        "(ILandroid/os/Parcel;)Z",          (void *)android_media_MediaPlayer2_setParameter},
+    {"getParameter",        "(I)Landroid/os/Parcel;",           (void *)android_media_MediaPlayer2_getParameter},
     {"setLooping",          "(Z)V",                             (void *)android_media_MediaPlayer2_setLooping},
     {"isLooping",           "()Z",                              (void *)android_media_MediaPlayer2_isLooping},
     {"_setVolume",          "(FF)V",                            (void *)android_media_MediaPlayer2_setVolume},
@@ -1517,7 +1514,6 @@
     {"setAudioSessionId",   "(I)V",                             (void *)android_media_MediaPlayer2_set_audio_session_id},
     {"_setAuxEffectSendLevel", "(F)V",                          (void *)android_media_MediaPlayer2_setAuxEffectSendLevel},
     {"attachAuxEffect",     "(I)V",                             (void *)android_media_MediaPlayer2_attachAuxEffect},
-    {"setNextMediaPlayer",  "(Landroid/media/MediaPlayer2;)V",  (void *)android_media_MediaPlayer2_setNextMediaPlayer},
     // Modular DRM
     { "_prepareDrm", "([B[B)V",                                 (void *)android_media_MediaPlayer2_prepareDrm },
     { "_releaseDrm", "()V",                                     (void *)android_media_MediaPlayer2_releaseDrm },
diff --git a/media/lib/remotedisplay/Android.mk b/media/lib/remotedisplay/Android.mk
index e88c0f1..63f9f91 100644
--- a/media/lib/remotedisplay/Android.mk
+++ b/media/lib/remotedisplay/Android.mk
@@ -42,3 +42,24 @@
 LOCAL_SRC_FILES := $(LOCAL_MODULE)
 
 include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := com.android.media.remotedisplay.stubs-gen
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_SRC_FILES := $(call all-java-files-under,java)
+LOCAL_DROIDDOC_STUB_OUT_DIR := $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/com.android.media.remotedisplay.stubs_intermediates/src
+LOCAL_DROIDDOC_OPTIONS:= \
+    -hide 111 -hide 113 -hide 125 -hide 126 -hide 127 -hide 128 \
+    -stubpackages com.android.media.remotedisplay \
+    -nodocs
+LOCAL_UNINSTALLABLE_MODULE := true
+include $(BUILD_DROIDDOC)
+com_android_media_remotedisplay_gen_stamp := $(full_target)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := com.android.media.remotedisplay.stubs
+LOCAL_SDK_VERSION := current
+LOCAL_SOURCE_FILES_ALL_GENERATED := true
+LOCAL_ADDITIONAL_DEPENDENCIES := $(com_android_media_remotedisplay_gen_stamp)
+com_android_media_remotedisplay_gen_stamp :=
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/media/lib/remotedisplay/README.txt b/media/lib/remotedisplay/README.txt
index 5738dbe..1a52c4d 100644
--- a/media/lib/remotedisplay/README.txt
+++ b/media/lib/remotedisplay/README.txt
@@ -1,8 +1,17 @@
-This library (com.android.media.remotedisplay.jar) is a shared java library
+There are two libraries defined in this directory:
+First, com.android.media.remotedisplay.jar is a shared java library
 containing classes required by unbundled remote display providers.
+Second, com.android.media.remotedisplay.stubs.jar is a stub for the shared
+library which provides build-time APIs to the unbundled clients.
+
+At runtime, the shared library is added to the classloader of the app via the
+<uses-library> tag. And since Java always tries to load a class from the
+parent classloader, regardless of whether the stub library is linked to the
+app statically or dynamically, the real classes are loaded from the shared
+library.
 
 --- Rules of this library ---
-o This library is effectively a PUBLIC API for unbundled remote display providers
+o The stub library is effectively a PUBLIC API for unbundled remote display providers
   that may be distributed outside the system image. So it MUST BE API STABLE.
   You can add but not remove. The rules are the same as for the
   public platform SDK API.
diff --git a/media/lib/signer/Android.mk b/media/lib/signer/Android.mk
index 69ca4d2..54aa968 100644
--- a/media/lib/signer/Android.mk
+++ b/media/lib/signer/Android.mk
@@ -42,3 +42,24 @@
 LOCAL_SRC_FILES := $(LOCAL_MODULE)
 
 include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := com.android.mediadrm.signer.stubs-gen
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_SRC_FILES := $(call all-java-files-under,java)
+LOCAL_DROIDDOC_STUB_OUT_DIR := $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/com.android.mediadrm.signer.stubs_intermediates/src
+LOCAL_DROIDDOC_OPTIONS:= \
+    -hide 111 -hide 113 -hide 125 -hide 126 -hide 127 -hide 128 \
+    -stubpackages com.android.mediadrm.signer \
+    -nodocs
+LOCAL_UNINSTALLABLE_MODULE := true
+include $(BUILD_DROIDDOC)
+com_android_mediadrm_signer_gen_stamp := $(full_target)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := com.android.mediadrm.signer.stubs
+LOCAL_SDK_VERSION := current
+LOCAL_SOURCE_FILES_ALL_GENERATED := true
+LOCAL_ADDITIONAL_DEPENDENCIES := $(com_android_mediadrm_signer_gen_stamp)
+com_android_mediadrm_signer_gen_stamp :=
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/media/lib/signer/README.txt b/media/lib/signer/README.txt
index 362ab8e..55df3fc 100644
--- a/media/lib/signer/README.txt
+++ b/media/lib/signer/README.txt
@@ -1,10 +1,19 @@
-This library (com.android.mediadrm.signer.jar) is a shared java library
+There are two libraries defined in this directory:
+First, com.android.mediadrm.signer.jar is a shared java library
 containing classes required by unbundled apps running on devices that use
 the certficate provisioning and private key signing capabilities provided
 by the MediaDrm API.
+Second, com.android.mediadrm.signer.stubs.jar is a stub for the shared library
+which provides build-time APIs to the unbundled clients.
+
+At runtime, the shared library is added to the classloader of the app via the
+<uses-library> tag. And since Java always tries to load a class from the
+parent classloader, regardless of whether the stub library is linked to the
+app statically or dynamically, the real classes are loaded from the shared
+library.
 
 --- Rules of this library ---
-o This library is effectively a PUBLIC API for unbundled CAST receivers
+o The stub library is effectively a PUBLIC API for unbundled CAST receivers
   that may be distributed outside the system image. So it MUST BE API STABLE.
   You can add but not remove. The rules are the same as for the
   public platform SDK API.
diff --git a/media/mca/samples/CameraEffectsRecordingSample/Android.mk b/media/mca/samples/CameraEffectsRecordingSample/Android.mk
index d3c4336..c81f2fc 100644
--- a/media/mca/samples/CameraEffectsRecordingSample/Android.mk
+++ b/media/mca/samples/CameraEffectsRecordingSample/Android.mk
@@ -23,6 +23,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := CameraEffectsRecordingSample
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_PROGUARD_ENABLED := disabled
 
diff --git a/media/mca/tests/Android.mk b/media/mca/tests/Android.mk
index 394f542..648af4e 100644
--- a/media/mca/tests/Android.mk
+++ b/media/mca/tests/Android.mk
@@ -11,6 +11,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := CameraEffectsTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_INSTRUMENTATION_FOR := CameraEffectsRecordingSample
 
diff --git a/media/packages/BluetoothMidiService/Android.mk b/media/packages/BluetoothMidiService/Android.mk
index 0565925..6f262bf 100644
--- a/media/packages/BluetoothMidiService/Android.mk
+++ b/media/packages/BluetoothMidiService/Android.mk
@@ -7,6 +7,7 @@
       $(call all-java-files-under,src)
 
 LOCAL_PACKAGE_NAME := BluetoothMidiService
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_CERTIFICATE := platform
 
 include $(BUILD_PACKAGE)
diff --git a/media/tests/EffectsTest/Android.mk b/media/tests/EffectsTest/Android.mk
index 25b4fe4..a066950 100644
--- a/media/tests/EffectsTest/Android.mk
+++ b/media/tests/EffectsTest/Android.mk
@@ -6,5 +6,6 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := EffectsTest
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 include $(BUILD_PACKAGE)
diff --git a/media/tests/MediaFrameworkTest/Android.mk b/media/tests/MediaFrameworkTest/Android.mk
index 145cde6..fb473f0 100644
--- a/media/tests/MediaFrameworkTest/Android.mk
+++ b/media/tests/MediaFrameworkTest/Android.mk
@@ -13,5 +13,6 @@
     android-ex-camera2
 
 LOCAL_PACKAGE_NAME := mediaframeworktest
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 include $(BUILD_PACKAGE)
diff --git a/media/tests/MtpTests/Android.mk b/media/tests/MtpTests/Android.mk
index 616e600..6375ed3 100644
--- a/media/tests/MtpTests/Android.mk
+++ b/media/tests/MtpTests/Android.mk
@@ -8,5 +8,6 @@
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
 
 LOCAL_PACKAGE_NAME := MtpTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 include $(BUILD_PACKAGE)
diff --git a/media/tests/NativeMidiDemo/Android.mk b/media/tests/NativeMidiDemo/Android.mk
index 6b08f6b..316858f 100644
--- a/media/tests/NativeMidiDemo/Android.mk
+++ b/media/tests/NativeMidiDemo/Android.mk
@@ -19,6 +19,7 @@
 LOCAL_PACKAGE_NAME := NativeMidiDemo
 
 #LOCAL_SDK_VERSION := current
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_PROGUARD_ENABLED := disabled
 LOCAL_SRC_FILES := $(call all-java-files-under, java)
 
diff --git a/media/tests/ScoAudioTest/Android.mk b/media/tests/ScoAudioTest/Android.mk
index ab12865..2ad91a4 100644
--- a/media/tests/ScoAudioTest/Android.mk
+++ b/media/tests/ScoAudioTest/Android.mk
@@ -2,6 +2,7 @@
 include $(CLEAR_VARS)
 
 #LOCAL_SDK_VERSION := current
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_MODULE_TAGS := tests
 
diff --git a/media/tests/SoundPoolTest/Android.mk b/media/tests/SoundPoolTest/Android.mk
index 7f947c0..9ca33c8 100644
--- a/media/tests/SoundPoolTest/Android.mk
+++ b/media/tests/SoundPoolTest/Android.mk
@@ -6,5 +6,6 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := SoundPoolTest
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 include $(BUILD_PACKAGE)
diff --git a/native/android/storage_manager.cpp b/native/android/storage_manager.cpp
index 137b72c..bf15b8d 100644
--- a/native/android/storage_manager.cpp
+++ b/native/android/storage_manager.cpp
@@ -21,7 +21,7 @@
 
 #include <binder/Binder.h>
 #include <binder/IServiceManager.h>
-#include <utils/Atomic.h>
+#include <cutils/atomic.h>
 #include <utils/Log.h>
 #include <utils/RefBase.h>
 #include <utils/String8.h>
diff --git a/native/webview/plat_support/Android.mk b/native/webview/plat_support/Android.mk
new file mode 100644
index 0000000..6a33fe2
--- /dev/null
+++ b/native/webview/plat_support/Android.mk
@@ -0,0 +1,52 @@
+#
+# Copyright (C) 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.
+#
+
+# This package provides the system interfaces allowing WebView to render.
+
+LOCAL_PATH := $(call my-dir)
+
+# Native support library (libwebviewchromium_plat_support.so) - does NOT link
+# any native chromium code.
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= libwebviewchromium_plat_support
+
+LOCAL_SRC_FILES:= \
+        draw_gl_functor.cpp \
+        jni_entry_point.cpp \
+        graphics_utils.cpp \
+        graphic_buffer_impl.cpp \
+
+LOCAL_C_INCLUDES:= \
+        external/skia/include/core \
+        frameworks/base/core/jni/android/graphics \
+        frameworks/native/include/ui \
+
+LOCAL_SHARED_LIBRARIES += \
+        libandroid_runtime \
+        liblog \
+        libcutils \
+        libui \
+        libutils \
+        libhwui \
+        libandroidfw
+
+LOCAL_MODULE_TAGS := optional
+
+# To remove warnings from skia header files
+LOCAL_CFLAGS := -Wno-unused-parameter
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/native/webview/plat_support/LICENSE b/native/webview/plat_support/LICENSE
new file mode 100644
index 0000000..972bb2e
--- /dev/null
+++ b/native/webview/plat_support/LICENSE
@@ -0,0 +1,27 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//    * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//    * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//    * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/native/webview/plat_support/draw_gl.h b/native/webview/plat_support/draw_gl.h
new file mode 100644
index 0000000..c8434b6
--- /dev/null
+++ b/native/webview/plat_support/draw_gl.h
@@ -0,0 +1,131 @@
+// Copyright 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+//******************************************************************************
+// This is a copy of the coresponding android_webview/public/browser header.
+// Any changes to the interface should be made there.
+//
+// The purpose of having the copy is twofold:
+//  - it removes the need to have Chromium sources present in the tree in order
+//    to build the plat_support library,
+//  - it captures API that the corresponding Android release supports.
+//******************************************************************************
+
+#ifndef ANDROID_WEBVIEW_PUBLIC_BROWSER_DRAW_GL_H_
+#define ANDROID_WEBVIEW_PUBLIC_BROWSER_DRAW_GL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// 1 is L/L MR1
+//
+// 2 starts at M, and added an imperfect workaround for complex clipping by
+// elevating the WebView into an FBO layer. If any transform, clip, or outline
+// clip occurs that would either likely use the stencil buffer for clipping, or
+// require shader based clipping in HWUI, the WebView is drawn into an FBO (if
+// it fits).
+// This is a temporary workaround for a lack of WebView support for stencil/
+// shader based round rect clipping, and should be removed when webview is
+// capable of supporting these clips internally when drawing.
+//
+// 3 starts during development of P, when android defaults from HWUI to skia as
+// the GL renderer. Skia already maintains and restores its GL state, so there
+// is no need for WebView to restore this state. Skia also no longer promises
+// GL state on entering draw, such as no vertex array buffer binding.
+static const int kAwDrawGLInfoVersion = 3;
+
+// Holds the information required to trigger an OpenGL drawing operation.
+struct AwDrawGLInfo {
+  int version;  // The AwDrawGLInfo this struct was built with.
+
+  // Input: tells the draw function what action to perform.
+  enum Mode {
+    kModeDraw = 0,
+    kModeProcess,
+    kModeProcessNoContext,
+    kModeSync,
+  } mode;
+
+  // Input: current clip rect in surface coordinates. Reflects the current state
+  // of the OpenGL scissor rect. Both the OpenGL scissor rect and viewport are
+  // set by the caller of the draw function and updated during View animations.
+  int clip_left;
+  int clip_top;
+  int clip_right;
+  int clip_bottom;
+
+  // Input: current width/height of destination surface.
+  int width;
+  int height;
+
+  // Input: is the View rendered into an independent layer.
+  // If false, the surface is likely to hold to the full screen contents, with
+  // the scissor box set by the caller to the actual View location and size.
+  // Also the transformation matrix will contain at least a translation to the
+  // position of the View to render, plus any other transformations required as
+  // part of any ongoing View animation. View translucency (alpha) is ignored,
+  // although the framework will set is_layer to true for non-opaque cases.
+  // Can be requested via the View.setLayerType(View.LAYER_TYPE_NONE, ...)
+  // Android API method.
+  //
+  // If true, the surface is dedicated to the View and should have its size.
+  // The viewport and scissor box are set by the caller to the whole surface.
+  // Animation transformations are handled by the caller and not reflected in
+  // the provided transformation matrix. Translucency works normally.
+  // Can be requested via the View.setLayerType(View.LAYER_TYPE_HARDWARE, ...)
+  // Android API method.
+  bool is_layer;
+
+  // Input: current transformation matrix in surface pixels.
+  // Uses the column-based OpenGL matrix format.
+  float transform[16];
+};
+
+// Function to invoke a direct GL draw into the client's pre-configured
+// GL context. Obtained via AwContents.getDrawGLFunction() (static).
+// |view_context| is an opaque identifier that was returned by the corresponding
+// call to AwContents.getAwDrawGLViewContext().
+// |draw_info| carries the in and out parameters for this draw.
+// |spare| ignored; pass NULL.
+typedef void (AwDrawGLFunction)(long view_context,
+                                AwDrawGLInfo* draw_info,
+                                void* spare);
+enum AwMapMode {
+  MAP_READ_ONLY,
+  MAP_WRITE_ONLY,
+  MAP_READ_WRITE,
+};
+
+// Called to create a GraphicBuffer
+typedef long AwCreateGraphicBufferFunction(int w, int h);
+// Called to release a GraphicBuffer
+typedef void AwReleaseGraphicBufferFunction(long buffer_id);
+// Called to map a GraphicBuffer in |mode|.
+typedef int AwMapFunction(long buffer_id, AwMapMode mode, void** vaddr);
+// Called to unmap a GraphicBuffer
+typedef int AwUnmapFunction(long buffer_id);
+// Called to get a native buffer pointer
+typedef void* AwGetNativeBufferFunction(long buffer_id);
+// Called to get the stride of the buffer
+typedef unsigned int AwGetStrideFunction(long buffer_id);
+
+static const int kAwDrawGLFunctionTableVersion = 1;
+
+// Set of functions used in rendering in hardware mode
+struct AwDrawGLFunctionTable {
+  int version;
+  AwCreateGraphicBufferFunction* create_graphic_buffer;
+  AwReleaseGraphicBufferFunction* release_graphic_buffer;
+  AwMapFunction* map;
+  AwUnmapFunction* unmap;
+  AwGetNativeBufferFunction* get_native_buffer;
+  AwGetStrideFunction* get_stride;
+};
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // ANDROID_WEBVIEW_PUBLIC_BROWSER_DRAW_GL_H_
diff --git a/native/webview/plat_support/draw_gl_functor.cpp b/native/webview/plat_support/draw_gl_functor.cpp
new file mode 100644
index 0000000..d54f558
--- /dev/null
+++ b/native/webview/plat_support/draw_gl_functor.cpp
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 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.
+ */
+
+// Provides a webviewchromium glue layer adapter from the internal Android
+// GL Functor data types into the types the chromium stack expects, and back.
+
+#define LOG_TAG "webviewchromium_plat_support"
+
+#include "draw_gl.h"
+
+#include <Properties.h>
+#include <errno.h>
+#include <jni.h>
+#include <private/hwui/DrawGlInfo.h>
+#include <string.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <utils/Functor.h>
+#include <utils/Log.h>
+
+#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
+#define COMPILE_ASSERT(expr, err) \
+__unused static const char (err)[(expr) ? 1 : -1] = "";
+
+namespace android {
+namespace {
+
+AwDrawGLFunction* g_aw_drawgl_function = NULL;
+
+class DrawGLFunctor : public Functor {
+ public:
+  explicit DrawGLFunctor(jlong view_context) : view_context_(view_context) {}
+  virtual ~DrawGLFunctor() {}
+
+  // Functor
+  virtual status_t operator ()(int what, void* data) {
+    using uirenderer::DrawGlInfo;
+    if (!g_aw_drawgl_function) {
+      ALOGE("Cannot draw: no DrawGL Function installed");
+      return DrawGlInfo::kStatusDone;
+    }
+
+    AwDrawGLInfo aw_info;
+    // TODO(boliu): Remove property check once OpenGL fallback is removed.
+    auto render_pipeline_type =
+        android::uirenderer::Properties::getRenderPipelineType();
+    aw_info.version = (render_pipeline_type ==
+                       android::uirenderer::RenderPipelineType::OpenGL)
+                          ? 2
+                          : kAwDrawGLInfoVersion;
+    switch (what) {
+      case DrawGlInfo::kModeDraw: {
+        aw_info.mode = AwDrawGLInfo::kModeDraw;
+        DrawGlInfo* gl_info = reinterpret_cast<DrawGlInfo*>(data);
+
+        // Map across the input values.
+        aw_info.clip_left = gl_info->clipLeft;
+        aw_info.clip_top = gl_info->clipTop;
+        aw_info.clip_right = gl_info->clipRight;
+        aw_info.clip_bottom = gl_info->clipBottom;
+        aw_info.width = gl_info->width;
+        aw_info.height = gl_info->height;
+        aw_info.is_layer = gl_info->isLayer;
+        COMPILE_ASSERT(NELEM(aw_info.transform) == NELEM(gl_info->transform),
+                       mismatched_transform_matrix_sizes);
+        for (int i = 0; i < NELEM(aw_info.transform); ++i) {
+          aw_info.transform[i] = gl_info->transform[i];
+        }
+        break;
+      }
+      case DrawGlInfo::kModeProcess:
+        aw_info.mode = AwDrawGLInfo::kModeProcess;
+        break;
+      case DrawGlInfo::kModeProcessNoContext:
+        aw_info.mode = AwDrawGLInfo::kModeProcessNoContext;
+        break;
+      case DrawGlInfo::kModeSync:
+        aw_info.mode = AwDrawGLInfo::kModeSync;
+        break;
+      default:
+        ALOGE("Unexpected DrawGLInfo type %d", what);
+        return DrawGlInfo::kStatusDone;
+    }
+
+    // Invoke the DrawGL method.
+    g_aw_drawgl_function(view_context_, &aw_info, NULL);
+
+    return DrawGlInfo::kStatusDone;
+  }
+
+ private:
+  intptr_t view_context_;
+};
+
+// Raise the file handle soft limit to the hard limit since gralloc buffers
+// uses file handles.
+void RaiseFileNumberLimit() {
+  static bool have_raised_limit = false;
+  if (have_raised_limit)
+    return;
+
+  have_raised_limit = true;
+  struct rlimit limit_struct;
+  limit_struct.rlim_cur = 0;
+  limit_struct.rlim_max = 0;
+  if (getrlimit(RLIMIT_NOFILE, &limit_struct) == 0) {
+    limit_struct.rlim_cur = limit_struct.rlim_max;
+    if (setrlimit(RLIMIT_NOFILE, &limit_struct) != 0) {
+      ALOGE("setrlimit failed: %s", strerror(errno));
+    }
+  } else {
+    ALOGE("getrlimit failed: %s", strerror(errno));
+  }
+}
+
+jlong CreateGLFunctor(JNIEnv*, jclass, jlong view_context) {
+  RaiseFileNumberLimit();
+  return reinterpret_cast<jlong>(new DrawGLFunctor(view_context));
+}
+
+void DestroyGLFunctor(JNIEnv*, jclass, jlong functor) {
+  delete reinterpret_cast<DrawGLFunctor*>(functor);
+}
+
+void SetChromiumAwDrawGLFunction(JNIEnv*, jclass, jlong draw_function) {
+  g_aw_drawgl_function = reinterpret_cast<AwDrawGLFunction*>(draw_function);
+}
+
+const char kClassName[] = "com/android/webview/chromium/DrawGLFunctor";
+const JNINativeMethod kJniMethods[] = {
+    { "nativeCreateGLFunctor", "(J)J",
+        reinterpret_cast<void*>(CreateGLFunctor) },
+    { "nativeDestroyGLFunctor", "(J)V",
+        reinterpret_cast<void*>(DestroyGLFunctor) },
+    { "nativeSetChromiumAwDrawGLFunction", "(J)V",
+        reinterpret_cast<void*>(SetChromiumAwDrawGLFunction) },
+};
+
+}  // namespace
+
+void RegisterDrawGLFunctor(JNIEnv* env) {
+  jclass clazz = env->FindClass(kClassName);
+  LOG_ALWAYS_FATAL_IF(!clazz, "Unable to find class '%s'", kClassName);
+
+  int res = env->RegisterNatives(clazz, kJniMethods, NELEM(kJniMethods));
+  LOG_ALWAYS_FATAL_IF(res < 0, "register native methods failed: res=%d", res);
+}
+
+}  // namespace android
diff --git a/native/webview/plat_support/draw_sw.h b/native/webview/plat_support/draw_sw.h
new file mode 100644
index 0000000..7423e13
--- /dev/null
+++ b/native/webview/plat_support/draw_sw.h
@@ -0,0 +1,66 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+//******************************************************************************
+// This is a copy of the coresponding android_webview/public/browser header.
+// Any changes to the interface should be made there.
+//
+// The purpose of having the copy is twofold:
+//  - it removes the need to have Chromium sources present in the tree in order
+//    to build the plat_support library,
+//  - it captures API that the corresponding Android release supports.
+//******************************************************************************
+
+#ifndef ANDROID_WEBVIEW_PUBLIC_BROWSER_DRAW_SW_H_
+#define ANDROID_WEBVIEW_PUBLIC_BROWSER_DRAW_SW_H_
+
+#include <jni.h>
+#include <stddef.h>
+
+#ifndef __cplusplus
+#error "Can't mix C and C++ when using jni.h"
+#endif
+
+class SkCanvasState;
+class SkPicture;
+
+static const int kAwPixelInfoVersion = 3;
+
+// Holds the information required to implement the SW draw to system canvas.
+struct AwPixelInfo {
+  int version;          // The kAwPixelInfoVersion this struct was built with.
+  SkCanvasState* state; // The externalize state in skia format.
+  // NOTE: If you add more members, bump kAwPixelInfoVersion.
+};
+
+// Function that can be called to fish out the underlying native pixel data
+// from a Java canvas object, for optimized rendering path.
+// Returns the pixel info on success, which must be freed via a call to
+// AwReleasePixelsFunction, or NULL.
+typedef AwPixelInfo* (AwAccessPixelsFunction)(JNIEnv* env, jobject canvas);
+
+// Must be called to balance every *successful* call to AwAccessPixelsFunction
+// (i.e. that returned true).
+typedef void (AwReleasePixelsFunction)(AwPixelInfo* pixels);
+
+// Called to create an Android Picture object encapsulating a native SkPicture.
+typedef jobject (AwCreatePictureFunction)(JNIEnv* env, SkPicture* picture);
+
+// Method that returns the current Skia function.
+typedef void (SkiaVersionFunction)(int* major, int* minor, int* patch);
+
+// Called to verify if the Skia versions are compatible.
+typedef bool (AwIsSkiaVersionCompatibleFunction)(SkiaVersionFunction function);
+
+static const int kAwDrawSWFunctionTableVersion = 1;
+
+// "vtable" for the functions declared in this file. An instance must be set via
+// AwContents.setAwDrawSWFunctionTable
+struct AwDrawSWFunctionTable {
+  int version;
+  AwAccessPixelsFunction* access_pixels;
+  AwReleasePixelsFunction* release_pixels;
+};
+
+#endif  // ANDROID_WEBVIEW_PUBLIC_BROWSER_DRAW_SW_H_
diff --git a/native/webview/plat_support/graphic_buffer_impl.cpp b/native/webview/plat_support/graphic_buffer_impl.cpp
new file mode 100644
index 0000000..4426778
--- /dev/null
+++ b/native/webview/plat_support/graphic_buffer_impl.cpp
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+// Provides the implementation of the GraphicBuffer interface in
+// renderer compostior
+
+#include "graphic_buffer_impl.h"
+
+#include <utils/Errors.h>
+
+namespace android {
+
+GraphicBufferImpl::GraphicBufferImpl(uint32_t w, uint32_t h)
+  : mBuffer(new android::GraphicBuffer(w, h, PIXEL_FORMAT_RGBA_8888,
+       android::GraphicBuffer::USAGE_HW_TEXTURE |
+       android::GraphicBuffer::USAGE_SW_READ_OFTEN |
+       android::GraphicBuffer::USAGE_SW_WRITE_OFTEN)) {
+}
+
+GraphicBufferImpl::~GraphicBufferImpl() {
+}
+
+// static
+long GraphicBufferImpl::Create(int w, int h) {
+  GraphicBufferImpl* buffer = new GraphicBufferImpl(
+      static_cast<uint32_t>(w), static_cast<uint32_t>(h));
+  if (buffer->InitCheck() != NO_ERROR) {
+    delete buffer;
+    return 0;
+  }
+  return reinterpret_cast<intptr_t>(buffer);
+}
+
+// static
+void GraphicBufferImpl::Release(long buffer_id) {
+  GraphicBufferImpl* buffer = reinterpret_cast<GraphicBufferImpl*>(buffer_id);
+  delete buffer;
+}
+
+// static
+int GraphicBufferImpl::MapStatic(long buffer_id, AwMapMode mode, void** vaddr) {
+  GraphicBufferImpl* buffer = reinterpret_cast<GraphicBufferImpl*>(buffer_id);
+  return buffer->Map(mode, vaddr);
+}
+
+// static
+int GraphicBufferImpl::UnmapStatic(long buffer_id) {
+  GraphicBufferImpl* buffer = reinterpret_cast<GraphicBufferImpl*>(buffer_id);
+  return buffer->Unmap();
+}
+
+// static
+void* GraphicBufferImpl::GetNativeBufferStatic(long buffer_id) {
+  GraphicBufferImpl* buffer = reinterpret_cast<GraphicBufferImpl*>(buffer_id);
+  return buffer->GetNativeBuffer();
+}
+
+// static
+uint32_t GraphicBufferImpl::GetStrideStatic(long buffer_id) {
+  GraphicBufferImpl* buffer = reinterpret_cast<GraphicBufferImpl*>(buffer_id);
+  return buffer->GetStride();
+}
+
+status_t GraphicBufferImpl::Map(AwMapMode mode, void** vaddr) {
+  int usage = 0;
+  switch (mode) {
+    case MAP_READ_ONLY:
+      usage = android::GraphicBuffer::USAGE_SW_READ_OFTEN;
+      break;
+    case MAP_WRITE_ONLY:
+      usage = android::GraphicBuffer::USAGE_SW_WRITE_OFTEN;
+      break;
+    case MAP_READ_WRITE:
+      usage = android::GraphicBuffer::USAGE_SW_READ_OFTEN |
+          android::GraphicBuffer::USAGE_SW_WRITE_OFTEN;
+      break;
+    default:
+      return INVALID_OPERATION;
+  }
+  return mBuffer->lock(usage, vaddr);
+}
+
+status_t GraphicBufferImpl::Unmap() {
+  return mBuffer->unlock();
+}
+
+status_t GraphicBufferImpl::InitCheck() const {
+  return mBuffer->initCheck();
+}
+
+void* GraphicBufferImpl::GetNativeBuffer() const {
+  return mBuffer->getNativeBuffer();
+}
+
+uint32_t GraphicBufferImpl::GetStride() const {
+  static const int kBytesPerPixel = 4;
+  return mBuffer->getStride() * kBytesPerPixel;
+}
+
+} // namespace android
diff --git a/native/webview/plat_support/graphic_buffer_impl.h b/native/webview/plat_support/graphic_buffer_impl.h
new file mode 100644
index 0000000..442710a
--- /dev/null
+++ b/native/webview/plat_support/graphic_buffer_impl.h
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+// Provides the implementation of the GraphicBuffer interface in
+// renderer compostior
+
+#ifndef ANDROID_GRAPHIC_BUFFER_IMPL_H
+#define ANDROID_GRAPHIC_BUFFER_IMPL_H
+
+#include <ui/GraphicBuffer.h>
+
+#include "draw_gl.h"
+
+namespace android {
+
+class GraphicBufferImpl {
+ public:
+  ~GraphicBufferImpl();
+
+  static long Create(int w, int h);
+  static void Release(long buffer_id);
+  static int MapStatic(long buffer_id, AwMapMode mode, void** vaddr);
+  static int UnmapStatic(long buffer_id);
+  static void* GetNativeBufferStatic(long buffer_id);
+  static uint32_t GetStrideStatic(long buffer_id);
+
+ private:
+  status_t Map(AwMapMode mode, void** vaddr);
+  status_t Unmap();
+  status_t InitCheck() const;
+  void* GetNativeBuffer() const;
+  uint32_t GetStride() const;
+  GraphicBufferImpl(uint32_t w, uint32_t h);
+
+  sp<android::GraphicBuffer> mBuffer;
+};
+
+}  // namespace android
+
+#endif  // ANDROID_GRAPHIC_BUFFER_IMPL_H
diff --git a/native/webview/plat_support/graphics_utils.cpp b/native/webview/plat_support/graphics_utils.cpp
new file mode 100644
index 0000000..89beb75
--- /dev/null
+++ b/native/webview/plat_support/graphics_utils.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 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.
+ */
+
+// Provides a webviewchromium glue layer adapter from the internal Android
+// graphics types into the types the chromium stack expects, and back.
+
+#define LOG_TAG "webviewchromium_plat_support"
+
+#include "draw_gl.h"
+#include "draw_sw.h"
+
+#include <cstdlib>
+#include <jni.h>
+#include <utils/Log.h>
+#include "graphic_buffer_impl.h"
+#include "GraphicsJNI.h"
+#include "SkCanvasStateUtils.h"
+#include "SkGraphics.h"
+#include "SkPicture.h"
+
+#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
+
+namespace android {
+namespace {
+
+class PixelInfo : public AwPixelInfo {
+ public:
+  explicit PixelInfo(android::Canvas* canvas);
+  ~PixelInfo();
+};
+
+
+PixelInfo::PixelInfo(android::Canvas* canvas) {
+  memset(this, 0, sizeof(AwPixelInfo));
+  version = kAwPixelInfoVersion;
+  state = canvas->captureCanvasState();
+}
+
+PixelInfo::~PixelInfo() {
+  if (state)
+    SkCanvasStateUtils::ReleaseCanvasState(state);
+}
+
+AwPixelInfo* GetPixels(JNIEnv* env, jobject java_canvas) {
+  android::Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, java_canvas);
+  if (!nativeCanvas)
+    return NULL;
+
+  PixelInfo* pixels = new PixelInfo(nativeCanvas);
+  if (!pixels->state) {
+      delete pixels;
+      pixels = NULL;
+  }
+  return pixels;
+}
+
+void ReleasePixels(AwPixelInfo* pixels) {
+  delete static_cast<PixelInfo*>(pixels);
+}
+
+jlong GetDrawSWFunctionTable(JNIEnv* env, jclass) {
+  static AwDrawSWFunctionTable function_table;
+  function_table.version = kAwDrawSWFunctionTableVersion;
+  function_table.access_pixels = &GetPixels;
+  function_table.release_pixels = &ReleasePixels;
+  return reinterpret_cast<intptr_t>(&function_table);
+}
+
+jlong GetDrawGLFunctionTable(JNIEnv* env, jclass) {
+  static AwDrawGLFunctionTable function_table;
+  function_table.version = kAwDrawGLFunctionTableVersion;
+  function_table.create_graphic_buffer = &GraphicBufferImpl::Create;
+  function_table.release_graphic_buffer = &GraphicBufferImpl::Release;
+  function_table.map = &GraphicBufferImpl::MapStatic;
+  function_table.unmap = &GraphicBufferImpl::UnmapStatic;
+  function_table.get_native_buffer = &GraphicBufferImpl::GetNativeBufferStatic;
+  function_table.get_stride = &GraphicBufferImpl::GetStrideStatic;
+  return reinterpret_cast<intptr_t>(&function_table);
+}
+
+const char kClassName[] = "com/android/webview/chromium/GraphicsUtils";
+const JNINativeMethod kJniMethods[] = {
+    { "nativeGetDrawSWFunctionTable", "()J",
+        reinterpret_cast<void*>(GetDrawSWFunctionTable) },
+    { "nativeGetDrawGLFunctionTable", "()J",
+        reinterpret_cast<void*>(GetDrawGLFunctionTable) },
+};
+
+}  // namespace
+
+void RegisterGraphicsUtils(JNIEnv* env) {
+  jclass clazz = env->FindClass(kClassName);
+  LOG_ALWAYS_FATAL_IF(!clazz, "Unable to find class '%s'", kClassName);
+
+  int res = env->RegisterNatives(clazz, kJniMethods, NELEM(kJniMethods));
+  LOG_ALWAYS_FATAL_IF(res < 0, "register native methods failed: res=%d", res);
+}
+
+}  // namespace android
diff --git a/native/webview/plat_support/jni_entry_point.cpp b/native/webview/plat_support/jni_entry_point.cpp
new file mode 100644
index 0000000..4771be1
--- /dev/null
+++ b/native/webview/plat_support/jni_entry_point.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#define LOG_TAG "webviewchromium_plat_support"
+
+#include <jni.h>
+#include <utils/Log.h>
+
+namespace android {
+
+void RegisterDrawGLFunctor(JNIEnv* env);
+void RegisterGraphicsUtils(JNIEnv* env);
+
+}  // namespace android
+
+JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+  JNIEnv* env = NULL;
+  jint ret = vm->AttachCurrentThread(&env, NULL);
+  LOG_ALWAYS_FATAL_IF(ret != JNI_OK, "AttachCurrentThread failed");
+  android::RegisterDrawGLFunctor(env);
+  android::RegisterGraphicsUtils(env);
+
+  return JNI_VERSION_1_4;
+}
diff --git a/packages/BackupRestoreConfirmation/Android.mk b/packages/BackupRestoreConfirmation/Android.mk
index b84c07f..532d272 100644
--- a/packages/BackupRestoreConfirmation/Android.mk
+++ b/packages/BackupRestoreConfirmation/Android.mk
@@ -22,6 +22,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := BackupRestoreConfirmation
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_CERTIFICATE := platform
 LOCAL_PRIVILEGED_MODULE := true
 
diff --git a/packages/BackupRestoreConfirmation/res/values-as/strings.xml b/packages/BackupRestoreConfirmation/res/values-as/strings.xml
new file mode 100644
index 0000000..4a86d64
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-as/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="backup_confirm_title" msgid="827563724209303345">"সম্পূৰ্ণ বেকআপ"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"সম্পূৰ্ণ পুনঃস্থাপন"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"এটা সংযোগ হৈ থকা ডেস্কট\'প কম্পিউটাৰলৈ সকলো ডেটাক সম্পূৰ্ণৰূপে পুনঃস্থাপনৰ বাবে অনুৰোধ কৰা হৈছে। আপুনি এই কাৰ্যক অনুমতি দিব বিচাৰেনে?\n\nযদিহে আপুনি নিজৰ ফালৰ পৰা এই অনুৰোধটো কৰা নাই, তেন্তে এই কাৰ্যক অনুমতি নিদিব।"</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"মোৰ ডেটাৰ বেকআপ লওক"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"বেকআপ নল\'ব"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"সংযোগ হৈ থকা এটা ডেস্কটপ কম্পিউটাৰৰ পৰা সকলো ডেটাৰ সম্পূৰ্ণ পুনঃস্থাপনৰ বাবে অনুৰোধ কৰা হৈছে। আপুনি এই কাৰ্য সম্পন্ন হ\'বলৈ দিব বিচাৰেনে?\n\nযদিহে আপুনে নিজৰ ফালৰ পৰা এই অনুৰোধটো কৰা নাই, তেন্তে এই কাৰ্য আৰম্ভ হ\'বলৈ নিদিব। এই কাৰ্যই ডিভাইচত থকা সকলো ডেটা সলনি কৰিব!"</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"মোৰ ডেটা পুনঃস্থাপন কৰক"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"পুনঃস্থাপন নকৰিব"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"অনুগ্ৰহ কৰি আপোনাৰ বৰ্তমানৰ বেকআপ পাছৱৰ্ডটো তলত দিয়ক:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"অনুগ্ৰহ কৰি তলত আপোনাৰ ডিভাইচৰ এনক্ৰিপশ্বন পাছৱৰ্ডটো দিয়ক৷"</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"অনুগ্ৰহ কৰি তলত আপোনাৰ ডিভাইচৰ এনক্ৰিপশ্বন পাছৱৰ্ডটো দিয়ক৷ এই পাছৱৰ্ডটো বেকআপ কাৰ্যৰ আৰ্কাইভ কৰিবলৈও ব্যৱহাৰ কৰা হ\'ব৷"</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"সম্পূৰ্ণৰূপে বেকআপ লোৱা ডেটা এনক্ৰিপ্ট কৰিবলৈ অনুগ্ৰহ কৰি এটা পাছৱৰ্ড দিয়ক। এই ঠাইটো খালী ৰাখিলে আপোনাৰ বৰ্তমানৰ বেকআপ পাছৱৰ্ডটো ব্যৱহাৰ কৰা হ\'ব:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"যদি আপুনি সম্পূৰ্ণ বেকআপ ডেটা এনক্ৰিপ্ট কৰিব বিচাৰিছে, তেতিয়াহ\'লে তলত পাছৱৰ্ড এটা দিয়ক:"</string>
+    <string name="backup_enc_password_required" msgid="7889652203371654149">"যিহেতু আপোনাৰ ডিভাইচটো এনক্ৰিপ্ট কৰা হৈছে, আপুনি আপোনাৰ বেকআপ এনক্ৰিপ্ট কৰাৰ প্ৰয়োজন। অনুগ্ৰহ কৰি তলত এটা পাছৱৰ্ড দিয়ক:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"যদি পুনঃস্থাপন কৰিবলগীয়া ডেটা এনক্ৰিপ্ট কৰা আছে, তেন্তে তলত পাছৱৰ্ড দিয়ক:"</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"বেকআপ লোৱা কাৰ্য আৰম্ভ কৰি আছে..."</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"বেকআপ লোৱা সম্পূৰ্ণ হ\'ল"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"পুনঃস্থাপন কাৰ্য আৰম্ভ কৰি আছে..."</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"পুনঃস্থাপন কাৰ্য সমাপ্ত হ\'ল"</string>
+    <string name="toast_timeout" msgid="5276598587087626877">"কাৰ্যটোৰ সময়সীমা উকলি গ\'ল"</string>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-bs/strings.xml b/packages/BackupRestoreConfirmation/res/values-bs/strings.xml
index e4852ed..bc52b06 100644
--- a/packages/BackupRestoreConfirmation/res/values-bs/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-bs/strings.xml
@@ -21,7 +21,7 @@
     <string name="backup_confirm_text" msgid="1878021282758896593">"Zatraženo je pravljenje potpune rezervne kopije svih podataka na povezani računar. Da li želite da dozvolite to?\n\nPrekinite radnju ukoliko to niste sami zatražili."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Napravi sigurnosnu kopiju mojih podataka"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Nemoj napraviti rezervnu kopiju"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Sa povezanog računara je upućen zahtjev za potpuno obnavljanje svih podataka. Želite li to dozvoliti?\n\nUkoliko niste uputili zahtjev za obnavljanje, prekinite radnju. Ovim će zamijeniti svi podaci koji su trenutno na uređaju!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Sa povezanog računara je upućen zahtjev za potpuno vraćanje svih podataka. Želite li to dozvoliti?\n\nUkoliko niste uputili zahtjev za vraćanje, prekinite radnju. Ovim će zamijeniti svi podaci koji su trenutno na uređaju!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Vrati moje podatke"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Ne vraćaj"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Ispod unesite svoju trenutnu lozinku za sigurnosnu kopiju:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-or/strings.xml b/packages/BackupRestoreConfirmation/res/values-or/strings.xml
new file mode 100644
index 0000000..77f3efb
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-or/strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="backup_confirm_title" msgid="827563724209303345">"ସମ୍ପୂର୍ଣ୍ଣ ବ୍ୟାକଅପ୍‌"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"ସମ୍ପୂର୍ଣ୍ଣ ରିଷ୍ଟୋର୍‌"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"ଏକ ସଂଯୁକ୍ତ ଡେସ୍କଟପ୍‌ କମ୍ପ୍ୟୁଟର୍‌କୁ ସମସ୍ତ ଡାଟାର ସମ୍ପୂର୍ଣ୍ଣ ବ୍ୟାକଅପ୍‌ କରିବାକୁ ଅନୁରୋଧ କରାଯାଇଛି। ଆପଣ ଏହିପରି କରିବାକୁ ଚାହିଁବେ?\n\nଯଦି ଆପଣ ନିଜେ ବ୍ୟାକଅପ୍‌ର ଅନୁରୋଧ କରିନାହାନ୍ତି, ତେବେ ଏହି କାମକୁ ଆଗକୁ ବଢ଼ିବାକୁ ଦିଅନ୍ତୁ ନାହିଁ।"</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"ମୋ ଡାଟାର ବ୍ୟାକଅପ୍‌ ନିଆଯାଉ"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"ବ୍ୟାକଅପ୍‌ ନିଆନଯାଉ"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"ଏକ ସଂଯୁକ୍ତ ଡେସ୍କଟପ୍‌ କମ୍ପ୍ୟୁଟର୍‌ରୁ ସମସ୍ତ ଡାଟାର ସମ୍ପୂର୍ଣ୍ଣ ରିଷ୍ଟୋର୍‌ ଅନୁରୋଧ କରାଯାଇଛି। ଆପଣ ଏହାକୁ ଅନୁମତି ଦେବାକୁ ଚାହିଁବେ କି?\n\nଯଦି ଆପଣ ନିଜେ ରିଷ୍ଟୋର୍‌ ଅନୁରୋଧ କରିନାହାନ୍ତି, ତେବେ ଏହା କାର୍ଯ୍ୟକୁ ଆଗକୁ ବଢ଼ିବାକୁ ଦିଅନ୍ତୁ ନାହିଁ। ଏହା ବର୍ତ୍ତମାନ ଡିଭାଇସ୍‍ରେ ଥିବା ଯେକୌଣସି ଡାଟାକୁ ବଦଳାଇଦେବ!"</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"ମୋ ଡାଟାକୁ ରିଷ୍ଟୋର୍‌ କରାଯାଉ"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"ରିଷ୍ଟୋର୍‍ କରନ୍ତୁ ନାହିଁ।"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"ଦୟାକରି ନିମ୍ନରେ ବର୍ତ୍ତମାନର ବ୍ୟାକଅପ୍‍ ପାସ୍‌ୱର୍ଡ ଲେଖନ୍ତୁ:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"ଦୟାକରି, ତଳେ ନିଜର ଏନକ୍ରିପ୍ସନ୍‌ ପାସ୍‌ୱର୍ଡକୁ ଦିଅନ୍ତୁ।"</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"ଦୟାକରି, ତଳେ ନିଜର ଡିଭାଇସ୍‌ ଏନକ୍ରିପ୍ସନ୍‌ ପାସ୍‌ୱର୍ଡ ଦିଅନ୍ତୁ। ବ୍ୟାକଅପ୍‌ ଆର୍କାଇଭ୍‌ ଏନ୍‌କ୍ରିପ୍ଟ କରିବା ପାଇଁ ମଧ୍ୟ ଏହା ବ୍ୟବହୃତ ହେବ।"</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"ପୂର୍ଣ୍ଣ ବ୍ୟାକଅପ୍‍ ଡାଟାକୁ ଏନକ୍ରୀପ୍ଟ ବ୍ୟବହାର କରିବା ପାଇଁ ଏକ ପାସୱର୍ଡ ଦିଅନ୍ତୁ। ଯଦି ଏହାକୁ ଖାଲି ଛାଡ଼ି ଦିଆଯାଏ, ତେବେ ଆପଣଙ୍କ ବର୍ତ୍ତମାନର ପାସୱର୍ଡ ବ୍ୟବହାର କରାଯିବ।"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"ଯଦି ଆପଣ ସମ୍ପୂର୍ଣ୍ଣ ବ୍ୟାକଅପ୍‌କୁ ଏନ୍‌କ୍ରିପ୍ଟ କରିବାକୁ ଚାହାନ୍ତି, ତେବେ ତଳେ ଗୋଟିଏ ପାସ୍‌ୱର୍ଡ ଦିଅନ୍ତୁ:"</string>
+    <string name="backup_enc_password_required" msgid="7889652203371654149">"ଆପଣଙ୍କ ଡିଭାଇସ୍‌କୁ ଏନକ୍ରିପ୍ଟ କରାଯାଇଥିବାରୁ ଆପଣଙ୍କୁ ନିଜ ବ୍ୟାକଅପକୁ ଏନକ୍ରିପ୍ଟ କରିବାକୁ ଦରକାର ପଡ଼ିବ। ଦୟାକରି ତଳେ ପାସ୍‌ୱର୍ଡ ଲେଖନ୍ତୁ:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"ଯଦି ରିଷ୍ଟୋର୍ ଡାଟା ଏନକ୍ରିପ୍ଟ ହୋଇଯାଇଥାଏ, ତେବେ ତଳେ ପାସ୍‌ୱର୍ଡ ଲେଖନ୍ତୁ:"</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"ବ୍ୟାକଅପ୍‌ ଆରମ୍ଭ କରୁଛି..."</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"ବ୍ୟାକଅପ୍‌ ସମାପ୍ତ ହେଲା"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"ରିଷ୍ଟୋର୍‌ ଆରମ୍ଭ ହେଉଛି..."</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"ରିଷ୍ଟୋର୍‌ ସମାପ୍ତ ହେଲା"</string>
+    <string name="toast_timeout" msgid="5276598587087626877">"କାର୍ଯ୍ୟର ସମୟ ସରିଯାଇଛି"</string>
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-as/strings.xml b/packages/CaptivePortalLogin/res/values-as/strings.xml
new file mode 100644
index 0000000..2281ce7
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-as/strings.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
+    <string name="action_use_network" msgid="6076184727448466030">"এই নেটৱৰ্কটো এইদৰে ব্যৱহাৰ কৰক"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"এই নেটৱৰ্কটো ব্যৱহাৰ নকৰিব"</string>
+    <!-- no translation found for action_bar_label (917235635415966620) -->
+    <skip />
+    <!-- no translation found for action_bar_title (5645564790486983117) -->
+    <skip />
+    <!-- no translation found for ssl_error_warning (6653188881418638872) -->
+    <skip />
+    <!-- no translation found for ssl_error_example (647898534624078900) -->
+    <skip />
+    <!-- no translation found for ssl_error_continue (6492718244923937110) -->
+    <skip />
+</resources>
diff --git a/packages/CaptivePortalLogin/res/values-or/strings.xml b/packages/CaptivePortalLogin/res/values-or/strings.xml
new file mode 100644
index 0000000..b7c8321
--- /dev/null
+++ b/packages/CaptivePortalLogin/res/values-or/strings.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
+    <string name="action_use_network" msgid="6076184727448466030">"ଏହି ନେଟ୍‌ୱର୍କ ଯେପରି ଅଛି, ସେହିପରି ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="action_do_not_use_network" msgid="4577366536956516683">"ଏହି ନେଟ୍‌ୱର୍କକୁ ବ୍ୟବହାର କରନ୍ତୁ ନାହିଁ"</string>
+    <string name="action_bar_label" msgid="917235635415966620">"ନେଟ୍‌ୱର୍କରେ ସାଇନ୍‍ ଇନ୍‍ କରନ୍ତୁ"</string>
+    <!-- no translation found for action_bar_title (5645564790486983117) -->
+    <skip />
+    <string name="ssl_error_warning" msgid="6653188881418638872">"ଆପଣ ଯୋଗ ଦେବାକୁ ଚେଷ୍ଟା କରୁଥିବା ନେଟ୍‌ୱର୍କର ସୁରକ୍ଷା ସମସ୍ୟା ଅଛି।"</string>
+    <string name="ssl_error_example" msgid="647898534624078900">"ଉଦାହରଣସ୍ୱରୂପ, ଲଗଇନ୍‍ ପୃଷ୍ଠା ଦେଖାଯାଇଥିବା ସଂସ୍ଥାର ନହୋଇଥାଇପାରେ।"</string>
+    <string name="ssl_error_continue" msgid="6492718244923937110">"ବ୍ରାଉଜର୍‍ ଜରିଆରେ ଯେମିତିବି ହେଉ ଜାରି ରଖନ୍ତୁ"</string>
+</resources>
diff --git a/packages/CarrierDefaultApp/res/values-as/strings.xml b/packages/CarrierDefaultApp/res/values-as/strings.xml
new file mode 100644
index 0000000..61171bc
--- /dev/null
+++ b/packages/CarrierDefaultApp/res/values-as/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+    <string name="android_system_label" msgid="2797790869522345065">"ম\'বাইল সেৱা প্ৰদান কৰা কোম্পানী"</string>
+    <string name="portal_notification_id" msgid="5155057562457079297">"ম\'বাইল ডেটা শেষ হৈছে"</string>
+    <string name="no_data_notification_id" msgid="668400731803969521">"আপোনাৰ ম\'বাইল ডেটা সেৱা নিষ্ক্ৰিয় কৰা হৈছে"</string>
+    <string name="portal_notification_detail" msgid="2295729385924660881">"%s ৱেবছাইটটোলৈ যাবলৈ টিপক"</string>
+    <string name="no_data_notification_detail" msgid="3112125343857014825">"অনুগ্ৰহ কৰি আপোনাৰ সেৱা প্ৰদানকাৰী %sৰ সৈতে যোগাযোগ কৰক"</string>
+    <!-- no translation found for no_mobile_data_connection_title (7449525772416200578) -->
+    <skip />
+    <!-- no translation found for no_mobile_data_connection (544980465184147010) -->
+    <skip />
+    <!-- no translation found for mobile_data_status_notification_channel_name (833999690121305708) -->
+    <skip />
+    <string name="action_bar_label" msgid="4290345990334377177">"ম\'বাইল নেটৱৰ্কত ছাইন ইন কৰক"</string>
+    <string name="ssl_error_warning" msgid="3127935140338254180">"আপুনি সংযোগ কৰিবলৈ বিচৰা নেটৱৰ্কটোত সুৰক্ষাজনিত সমস্যা আছে।"</string>
+    <string name="ssl_error_example" msgid="6188711843183058764">"উদাহৰণ স্বৰূপে, আপোনাক দেখুওৱা লগ ইনৰ পৃষ্ঠাটো প্ৰতিষ্ঠানটোৰ নিজা নহ\'বও পাৰে।"</string>
+    <string name="ssl_error_continue" msgid="1138548463994095584">"তথাপিও ব্ৰাউজাৰৰ জৰিয়তে অব্যাহত ৰাখক"</string>
+</resources>
diff --git a/packages/CompanionDeviceManager/Android.mk b/packages/CompanionDeviceManager/Android.mk
index f730356..7ec6e11 100644
--- a/packages/CompanionDeviceManager/Android.mk
+++ b/packages/CompanionDeviceManager/Android.mk
@@ -21,6 +21,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := CompanionDeviceManager
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 include $(BUILD_PACKAGE)
 
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
index 7e23ee1..16ef59f 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
@@ -41,7 +41,8 @@
     private static final boolean DEBUG = false;
     private static final String LOG_TAG = "DeviceChooserActivity";
 
-    private ListView mDeviceListView;
+    View mLoadingIndicator = null;
+    ListView mDeviceListView;
     private View mPairButton;
     private View mCancelButton;
 
@@ -80,8 +81,9 @@
                     onSelectionUpdate();
                 }
             });
-            mDeviceListView.addFooterView(getProgressBar(), null, false);
+            mDeviceListView.addFooterView(mLoadingIndicator = getProgressBar(), null, false);
         }
+        getService().mActivity = this;
 
         mCancelButton = findViewById(R.id.button_cancel);
         mCancelButton.setOnClickListener(v -> cancel());
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
index 1e26231..a5f0f24 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
@@ -22,6 +22,7 @@
 import static com.android.internal.util.ArrayUtils.isEmpty;
 import static com.android.internal.util.CollectionUtils.emptyIfNull;
 import static com.android.internal.util.CollectionUtils.size;
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -50,6 +51,7 @@
 import android.graphics.Color;
 import android.graphics.drawable.Drawable;
 import android.net.wifi.WifiManager;
+import android.os.Handler;
 import android.os.IBinder;
 import android.os.Parcelable;
 import android.os.RemoteException;
@@ -63,7 +65,9 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.CollectionUtils;
 import com.android.internal.util.Preconditions;
+import com.android.internal.util.function.pooled.PooledLambda;
 
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
@@ -73,6 +77,8 @@
     private static final boolean DEBUG = false;
     private static final String LOG_TAG = "DeviceDiscoveryService";
 
+    private static final long SCAN_TIMEOUT = 20000;
+
     static DeviceDiscoveryService sInstance;
 
     private BluetoothAdapter mBluetoothAdapter;
@@ -93,6 +99,8 @@
     IFindDeviceCallback mFindCallback;
 
     ICompanionDeviceDiscoveryServiceCallback mServiceCallback;
+    boolean mIsScanning = false;
+    @Nullable DeviceChooserActivity mActivity = null;
 
     private final ICompanionDeviceDiscoveryService mBinder =
             new ICompanionDeviceDiscoveryService.Stub() {
@@ -196,6 +204,10 @@
                     new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
             mWifiManager.startScan();
         }
+        mIsScanning = true;
+        Handler.getMain().sendMessageDelayed(
+                obtainMessage(DeviceDiscoveryService::stopScan, this),
+                SCAN_TIMEOUT);
     }
 
     private boolean shouldScan(List<? extends DeviceFilter> mediumSpecificFilters) {
@@ -219,6 +231,15 @@
     private void stopScan() {
         if (DEBUG) Log.i(LOG_TAG, "stopScan()");
 
+        if (!mIsScanning) return;
+        mIsScanning = false;
+
+        DeviceChooserActivity activity = mActivity;
+        if (activity != null) {
+            activity.mDeviceListView.removeFooterView(activity.mLoadingIndicator);
+            mActivity = null;
+        }
+
         mBluetoothAdapter.cancelDiscovery();
         if (mBluetoothBroadcastReceiver != null) {
             unregisterReceiver(mBluetoothBroadcastReceiver);
diff --git a/packages/DefaultContainerService/Android.mk b/packages/DefaultContainerService/Android.mk
index 0de2c1f..01c8768 100644
--- a/packages/DefaultContainerService/Android.mk
+++ b/packages/DefaultContainerService/Android.mk
@@ -6,6 +6,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := DefaultContainerService
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_JNI_SHARED_LIBRARIES := libdefcontainer_jni
 
diff --git a/packages/DefaultContainerService/res/values-as/strings.xml b/packages/DefaultContainerService/res/values-as/strings.xml
new file mode 100644
index 0000000..1b6391c
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-as/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="service_name" msgid="4841491635055379553">"পেকেজ চোৱা সহায়ক"</string>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-or/strings.xml b/packages/DefaultContainerService/res/values-or/strings.xml
new file mode 100644
index 0000000..394c278
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-or/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="service_name" msgid="4841491635055379553">"ପ୍ୟାକେଜ୍‌ ଆକ୍ସେସ୍‍ ସହାୟକ"</string>
+</resources>
diff --git a/packages/EasterEgg/Android.mk b/packages/EasterEgg/Android.mk
index a825581..605a75d 100644
--- a/packages/EasterEgg/Android.mk
+++ b/packages/EasterEgg/Android.mk
@@ -21,6 +21,7 @@
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := EasterEgg
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_CERTIFICATE := platform
 
 include $(BUILD_PACKAGE)
diff --git a/packages/ExtServices/Android.mk b/packages/ExtServices/Android.mk
index d0c2b9f..467d7ed 100644
--- a/packages/ExtServices/Android.mk
+++ b/packages/ExtServices/Android.mk
@@ -21,6 +21,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := ExtServices
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_CERTIFICATE := platform
 
diff --git a/packages/ExtServices/tests/Android.mk b/packages/ExtServices/tests/Android.mk
index 1eb5847..0a95b85 100644
--- a/packages/ExtServices/tests/Android.mk
+++ b/packages/ExtServices/tests/Android.mk
@@ -18,6 +18,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := ExtServicesUnitTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_INSTRUMENTATION_FOR := ExtServices
 
diff --git a/packages/ExtShared/Android.mk b/packages/ExtShared/Android.mk
index d8052df..7dbf79f 100644
--- a/packages/ExtShared/Android.mk
+++ b/packages/ExtShared/Android.mk
@@ -21,6 +21,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := ExtShared
+LOCAL_SDK_VERSION := current
 
 LOCAL_CERTIFICATE := platform
 
diff --git a/packages/ExternalStorageProvider/Android.mk b/packages/ExternalStorageProvider/Android.mk
index db825ff4..9e99313 100644
--- a/packages/ExternalStorageProvider/Android.mk
+++ b/packages/ExternalStorageProvider/Android.mk
@@ -6,6 +6,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := ExternalStorageProvider
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_CERTIFICATE := platform
 LOCAL_PRIVILEGED_MODULE := true
 
diff --git a/packages/ExternalStorageProvider/res/values-as/strings.xml b/packages/ExternalStorageProvider/res/values-as/strings.xml
new file mode 100644
index 0000000..278b84e
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-as/strings.xml
@@ -0,0 +1,23 @@
+<?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">
+    <string name="app_label" msgid="7123375275748530234">"বাহ্যিক সঞ্চয়াগাৰ"</string>
+    <string name="storage_description" msgid="8541974407321172792">"স্থানীয় সঞ্চয়াগাৰ"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"আভ্যন্তৰীণ সঞ্চয়াগাৰ"</string>
+    <string name="root_documents" msgid="4051252304075469250">"নথিপত্রসমূহ"</string>
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-or/strings.xml b/packages/ExternalStorageProvider/res/values-or/strings.xml
new file mode 100644
index 0000000..034d8a4
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-or/strings.xml
@@ -0,0 +1,24 @@
+<?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">
+    <string name="app_label" msgid="7123375275748530234">"ଏକ୍ସଟର୍ନଲ୍‌ ଷ୍ଟୋରେଜ୍‌"</string>
+    <!-- no translation found for storage_description (8541974407321172792) -->
+    <skip />
+    <string name="root_internal_storage" msgid="827844243068584127">"ଇଣ୍ଟର୍ନଲ୍‌ ଷ୍ଟୋରେଜ୍‌"</string>
+    <string name="root_documents" msgid="4051252304075469250">"ଡକ୍ୟୁମେଣ୍ଟ"</string>
+</resources>
diff --git a/packages/FakeOemFeatures/Android.mk b/packages/FakeOemFeatures/Android.mk
index d96bb3d..43de8e5 100644
--- a/packages/FakeOemFeatures/Android.mk
+++ b/packages/FakeOemFeatures/Android.mk
@@ -6,6 +6,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := FakeOemFeatures
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_CERTIFICATE := platform
 
 LOCAL_PROGUARD_ENABLED := disabled
diff --git a/packages/FusedLocation/Android.mk b/packages/FusedLocation/Android.mk
index 7406eaf4..d795870 100644
--- a/packages/FusedLocation/Android.mk
+++ b/packages/FusedLocation/Android.mk
@@ -22,6 +22,7 @@
 LOCAL_JAVA_LIBRARIES := com.android.location.provider
 
 LOCAL_PACKAGE_NAME := FusedLocation
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_CERTIFICATE := platform
 LOCAL_PRIVILEGED_MODULE := true
 
diff --git a/packages/FusedLocation/res/values-as/strings.xml b/packages/FusedLocation/res/values-as/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-as/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-or/strings.xml b/packages/FusedLocation/res/values-or/strings.xml
new file mode 100644
index 0000000..b95bc37a
--- /dev/null
+++ b/packages/FusedLocation/res/values-or/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"ଫ୍ୟୁଜ୍‍ଡ୍‍ ଲୋକେଶନ୍‍"</string>
+</resources>
diff --git a/packages/InputDevices/Android.mk b/packages/InputDevices/Android.mk
index e7190dc..6de1f1d 100644
--- a/packages/InputDevices/Android.mk
+++ b/packages/InputDevices/Android.mk
@@ -22,6 +22,7 @@
 LOCAL_JAVA_LIBRARIES := 
 
 LOCAL_PACKAGE_NAME := InputDevices
+LOCAL_SDK_VERSION := current
 LOCAL_CERTIFICATE := platform
 LOCAL_PRIVILEGED_MODULE := true
 
diff --git a/packages/InputDevices/res/values-as/strings.xml b/packages/InputDevices/res/values-as/strings.xml
new file mode 100644
index 0000000..26da1b1
--- /dev/null
+++ b/packages/InputDevices/res/values-as/strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"ইনপুট ডিভাইচসমূহ"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android কীব\'ৰ্ড"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"ইংৰাজী (ইউ. কে.)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"ইংৰাজী ( ইউ. এছ.)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"ইংৰাজী (ইউ. কে.), আন্তঃৰাষ্ট্ৰীয় ষ্টাইল"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"ইংৰাজী (ইউ. কে.), ক\'লমেক ষ্টাইল"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"ইংৰাজী (ইউ. কে.), ডভ\'ৰাক ষ্টাইল"</string>
+    <!-- no translation found for keyboard_layout_english_us_workman_label (2944541595262173111) -->
+    <skip />
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"জাৰ্মান"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"ফৰাচী"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"ফৰাচী (কানাডা)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"ৰাছিয়ান"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"ৰাছিয়ান, মেক ষ্টাইল"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"স্পেনিশ্ব"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"ছুইছ ফৰাচী"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"ছুইছ জাৰ্মান"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"বেলজিয়ান"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"বুলগেৰিয়ান"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"ইটালিয়ান"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"ডেনিশ্ব"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"ন\'ৰৱেয়ান"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"ছুইডিশ্ব"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"ফিনিশ্ব"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"ক্ৰ\'ৱেশ্বিয়ান"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"চ্চেক"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"ইষ্ট\'নিয়া"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"হাংগেৰিয়ান"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"আইচলেণ্ডিক"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"ব্ৰাজিলিয়ান"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"পৰ্টুগীজ"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"শ্ল\'ভাক"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"শ্ল\'ভেনিয়া"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"তুৰ্কী"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"ইউক্ৰেনিয়ান"</string>
+    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"আৰবী"</string>
+    <string name="keyboard_layout_greek" msgid="7289253560162386040">"গ্ৰীক"</string>
+    <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"হিব্ৰু"</string>
+    <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"লিথুৱানিয়ান"</string>
+    <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"স্পেনিশ্ব (লেটিন)"</string>
+    <string name="keyboard_layout_latvian" msgid="4405417142306250595">"লাটভিয়ান"</string>
+    <!-- no translation found for keyboard_layout_persian (3920643161015888527) -->
+    <skip />
+    <!-- no translation found for keyboard_layout_azerbaijani (7315895417176467567) -->
+    <skip />
+</resources>
diff --git a/packages/InputDevices/res/values-or/strings.xml b/packages/InputDevices/res/values-or/strings.xml
new file mode 100644
index 0000000..2b982da
--- /dev/null
+++ b/packages/InputDevices/res/values-or/strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"ଇନପୁଟ୍‌ ଡିଭାଇସ୍"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android କୀ’ବୋର୍ଡ"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"ଇଂରାଜୀ (ୟୁକେ)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"ଇଂରାଜୀ (ୟୁଏସ୍‍)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"ଇଂରାଜୀ (ୟୁଏସ୍‍), ଇଣ୍ଟରନେସନାଲ୍‍ ଷ୍ଟାଇଲ୍‍"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"ଇଂରାଜୀ (ୟୁଏସ୍‍), କୋଲେମକ୍‍ ଷ୍ଟାଇଲ୍‍"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"ଇଂରାଜୀ (ୟୁଏସ୍‍), ଡଭୋରାକ୍‌ ଷ୍ଟାଇଲ୍‍"</string>
+    <!-- no translation found for keyboard_layout_english_us_workman_label (2944541595262173111) -->
+    <skip />
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"ଜର୍ମାନ୍‌"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"ଫ୍ରେଞ୍ଚ"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"ଫ୍ରେଞ୍ଚ (କାନାଡ଼ା)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"ଋଷିଆ‍ନ୍‍"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"ଋଷିଆନ୍‍, ମ୍ୟାକ୍‍ ଷ୍ଟାଇଲ୍‍"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"ସ୍ପାନିଶ୍‍"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"ସୁଇସ୍ ଫ୍ରେଞ୍ଚ"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"ସୁଇସ୍ ଜର୍ମାନ୍‍"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"ବେଲ୍‍ଜିଆନ୍‍"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"ବୁଲଗାରିଆନ୍‍"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"ଇଟାଲିୟାନ୍‌"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"ଡାନିଶ୍‍"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"ନରୱେଜିଆନ୍"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"ସ୍ଵେଡିଶ୍‌"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"ଫିନ୍ନିଶ୍‍"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"କ୍ରୋଆଶିଆନ୍"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"ଚେକ୍"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"ଇଷ୍ଟୋନିଆନ୍"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"ହଙ୍ଗେରିଆନ୍"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"ଆଇସଲାଣ୍ଡିକ୍"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"ବ୍ରାଜିଲିୟାନ୍"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"ପର୍ତ୍ତୁଗୀଜ୍"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"ସ୍ଲୋଭାକ୍"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"ସ୍ଲୋଭେନିଆନ୍"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"ତୁର୍କିସ୍"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"ୟୁକ୍ରାନିଆନ୍"</string>
+    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"ଆରବିକ୍‍"</string>
+    <string name="keyboard_layout_greek" msgid="7289253560162386040">"ଗ୍ରୀକ୍"</string>
+    <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"ହିବ୍ର୍ୟୁ"</string>
+    <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"ଲିଥୁଆନିଆନ୍"</string>
+    <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"ସ୍ପାନିଶ୍‍ (ଲାଟିନ୍‌)"</string>
+    <string name="keyboard_layout_latvian" msgid="4405417142306250595">"ଲାଟିଭିଆନ୍‍"</string>
+    <!-- no translation found for keyboard_layout_persian (3920643161015888527) -->
+    <skip />
+    <!-- no translation found for keyboard_layout_azerbaijani (7315895417176467567) -->
+    <skip />
+</resources>
diff --git a/packages/MtpDocumentsProvider/Android.mk b/packages/MtpDocumentsProvider/Android.mk
index a9e9b2e..2d62a07 100644
--- a/packages/MtpDocumentsProvider/Android.mk
+++ b/packages/MtpDocumentsProvider/Android.mk
@@ -4,6 +4,7 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_PACKAGE_NAME := MtpDocumentsProvider
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_CERTIFICATE := media
 LOCAL_PRIVILEGED_MODULE := true
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
diff --git a/packages/MtpDocumentsProvider/perf_tests/Android.mk b/packages/MtpDocumentsProvider/perf_tests/Android.mk
index f0d4878..6504af1 100644
--- a/packages/MtpDocumentsProvider/perf_tests/Android.mk
+++ b/packages/MtpDocumentsProvider/perf_tests/Android.mk
@@ -5,6 +5,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
 LOCAL_PACKAGE_NAME := MtpDocumentsProviderPerfTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_INSTRUMENTATION_FOR := MtpDocumentsProvider
 LOCAL_CERTIFICATE := media
 
diff --git a/packages/MtpDocumentsProvider/res/values-bs/strings.xml b/packages/MtpDocumentsProvider/res/values-bs/strings.xml
index 33323f8..18c2363 100644
--- a/packages/MtpDocumentsProvider/res/values-bs/strings.xml
+++ b/packages/MtpDocumentsProvider/res/values-bs/strings.xml
@@ -19,7 +19,7 @@
     <string name="app_label" msgid="6271216747302322594">"MTP Host"</string>
     <string name="downloads_app_label" msgid="7120690641874849726">"Preuzimanja"</string>
     <string name="root_name" msgid="5819495383921089536">"<xliff:g id="DEVICE_MODEL">%1$s</xliff:g> <xliff:g id="STORAGE_NAME">%2$s</xliff:g>"</string>
-    <string name="accessing_notification_title" msgid="3030133609230917944">"Pristupanje datotekama iz uređaja <xliff:g id="DEVICE_MODEL">%1$s</xliff:g>"</string>
+    <string name="accessing_notification_title" msgid="3030133609230917944">"Pristupanje fajlovima iz uređaja <xliff:g id="DEVICE_MODEL">%1$s</xliff:g>"</string>
     <string name="error_busy_device" msgid="3997316850357386589">"Drugi uređaj je zauzet. Nećete moći prenositi fajlove dok ne bude dostupan."</string>
     <string name="error_locked_device" msgid="7557872102188356147">"Fajlovi nisu pronađeni. Moguće je da je drugi uređaj zaključan. Ako jeste, otključajte ga i pokušajte ponovo."</string>
 </resources>
diff --git a/packages/MtpDocumentsProvider/tests/Android.mk b/packages/MtpDocumentsProvider/tests/Android.mk
index ba346f42..11daac3 100644
--- a/packages/MtpDocumentsProvider/tests/Android.mk
+++ b/packages/MtpDocumentsProvider/tests/Android.mk
@@ -6,6 +6,7 @@
 LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base android.test.mock
 LOCAL_STATIC_JAVA_LIBRARIES := junit
 LOCAL_PACKAGE_NAME := MtpDocumentsProviderTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_INSTRUMENTATION_FOR := MtpDocumentsProvider
 LOCAL_CERTIFICATE := media
 LOCAL_COMPATIBILITY_SUITE := device-tests
diff --git a/packages/Osu/Android.mk b/packages/Osu/Android.mk
index 1d45aa9..63c7578 100644
--- a/packages/Osu/Android.mk
+++ b/packages/Osu/Android.mk
@@ -14,6 +14,7 @@
 LOCAL_JAVA_LIBRARIES := telephony-common ims-common bouncycastle conscrypt
 
 LOCAL_PACKAGE_NAME := Osu
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_CERTIFICATE := platform
 LOCAL_PRIVILEGED_MODULE := true
 
diff --git a/packages/Osu2/Android.mk b/packages/Osu2/Android.mk
index 05586f0..063ac7e 100644
--- a/packages/Osu2/Android.mk
+++ b/packages/Osu2/Android.mk
@@ -9,6 +9,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := Osu2
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_CERTIFICATE := platform
 LOCAL_PRIVILEGED_MODULE := true
 
diff --git a/packages/Osu2/tests/Android.mk b/packages/Osu2/tests/Android.mk
index afc743d..23db7a9 100644
--- a/packages/Osu2/tests/Android.mk
+++ b/packages/Osu2/tests/Android.mk
@@ -25,6 +25,7 @@
 LOCAL_JACK_FLAGS := --multi-dex native
 
 LOCAL_PACKAGE_NAME := OsuTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_COMPATIBILITY_SUITE := device-tests
 
 LOCAL_INSTRUMENTATION_FOR := Osu2
diff --git a/packages/PrintRecommendationService/Android.mk b/packages/PrintRecommendationService/Android.mk
index 66cb057..1220349 100644
--- a/packages/PrintRecommendationService/Android.mk
+++ b/packages/PrintRecommendationService/Android.mk
@@ -21,9 +21,8 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := PrintRecommendationService
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 include $(BUILD_PACKAGE)
 
-LOCAL_SDK_VERSION := system_current
-
 include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/packages/PrintSpooler/Android.mk b/packages/PrintSpooler/Android.mk
index 6feb8a6..e356f38 100644
--- a/packages/PrintSpooler/Android.mk
+++ b/packages/PrintSpooler/Android.mk
@@ -26,6 +26,7 @@
     src/com/android/printspooler/renderer/IPdfEditor.aidl
 
 LOCAL_PACKAGE_NAME := PrintSpooler
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_JNI_SHARED_LIBRARIES := libprintspooler_jni
 LOCAL_STATIC_ANDROID_LIBRARIES := \
diff --git a/packages/PrintSpooler/res/values-as/strings.xml b/packages/PrintSpooler/res/values-as/strings.xml
new file mode 100644
index 0000000..2beaac8
--- /dev/null
+++ b/packages/PrintSpooler/res/values-as/strings.xml
@@ -0,0 +1,125 @@
+<?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">
+    <string name="app_label" msgid="4469836075319831821">"স্পুলাৰ প্ৰিণ্ট কৰক"</string>
+    <string name="more_options_button" msgid="2243228396432556771">"অধিক বিকল্প"</string>
+    <string name="label_destination" msgid="9132510997381599275">"লক্ষ্যস্থান"</string>
+    <string name="label_copies" msgid="3634531042822968308">"প্ৰতিলিপিসমূহ"</string>
+    <string name="label_copies_summary" msgid="3861966063536529540">"প্ৰতিলিপসমূহ:"</string>
+    <string name="label_paper_size" msgid="908654383827777759">"কাগজৰ আকাৰ"</string>
+    <string name="label_paper_size_summary" msgid="5668204981332138168">"কাগজৰ আকাৰ:"</string>
+    <string name="label_color" msgid="1108690305218188969">"ৰং"</string>
+    <!-- no translation found for label_duplex (5370037254347072243) -->
+    <skip />
+    <string name="label_orientation" msgid="2853142581990496477">"দিশ"</string>
+    <string name="label_pages" msgid="7768589729282182230">"পৃষ্ঠাসমূহ"</string>
+    <!-- no translation found for destination_default_text (5422708056807065710) -->
+    <skip />
+    <string name="template_all_pages" msgid="3322235982020148762">"সকলো <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
+    <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g>ৰ পৰিসৰ"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"যেনে: ১—৫, ৮, ১১—১৩"</string>
+    <string name="print_preview" msgid="8010217796057763343">"প্ৰিণ্টৰ পূৰ্বদৰ্শন"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"পূৰ্বদৰ্শনৰ বাবে PDF ভিউৱাৰ ইনষ্টল কৰক"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"প্ৰিণ্টিং এপ্ ক্ৰেশ্ব হৈছে"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"প্ৰিণ্টিং প্ৰস্তুত কৰি আছে"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"PDF ৰূপে ছেভ কৰক"</string>
+    <string name="all_printers" msgid="5018829726861876202">"সকলো প্ৰিণ্টাৰ…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"প্ৰিণ্ট সংবাদ"</string>
+    <!-- no translation found for current_page_template (5145005201131935302) -->
+    <skip />
+    <string name="page_description_template" msgid="6831239682256197161">"পৃষ্ঠা <xliff:g id="PAGE_COUNT">%2$d</xliff:g>ৰ <xliff:g id="CURRENT_PAGE">%1$d</xliff:g>"</string>
+    <string name="summary_template" msgid="8899734908625669193">"সাৰাংশ, প্ৰতিলিপিসমূহ <xliff:g id="COPIES">%1$s</xliff:g>, কাগজৰ আকাৰ <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+    <string name="expand_handle" msgid="7282974448109280522">"হেণ্ডেল বিস্তাৰ কৰক"</string>
+    <string name="collapse_handle" msgid="6886637989442507451">"হেণ্ডেল সংকুচিত কৰক"</string>
+    <string name="print_button" msgid="645164566271246268">"প্ৰিণ্ট কৰক"</string>
+    <string name="savetopdf_button" msgid="2976186791686924743">"PDFৰ জৰিয়তে ছেভ কৰক"</string>
+    <string name="print_options_expanded" msgid="6944679157471691859">"প্ৰিণ্ট বিকল্পসমূহ বিস্তাৰ কৰা হ\'ল"</string>
+    <string name="print_options_collapsed" msgid="7455930445670414332">"প্ৰিণ্ট বিকল্পসমূহ সংকুচিত কৰা হ\'ল"</string>
+    <string name="search" msgid="5421724265322228497">"সন্ধান কৰক"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"সকলো প্ৰিণ্টাৰ"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"সেৱা যোগ কৰক"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"সন্ধান বাকচটো দেখুওৱা হ\'ল"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"সন্ধান বাকচটো ঢাক খাই আছে"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"প্ৰিণ্টাৰ যোগ কৰক"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"প্ৰিণ্টাৰ বাছনি কৰক"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"প্ৰিণ্টাৰ পাহৰি যাওক"</string>
+    <!-- no translation found for print_search_result_count_utterance (6997663738361080868) -->
+    <!-- no translation found for printer_extended_description_template (1366699227703381874) -->
+    <skip />
+    <!-- no translation found for printer_info_desc (7181988788991581654) -->
+    <skip />
+    <!-- no translation found for notification_channel_progress (872788690775721436) -->
+    <skip />
+    <!-- no translation found for notification_channel_failure (9042250774797916414) -->
+    <skip />
+    <!-- no translation found for could_not_create_file (3425025039427448443) -->
+    <skip />
+    <!-- no translation found for print_services_disabled_toast (9089060734685174685) -->
+    <skip />
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"প্ৰিণ্টাৰৰ সন্ধান কৰি আছে"</string>
+    <!-- no translation found for print_no_print_services (8561247706423327966) -->
+    <skip />
+    <string name="print_no_printers" msgid="4869403323900054866">"প্ৰিণ্টাৰ পোৱা নগ\'ল"</string>
+    <!-- no translation found for cannot_add_printer (7840348733668023106) -->
+    <skip />
+    <!-- no translation found for select_to_add_printers (3800709038689830974) -->
+    <skip />
+    <!-- no translation found for enable_print_service (3482815747043533842) -->
+    <skip />
+    <!-- no translation found for enabled_services_title (7036986099096582296) -->
+    <skip />
+    <!-- no translation found for recommended_services_title (3799434882937956924) -->
+    <skip />
+    <!-- no translation found for disabled_services_title (7313253167968363211) -->
+    <skip />
+    <!-- no translation found for all_services_title (5578662754874906455) -->
+    <skip />
+    <!-- no translation found for print_services_recommendation_subtitle (5678487708807185138) -->
+    <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> প্ৰিণ্ট কৰি থকা হৈছে"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> বাতিল কৰি থকা হৈছে"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"প্ৰিণ্টাৰৰ আসোঁৱাহ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> প্ৰিণ্টাৰে অৱৰোধ কৰিছে"</string>
+    <string name="cancel" msgid="4373674107267141885">"বাতিল কৰক"</string>
+    <string name="restart" msgid="2472034227037808749">"ৰিষ্টাৰ্ট কৰক"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"প্ৰিণ্টাৰ সংযোগ হৈ থকা নাই"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"অজ্ঞাত"</string>
+    <!-- no translation found for print_service_security_warning_title (2160752291246775320) -->
+    <skip />
+    <!-- no translation found for print_service_security_warning_summary (1427434625361692006) -->
+    <skip />
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"ক\'লা আৰু বগা"</item>
+    <item msgid="2762241247228983754">"ৰং"</item>
+  </string-array>
+  <string-array name="duplex_mode_labels">
+    <item msgid="3882302912790928315">"একো নাই"</item>
+    <item msgid="7296563835355641719">"দীঘল প্ৰান্ত"</item>
+    <item msgid="79513688117503758">"চুটি প্ৰান্ত"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"প\'ৰ্ট্ৰেইট"</item>
+    <item msgid="3199660090246166812">"লেণ্ডস্কেইপ"</item>
+  </string-array>
+    <string name="print_write_error_message" msgid="5787642615179572543">"ফাইলত লিখিব পৰা নহ\'ল"</string>
+    <string name="print_error_default_message" msgid="8602678405502922346">"দুঃখিত, প্ৰিণ্টিঙৰ কাম নহ\'ল। পুনৰ চেষ্টা কৰক।"</string>
+    <string name="print_error_retry" msgid="1426421728784259538">"পুনৰ চেষ্টা কৰক"</string>
+    <string name="print_error_printer_unavailable" msgid="8985614415253203381">"এই প্ৰিণ্টাৰটো বৰ্তমান উপলব্ধ নহয়।"</string>
+    <!-- no translation found for print_cannot_load_page (6179560924492912009) -->
+    <skip />
+    <string name="print_preparing_preview" msgid="3939930735671364712">"পূৰ্বদৰ্শন প্ৰস্তুত কৰি আছে…"</string>
+</resources>
diff --git a/packages/PrintSpooler/res/values-or/strings.xml b/packages/PrintSpooler/res/values-or/strings.xml
new file mode 100644
index 0000000..bfe4bfe
--- /dev/null
+++ b/packages/PrintSpooler/res/values-or/strings.xml
@@ -0,0 +1,127 @@
+<?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">
+    <string name="app_label" msgid="4469836075319831821">"ପ୍ରିଣ୍ଟ ସ୍ପୁଲର୍‍"</string>
+    <string name="more_options_button" msgid="2243228396432556771">"ଅଧିକ ବିକଳ୍ପ"</string>
+    <string name="label_destination" msgid="9132510997381599275">"ଲକ୍ଷ୍ୟସ୍ଥଳ"</string>
+    <string name="label_copies" msgid="3634531042822968308">"କପୀଗୁଡ଼ିକ"</string>
+    <string name="label_copies_summary" msgid="3861966063536529540">"କପୀଗୁଡ଼ିକ:"</string>
+    <string name="label_paper_size" msgid="908654383827777759">"କାଗଜର ଆକାର"</string>
+    <string name="label_paper_size_summary" msgid="5668204981332138168">"କାଗଜର ଆକାର:"</string>
+    <string name="label_color" msgid="1108690305218188969">"ରଙ୍ଗ"</string>
+    <string name="label_duplex" msgid="5370037254347072243">"ଦୁଇ-ତରଫା"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"ଓରିଏଣ୍ଟେଶନ୍‍"</string>
+    <string name="label_pages" msgid="7768589729282182230">"ପୃଷ୍ଠା"</string>
+    <!-- no translation found for destination_default_text (5422708056807065710) -->
+    <skip />
+    <string name="template_all_pages" msgid="3322235982020148762">"ସମସ୍ତ <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
+    <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g>ର ରେଞ୍ଜ"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"ଯେପରିକି 1—5,8,11—13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"ପ୍ରିଣ୍ଟ ଝଲକ"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"ଝଲକ ଦେଖିବା ପାଇଁ PDF ଭ୍ୟୁଅର୍‍ ଇନଷ୍ଟଲ୍‍ କରନ୍ତୁ"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"ପ୍ରିଣ୍ଟିଙ୍ଗ ଆପ୍‍ କ୍ରାଶ୍‍ ହୋଇଗଲା"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"ପ୍ରିଣ୍ଟ ଜବ୍‍ ତିଆରି କରାଯାଉଛି"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"PDF ଭାବରେ ସେଭ୍‍ କରନ୍ତୁ"</string>
+    <string name="all_printers" msgid="5018829726861876202">"ସମସ୍ତ ପ୍ରିଣ୍ଟର୍‌…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"ପ୍ରିଣ୍ଟ ଡାୟଲଗ୍‍"</string>
+    <!-- no translation found for current_page_template (5145005201131935302) -->
+    <skip />
+    <string name="page_description_template" msgid="6831239682256197161">"<xliff:g id="PAGE_COUNT">%2$d</xliff:g>ରୁ <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> ପୃଷ୍ଠା"</string>
+    <string name="summary_template" msgid="8899734908625669193">"ସାରାଂଶ, କପୀ <xliff:g id="COPIES">%1$s</xliff:g>, କାଗଜ ଆକାର <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string>
+    <string name="expand_handle" msgid="7282974448109280522">"ହ୍ୟାଣ୍ଡେଲ୍ ବଡ଼ କରନ୍ତୁ"</string>
+    <string name="collapse_handle" msgid="6886637989442507451">"ହ୍ୟାଣ୍ଡେଲ୍ ଛୋଟ କରନ୍ତୁ"</string>
+    <string name="print_button" msgid="645164566271246268">"ପ୍ରିଣ୍ଟ କରନ୍ତୁ"</string>
+    <string name="savetopdf_button" msgid="2976186791686924743">"PDFରେ ସେଭ୍‍ କରନ୍ତୁ"</string>
+    <string name="print_options_expanded" msgid="6944679157471691859">"ପ୍ରିଣ୍ଟ ବିକଳ୍ପକୁ ବଡ଼ କରାଯାଇଛି"</string>
+    <string name="print_options_collapsed" msgid="7455930445670414332">"ପ୍ରିଣ୍ଟ ବିକଳ୍ପକୁ ଛୋଟ କରାଯାଇଛି"</string>
+    <string name="search" msgid="5421724265322228497">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"ସମସ୍ତ ପ୍ରିଣ୍ଟର୍‌"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"ସେବା ଯୋଡ଼ନ୍ତୁ"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"ସର୍ଚ୍ଚ ବକ୍ସ ଦେଖାଯାଇଛି"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"ସର୍ଚ୍ଚ ବକ୍ସ ଲୁଚି ରହିଛି"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"ପ୍ରିଣ୍ଟର୍‌ ଯୋଡ଼ନ୍ତୁ"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"ପ୍ରିଣ୍ଟର୍‍ ଚୟନ କରନ୍ତୁ"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"ପ୍ରିଣ୍ଟର୍‍ ଭୁଲିଯାଆନ୍ତୁ"</string>
+    <plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g>ଟି ପ୍ରିଣ୍ଟର୍‍ ମିଳିଲା</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$s</xliff:g>ଟି ପ୍ରିଣ୍ଟର୍‍ ମିଳିଲା</item>
+    </plurals>
+    <!-- no translation found for printer_extended_description_template (1366699227703381874) -->
+    <skip />
+    <!-- no translation found for printer_info_desc (7181988788991581654) -->
+    <skip />
+    <!-- no translation found for notification_channel_progress (872788690775721436) -->
+    <skip />
+    <!-- no translation found for notification_channel_failure (9042250774797916414) -->
+    <skip />
+    <!-- no translation found for could_not_create_file (3425025039427448443) -->
+    <skip />
+    <!-- no translation found for print_services_disabled_toast (9089060734685174685) -->
+    <skip />
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"ପ୍ରିଣ୍ଟର୍‌ ଖୋଜାଯାଉଛି"</string>
+    <!-- no translation found for print_no_print_services (8561247706423327966) -->
+    <skip />
+    <string name="print_no_printers" msgid="4869403323900054866">"କୌଣସି ପ୍ରିଣ୍ଟର୍‍ ମିଳିଲା ନାହିଁ"</string>
+    <!-- no translation found for cannot_add_printer (7840348733668023106) -->
+    <skip />
+    <!-- no translation found for select_to_add_printers (3800709038689830974) -->
+    <skip />
+    <!-- no translation found for enable_print_service (3482815747043533842) -->
+    <skip />
+    <!-- no translation found for enabled_services_title (7036986099096582296) -->
+    <skip />
+    <!-- no translation found for recommended_services_title (3799434882937956924) -->
+    <skip />
+    <!-- no translation found for disabled_services_title (7313253167968363211) -->
+    <skip />
+    <!-- no translation found for all_services_title (5578662754874906455) -->
+    <skip />
+    <!-- no translation found for print_services_recommendation_subtitle (5678487708807185138) -->
+    <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ପ୍ରିଣ୍ଟ କରାଯାଉଛି"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> କ୍ୟାନ୍ସଲ୍‍ କରାଯାଉଛି"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ପ୍ରିଣ୍ଟର୍‍ ତ୍ରୁଟି"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"ପ୍ରିଣ୍ଟର୍‍ ଦ୍ୱାରା ରୋକାଯାଇଥିବା <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancel" msgid="4373674107267141885">"କ୍ୟାନ୍ସଲ୍‍"</string>
+    <string name="restart" msgid="2472034227037808749">"ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"ପ୍ରିଣ୍ଟର୍‍କୁ କୌଣସି ସଂଯୋଗ ନାହିଁ"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"ଅଜଣା"</string>
+    <!-- no translation found for print_service_security_warning_title (2160752291246775320) -->
+    <skip />
+    <!-- no translation found for print_service_security_warning_summary (1427434625361692006) -->
+    <skip />
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"କଳା ଓ ଧଳା"</item>
+    <item msgid="2762241247228983754">"ରଙ୍ଗ"</item>
+  </string-array>
+  <string-array name="duplex_mode_labels">
+    <item msgid="3882302912790928315">"କିଛିନୁହେଁ"</item>
+    <item msgid="7296563835355641719">"ଲମ୍ବା ପ୍ରାନ୍ତ"</item>
+    <item msgid="79513688117503758">"ଛୋଟ ପ୍ରାନ୍ତ"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"ପୋର୍ଟ୍ରେଟ୍"</item>
+    <item msgid="3199660090246166812">"ଲ୍ୟାଣ୍ଡସ୍କେପ୍"</item>
+  </string-array>
+    <string name="print_write_error_message" msgid="5787642615179572543">"ଫାଇଲ‍ରେ ଲେଖିପାରିଲା ନାହିଁ"</string>
+    <string name="print_error_default_message" msgid="8602678405502922346">"କାମ କଲାନାହିଁ, ପୁଣିଥରେ ଚେଷ୍ଟା କରନ୍ତୁ"</string>
+    <string name="print_error_retry" msgid="1426421728784259538">"ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
+    <string name="print_error_printer_unavailable" msgid="8985614415253203381">"ପ୍ରିଣ୍ଟର୍‍ ବର୍ତ୍ତମାନ ଉପଲବ୍ଧ ନାହିଁ।"</string>
+    <!-- no translation found for print_cannot_load_page (6179560924492912009) -->
+    <skip />
+    <string name="print_preparing_preview" msgid="3939930735671364712">"ଝଲକ ତିଆରି କରାଯାଉଛି…"</string>
+</resources>
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerProvider.java b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerProvider.java
index 06723c3..24449fd 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerProvider.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerProvider.java
@@ -16,6 +16,8 @@
 
 package com.android.printspooler.model;
 
+import static android.content.Context.BIND_AUTO_CREATE;
+
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -32,7 +34,7 @@
         mContext = context;
         mCallback = callback;
         Intent intent = new Intent(mContext, PrintSpoolerService.class);
-        mContext.bindService(intent, this, 0);
+        mContext.bindService(intent, this, BIND_AUTO_CREATE);
     }
 
     public PrintSpoolerService getSpooler() {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
index 53e8813..eba5edb 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
@@ -31,6 +31,7 @@
 import android.os.AsyncTask;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
@@ -58,11 +59,11 @@
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.logging.MetricsLogger;
-import com.android.internal.os.HandlerCaller;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.dump.DualDumpOutputStream;
+import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.printspooler.R;
 import com.android.printspooler.util.ApprovedPrintServices;
 
@@ -116,8 +117,6 @@
 
     private IPrintSpoolerClient mClient;
 
-    private HandlerCaller mHandlerCaller;
-
     private PersistenceManager mPersistanceManager;
 
     private NotificationController mNotificationController;
@@ -134,8 +133,6 @@
     @Override
     public void onCreate() {
         super.onCreate();
-        mHandlerCaller = new HandlerCaller(this, getMainLooper(),
-                new HandlerCallerCallback(), false);
 
         mPersistanceManager = new PersistenceManager();
         mNotificationController = new NotificationController(PrintSpoolerService.this);
@@ -230,93 +227,73 @@
     }
 
     private void sendOnPrintJobQueued(PrintJobInfo printJob) {
-        Message message = mHandlerCaller.obtainMessageO(
-                HandlerCallerCallback.MSG_ON_PRINT_JOB_QUEUED, printJob);
-        mHandlerCaller.executeOrSendMessage(message);
+        Message message = PooledLambda.obtainMessage(
+                PrintSpoolerService::onPrintJobQueued, this, printJob);
+        Handler.getMain().executeOrSendMessage(message);
     }
 
     private void sendOnAllPrintJobsForServiceHandled(ComponentName service) {
-        Message message = mHandlerCaller.obtainMessageO(
-                HandlerCallerCallback.MSG_ON_ALL_PRINT_JOBS_FOR_SERIVICE_HANDLED, service);
-        mHandlerCaller.executeOrSendMessage(message);
+        Message message = PooledLambda.obtainMessage(
+                PrintSpoolerService::onAllPrintJobsForServiceHandled, this, service);
+        Handler.getMain().executeOrSendMessage(message);
     }
 
     private void sendOnAllPrintJobsHandled() {
-        Message message = mHandlerCaller.obtainMessage(
-                HandlerCallerCallback.MSG_ON_ALL_PRINT_JOBS_HANDLED);
-        mHandlerCaller.executeOrSendMessage(message);
+        Message message = PooledLambda.obtainMessage(
+                PrintSpoolerService::onAllPrintJobsHandled, this);
+        Handler.getMain().executeOrSendMessage(message);
     }
 
-    private final class HandlerCallerCallback implements HandlerCaller.Callback {
-        public static final int MSG_SET_CLIENT = 1;
-        public static final int MSG_ON_PRINT_JOB_QUEUED = 2;
-        public static final int MSG_ON_ALL_PRINT_JOBS_FOR_SERIVICE_HANDLED = 3;
-        public static final int MSG_ON_ALL_PRINT_JOBS_HANDLED = 4;
-        public static final int MSG_CHECK_ALL_PRINTJOBS_HANDLED = 5;
-        public static final int MSG_ON_PRINT_JOB_STATE_CHANGED = 6;
 
-        @Override
-        public void executeMessage(Message message) {
-            switch (message.what) {
-                case MSG_SET_CLIENT: {
-                    synchronized (mLock) {
-                        mClient = (IPrintSpoolerClient) message.obj;
-                        if (mClient != null) {
-                            Message msg = mHandlerCaller.obtainMessage(
-                                    HandlerCallerCallback.MSG_CHECK_ALL_PRINTJOBS_HANDLED);
-                            mHandlerCaller.sendMessageDelayed(msg,
-                                    CHECK_ALL_PRINTJOBS_HANDLED_DELAY);
-                        }
-                    }
-                } break;
+    private void onPrintJobStateChanged(PrintJobInfo printJob) {
+        if (mClient != null) {
+            try {
+                mClient.onPrintJobStateChanged(printJob);
+            } catch (RemoteException re) {
+                Slog.e(LOG_TAG, "Error notify for print job state change.", re);
+            }
+        }
+    }
 
-                case MSG_ON_PRINT_JOB_QUEUED: {
-                    PrintJobInfo printJob = (PrintJobInfo) message.obj;
-                    if (mClient != null) {
-                        try {
-                            mClient.onPrintJobQueued(printJob);
-                        } catch (RemoteException re) {
-                            Slog.e(LOG_TAG, "Error notify for a queued print job.", re);
-                        }
-                    }
-                } break;
+    private void onAllPrintJobsHandled() {
+        if (mClient != null) {
+            try {
+                mClient.onAllPrintJobsHandled();
+            } catch (RemoteException re) {
+                Slog.e(LOG_TAG, "Error notify for all print job handled.", re);
+            }
+        }
+    }
 
-                case MSG_ON_ALL_PRINT_JOBS_FOR_SERIVICE_HANDLED: {
-                    ComponentName service = (ComponentName) message.obj;
-                    if (mClient != null) {
-                        try {
-                            mClient.onAllPrintJobsForServiceHandled(service);
-                        } catch (RemoteException re) {
-                            Slog.e(LOG_TAG, "Error notify for all print jobs per service"
-                                    + " handled.", re);
-                        }
-                    }
-                } break;
+    private void onAllPrintJobsForServiceHandled(ComponentName service) {
+        if (mClient != null) {
+            try {
+                mClient.onAllPrintJobsForServiceHandled(service);
+            } catch (RemoteException re) {
+                Slog.e(LOG_TAG, "Error notify for all print jobs per service"
+                        + " handled.", re);
+            }
+        }
+    }
 
-                case MSG_ON_ALL_PRINT_JOBS_HANDLED: {
-                    if (mClient != null) {
-                        try {
-                            mClient.onAllPrintJobsHandled();
-                        } catch (RemoteException re) {
-                            Slog.e(LOG_TAG, "Error notify for all print job handled.", re);
-                        }
-                    }
-                } break;
+    private void onPrintJobQueued(PrintJobInfo printJob) {
+        if (mClient != null) {
+            try {
+                mClient.onPrintJobQueued(printJob);
+            } catch (RemoteException re) {
+                Slog.e(LOG_TAG, "Error notify for a queued print job.", re);
+            }
+        }
+    }
 
-                case MSG_CHECK_ALL_PRINTJOBS_HANDLED: {
-                    checkAllPrintJobsHandled();
-                } break;
-
-                case MSG_ON_PRINT_JOB_STATE_CHANGED: {
-                    if (mClient != null) {
-                        PrintJobInfo printJob = (PrintJobInfo) message.obj;
-                        try {
-                            mClient.onPrintJobStateChanged(printJob);
-                        } catch (RemoteException re) {
-                            Slog.e(LOG_TAG, "Error notify for print job state change.", re);
-                        }
-                    }
-                } break;
+    private void setClient(IPrintSpoolerClient client) {
+        synchronized (mLock) {
+            mClient = client;
+            if (mClient != null) {
+                Message msg = PooledLambda.obtainMessage(
+                        PrintSpoolerService::checkAllPrintJobsHandled, this);
+                Handler.getMain().sendMessageDelayed(msg,
+                        CHECK_ALL_PRINTJOBS_HANDLED_DELAY);
             }
         }
     }
@@ -379,10 +356,9 @@
             addPrintJobLocked(printJob);
             setPrintJobState(printJob.getId(), PrintJobInfo.STATE_CREATED, null);
 
-            Message message = mHandlerCaller.obtainMessageO(
-                    HandlerCallerCallback.MSG_ON_PRINT_JOB_STATE_CHANGED,
-                    printJob);
-            mHandlerCaller.executeOrSendMessage(message);
+            Message message = PooledLambda.obtainMessage(
+                    PrintSpoolerService::onPrintJobStateChanged, this, printJob);
+            Handler.getMain().executeOrSendMessage(message);
         }
     }
 
@@ -546,10 +522,9 @@
      * @param printJob The updated print job.
      */
     private void notifyPrintJobUpdated(PrintJobInfo printJob) {
-        Message message = mHandlerCaller.obtainMessageO(
-                HandlerCallerCallback.MSG_ON_PRINT_JOB_STATE_CHANGED,
-                printJob);
-        mHandlerCaller.executeOrSendMessage(message);
+        Message message = PooledLambda.obtainMessage(
+                PrintSpoolerService::onPrintJobStateChanged, this, printJob);
+        Handler.getMain().executeOrSendMessage(message);
 
         mNotificationController.onUpdateNotifications(mPrintJobs);
     }
@@ -742,10 +717,9 @@
                 }
                 mNotificationController.onUpdateNotifications(mPrintJobs);
 
-                Message message = mHandlerCaller.obtainMessageO(
-                        HandlerCallerCallback.MSG_ON_PRINT_JOB_STATE_CHANGED,
-                        printJob);
-                mHandlerCaller.executeOrSendMessage(message);
+                Message message = PooledLambda.obtainMessage(
+                        PrintSpoolerService::onPrintJobStateChanged, this, printJob);
+                Handler.getMain().executeOrSendMessage(message);
             }
         }
     }
@@ -1472,9 +1446,9 @@
 
         @Override
         public void setClient(IPrintSpoolerClient client) {
-            Message message = mHandlerCaller.obtainMessageO(
-                    HandlerCallerCallback.MSG_SET_CLIENT, client);
-            mHandlerCaller.executeOrSendMessage(message);
+            Message message = PooledLambda.obtainMessage(
+                    PrintSpoolerService::setClient, PrintSpoolerService.this, client);
+            Handler.getMain().executeOrSendMessage(message);
         }
 
         @Override
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
index b6a003d..1644546 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
@@ -16,7 +16,6 @@
 
 package com.android.printspooler.model;
 
-import android.annotation.NonNull;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.net.Uri;
@@ -39,6 +38,7 @@
 import android.print.PrintDocumentInfo;
 import android.util.Log;
 
+import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.printspooler.R;
 import com.android.printspooler.util.PageRangeUtils;
 
@@ -549,6 +549,9 @@
     }
 
     private static abstract class AsyncCommand implements Runnable {
+        /** Message indicated the desire to {@link #forceCancel} a command */
+        static final int MSG_FORCE_CANCEL = 0;
+
         private static final int STATE_PENDING = 0;
         private static final int STATE_RUNNING = 1;
         private static final int STATE_COMPLETED = 2;
@@ -574,7 +577,7 @@
 
         public AsyncCommand(Looper looper, IPrintDocumentAdapter adapter, RemotePrintDocumentInfo document,
                 CommandDoneCallback doneCallback) {
-            mHandler = new AsyncCommandHandler(looper);
+            mHandler = new Handler(looper);
             mAdapter = adapter;
             mDocument = document;
             mDoneCallback = doneCallback;
@@ -594,12 +597,12 @@
          */
         protected void removeForceCancel() {
             if (DEBUG) {
-                if (mHandler.hasMessages(AsyncCommandHandler.MSG_FORCE_CANCEL)) {
+                if (mHandler.hasMessages(MSG_FORCE_CANCEL)) {
                     Log.i(LOG_TAG, "[FORCE CANCEL] Removed");
                 }
             }
 
-            mHandler.removeMessages(AsyncCommandHandler.MSG_FORCE_CANCEL);
+            mHandler.removeMessages(MSG_FORCE_CANCEL);
         }
 
         /**
@@ -628,7 +631,8 @@
                         Log.i(LOG_TAG, "[FORCE CANCEL] queued");
                     }
                     mHandler.sendMessageDelayed(
-                            mHandler.obtainMessage(AsyncCommandHandler.MSG_FORCE_CANCEL),
+                            PooledLambda.obtainMessage(AsyncCommand::forceCancel, this)
+                                    .setWhat(MSG_FORCE_CANCEL),
                             FORCE_CANCEL_TIMEOUT);
                 }
 
@@ -698,34 +702,15 @@
             return mError;
         }
 
-        /**
-         * Handler for the async command.
-         */
-        private class AsyncCommandHandler extends Handler {
-            /** Message indicated the desire for to force cancel a command */
-            final static int MSG_FORCE_CANCEL = 0;
-
-            AsyncCommandHandler(@NonNull Looper looper) {
-                super(looper);
-            }
-
-            @Override
-            public void handleMessage(Message msg) {
-                switch (msg.what) {
-                    case MSG_FORCE_CANCEL:
-                        if (isCanceling()) {
-                            if (DEBUG) {
-                                Log.i(LOG_TAG, "[FORCE CANCEL] executed");
-                            }
-                            failed("Command did not respond to cancellation in "
-                                    + FORCE_CANCEL_TIMEOUT + " ms");
-
-                            mDoneCallback.onDone();
-                        }
-                        break;
-                    default:
-                        // not reached;
+        private void forceCancel() {
+            if (isCanceling()) {
+                if (DEBUG) {
+                    Log.i(LOG_TAG, "[FORCE CANCEL] executed");
                 }
+                failed("Command did not respond to cancellation in "
+                        + FORCE_CANCEL_TIMEOUT + " ms");
+
+                mDoneCallback.onDone();
             }
         }
     }
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index d73a5d7..83d7e16 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -306,19 +306,22 @@
         // This will take just a few milliseconds, so just wait to
         // bind to the local service before showing the UI.
         mSpoolerProvider = new PrintSpoolerProvider(this,
-                new Runnable() {
-            @Override
-            public void run() {
-                if (isFinishing() || isDestroyed()) {
-                    // onPause might have not been able to cancel the job, see PrintActivity#onPause
-                    // To be sure, cancel the job again. Double canceling does no harm.
-                    mSpoolerProvider.getSpooler().setPrintJobState(mPrintJob.getId(),
-                            PrintJobInfo.STATE_CANCELED, null);
-                } else {
-                    onConnectedToPrintSpooler(adapter);
-                }
-            }
-        });
+                () -> {
+                    if (isFinishing() || isDestroyed()) {
+                        if (savedInstanceState != null) {
+                            // onPause might have not been able to cancel the job, see
+                            // PrintActivity#onPause
+                            // To be sure, cancel the job again. Double canceling does no harm.
+                            mSpoolerProvider.getSpooler().setPrintJobState(mPrintJob.getId(),
+                                    PrintJobInfo.STATE_CANCELED, null);
+                        }
+                    } else {
+                        if (savedInstanceState == null) {
+                            mSpoolerProvider.getSpooler().createPrintJob(mPrintJob);
+                        }
+                        onConnectedToPrintSpooler(adapter);
+                    }
+                });
 
         getLoaderManager().initLoader(LOADER_ID_ENABLED_PRINT_SERVICES, null, this);
     }
diff --git a/packages/PrintSpooler/tests/outofprocess/Android.mk b/packages/PrintSpooler/tests/outofprocess/Android.mk
index 149be74..161a600 100644
--- a/packages/PrintSpooler/tests/outofprocess/Android.mk
+++ b/packages/PrintSpooler/tests/outofprocess/Android.mk
@@ -20,10 +20,11 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_JAVA_LIBRARIES := android.test.runner.stubs
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-test ub-uiautomator mockito-target-minus-junit4 print-test-util-lib
 
 LOCAL_PACKAGE_NAME := PrintSpoolerOutOfProcessTests
+LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := device-tests
 
 include $(BUILD_PACKAGE)
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index f2c05bf..6c8c69a 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"የሲም መዳረሻ"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"ኤችዲ ኦዲዮ፦ <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"ኤችዲ ኦዲዮ"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"መስሚያ አጋዥ መሣሪያ"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"ከመስሚያ አጋዥ መሣሪያ ጋር ተገናኝቷል"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"ወደ ማህደረ  መረጃ  አውዲዮ ተያይዟል"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ወደ ስልክ አውዲዮ ተያይዟል"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ወደ ፋይል ዝውውር አገልጋይ ተያይዟል"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ለስልክ ድምፅ ተጠቀም"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ለፋይል ዝውውር ተጠቀም"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ለውፅአት ተጠቀም"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"ለመስሚያ አጋዥ መሣሪያ ተጠቀም"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"አጣምር"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"አጣምር"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"ይቅር"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 6acc8e9..40c16b9 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"‏الوصول إلى شريحة SIM"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"صوت عالي الدقة: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"صوت عالي الدقة"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"سماعة الأذن الطبية"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"تم توصيل سماعة الأذن الطبية"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"متصل بالإعدادات الصوتية للوسائط"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"متصل بالإعدادات الصوتية للهاتف"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"متصل بخادم نقل الملف"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"الاستخدام لإعدادات الهاتف الصوتية"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"استخدامه لنقل الملفات"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"استخدام للإدخال"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"استخدام سماعة الأذن الطبية"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"اقتران"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"إقران"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"إلغاء"</string>
diff --git a/packages/SettingsLib/res/values-as/arrays.xml b/packages/SettingsLib/res/values-as/arrays.xml
new file mode 100644
index 0000000..0eff708
--- /dev/null
+++ b/packages/SettingsLib/res/values-as/arrays.xml
@@ -0,0 +1,253 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wifi_status">
+    <item msgid="1922181315419294640"></item>
+    <item msgid="8934131797783724664">"স্কেন কৰি থকা হৈছে…"</item>
+    <item msgid="8513729475867537913">"সংযোগ কৰি থকা হৈছে…"</item>
+    <item msgid="515055375277271756">"বিস্বাশযোগ্যতা প্ৰমাণ কৰি থকা হৈছে …"</item>
+    <item msgid="1943354004029184381">"আইপি ঠিকনা সংগ্ৰহ কৰি থকা হৈছে…"</item>
+    <item msgid="4221763391123233270">"সংযোগ কৰা হ’ল"</item>
+    <item msgid="624838831631122137">"স্থগিত"</item>
+    <item msgid="7979680559596111948">"সংযোগ বিচ্ছিন্ন কৰি থকা হৈছে"</item>
+    <item msgid="1634960474403853625">"সংযোগ বিচ্ছিন্ন"</item>
+    <item msgid="746097431216080650">"অসফল"</item>
+    <item msgid="6367044185730295334">"অৱৰোধিত"</item>
+    <item msgid="503942654197908005">"কিছুসময়ৰ বাবে দুৰ্বল সংযোগ দেখুওৱা হোৱা নাই"</item>
+  </string-array>
+  <string-array name="wifi_status_with_ssid">
+    <item msgid="7714855332363650812"></item>
+    <item msgid="8878186979715711006">"স্কেন কৰি থকা হৈছে…"</item>
+    <item msgid="355508996603873860">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>ৰ সৈতে সংযোগ কৰি থকা হৈছে…"</item>
+    <item msgid="554971459996405634">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>ৰ জৰিয়তে সত্যাপন কৰি থকা হৈছে…"</item>
+    <item msgid="7928343808033020343">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>ৰ আইপি ঠিকনা পৰা সংগ্ৰহ কৰি থকা হৈছে…"</item>
+    <item msgid="8937994881315223448">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>ৰ সৈতে সংযোগ কৰা হ\'ল"</item>
+    <item msgid="1330262655415760617">"স্থগিত"</item>
+    <item msgid="7698638434317271902">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>ৰ পৰা সংযোগ বিচ্ছিন্ন কৰি থকা হৈছে…"</item>
+    <item msgid="197508606402264311">"সংযোগ বিচ্ছিন্ন"</item>
+    <item msgid="8578370891960825148">"বিফল হৈছে"</item>
+    <item msgid="5660739516542454527">"অৱৰোধিত"</item>
+    <item msgid="1805837518286731242">"কিছুসময়ৰ বাবে দুৰ্বল সংযোগ দেখুওৱা হোৱা নাই"</item>
+  </string-array>
+  <string-array name="hdcp_checking_titles">
+    <item msgid="441827799230089869">"কেতিয়াও পৰীক্ষা নকৰিব"</item>
+    <item msgid="6042769699089883931">"কেৱল DRM সমলৰ বাবে পৰীক্ষা কৰক"</item>
+    <item msgid="9174900380056846820">"সদায় পৰীক্ষা কৰক"</item>
+  </string-array>
+  <string-array name="hdcp_checking_summaries">
+    <item msgid="505558545611516707">"কেতিয়াও HDCP পৰীক্ষণ ব্যৱহাৰ নকৰিব"</item>
+    <item msgid="3878793616631049349">"কেৱল DRM সমলৰ বাবে HDCP পৰীক্ষণ ব্যৱহাৰ কৰক"</item>
+    <item msgid="45075631231212732">"সদায় HDCP পৰীক্ষণ ব্যৱহাৰ কৰক"</item>
+  </string-array>
+  <string-array name="bluetooth_avrcp_versions">
+    <item msgid="5347678900838034763">"AVRCP ১.৪ (ডিফ’ল্ট)"</item>
+    <item msgid="2809759619990248160">"AVRCP ১.৩"</item>
+    <item msgid="6199178154704729352">"AVRCP ১.৫"</item>
+    <item msgid="5172170854953034852">"AVRCP ১.৬"</item>
+  </string-array>
+  <string-array name="bluetooth_avrcp_version_values">
+    <item msgid="2838624067805073303">"avrcp14"</item>
+    <item msgid="3011533352527449572">"avrcp১৩"</item>
+    <item msgid="8837606198371920819">"avrcp১৫"</item>
+    <item msgid="3422726142222090896">"avrcp১৬"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_titles">
+    <item msgid="7065842274271279580">"ছিষ্টেমৰ বাছনি ব্যৱহাৰ কৰক (ডিফ\'ল্ট)"</item>
+    <item msgid="7539690996561263909">"এছবিচি"</item>
+    <item msgid="686685526567131661">"এএচি"</item>
+    <item msgid="5254942598247222737">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> অডিঅ\'"</item>
+    <item msgid="2091430979086738145">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> অডিঅ’"</item>
+    <item msgid="6751080638867012696">"LDAC"</item>
+    <item msgid="723675059572222462">"বিকল্প ক\'ডেকসমূহ সক্ষম কৰক"</item>
+    <item msgid="3304843301758635896">"বিকল্প ক\'ডেকসমূহ অসক্ষম কৰক"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_summaries">
+    <item msgid="5062108632402595000">"ছিষ্টেমৰ বাছনি ব্যৱহাৰ কৰক (ডিফল্ট)"</item>
+    <item msgid="6898329690939802290">"এছবিচি"</item>
+    <item msgid="6839647709301342559">"এএচি"</item>
+    <item msgid="7848030269621918608">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> অডিঅ’"</item>
+    <item msgid="298198075927343893">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> অডিঅ’"</item>
+    <item msgid="7950781694447359344">"LDAC"</item>
+    <item msgid="2209680154067241740">"বিকল্প ক\'ডেকসমূহ সক্ষম কৰক"</item>
+    <item msgid="741805482892725657">"ঐচ্ছিক ক’ডেকসমূহ অক্ষম কৰক"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
+    <item msgid="3093023430402746802">"ছিষ্টেমৰ বাছনি ব্যৱহাৰ কৰক (ডিফ\'ল্ট)"</item>
+    <item msgid="8895532488906185219">"৪৪.১ কিল\'হাৰ্টজ"</item>
+    <item msgid="2909915718994807056">"৪৮.০ কিল’হাৰ্টজ"</item>
+    <item msgid="3347287377354164611">"৮৮.২ কিল\'হাৰ্টজ"</item>
+    <item msgid="1234212100239985373">"৯৬.০ কিল’হাৰ্টজ"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_sample_rate_summaries">
+    <item msgid="3214516120190965356">"ছিষ্টেমৰ বাছনি ব্যৱহাৰ কৰক (ডিফ’ল্ট)"</item>
+    <item msgid="4482862757811638365">"৪৪.১ কিল’হাৰ্টজ"</item>
+    <item msgid="354495328188724404">"৪৮.০ কিল’হাৰ্টজ"</item>
+    <item msgid="7329816882213695083">"৮৮.২ কিল\'হাৰ্টজ"</item>
+    <item msgid="6967397666254430476">"৯৬.০ কিল’হাৰ্টজ"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_bits_per_sample_titles">
+    <item msgid="2684127272582591429">"ছিষ্টেমৰ বাছনি ব্যৱহাৰ কৰক (ডিফ\'ল্ট)"</item>
+    <item msgid="5618929009984956469">"১৬ বিট/নমুনা"</item>
+    <item msgid="3412640499234627248">"২৪ বিট/নমুনা"</item>
+    <item msgid="121583001492929387">"৩২ বিট/নমুনা"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_bits_per_sample_summaries">
+    <item msgid="1081159789834584363">"ছিষ্টেমৰ বাছনি ব্যৱহাৰ কৰক (ডিফ’ল্ট)"</item>
+    <item msgid="4726688794884191540">"১৬ বিট/নমুনা"</item>
+    <item msgid="305344756485516870">"২৪ বিট/নমুনা"</item>
+    <item msgid="244568657919675099">"৩২ বিট/নমুনা"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_channel_mode_titles">
+    <item msgid="5226878858503393706">"ছিষ্টেমৰ বাছনি ব্যৱহাৰ কৰক (ডিফ\'ল্ট)"</item>
+    <item msgid="4106832974775067314">"ম\'ন\'"</item>
+    <item msgid="5571632958424639155">"ষ্টেৰিঅ\'"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_channel_mode_summaries">
+    <item msgid="4118561796005528173">"ছিষ্টেমৰ বাছনি ব্যৱহাৰ কৰক (ডিফ\'ল্ট)"</item>
+    <item msgid="8900559293912978337">"ম\'ন\'"</item>
+    <item msgid="8883739882299884241">"ষ্টেৰিঅ\'"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
+    <item msgid="7158319962230727476">"ধ্বনিৰ মানৰ বাবে অপ্টিমাইজ কৰা হৈছে (৯৯০কি.বা.প্ৰ.ছে./৯০৯কি.বা.প্ৰ.ছে.)"</item>
+    <item msgid="2921767058740704969">"ধ্বনি আৰু সংযোগৰ সন্তুলিত গুণগত মান (৬৬০কে.বি.প্ৰ.ছে./৬০৬কে.বি.প্ৰ.ছে."</item>
+    <item msgid="8860982705384396512">"সংযোগৰ ক্ষমতা অনুযায়ী সৰ্বোত্তম (৩৩০কে.বি.প্ৰ.ছে/৩০৩কে.বি.প্ৰ.ছে)"</item>
+    <item msgid="4414060457677684127">"সৰ্বশ্ৰেষ্ঠ প্ৰচেষ্টা (খাপ খাব পৰা ৰেইট)"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
+    <item msgid="6398189564246596868">"অডিঅ\' গুণমানৰ বাবে অপ্টিমাইজ কৰা হৈছে"</item>
+    <item msgid="4327143584633311908">"ধ্বনি আৰু সংযোগৰ সন্তুলিত গুণগত মান"</item>
+    <item msgid="4681409244565426925">"সংযোগৰ ক্ষমতা অনুযায়ী সৰ্বোত্তম"</item>
+    <item msgid="364670732877872677">"উত্তম প্ৰচেষ্টা (খাপ খাব পৰা বিট ৰেইট)"</item>
+  </string-array>
+  <string-array name="select_logd_size_titles">
+    <item msgid="8665206199209698501">"অফ কৰক"</item>
+    <item msgid="1593289376502312923">"৬৪কে."</item>
+    <item msgid="487545340236145324">"২৫৬কে."</item>
+    <item msgid="2423528675294333831">"১মি."</item>
+    <item msgid="180883774509476541">"4M"</item>
+    <item msgid="2803199102589126938">"১৬মি."</item>
+  </string-array>
+  <string-array name="select_logd_size_lowram_titles">
+    <item msgid="6089470720451068364">"অফ কৰক"</item>
+    <item msgid="4622460333038586791">"৬৪কে."</item>
+    <item msgid="2212125625169582330">"২৫৬কে."</item>
+    <item msgid="1704946766699242653">"১মি."</item>
+  </string-array>
+  <string-array name="select_logd_size_summaries">
+    <item msgid="6921048829791179331">"অফ কৰক"</item>
+    <item msgid="2969458029344750262">"প্ৰতিটো লগ বাফাৰত ৬৪কে."</item>
+    <item msgid="1342285115665698168">"প্ৰতি লগ বাফাৰত 256K"</item>
+    <item msgid="1314234299552254621">"প্ৰতিটো লগ বাফাৰত ১মি."</item>
+    <item msgid="3606047780792894151">"প্ৰতিটো লগ বাফাৰত ৪মি."</item>
+    <item msgid="5431354956856655120">"প্ৰতিটো লগ বাফাৰত ১৬মি."</item>
+  </string-array>
+  <string-array name="select_logpersist_titles">
+    <item msgid="1744840221860799971">"অফ অৱস্থাত আছে"</item>
+    <item msgid="3054662377365844197">"সকলো"</item>
+    <item msgid="688870735111627832">"ৰেডিঅ\'ৰ বাহিৰে সকলো"</item>
+    <item msgid="2850427388488887328">"কেৱল কাৰ্ণেল"</item>
+  </string-array>
+  <string-array name="select_logpersist_summaries">
+    <item msgid="2216470072500521830">"অফ কৰক"</item>
+    <item msgid="172978079776521897">"সকলো লগ বাফাৰ"</item>
+    <item msgid="3873873912383879240">"ৰেডিঅ\' লগ বাফাৰৰ বাহিৰে সকলো"</item>
+    <item msgid="8489661142527693381">"কেৱল কাৰ্ণেল লগ বাফাৰ"</item>
+  </string-array>
+  <string-array name="window_animation_scale_entries">
+    <item msgid="8134156599370824081">"এনিমেশ্বন অফ"</item>
+    <item msgid="6624864048416710414">"এনিমেশ্বন স্কেল .৫গুণ"</item>
+    <item msgid="2219332261255416635">"এনিমেশ্বন স্কেল ১গুণ"</item>
+    <item msgid="3544428804137048509">"এনিমেশ্বন স্কেল ১.৫গুণ"</item>
+    <item msgid="3110710404225974514">"এনিমেশ্বন স্কেল ২গুণ"</item>
+    <item msgid="4402738611528318731">"এনিমেশ্বন স্কেল ৫গুণ"</item>
+    <item msgid="6189539267968330656">"এনিমেশ্বন স্কেল ১০গু"</item>
+  </string-array>
+  <string-array name="transition_animation_scale_entries">
+    <item msgid="8464255836173039442">"এনিমেশ্বন অফ"</item>
+    <item msgid="3375781541913316411">"এনিমেশ্বন স্কেল .৫গুণ"</item>
+    <item msgid="1991041427801869945">"এনিমেশ্বন স্কেল 1গু"</item>
+    <item msgid="4012689927622382874">"এনিমেশ্বন স্কেল .৫গুণ"</item>
+    <item msgid="3289156759925947169">"এনিমেশ্বন স্কেল ২গুণ"</item>
+    <item msgid="7705857441213621835">"এনিমেশ্বন স্কেল ৫গুণ"</item>
+    <item msgid="6660750935954853365">"এনিমেশ্বন স্কেল ১০গুণ"</item>
+  </string-array>
+  <string-array name="animator_duration_scale_entries">
+    <item msgid="6039901060648228241">"এনিমেশ্বন অফ অৱস্থাত আছে"</item>
+    <item msgid="1138649021950863198">"এনিমেশ্বন স্কেল .৫গুণ"</item>
+    <item msgid="4394388961370833040">"এনিমেশ্বন স্কেল ১গুণ"</item>
+    <item msgid="8125427921655194973">"এনিমেশ্বন স্কেল ১.৫গুণ"</item>
+    <item msgid="3334024790739189573">"এনিমেশ্বন স্কেল ২গুণ"</item>
+    <item msgid="3170120558236848008">"এনিমেশ্বন স্কেল ৫গুণ"</item>
+    <item msgid="1069584980746680398">"এনিমেশ্বন স্কেল ১০গুণ"</item>
+  </string-array>
+  <string-array name="overlay_display_devices_entries">
+    <item msgid="1606809880904982133">"নাই"</item>
+    <item msgid="9033194758688161545">"৪৮০পি."</item>
+    <item msgid="1025306206556583600">"৪৮০পি. (সুৰক্ষিত)"</item>
+    <item msgid="1853913333042744661">"৭২০পি."</item>
+    <item msgid="3414540279805870511">"৭২০পি. (সুৰক্ষিত)"</item>
+    <item msgid="9039818062847141551">"১০৮০পি."</item>
+    <item msgid="4939496949750174834">"১০৮০পি. (সুৰক্ষিত)"</item>
+    <item msgid="1833612718524903568">"4K"</item>
+    <item msgid="238303513127879234">"৪কে. (সুৰক্ষিত)"</item>
+    <item msgid="3547211260846843098">"৪কে. (বৰ্ধিত)"</item>
+    <item msgid="5411365648951414254">"৪কে. (বৰ্ধিত, সুৰক্ষিত)"</item>
+    <item msgid="1311305077526792901">"৭২০পি., ১০৮০পি. (দ্বৈত স্ক্ৰীণ)"</item>
+  </string-array>
+  <string-array name="enable_opengl_traces_entries">
+    <item msgid="3191973083884253830">"নাই"</item>
+    <item msgid="9089630089455370183">"লগকেট"</item>
+    <item msgid="5397807424362304288">"ছিছট্ৰেইচ (গ্ৰাফিক্স)"</item>
+    <item msgid="1340692776955662664">"glGetErrorত কলৰ খাপ"</item>
+  </string-array>
+  <string-array name="show_non_rect_clip_entries">
+    <item msgid="993742912147090253">"অফ কৰক"</item>
+    <item msgid="675719912558941285">"আয়তাকাৰ নোহোৱা ক্লিপ অঞ্চল নীলাৰে আঁকক"</item>
+    <item msgid="1064373276095698656">"পৰীক্ষণ কৰা চিত্ৰাংকণ কমাণ্ডবোৰ সেউজীয়া ৰঙত হাইলাইট কৰক"</item>
+  </string-array>
+  <string-array name="track_frame_time_entries">
+    <item msgid="2193584639058893150">"অফ"</item>
+    <item msgid="2751513398307949636">"স্ক্ৰীণত দণ্ড হিচাপে"</item>
+    <item msgid="2355151170975410323">"<xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g>ত"</item>
+  </string-array>
+  <string-array name="debug_hw_overdraw_entries">
+    <item msgid="8190572633763871652">"বন্ধ কৰক"</item>
+    <item msgid="7688197031296835369">"পিক্সেল একাধিকবাৰ ব্যৱহৃত অংশসমূহ দেখুৱাওক"</item>
+    <item msgid="2290859360633824369">"ডিউটাৰএন\'মেলীৰ অংশসমূহ দেখুৱাওক"</item>
+  </string-array>
+  <string-array name="app_process_limit_entries">
+    <item msgid="3401625457385943795">"মান্য সীমা"</item>
+    <item msgid="4071574792028999443">"নেপথ্যত কোনো প্ৰক্ৰিয়া চলি থকা নাই"</item>
+    <item msgid="4810006996171705398">"সৰ্বাধিক ১টা প্ৰক্ৰিয়া"</item>
+    <item msgid="8586370216857360863">"সৰ্বাধিক ২টা প্ৰক্ৰিয়া"</item>
+    <item msgid="836593137872605381">"সৰ্বাধিক ৩টা প্ৰক্ৰিয়া"</item>
+    <item msgid="7899496259191969307">"সৰ্বাধিক ৪টা প্ৰক্ৰিয়া"</item>
+  </string-array>
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"চ্চাৰ্জ কৰি থকা হৈছে"</item>
+    <item msgid="5220695614993094977">"এমটিপি (মিডিয়া ট্ৰান্সফাৰ প্ৰ’ট’কল)"</item>
+    <item msgid="2086000968159047375">"পিটিপি (পিকচাৰ ট্ৰান্সফাৰ প্ৰ’ট’কল)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB ইথাৰনেট)"</item>
+    <item msgid="1718924214939774352">"ধ্বনিৰ উৎস"</item>
+    <item msgid="8126315616613006284">"এমআইডিআই"</item>
+  </string-array>
+</resources>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
new file mode 100644
index 0000000..b4d1af8
--- /dev/null
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -0,0 +1,466 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_fail_to_scan" msgid="1265540342578081461">"নেটৱৰ্ক বিচাৰি স্কেন কৰিব পৰা নাই"</string>
+    <string name="wifi_security_none" msgid="7985461072596594400">"নাই"</string>
+    <string name="wifi_remembered" msgid="4955746899347821096">"ছেভ কৰি থোৱা নেটৱৰ্কসমূহ"</string>
+    <string name="wifi_disabled_generic" msgid="4259794910584943386">"নিষ্ক্ৰিয় হৈ আছে"</string>
+    <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP কনফিগাৰেশ্বন বিফল হৈছে"</string>
+    <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"নিম্নমানৰ নেটৱৰ্কৰ বাবে সংযোগ কৰা হোৱা নাই"</string>
+    <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"ৱাই-ফাই সংযোগ বিফল হৈছে"</string>
+    <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"সত্য়াপন কৰাত সমস্যা হৈছে"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"সংযোগ কৰিব নোৱাৰে"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\'ৰ সৈতে সংযোগ কৰিব পৰা নাই"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"পাছৱৰ্ড পৰীক্ষা কৰি আকৌ চেষ্টা কৰক"</string>
+    <string name="wifi_not_in_range" msgid="1136191511238508967">"পৰিসৰৰ ভিতৰত নাই"</string>
+    <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"স্বয়ংক্ৰিয়ভাৱে সংযোগ নহ\'ব"</string>
+    <string name="wifi_no_internet" msgid="4663834955626848401">"ইণ্টাৰনেট সংযোগ নাই"</string>
+    <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g>এ ছেভ কৰিছে"</string>
+    <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s মাধ্যমেদি স্বয়ংক্ৰিয়ভাৱে সংযোগ কৰা হৈছে"</string>
+    <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"নেটৱৰ্ক ৰেটিং প্ৰদানকাৰীৰ জৰিয়তে স্বয়ং সংয়োগ কৰা হ\'ল"</string>
+    <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s-ৰ মাধ্যমেদি সংযোগ কৰা হৈছে"</string>
+    <string name="available_via_passpoint" msgid="1617440946846329613">"%1$sৰ মাধ্যমেৰে উপলব্ধ"</string>
+    <string name="wifi_connected_no_internet" msgid="8202906332837777829">"সংযোজিত, ইণ্টাৰনেট নাই"</string>
+    <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"একচেছ পইণ্ট কিছু সময়ৰ বাবে পূৰ্ণ হৈ আছে"</string>
+    <string name="connected_via_carrier" msgid="7583780074526041912">"%1$sৰ যোগেৰে সংযোজিত"</string>
+    <string name="available_via_carrier" msgid="1469036129740799053">"%1$sৰ মাধ্যমেৰে উপলব্ধ"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"অতি লেহেম"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"লেহেমীয়া"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"ঠিক"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"মধ্যমীয়া"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"দ্ৰুত"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"অতি দ্ৰুত"</string>
+    <string name="preference_summary_default_combination" msgid="8532964268242666060">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
+    <string name="bluetooth_disconnected" msgid="6557104142667339895">"সংযোগ বিচ্ছিন্ন কৰা হ’ল"</string>
+    <string name="bluetooth_disconnecting" msgid="8913264760027764974">"সংযোগ বিচ্ছিন্ন কৰি থকা হৈছে…"</string>
+    <string name="bluetooth_connecting" msgid="8555009514614320497">"সংযোগ কৰি থকা হৈছে…"</string>
+    <!-- no translation found for bluetooth_connected (5427152882755735944) -->
+    <skip />
+    <string name="bluetooth_pairing" msgid="1426882272690346242">"যোৰা লগোৱা হৈছে…"</string>
+    <!-- no translation found for bluetooth_connected_no_headset (616068069034994802) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_a2dp (3736431800395923868) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_map (3200033913678466453) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp (2047403011284187056) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_battery_level (5162924691231307748) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_headset_battery_level (1610296229139400266) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (3908466636369853652) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1163440823807659316) -->
+    <skip />
+    <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"মিডিয়াৰ অডিঅ’"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ফ\'ন কলসমূহ"</string>
+    <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ফাইল স্থানান্তৰণ"</string>
+    <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ইনপুট ডিভাইচ"</string>
+    <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ইণ্টাৰনেট সংযোগ"</string>
+    <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"শ্বেয়াৰিঙৰ সৈতে যোগাযোগ কৰক"</string>
+    <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"সম্পৰ্ক শ্বেয়াৰ কৰিবলৈ ব্যৱহাৰ কৰক"</string>
+    <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ইণ্টাৰনেট সংযোগ শ্বেয়াৰ"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"পাঠ বাৰ্তা"</string>
+    <string name="bluetooth_profile_sap" msgid="5764222021851283125">"ছিম প্ৰৱেশ"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"এইচ্ছডি অডি\'অ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"এইচ্ছডি অডিঅ’"</string>
+    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
+    <skip />
+    <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"মিডিয়া অডিঅ’লৈ সংযোগ হৈছে"</string>
+    <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ফোন অডিঅ\'ৰ লগত সংযোগ কৰা হ\'ল"</string>
+    <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ফাইল ট্ৰান্সফাৰ ছাৰ্ভাৰৰ সৈতে সংযোজিত হৈ আছে"</string>
+    <string name="bluetooth_map_profile_summary_connected" msgid="8191407438851351713">"মেপৰ সৈতে সংযোগ কৰক"</string>
+    <string name="bluetooth_sap_profile_summary_connected" msgid="8561765057453083838">"SAPৰ সৈতে সংযোজিত হৈ আছে"</string>
+    <string name="bluetooth_opp_profile_summary_not_connected" msgid="1267091356089086285">"ফাইল স্থানান্তৰণ ছাৰ্ভাৰৰ সৈতে সংযোজিত হৈ থকা নাই"</string>
+    <string name="bluetooth_hid_profile_summary_connected" msgid="3381760054215168689">"ইনপুট ডিভাইচৰ সৈতে সংযোজিত হৈ আছে"</string>
+    <string name="bluetooth_pan_user_profile_summary_connected" msgid="6436258151814414028">"ইণ্টাৰনেটৰ বাবে ডিভাইচৰ সৈতে সংযোজিত"</string>
+    <string name="bluetooth_pan_nap_profile_summary_connected" msgid="1322694224800769308">"ডিভাইচৰ সৈতে স্থানীয় ইণ্টাৰনেট সংযোগ শ্বেয়াৰ কৰা হৈছে"</string>
+    <string name="bluetooth_pan_profile_summary_use_for" msgid="5736111170225304239">"ইণ্টাৰনেট চলাবলৈ ব্যৱহাৰ কৰক"</string>
+    <string name="bluetooth_map_profile_summary_use_for" msgid="5154200119919927434">"মেপৰ বাবে ব্যৱহাৰ কৰক"</string>
+    <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"ছিমত প্ৰৱেশৰ বাবে ব্যৱহাৰ কৰক"</string>
+    <string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"মিডিয়া অডিঅ\'ৰ বাবে ব্যৱহাৰ কৰক"</string>
+    <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ফ\'ন অডিঅ\'ৰ বাবে ব্যৱহাৰ কৰক"</string>
+    <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ফাইল স্থানান্তৰ কৰিবলৈ ব্যৱহাৰ কৰক"</string>
+    <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ইনপুটৰ বাবে ব্যৱহাৰ কৰক"</string>
+    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
+    <skip />
+    <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"যোৰা লগাওক"</string>
+    <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"যোৰা লগাওক"</string>
+    <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"বাতিল কৰক"</string>
+    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"যোৰা লগালে ইয়ে সংযোজিত কৰাৰ সময়ত আপোনাৰ সম্পৰ্কসমূহ আৰু কলৰ ইতিহাস চাবলৈ অনুমতি দিব।"</string>
+    <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>ৰ সৈতে যোৰা লগাব পৰা নগ\'ল৷"</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"এটা ভুল পিন বা পাছকীৰ কাৰণে <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ৰ সৈতে যোৰা লগাব পৰা নাই৷"</string>
+    <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>ৰ সৈতে যোগাযোগ কৰিব পৰা নগ\'ল"</string>
+    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>এ যোৰা লগাব বিচৰা নাই"</string>
+    <string name="bluetooth_talkback_computer" msgid="4875089335641234463">"কম্পিউটাৰ"</string>
+    <string name="bluetooth_talkback_headset" msgid="5140152177885220949">"হেডছেট"</string>
+    <string name="bluetooth_talkback_phone" msgid="4260255181240622896">"ফ\'ন"</string>
+    <string name="bluetooth_talkback_imaging" msgid="551146170554589119">"ইমেজিং"</string>
+    <string name="bluetooth_talkback_headphone" msgid="26580326066627664">"হেডফ\'ন"</string>
+    <string name="bluetooth_talkback_input_peripheral" msgid="5165842622743212268">"ইনপুট সম্পৰ্কীয় বাহ্য় ডিভাইচ"</string>
+    <string name="bluetooth_talkback_bluetooth" msgid="5615463912185280812">"ব্লুটুথ"</string>
+    <string name="accessibility_wifi_off" msgid="1166761729660614716">"ৱাই-ফাই অফহৈ আছে।"</string>
+    <string name="accessibility_no_wifi" msgid="8834610636137374508">"ৱাইফাই সংযোগ বিচ্ছিন্ন হৈ আছে।"</string>
+    <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"ৱাই-ফাই এদাল দণ্ড।"</string>
+    <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"ৱাই-ফাইৰ দুডাল দণ্ড।"</string>
+    <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"ৱাই-ফাইৰ তিনিডাল দণ্ড।"</string>
+    <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"ৱাই-ফাই সংকেত সৰ্বোচ্চ।"</string>
+    <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"মুক্ত নেটৱৰ্ক"</string>
+    <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"সুৰক্ষিত নেটৱৰ্ক"</string>
+    <string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
+    <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"আঁতৰোৱা এপ্‌সমূহ"</string>
+    <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"আঁতৰোৱা এপ্‌ আৰু ব্যৱহাৰকাৰীসমূহ"</string>
+    <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB টেডাৰিং"</string>
+    <string name="tether_settings_title_wifi" msgid="3277144155960302049">"প\'ৰ্টেবল হটস্পট"</string>
+    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"ব্লুটুথ টেডাৰিং"</string>
+    <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"টেডাৰ কৰি থকা হৈছে"</string>
+    <string name="tether_settings_title_all" msgid="8356136101061143841">"টেদৰিং আৰু প\'ৰ্টেবল হ\'টস্পট"</string>
+    <string name="managed_user_title" msgid="8109605045406748842">"কৰ্মস্থানৰ সকলো এপ"</string>
+    <string name="user_guest" msgid="8475274842845401871">"অতিথি"</string>
+    <string name="unknown" msgid="1592123443519355854">"অজ্ঞাত"</string>
+    <string name="running_process_item_user_label" msgid="3129887865552025943">"ব্যৱহাৰকাৰী: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="launch_defaults_some" msgid="313159469856372621">"কিছুমান ডিফ\'ল্ট ছেট কৰা হৈছে"</string>
+    <string name="launch_defaults_none" msgid="4241129108140034876">"কোনো ডিফ\'ল্ট ছেট কৰা হোৱা নাই"</string>
+    <string name="tts_settings" msgid="8186971894801348327">"পাঠৰ পৰা কথনৰ ছেটিংসমূহ"</string>
+    <string name="tts_settings_title" msgid="1237820681016639683">"পাঠৰ পৰা কথনৰ আউটপুট"</string>
+    <string name="tts_default_rate_title" msgid="6030550998379310088">"কথা কোৱাৰ হাৰ"</string>
+    <string name="tts_default_rate_summary" msgid="4061815292287182801">"পাঠ কথনৰ বেগ"</string>
+    <string name="tts_default_pitch_title" msgid="6135942113172488671">"পিচ্চ"</string>
+    <string name="tts_default_pitch_summary" msgid="1944885882882650009">"সংশ্লেষিত কথনৰ সুৰক প্ৰভাৱিত কৰে"</string>
+    <string name="tts_default_lang_title" msgid="8018087612299820556">"ভাষা"</string>
+    <string name="tts_lang_use_system" msgid="2679252467416513208">"ছিষ্টেমৰ ভাষা ব্যৱহাৰ কৰক"</string>
+    <string name="tts_lang_not_selected" msgid="7395787019276734765">"ভাষা বাছনি কৰা হোৱা নাই"</string>
+    <string name="tts_default_lang_summary" msgid="5219362163902707785">"কথিত পাঠৰ বাবে ভাষা-নিৰ্দিষ্ট কণ্ঠস্বৰ ছেট কৰে"</string>
+    <string name="tts_play_example_title" msgid="7094780383253097230">"এটা উদাহৰণ মাতি শুনোৱা শুনক"</string>
+    <string name="tts_play_example_summary" msgid="8029071615047894486">"কণ্ঠস্বৰ সংশ্লেষণৰ এটা চুটি উদাহৰণ দেখুৱাওক"</string>
+    <string name="tts_install_data_title" msgid="4264378440508149986">"ভইচ ডেটা ইনষ্টল কৰক"</string>
+    <string name="tts_install_data_summary" msgid="5742135732511822589">"কণ্ঠস্বৰ সংশ্লেষণৰ বাবে দৰকাৰী ভইচ ডেটা ইনষ্টল কৰক"</string>
+    <string name="tts_engine_security_warning" msgid="8786238102020223650">"এই কণ্ঠধ্বনি সংশ্লেষক ইঞ্জিনটোৱে কথিত ব্যক্তিগত ডেটা যেনে পাছৱৰ্ড আৰু ক্ৰেডিট কাৰ্ডৰ নম্বৰ আদিকে ধৰি সকলো পাঠ সংগ্ৰহ কৰবলৈ সক্ষম হ\'ব পাৰে। ই <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> ইঞ্জিনটোৰ লগত আহিছে। এই কণ্ঠধ্বনি সংশ্লেষক ইঞ্জিনটো সক্ষম কৰিবনে?"</string>
+    <string name="tts_engine_network_required" msgid="1190837151485314743">"পাঠৰ পৰা কথন আউটপুটৰ বাবে এই ভাষাটোক এক কৰ্মক্ষম নেটৱৰ্ক সংযোগৰ দৰকাৰ।"</string>
+    <string name="tts_default_sample_string" msgid="4040835213373086322">"কথনভংগী সংশ্লেষণৰ ই এটা উদাহৰণ"</string>
+    <string name="tts_status_title" msgid="7268566550242584413">"ভাষাৰ ডিফ\'ল্ট স্থিতি"</string>
+    <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> সম্পূৰ্ণৰূপে সমৰ্থিত"</string>
+    <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g>ক নেটৱৰ্ক সংযোগৰ দৰকাৰ"</string>
+    <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> সমৰ্থিত নহয়"</string>
+    <string name="tts_status_checking" msgid="5339150797940483592">"পৰীক্ষা কৰি থকা হৈছে…"</string>
+    <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g>ৰ বাবে ছেটিংসমূহ"</string>
+    <string name="tts_engine_settings_button" msgid="1030512042040722285">"ইঞ্জিনৰ ছেটিংসমূহ লঞ্চ কৰক"</string>
+    <string name="tts_engine_preference_section_title" msgid="448294500990971413">"অগ্ৰাধিকাৰপ্ৰাপ্ত ইঞ্জিন"</string>
+    <string name="tts_general_section_title" msgid="4402572014604490502">"সাধাৰণ"</string>
+    <string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"কথনভংগী তীব্ৰতা ৰিছেট কৰক"</string>
+    <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"পাঠ উচ্চাৰণৰ স্বৰ-তীব্ৰতা ৰিছেট কৰক যিটো ডিফল্ট হিচাপে ব্যৱহাৰ কৰা হ\'ব।"</string>
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"অতি লেহেম"</item>
+    <item msgid="4795095314303559268">"লেহেমীয়া"</item>
+    <item msgid="8903157781070679765">"সাধাৰণ"</item>
+    <item msgid="164347302621392996">"দ্ৰুত"</item>
+    <item msgid="5794028588101562009">"দ্ৰুত"</item>
+    <item msgid="7163942783888652942">"অতি দ্ৰুত"</item>
+    <item msgid="7831712693748700507">"দ্ৰুত"</item>
+    <item msgid="5194774745031751806">"অতি দ্ৰুত"</item>
+    <item msgid="9085102246155045744">"দ্ৰুততম"</item>
+  </string-array>
+    <string name="choose_profile" msgid="6921016979430278661">"প্ৰ’ফাইল বাছনি কৰক"</string>
+    <string name="category_personal" msgid="1299663247844969448">"ব্যক্তিগত"</string>
+    <string name="category_work" msgid="8699184680584175622">"কৰ্মস্থান-সম্পৰ্কীয়"</string>
+    <string name="development_settings_title" msgid="215179176067683667">"বিকাশকৰ্তাৰ বিকল্পসমূহ"</string>
+    <string name="development_settings_enable" msgid="542530994778109538">"বিকাশকৰ্তা বিষয়ক বিকল্পসমূহ সক্ষম কৰক"</string>
+    <string name="development_settings_summary" msgid="1815795401632854041">"এপৰ বিকাশৰ বাবে বিকল্পসমূহ ছেট কৰক"</string>
+    <string name="development_settings_not_available" msgid="4308569041701535607">"এইজন ব্যৱহাৰকাৰীৰ বাবে বিকাশকৰ্তাৰ বিকল্পসমূহ উপলব্ধ নহয়"</string>
+    <string name="vpn_settings_not_available" msgid="956841430176985598">"ভিপিএন ছেটিংসমূহ এই ব্যৱহাৰকাৰীজনৰ বাবে উপলব্ধ নহয়"</string>
+    <string name="tethering_settings_not_available" msgid="6765770438438291012">"এই ব্যৱহাৰকাৰীৰ বাবে টেডাৰিং ছেটিংসমূহ উপলব্ধ নহয়"</string>
+    <string name="apn_settings_not_available" msgid="7873729032165324000">"এই ব্যৱহাৰকাৰীৰ বাবে একচেছ পইণ্টৰ নাম ছেটিংসমূহ উপলব্ধ নহয়"</string>
+    <string name="enable_adb" msgid="7982306934419797485">"ইউএছবি ডিবাগিং"</string>
+    <string name="enable_adb_summary" msgid="4881186971746056635">"USB সংযোগ হৈ থকাৰ অৱস্থাত ডিবাগ ম\'ড"</string>
+    <string name="clear_adb_keys" msgid="4038889221503122743">"ইউএছবি ডিবাগিং অনুমতিসমূহ প্ৰত্যাহাৰ কৰক"</string>
+    <string name="bugreport_in_power" msgid="7923901846375587241">"বাগ ৰিপৰ্টৰ শ্ৱৰ্টকাট"</string>
+    <string name="bugreport_in_power_summary" msgid="1778455732762984579">"পাৱাৰ মেনুত বাগ প্ৰতিবেদন গ্ৰহণ কৰিবলৈ এটা বুটাম দেখুৱাওক"</string>
+    <string name="keep_screen_on" msgid="1146389631208760344">"জাগ্ৰত কৰি ৰাখক"</string>
+    <string name="keep_screen_on_summary" msgid="2173114350754293009">"চ্চাৰ্জ হৈ থকাৰ সময়ত স্ক্ৰীণ কেতিয়াও সুপ্ত অৱস্থালৈ নাযায়"</string>
+    <string name="bt_hci_snoop_log" msgid="3340699311158865670">"ব্লুটুথ HCI স্নুপ ল’গ সক্ষম কৰক"</string>
+    <string name="bt_hci_snoop_log_summary" msgid="730247028210113851">"ব্লুটুথ HCI পেকেটসমূহ এটা ফাইলত ৰাখক"</string>
+    <string name="oem_unlock_enable" msgid="6040763321967327691">"ঔইএম আনলক"</string>
+    <string name="oem_unlock_enable_summary" msgid="4720281828891618376">"বুটল\'ডাৰটো আনলক কৰিবলৈ অনুমতি দিয়ক"</string>
+    <string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"ঔইএম আনলক কৰাৰ অনুমতি দিবনে?"</string>
+    <string name="confirm_enable_oem_unlock_text" msgid="5517144575601647022">"সাৱধান: এই ছেটিংটো সক্ষম কৰি থাকোতে ডিভাইচৰ সুৰক্ষা সুবিধাসমূহে কাম নকৰিব।"</string>
+    <string name="mock_location_app" msgid="7966220972812881854">"নকল অৱস্থানৰ এপ্ বাছনি কৰক"</string>
+    <string name="mock_location_app_not_set" msgid="809543285495344223">"কোনো নকল অৱস্থান এপ্ নিৰ্ধাৰণ কৰা হোৱা নাই"</string>
+    <string name="mock_location_app_set" msgid="8966420655295102685">"নকল অৱস্থানৰ এপ্: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="debug_networking_category" msgid="7044075693643009662">"নেটৱৰ্কিং"</string>
+    <string name="wifi_display_certification" msgid="8611569543791307533">"বেতাঁৰ ডিছপ্লে প্ৰমাণীকৰণ"</string>
+    <string name="wifi_verbose_logging" msgid="4203729756047242344">"ৱাই-ফাই ভাৰ্ব\'ছ লগিং সক্ষম কৰক"</string>
+    <!-- no translation found for wifi_connected_mac_randomization (3168165236877957767) -->
+    <skip />
+    <string name="mobile_data_always_on" msgid="8774857027458200434">"ম\'বাইল ডেটা সদা-সক্ৰিয়"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"টেডাৰিং হাৰ্ডৱেৰ ত্বৰণ"</string>
+    <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"নামবিহীন ব্লুটুথ ডিভাইচসমূহ দেখুৱাওক"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"পূৰ্ণ মাত্ৰাৰ ভলিউম অক্ষম কৰক"</string>
+    <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ব্লুটুথ AVRCP সংস্কৰণ"</string>
+    <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ব্লুটুথ AVRCP সংস্কৰণ বাছনি কৰক"</string>
+    <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ব্লুটুথ অডিঅ’ ক’ডেক"</string>
+    <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"ব্লুটুথ অডিঅ’ ক’ডেক বাছনি কৰক"</string>
+    <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"ব্লুটুথ অডিঅ\' ছেম্পল ৰেইট"</string>
+    <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="5628790207448471613">"ব্লুটুথ অডিঅ\' ক\'ডেক বাছনি কৰক:\nনমুনাৰ হাৰ"</string>
+    <string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="2099645202720164141">"প্ৰতি ছেম্পলত ব্লুটুথ অডিঅ\' বিটসমূহ"</string>
+    <string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4546131401358681321">"ব্লুটুথ অডিঅ\' ক\'ডেক বাছনি কৰক:\nবিট প্ৰতি নমুনা"</string>
+    <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="884855779449390540">"ব্লুটুথ অডিঅ\' চেনেল ম\'ড"</string>
+    <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="9133545781346216071">"ব্লুটুথ অডিঅ\' ক\'ডেক বাছনি কৰক:\nচ্চেনেল ম\'ড"</string>
+    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"ব্লুটুথ অডিঅ’ LDAC ক’ডেক: পৰিৱেশনৰ মান"</string>
+    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"ব্লুটুথ LDAC ক\'ডেক বাছনি কৰক:\nপৰিৱেশনৰ মান"</string>
+    <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ষ্ট্ৰীম কৰি থকা হৈছে: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
+    <string name="select_private_dns_configuration_title" msgid="3700456559305263922">"ব্যক্তিগত DNS"</string>
+    <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"ব্যক্তিগত DNS ম\'ড বাছনি কৰক"</string>
+    <string name="private_dns_mode_off" msgid="8236575187318721684">"অফ"</string>
+    <string name="private_dns_mode_opportunistic" msgid="7608409735589131766">"সুবিধাবাদী"</string>
+    <string name="private_dns_mode_provider" msgid="8354935160639360804">"ব্যক্তিগত ডিএনএছ প্ৰদানকাৰীৰ হোষ্টনাম"</string>
+    <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"ডিএনএছ সেৱা যোগানকাৰীৰ হ\'ষ্টনাম দিয়ক"</string>
+    <string name="wifi_display_certification_summary" msgid="1155182309166746973">"বেতাঁৰ ডিছপ্লে প্ৰমাণপত্ৰৰ বাবে বিকল্পসমূহ দেখুৱাওক"</string>
+    <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ৱাই-ফাই লগিঙৰ মাত্ৰা বঢ়াওক, Wi‑Fi পিকাৰত প্ৰতি SSID RSSI দেখুৱাওক"</string>
+    <!-- no translation found for wifi_connected_mac_randomization_summary (1743059848752201485) -->
+    <skip />
+    <string name="select_logd_size_title" msgid="7433137108348553508">"লগাৰৰ বাফাৰৰ আকাৰ"</string>
+    <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"প্ৰতিটো লগ বাফাৰত ল\'গাৰৰ আকাৰ বাছনি কৰক"</string>
+    <string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"লগাৰৰ স্থায়ী সঞ্চয়াগাৰৰ বস্তুবোৰ মচিবনে?"</string>
+    <string name="dev_logpersist_clear_warning_message" msgid="2256582531342994562">"পাৰ্ছিছটেণ্ট লগাৰ ব্যৱহাৰ কৰ নিৰীক্ষণ নকৰাৰ সময়ত, আমি আপোনাৰ ডিভাইচত থকা লগাৰ ডেটা নিৱাসীক মচা দৰকাৰ।"</string>
+    <string name="select_logpersist_title" msgid="7530031344550073166">"ডিভাইচটোত লগাৰৰ ডেটা নিৰবচ্ছিন্নভাৱে সঞ্চয় কৰক"</string>
+    <string name="select_logpersist_dialog_title" msgid="4003400579973269060">"ডিভাইচত স্থায়ীভাৱে সঞ্চয় কৰিবলৈ লগ বাফাৰবোৰ বাছনি কৰক"</string>
+    <string name="select_usb_configuration_title" msgid="2649938511506971843">"ইউএছবি কনফিগাৰেশ্বন বাছনি কৰক"</string>
+    <string name="select_usb_configuration_dialog_title" msgid="6385564442851599963">"ইউএছবি কনফিগাৰেশ্বন বাছনি কৰক"</string>
+    <string name="allow_mock_location" msgid="2787962564578664888">"নকল অৱস্থানৰ অনুমতি দিয়ক"</string>
+    <string name="allow_mock_location_summary" msgid="317615105156345626">"নকল অৱস্থানৰ অনুমতি দিয়ক"</string>
+    <string name="debug_view_attributes" msgid="6485448367803310384">"দৃশ্যৰ গুণাগুণ নিৰীক্ষণ সক্ষম কৰক"</string>
+    <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"ৱাই-ফাই থকা সময়তো সদায় ম\'বাইল ডেটা সক্ৰিয় ৰাখক (খৰতকীয়াকৈ নেটৱৰ্ক সলনি কৰিবৰ বাবে)।"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"যদিহে উপলব্ধ হয় তেন্তে টেডাৰিং হাৰ্ডৱেৰ ত্বৰণ ব্যৱহাৰ কৰক"</string>
+    <string name="adb_warning_title" msgid="6234463310896563253">"ইউএছবি ডিবাগিঙৰ অনুমতি দিয়েনে?"</string>
+    <string name="adb_warning_message" msgid="7316799925425402244">"ইউএছবি ডিবাগ কৰা কাৰ্য কেৱল বিকাশৰ উদ্দেশ্যৰেহে কৰা হৈছে৷ আপোনাৰ কম্পিউটাৰ আৰু আপোনাৰ ডিভাইচৰ মাজত ডেটা প্ৰতিলিপি কৰিবলৈ এইটো ব্যৱহাৰ কৰক, কোনো জাননী নিদিয়াকৈয়ে আপোনাৰ ডিভাইচত এপ্‌সমূহ ইনষ্টল কৰক আৰু লগ ডেটা পঢ়ক৷"</string>
+    <string name="adb_keys_warning_message" msgid="5659849457135841625">"আপুনি আগতে ইউএছবি ডিবাগিঙৰ বাবে প্ৰৱেশৰ অনুমতি দিয়া সকলো কম্পিউটাৰৰ পৰা সেই অনুমতি প্ৰত্যাহাৰ কৰেনে?"</string>
+    <string name="dev_settings_warning_title" msgid="7244607768088540165">"বিকাশৰ কামৰ বাবে থকা ছেটিংবিলাকক অনুমতি দিবনে?"</string>
+    <string name="dev_settings_warning_message" msgid="2298337781139097964">"এই ছেটিংসমূহ বিকাশৰ কামত ব্যৱহাৰ কৰিবলৈ তৈয়াৰ কৰা হৈছে। সেইবিলাকে আপোনাৰ ডিভাইচ আৰু তাত থকা এপ্লিকেশ্বনসমূহক অকামিলা কৰি পেলাব পাৰে আৰু সেইবিলাকৰ কাৰণে এপ্লিকেশ্বনসমূহে অদ্ভুত আচৰণ কৰিব পাৰে।"</string>
+    <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"ইউএছবিৰ যোগেৰে এপৰ সত্যাপন কৰক"</string>
+    <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ADB/ADTৰ যোগেৰে ইনষ্টল কৰা এপসমূহে কিবা ক্ষতিকাৰক আচৰণ কৰিছে নেকি পৰীক্ষা কৰক।"</string>
+    <string name="bluetooth_show_devices_without_names_summary" msgid="2351196058115755520">"নামহীন ব্লুটুথ ডিভাইচসমূহ (মাত্ৰ MAC ঠিকনাযুক্ত) দেখুওৱা হ\'ব"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"ৰিম\'ট ডিভাইচবিলাকৰ সৈতে ভলিউম সম্পৰ্কীয় সমস্যা, যেনেকৈ অতি উচ্চ ভলিউম বা নিয়ন্ত্ৰণ কৰিবই নোৱাৰা অৱস্থাত ব্লুটুথৰ পূৰ্ণ ভলিউম সুবিধা অক্ষম কৰে।"</string>
+    <string name="enable_terminal_title" msgid="95572094356054120">"স্থানীয় টাৰ্মিনেল"</string>
+    <string name="enable_terminal_summary" msgid="67667852659359206">"স্থানীয় শ্বেল প্ৰৱেশাধিকাৰ দিয়া টাৰ্মিনেল এপ্ সক্ষম কৰক"</string>
+    <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP পৰীক্ষণ"</string>
+    <string name="hdcp_checking_dialog_title" msgid="5141305530923283">"HDCP পৰীক্ষণ আচৰণ ছেট কৰক"</string>
+    <string name="debug_debugging_category" msgid="6781250159513471316">"ডিবাগিং"</string>
+    <string name="debug_app" msgid="8349591734751384446">"ডিবাগ এপ্ বাছনি কৰক"</string>
+    <string name="debug_app_not_set" msgid="718752499586403499">"কোনো ডিবাগ এপ্লিকেশ্বন ছেট কৰা হোৱা নাই"</string>
+    <string name="debug_app_set" msgid="2063077997870280017">"ডিবাগিং এপ্লিকেশ্বন: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="select_application" msgid="5156029161289091703">"এপ্লিকেশ্বন বাছনি কৰক"</string>
+    <string name="no_application" msgid="2813387563129153880">"একোৱেই নাই"</string>
+    <string name="wait_for_debugger" msgid="1202370874528893091">"ডিবাগাৰৰ বাবে অপেক্ষা কৰক"</string>
+    <string name="wait_for_debugger_summary" msgid="1766918303462746804">"ডিবাগ কৰা এপ্লিকেশ্বনবোৰে কাৰ্য ৰূপায়ণ কৰাৰ আগতে ডিবাগাৰ সংলগ্ন হোৱা কাৰ্যলৈ অপেক্ষা কৰে"</string>
+    <string name="debug_input_category" msgid="1811069939601180246">"ইনপুট"</string>
+    <string name="debug_drawing_category" msgid="6755716469267367852">"অংকন"</string>
+    <string name="debug_hw_drawing_category" msgid="6220174216912308658">"হাৰ্ডৱেৰৰদ্বাৰা ত্বৰিত ৰেণ্ডাৰিং"</string>
+    <string name="media_category" msgid="4388305075496848353">"মিডিয়া"</string>
+    <string name="debug_monitoring_category" msgid="7640508148375798343">"নিৰীক্ষণ কৰি থকা হৈছে"</string>
+    <string name="strict_mode" msgid="1938795874357830695">"কঠোৰ ম’ড সক্ষম কৰা হৈছে"</string>
+    <string name="strict_mode_summary" msgid="142834318897332338">"যেতিয়া এপসমূহে মুখ্য থ্ৰেডত দীঘলীয়া কাৰ্যকলাপ চলাই, তেতিয়া স্ক্ৰীণ ফ্লাশ্ব কৰক"</string>
+    <string name="pointer_location" msgid="6084434787496938001">"পইণ্টাৰৰ অৱস্থান"</string>
+    <string name="pointer_location_summary" msgid="840819275172753713">"চলিত স্পৰ্শ-বিষয়ক তথ্যসহ স্ক্ৰীণ অভাৰলে\'"</string>
+    <string name="show_touches" msgid="2642976305235070316">"টেপসমূহ দেখুৱাওক"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"টিপিলে দৃশ্যায়িত ফীডবেক দিয়ক"</string>
+    <string name="show_screen_updates" msgid="5470814345876056420">"পৃষ্ঠভাগৰ আপডেইট দেখুৱাওক"</string>
+    <string name="show_screen_updates_summary" msgid="2569622766672785529">"আপডেইট হওতে গোটেই ৱিণ্ড পৃষ্ঠসমূহ ফ্লাশ্ব কৰক"</string>
+    <string name="show_hw_screen_updates" msgid="5036904558145941590">"জিপিইউৰ দৰ্শন আপডেইটসমূহ দেখুৱাওক"</string>
+    <string name="show_hw_screen_updates_summary" msgid="1115593565980196197">"জিপিইউৰ জৰিয়তে অঁকাৰ সময়ত ৱিণ্ড’ৰ ভিতৰত ফ্লাশ্ব দৰ্শন"</string>
+    <string name="show_hw_layers_updates" msgid="5645728765605699821">"হাৰ্ডৱেৰৰ তৰপৰ আপডেইট দেখুৱাওক"</string>
+    <string name="show_hw_layers_updates_summary" msgid="5296917233236661465">"হাৰ্ডৱেৰ লেয়াৰ আপডেইট হওতে সিঁহতক সেউজীয়া ৰঙেৰে ফ্লাশ্ব কৰক"</string>
+    <string name="debug_hw_overdraw" msgid="2968692419951565417">"GPU অভাৰড্ৰ ডিবাগ কৰক"</string>
+    <string name="disable_overlays" msgid="2074488440505934665">"HW অ’ভাৰলে অক্ষম কৰক"</string>
+    <string name="disable_overlays_summary" msgid="3578941133710758592">"স্ক্ৰীণ কম্প’জিট কৰাৰ বাবে সদায় জিপিইউ ব্যৱহাৰ কৰক"</string>
+    <string name="simulate_color_space" msgid="6745847141353345872">"ৰঙৰ ঠাই ছিমিউলেইট কৰক"</string>
+    <string name="enable_opengl_traces_title" msgid="6790444011053219871">"OpenGL ট্ৰেছ সক্ষম কৰক"</string>
+    <string name="usb_audio_disable_routing" msgid="8114498436003102671">"ইউএছবি অডিঅ\' ৰাউটিং অক্ষম কৰক"</string>
+    <string name="usb_audio_disable_routing_summary" msgid="980282760277312264">"স্বয়ংক্ৰিয়ভাৱে ইউএছবি ধ্বনিৰ আনুষংগিক আহিলাবিলাকলৈ ৰাউটিং কৰাটো অক্ষম কৰক"</string>
+    <string name="debug_layout" msgid="5981361776594526155">"লেআউটৰ সময় দেখুৱাওক"</string>
+    <string name="debug_layout_summary" msgid="2001775315258637682">"ক্লিপ বাউণ্ড, মাৰ্জিন আদিসমূহ দেখুৱাওক"</string>
+    <string name="force_rtl_layout_all_locales" msgid="2259906643093138978">"আৰটিএল চানেকিৰ দিশ বলেৰে সলনি কৰক"</string>
+    <string name="force_rtl_layout_all_locales_summary" msgid="9192797796616132534">"সকলো ভাষাৰ বাবে স্ক্ৰীণৰ চানেকিৰ দিশ RTLলৈ বলেৰে সলনি কৰক"</string>
+    <string name="force_hw_ui" msgid="6426383462520888732">"জিপিইউ ৰেণ্ডাৰিং বলেৰে ব্যৱহাৰ কৰক"</string>
+    <string name="force_hw_ui_summary" msgid="5535991166074861515">"2d চিত্ৰাংকনৰ বাবে GPUক বলেৰে ব্যৱহাৰ কৰক"</string>
+    <string name="force_msaa" msgid="7920323238677284387">"বল ৪গুণ MSAA"</string>
+    <string name="force_msaa_summary" msgid="9123553203895817537">"OpenGL ES 2.0 এপত ৪গুণ MSAA সক্ষম কৰক"</string>
+    <string name="show_non_rect_clip" msgid="505954950474595172">"আয়তাকৃতিৰ নোহোৱা ক্লিপ প্ৰক্ৰিয়াসমূহ ডিবাগ কৰক"</string>
+    <string name="track_frame_time" msgid="6146354853663863443">"প্ৰ\'ফাইল জিপিইউ ৰেণ্ডাৰিং"</string>
+    <string name="enable_gpu_debug_layers" msgid="3848838293793255097">"জিপিইউ ডিবাগ স্তৰবোৰ সক্ষম কৰক"</string>
+    <string name="enable_gpu_debug_layers_summary" msgid="8009136940671194940">"ডিবাগ এপসমূহৰ বাবে জিপিইউ ডিবাগ তৰপ ল\'ড কৰিবলৈ অনুমতি দিয়ক"</string>
+    <string name="window_animation_scale_title" msgid="6162587588166114700">"ৱিণ্ড\' এনিমেশ্বন স্কেল"</string>
+    <string name="transition_animation_scale_title" msgid="387527540523595875">"ট্ৰাঞ্জিশ্বন এনিমেশ্বন স্কেল"</string>
+    <string name="animator_duration_scale_title" msgid="3406722410819934083">"এনিমেটৰ কালদৈৰ্ঘ্য স্কেল"</string>
+    <string name="overlay_display_devices_title" msgid="5364176287998398539">"গৌণ প্ৰদৰ্শনৰ নকল বনাওক"</string>
+    <string name="debug_applications_category" msgid="4206913653849771549">"এপসমূহ"</string>
+    <string name="immediately_destroy_activities" msgid="1579659389568133959">"কাৰ্যকলাপসমূহ নাৰাখিব"</string>
+    <string name="immediately_destroy_activities_summary" msgid="3592221124808773368">"ব্যৱহাৰকাৰী ওলোৱাৰ লগে লগে সকলো কাৰ্যকলাপ মচক"</string>
+    <string name="app_process_limit_title" msgid="4280600650253107163">"নেপথ্যত চলা প্ৰক্ৰিয়াৰ সীমা"</string>
+    <string name="show_all_anrs" msgid="28462979638729082">"সকলো এএনআৰ দেখুৱাওক"</string>
+    <string name="show_all_anrs_summary" msgid="641908614413544127">"নেপথ্য এপসমূহৰ বাবে এপে সঁহাৰি দিয়া নাই মন্তব্য দেখুৱাওক"</string>
+    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"জাননী চ্চেনেলৰ সকীয়নিসমূহ দেখুৱাওক"</string>
+    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"কোনো এপে বৈধ চ্চেনেল নোহোৱাকৈ কোনো জাননী প\'ষ্ট কৰিলে স্ক্ৰীণত সকীয়নি প্ৰদৰ্শন হয়"</string>
+    <string name="force_allow_on_external" msgid="3215759785081916381">"বাহ্যিক সঞ্চয়াগাৰত এপক বলেৰে অনুমতি দিয়ক"</string>
+    <string name="force_allow_on_external_summary" msgid="3640752408258034689">"মেনিফেষ্টৰ মান যিয়েই নহওক, বাহ্যিক সঞ্চয়াগাৰত লিখিবলৈ যিকোনো এপক উপযুক্ত কৰি তোলে"</string>
+    <string name="force_resizable_activities" msgid="8615764378147824985">"বলেৰে কাৰ্যকলাপসমূহৰ আকাৰ সলনি কৰিব পৰা কৰক"</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"মেনিফেষ্টৰ মান যিয়েই নহওক, মাল্টি-ৱিণ্ডৰ বাবে সকলো কাৰ্যকলাপৰ আকাৰ সলনি কৰিব পৰা কৰক।"</string>
+    <string name="enable_freeform_support" msgid="1461893351278940416">"ফ্ৰিফৰ্ম ৱিণ্ড\'জ সক্ষম কৰক"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"পৰীক্ষামূলক ফ্ৰী-ফৰ্ম ৱিণ্ড’বোৰৰ বাবে সহায়তা সক্ষম কৰক৷"</string>
+    <string name="local_backup_password_title" msgid="3860471654439418822">"ডেস্কটপ বেকআপ পাছৱৰ্ড"</string>
+    <string name="local_backup_password_summary_none" msgid="6951095485537767956">"ডেস্কটপৰ পূৰ্ণ বেকআপ এতিয়ালৈকে সংৰক্ষিত অৱস্থাত নাই"</string>
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"ডেস্কটপ সম্পূৰ্ণ বেকআপৰ বাবে পাছৱৰ্ডটো সলনি কৰিবলৈ বা আঁতৰাবলৈ টিপক"</string>
+    <string name="local_backup_password_toast_success" msgid="582016086228434290">"নতুন বেকআপ পাছৱৰ্ড ছেট কৰা হ\'ল"</string>
+    <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"নতুন পাছৱৰ্ডটোৰ লগত নিশ্চিত কৰা পাছৱৰ্ডটো মিলা নাই"</string>
+    <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"বেকআপ পাছৱৰ্ড নিৰ্ধাৰণ কৰিব পৰা নহ\'ল"</string>
+  <string-array name="color_mode_names">
+    <item msgid="2425514299220523812">"জীৱন্ত (ডিফল্ট)"</item>
+    <item msgid="8446070607501413455">"প্ৰাকৃতিক"</item>
+    <item msgid="6553408765810699025">"মানক"</item>
+  </string-array>
+  <string-array name="color_mode_descriptions">
+    <item msgid="4979629397075120893">"বৰ্ধিত ৰং"</item>
+    <item msgid="8280754435979370728">"চকুৱে দেখা পোৱা ধৰণৰ প্ৰাকৃতিক ৰং"</item>
+    <item msgid="5363960654009010371">"ডিজিটেল সমলৰ বাবে ৰং অপ্টিমাইজ কৰা হৈছে"</item>
+  </string-array>
+    <!-- no translation found for inactive_apps_title (9042996804461901648) -->
+    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"নিষ্ক্ৰিয়। ট\'গল কৰিবলৈ টিপক।"</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"সক্ৰিয়। ট\'গল কৰিবলৈ টিপক।"</string>
+    <!-- no translation found for standby_bucket_summary (6567835350910684727) -->
+    <skip />
+    <string name="runningservices_settings_title" msgid="8097287939865165213">"চলিত সেৱা"</string>
+    <string name="runningservices_settings_summary" msgid="854608995821032748">"বৰ্তমান চলি থকা সেৱাসমূহ চাওক আৰু নিয়ন্ত্ৰণ কৰক"</string>
+    <string name="select_webview_provider_title" msgid="4628592979751918907">"ৱেবভিউ প্ৰয়োগ"</string>
+    <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"ৱেবভিউ প্ৰয়োগ ছেট কৰক"</string>
+    <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"বাছনিটো এতিয়া আৰু মান্য় নহয়। আকৌ চেষ্টা কৰক।"</string>
+    <string name="convert_to_file_encryption" msgid="3060156730651061223">"ফাইল এনক্ৰিপশ্বন কৰিবলৈ ৰূপান্তৰ কৰক"</string>
+    <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"ৰূপান্তৰ কৰক…"</string>
+    <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"ফাইল ইতিমধ্যে এনক্ৰিপ্ট কৰা হৈছে"</string>
+    <string name="title_convert_fbe" msgid="1263622876196444453">"ফাইল-ভিত্তিক এনক্ৰিপশ্বনলৈ ৰূপান্তৰ কৰা হৈছে"</string>
+    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"ডেটা বিভাজনক ফাইল ভিত্তিক এনক্ৰিপশ্বনলৈ সলনি কৰক।\n !!সাৱধান!! ই আপোনাৰ সকলো ডেটা মচিব।\n এই সুবিধাটো আলফা পৰীক্ষণ অৱস্থাত আছে গতিকে ই সঠিকভাৱে কাম নকৰিব পাৰে।\n অব্যাহত ৰাখিবলৈ \'মচক আৰু ৰূপান্তৰ কৰক…\' দবাওক।"</string>
+    <string name="button_convert_fbe" msgid="5152671181309826405">"মচক আৰু ৰূপান্তৰ কৰক…"</string>
+    <string name="picture_color_mode" msgid="4560755008730283695">"চিত্ৰৰ ৰং ম’ড"</string>
+    <string name="picture_color_mode_desc" msgid="1141891467675548590">"এছআৰজিবি ব্যৱহাৰ কৰক"</string>
+    <string name="daltonizer_mode_disabled" msgid="7482661936053801862">"নিষ্ক্ৰিয় হৈ আছে"</string>
+    <string name="daltonizer_mode_monochromacy" msgid="8485709880666106721">"ম\'ন\'ক্ৰ\'মেচী"</string>
+    <string name="daltonizer_mode_deuteranomaly" msgid="5475532989673586329">"ডিউটাৰএন\'মেলী (ৰঙা-সেউজীয়া)"</string>
+    <string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"প্ৰ’টানোমালি (ৰঙা-সেউজীয়া)"</string>
+    <string name="daltonizer_mode_tritanomaly" msgid="481725854987912389">"ট্ৰাইটান\'মেলী (নীলা-হালধীয়া)"</string>
+    <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ৰং শুধৰণী"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"এই সুবিধাটো পৰীক্ষামূলক, সেয়ে ই কাৰ্যক্ষমতাৰ ওপৰত প্ৰভাৱ পেলাব পাৰে।"</string>
+    <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g>ৰ দ্বাৰা অগ্ৰাহ্য কৰা হৈছে"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"প্ৰায় <xliff:g id="TIME">%1$s</xliff:g> বাকী আছে"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"আপোনাৰ ব্যৱহাৰৰ ওপৰত ভিত্তি কৰি প্ৰায় <xliff:g id="TIME">%1$s</xliff:g> বাকী আছে"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"সম্পূৰ্ণকৈ চ্চাৰ্জ হ\'বলৈ <xliff:g id="TIME">%1$s</xliff:g> বাকী"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> বাকী"</string>
+    <!-- no translation found for power_remaining_less_than_duration_only (5996752448813295329) -->
+    <skip />
+    <!-- no translation found for power_remaining_less_than_duration (7967078125657859046) -->
+    <skip />
+    <!-- no translation found for power_remaining_more_than_subtext (6846716609975752316) -->
+    <skip />
+    <!-- no translation found for power_remaining_only_more_than_subtext (8884488700395194194) -->
+    <skip />
+    <!-- no translation found for power_remaining_duration_only_shutdown_imminent (8168317165722752881) -->
+    <skip />
+    <!-- no translation found for power_remaining_duration_only_shutdown_imminent (5957064378548718872) -->
+    <skip />
+    <!-- no translation found for power_remaining_duration_only_shutdown_imminent (9055596817716471373) -->
+    <skip />
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - প্ৰায় <xliff:g id="TIME">%2$s</xliff:g> বাকী আছে"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - আপোনাৰ ব্যৱহাৰক ভিত্তি কৰি প্ৰায় <xliff:g id="TIME">%2$s</xliff:g> বাকী আছে"</string>
+    <!-- no translation found for power_remaining_duration_shutdown_imminent (7679005631124015335) -->
+    <skip />
+    <!-- no translation found for power_remaining_duration_shutdown_imminent (261050880878965621) -->
+    <skip />
+    <!-- no translation found for power_remaining_duration_shutdown_imminent (2020049829798578618) -->
+    <skip />
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> সম্পূৰ্ণৰূপে চ্চাৰ্জ হোৱা পৰ্যন্ত"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"অজ্ঞাত"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"চাৰ্জ কৰি থকা হৈছে"</string>
+    <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"চ্চাৰ্জ হৈ আছে"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"চ্চাৰ্জ কৰা নাই"</string>
+    <string name="battery_info_status_not_charging" msgid="8523453668342598579">"প্লাগ কৰি থোৱা হৈছে, এই মুহূৰ্তত চ্চাৰ্জ কৰিব নোৱাৰি"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"পূৰ্ণ"</string>
+    <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"এডমিনৰ দ্বাৰা নিয়ন্ত্ৰিত"</string>
+    <string name="enabled_by_admin" msgid="5302986023578399263">"প্ৰশাসকে সক্ষম কৰিছে"</string>
+    <string name="disabled_by_admin" msgid="8505398946020816620">"এডমিনে অক্ষম কৰিছে ৰাখিছে"</string>
+    <string name="disabled" msgid="9206776641295849915">"নিষ্ক্ৰিয়"</string>
+    <string name="external_source_trusted" msgid="2707996266575928037">"অনুমতি দিয়া হৈছে"</string>
+    <string name="external_source_untrusted" msgid="2677442511837596726">"অনুমতি দিয়া হোৱা নাই"</string>
+    <string name="install_other_apps" msgid="6986686991775883017">"অজ্ঞাত এপ্ ইনষ্টল কৰক"</string>
+    <string name="home" msgid="3256884684164448244">"ছেটিংসমূহৰ গৃহপৃষ্ঠা"</string>
+  <string-array name="battery_labels">
+    <item msgid="8494684293649631252">"০%"</item>
+    <item msgid="8934126114226089439">"৫০%"</item>
+    <item msgid="1286113608943010849">"১০০%"</item>
+  </string-array>
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> আগত"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> বাকী আছে"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"সৰু"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ডিফ’ল্ট"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"ডাঙৰ"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"বৃহত্তৰ"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"সকলোতকৈ ডাঙৰ"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"নিজৰ উপযোগিতা অনুযায়ী (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
+    <string name="help_feedback_label" msgid="6815040660801785649">"সহায় আৰু ফীডবেক"</string>
+    <string name="content_description_menu_button" msgid="8182594799812351266">"মেনু"</string>
+    <string name="retail_demo_reset_message" msgid="118771671364131297">"ডেম’ ম\'ডত ফেক্টৰী ৰিছেট কৰিবলৈ পাছৱৰ্ড দিয়ক"</string>
+    <string name="retail_demo_reset_next" msgid="8356731459226304963">"পৰৱৰ্তী"</string>
+    <string name="retail_demo_reset_title" msgid="696589204029930100">"পাছৱৰ্ড দৰকাৰী"</string>
+    <string name="active_input_method_subtypes" msgid="3596398805424733238">"সক্ৰিয়হৈ থকা ইনপুট পদ্ধতিসমূহ"</string>
+    <string name="use_system_language_to_select_input_method_subtypes" msgid="5747329075020379587">"ছিষ্টেমৰ ভাষা ব্যৱহাৰ কৰক"</string>
+    <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>ৰ ছেটিংবিলাক খুলিব পৰা নগ\'ল"</string>
+    <string name="ime_security_warning" msgid="4135828934735934248">"এই ইনপুট পদ্ধতিটোৱে আপুনি টাইপ কৰা আপোনাৰ ব্যক্তিগত ডেটা যেনে পাছৱৰ্ডসমূহ আৰু ক্ৰেডিট কাৰ্ডৰ নম্বৰসমূহকে ধৰি সকলো পাঠ সংগ্ৰহ কৰিবলৈ সক্ষম হ\'ব পাৰে। <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> এপটোৰ লগত ই সংলগ্ন। এই ইনপুট পদ্ধতিটো ব্যৱহাৰ কৰেনে?"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"টোকা: ৰিবুট কৰাৰ পিছত আপুনি ফ\'নটো আনলক নকৰালৈকে এই এপটো ষ্টাৰ্ট নহ\'ব"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"আইএমএছ পঞ্জীয়ন স্থিতি"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"পঞ্জীকৃত"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"পঞ্জীকৃত নহয়"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"উপলব্ধ নহয়"</string>
+    <!-- no translation found for wifi_tether_connected_summary (3871603864314407780) -->
+    <!-- no translation found for accessibility_manual_zen_more_time (1636187409258564291) -->
+    <skip />
+    <!-- no translation found for accessibility_manual_zen_less_time (6590887204171164991) -->
+    <skip />
+    <!-- no translation found for zen_mode_enable_dialog_turn_on (8287824809739581837) -->
+    <skip />
+    <string name="cancel" msgid="6859253417269739139">"বাতিল কৰক"</string>
+    <!-- no translation found for zen_mode_settings_turn_on_dialog_title (2297134204747331078) -->
+    <skip />
+    <string name="zen_mode_settings_summary_off" msgid="6119891445378113334">"কেতিয়াও নহয়"</string>
+    <!-- no translation found for zen_interruption_level_priority (2078370238113347720) -->
+    <skip />
+    <!-- no translation found for zen_mode_and_condition (4927230238450354412) -->
+    <skip />
+    <!-- no translation found for zen_alarm_warning_indef (3007988140196673193) -->
+    <skip />
+    <!-- no translation found for zen_alarm_warning (6236690803924413088) -->
+    <skip />
+    <!-- no translation found for alarm_template (4996153414057676512) -->
+    <skip />
+    <!-- no translation found for alarm_template_far (3779172822607461675) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 97ccf91..1a0a251 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Доступ да SIM-карты"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Аўдыя ў HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Аўдыя ў HD"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Слыхавы апарат"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Падключана да слыхавога апарата"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Падключана да аўдыё медыа"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Падключана да аўдыё тэлефона"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Падключаны да серверу перадачы файлаў"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Выкарыстоўваць для аўдыё тэлефона"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Выкарыстоўваць для перадачы файлаў"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Выкарыстоўваць для ўводу"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Выкарыстоўваць для слыхавога апарата"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Падлучыць"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"СПАЛУЧЫЦЬ"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Скасаваць"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 9bde546..d071c64 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Достъп до SIM картата"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Висококачествено аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Висококачествено аудио"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Слухов апарат"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Има връзка със слуховия апарат"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Установена е връзка с медийно аудио"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Връзка със звука на телефона"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Установена е връзка със сървър за трансфер на файлове"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Използване на телефон за аудио"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Използване на за пренос на файлове"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Да се използва за въвеждане"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Използване за слухов апарат"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Сдвояване"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"СДВОЯВАНЕ"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Отказ"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 28b879bd..baa31e6 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"সিম -এর অ্যাক্সেস"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD অডিও: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD অডিও"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"হিয়ারিং এড"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"শ্রবণ যন্ত্রের সাথে কানেক্ট রয়েছে"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"মিডিয়া অডিওতে সংযুক্ত রয়েছে"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ফোন অডিওতে সংযুক্ত"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ফাইল স্থানান্তর সার্ভারের সঙ্গে সংযুক্ত"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ফোন অডিওয়ের জন্য ব্যবহার করুন"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ফাইল স্থানান্তরের জন্য ব্যবহার করুন"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ইনপুটের জন্য ব্যবহার করুন"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"শ্রবণ যন্ত্রের জন্য ব্যবহার করুন"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"যুক্ত করুন"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"যুক্ত করুন"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"বাতিল করুন"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 998ef58..fe1c6bc 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Πρόσβαση SIM"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Ήχος HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Ήχος HD"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Βοήθημα ακοής"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Συνδέθηκε σε βοήθημα ακοής"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Συνδέθηκε σε ήχο πολυμέσων"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Συνδεδεμένο στον ήχο τηλεφώνου"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Συνδεδεμένο σε διακομιστή μεταφοράς αρχείων"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Χρήση για ήχο τηλεφώνου"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Χρήση για τη μεταφορά αρχείων"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Χρήση για είσοδο"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Χρήση για βοήθημα ακοής"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Σύζευξη"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ΣΥΖΕΥΞΗ"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Ακύρωση"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index f38643f..bf62e59 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acceso SIM"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Audio en HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Audio en HD"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Audífonos"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Conectado a un audífono"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Conectado al audio multimedia"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Conectado al audio del dispositivo"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Conectado al servidor de transferencia de archivo"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Utilizar para el audio del dispositivo"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Utilizar para la transferencia de archivos"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Utilizar para entrada"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Usar con audífonos"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Vincular"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"SINCRONIZAR"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Cancelar"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 382a514..77d55ff 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM-kaardi juurdepääs"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD-heli: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD-heli"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Kuuldeaparaat"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Kuuldeaparaadiga ühendatud"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Ühendatud meediumiheliga"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Ühendatud telefoniheliga"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Ühendatud failiedastuse serveriga"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Kasuta telefoniheli jaoks"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Kasutage failide edastamiseks"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Kasutage sisendi jaoks"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Kuuldeaparaadiga kasutamiseks"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Seo"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"SEO"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Tühista"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 15fe55b..effcd47 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acceso á SIM"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Audio en HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Audio en HD"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Audiófonos"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Conectouse aos audiófonos"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Conectado ao audio multimedia"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Conectado ao audio do teléfono"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Conectado ao servidor de transferencia de ficheiros"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Utilízase para o audio do teléfono"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Utilízase para a transferencia de ficheiros"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Utilízase para a entrada"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Usar para o audiófono"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Sincronizar"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"SINCRONIZAR"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Cancelar"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 617230e..c517b8b 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"સિમ ઍક્સેસ"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ઑડિઓ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ઑડિઓ"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"સાંભળવામાં સહાય આપતું યંત્ર"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"સાંભળવામાં સહાય આપતા યંત્ર સાથે કનેક્ટ કરેલ"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"મીડિયા ઑડિઓ સાથે કનેક્ટ કર્યુ"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ફોન ઑડિઓ સાથે કનેક્ટ થયાં"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ફાઇલ સ્થાનાંતરણ સેવાથી કનેક્ટ થયાં"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ફોન ઑડિઓ માટે ઉપયોગ કરો"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ફાઇલ સ્થાનાંતર માટે ઉપયોગ કરો"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ઇનપુટ માટે ઉપયોગ કરો"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"સાંભળવામાં સહાય આપતા યંત્ર માટે ઉપયોગ કરો"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"જોડી"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"જોડાણ બનાવો"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"રદ કરો"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 4a12196..2726c46 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"सिम ऐक्सेस"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ऑडियो: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ऑडियो"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"सुनने में मददगार डिवाइस"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"सुनने में मददगार डिवाइस से जाेड़ा गया"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"मीडिया ऑडियो से कनेक्‍ट किया गया"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"फ़ोन ऑडियो से कनेक्‍ट किया गया"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"फ़ाइल स्‍थानांतरण सर्वर से कनेक्‍ट किया गया"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"फ़ोन ऑडियो के लिए उपयोग करें"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"फ़ाइल स्‍थानांतरण के लिए उपयोग करें"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"इनपुट के लिए उपयोग करें"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"सुनने में मददगार डिवाइस के लिए इस्तेमाल करें"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"युग्‍म बनाएं"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"दूसरे डिवाइस से जोड़ें"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"रद्द करें"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 8e5cf7d..35a5560 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM-elérés"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD audio"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Hallókészülék"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Csatlakoztatva a hallókészülékhez"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Csatlakoztatva az eszköz hangjához"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Csatlakoztatva a telefon hangjához"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Csatlakozva a fájlküldő szerverhez"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Felhasználás a telefon hangjához"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Felhasználás fájlátvitelre"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Használat beviteli eszközként"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Használat hallókészülékhez"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Párosítás"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"PÁROSÍTÁS"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Mégse"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index e5e5beb..44a1714 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM քարտի հասանելիություն"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD աուդիո՝ <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD աուդիո"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Լսողական ապարատ"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Միացված է լսողական ապարատին"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Միացված է մեդիա աուդիոյին"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Միացված է հեռախոսի ձայնային տվյալներին"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Միացված է ֆայլերի փոխանցման սերվերին"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Օգտագործել հեռախոսի աուդիոյի համար"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Օգտագործել ֆայլի փոխանցման համար"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Օգտագործել ներմուծման համար"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Օգտագործել լսողական ապարատի համար"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Զուգավորել"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"Զուգավորել"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Չեղարկել"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index b957898..81307f7 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"‏גישה ל-SIM"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"‏אודיו באיכות HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"‏אודיו באיכות HD"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"מכשיר שמיעה"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"מחובר למכשיר שמיעה"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"מחובר לאודיו של מדיה"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"מחובר לאודיו של הטלפון"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"מחובר לשרת העברת קבצים"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"השתמש עבור האודיו של הטלפון"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"השתמש להעברת קבצים"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"השתמש לקלט"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"יש להשתמש עבור מכשיר שמיעה"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"התאם"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"התאם"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"ביטול"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 953b2e3..346a96d 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIMアクセス"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD オーディオ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD オーディオ"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"補聴器"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"補聴器に接続済み"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"メディアの音声に接続"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"携帯電話の音声に接続"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ファイル転送サーバーに接続"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"携帯電話の音声に使用"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ファイル転送に使用"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"入力に使用"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"補聴器に使用"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"ペア設定する"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ペア設定する"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"キャンセル"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index a5fd213..db03069 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM წვდომა"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD აუდიო: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD აუდიო"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"სმენის აპარატი"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"დაკავშირებულია სმენის აპარატთან"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"დაკავშირებულია აუდიო მულტიმედიურ სისტემასთან"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"დაკავშირებულია ტელეფონის აუდიო მოწყობილობასთან"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"დაკავშირებულია ფაილების გადაცემის სერვერთან"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"გამოიყენეთ ტელეფონის აუდიომოწყობილობაში"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ფაილების ტრანსფერისათვის გამოყენება"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"შეტანისთვის გამოყენება"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"სმენის აპარატის გამოყენება"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"დაწყვილება"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"დაწყვილება"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"გაუქმება"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 4e2dacb..acd7d87 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM картасына кіру"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD форматты аудиомазмұн: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD форматты аудиомазмұн"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Есту аппараты"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Есту аппаратына жалғанған"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Медиа аудиосына жалғанған"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Телефон аудиосына қосылған"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Файл жіберу серверіне жалғанған"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Телефон аудиосы үшін қолдану"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Файлды жіберу үшін қолдану"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Кіріс үшін қолдану"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Есту аппаратына пайдалану"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Жұптау"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ЖҰПТАУ"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Бас тарту"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 400be09..9f55983 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"ಸಿಮ್ ಪ್ರವೇಶ"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ಆಡಿಯೋ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ಆಡಿಯೋ"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"ಶ್ರವಣ ಸಾಧನ"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"ಶ್ರವಣ ಸಾಧನಕ್ಕೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"ಮಾಧ್ಯಮ ಆಡಿಯೋಗೆ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ಫೋನ್ ಆಡಿಯೋಗೆ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ಫೈಲ್ ವರ್ಗಾವಣೆ ಸರ್ವರ್‌ಗೆ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ಫೋನ್‌ ಆಡಿಯೋಗಾಗಿ ಬಳಕೆ"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ಫೈಲ್‌ ವರ್ಗಾವಣೆಗಾಗಿ ಬಳಸು"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ಇನ್‌ಪುಟ್‌ಗಾಗಿ ಬಳಸು"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"ಶ್ರವಣ ಸಾಧನಕ್ಕಾಗಿ ಬಳಸಿ"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"ಜೋಡಿ"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ಜೋಡಿ ಮಾಡು"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"ರದ್ದುಮಾಡಿ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index ab02029..35a2867 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM 액세스"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD 오디오: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD 오디오"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"보청기"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"보청기에 연결됨"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"미디어 오디오에 연결됨"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"휴대전화 오디오에 연결됨"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"파일 전송 서버에 연결됨"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"휴대전화 오디오에 사용"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"파일 전송에 사용"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"입력에 사용"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"보청기에 사용"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"페어링"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"페어링"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"취소"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 993fc33..c1f73cc 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM картаны пайдалануу мүмкүнчүлүгү"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD форматындагы аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD форматындагы аудио"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Угуу аппараты"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Угуу аппаратына туташты"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Медиа аудиого туташты"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Телефон аудиосуна туташты"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Файл өткөрүү серверине туташты"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Телефон аудиосу үчүн колдонулсун"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Файл өткөрүү үчүн колдонулсун"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Киргизүү үчүн колдонулсун"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Угуу аппараты үчүн колдонуу"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Жупташтыруу"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ЖУПТАШТЫРУУ"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Жок"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index dc771f8..24cc69e 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Piekļuve SIM kartei"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD audio"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Dzirdes aparāts"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Izveidots savienojums ar dzirdes aparātu"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Savienots ar multivides audio"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Savienots ar tālruņa audio"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Savienots ar failu pārsūtīšanas serveri"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Izmantot tālruņa skaņai"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Izmantot faila pārsūtīšanai"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Izmantot ievadei"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Izmantot dzirdes aparātam"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Izveidot pāri"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"SAVIENOT PĀRĪ"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Atcelt"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 4ef3e86..4798a6f 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Пристап до SIM"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD аудио"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Слушно помагало"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Поврзано со слушно помагало"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Поврзан со аудио на медиуми"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Поврзан со аудио на телефон"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Поврзан со сервер за пренос на датотеки"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Користи за аудио на телефон"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Користи за пренос на датотеки"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Користи за внес"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Користете како слушно помагало"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Спари"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"СПАРИ"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Откажи"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index c242701..04b08f4 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM ആക്സസ്"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ഓഡിയോ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ഓഡിയോ"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"ശ്രവണ സഹായി"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"ശ്രവണ സഹായിലേക്ക് കണക്റ്റ് ചെയ്‌‌തു"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"മീഡിയ ഓഡിയോയിലേക്ക് കണ‌ക്റ്റുചെയ്‌തു"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ഫോൺ ഓഡിയോയിൽ കണ‌ക്റ്റുചെ‌യ്‌തു"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ഫയൽ കൈമാറ്റ സെർവറിലേക്ക് കണ‌ക്റ്റുചെ‌യ്‌തു"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ഫോൺ ഓഡിയോയ്ക്കായി ഉപയോഗിക്കുക"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ഫയൽ കൈമാറ്റത്തിനായി ഉപയോഗിക്കുന്നു"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ഇൻപുട്ടിനായി ഉപയോഗിക്കുക"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"ശ്രവണ സഹായത്തിനായി ഉപയോഗിക്കുക"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"ജോടിയാക്കുക"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ജോടിയാക്കുക"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"റദ്ദാക്കുക"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 7934e8d..26f4344 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"सिम प्रवेश"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ऑडिओ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ऑडिओ"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"ऐकण्याची सुविधा"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"ऐकण्याच्या सुविधेशी कनेक्ट केलेले आहे"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"मीडिया ऑडिओवर कनेक्ट केले"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"फोन ऑडिओ वर कनेक्ट केले"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"फाईल स्थानांतर सर्व्हरवर कनेक्ट केले"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"फोन ऑडिओसाठी वापरा"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"फाईल स्थानांतरणासाठी वापरा"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"इनपुट साठी वापरा"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"ऐकण्याच्या सुविधेसाठी वापरा"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"पेअर करा"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"पेअर करा"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"रद्द करा"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index e1aa376..8e24cee 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Akses SIM"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Audio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Audio HD"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Alat Bantu Pendengaran"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Disambungkan ke Alat Bantu Pendengaran"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Disambungkan ke audio media"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Disambungkan ke audio telefon"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Bersambung ke pelayan pemindahan fail"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Gunakan untuk audio telefon"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Gunakan untuk pemindahan fail"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Gunakan untuk input"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Gunakan untuk Alat Bantu Pendengaran"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Jadikan pasangan"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"JADIKAN PASANGAN"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Batal"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index f962316..0b54624 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Tilgang til SIM-kortet"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD-lyd: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD-lyd"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Høreapparat"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Koblet til høreapparat"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Koblet til medielyd"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Koblet til telefonlyd"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Koblet til tjener for filoverføring"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Bruk for telefonlyd"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Bruk til filoverføring"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Bruk for inndata"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Bruk for høreapparat"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Sammenkoble"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"KOBLE TIL"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Avbryt"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 0cac05e..7b78009 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM पहुँच"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD अडियो: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD अडियो"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"सुन्नमा मद्दत गर्ने यन्त्र"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"सुन्नमा मद्दत गर्ने यन्त्रमा जडान गरियो"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"मिडिया अडियोसँग जडित"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"फोन अडियोमा जडान गरियो"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"फाइल ट्रान्सफर सर्भरमा जडान गरियो"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"फोन अडियोको लागि प्रयोग गर्नुहोस्"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"फाइल ट्रान्सफरका लागि प्रयोग गर्नुहोस्"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"इनपुटको लागि प्रयोग गर्नुहोस्"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"सुन्नमा मद्दत गर्ने यन्त्रका लागि प्रयोग गर्नुहोस्"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"जोडी"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"जोडी"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"रद्द गर्नुहोस्"</string>
diff --git a/packages/SettingsLib/res/values-or/arrays.xml b/packages/SettingsLib/res/values-or/arrays.xml
new file mode 100644
index 0000000..22f6eda
--- /dev/null
+++ b/packages/SettingsLib/res/values-or/arrays.xml
@@ -0,0 +1,253 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wifi_status">
+    <item msgid="1922181315419294640"></item>
+    <item msgid="8934131797783724664">"ସ୍କାନ୍‌ କରୁଛି…"</item>
+    <item msgid="8513729475867537913">"ସଂଯୋଗ କରୁଛି…"</item>
+    <item msgid="515055375277271756">"ପ୍ରାମାଣିକୀକରଣ କରାଯାଉଛି…"</item>
+    <item msgid="1943354004029184381">"IP ଠିକଣା ପ୍ରାପ୍ତ କରୁଛି…"</item>
+    <item msgid="4221763391123233270">"ସଂଯୋଜିତ"</item>
+    <item msgid="624838831631122137">"ନିଲମ୍ବିତ"</item>
+    <item msgid="7979680559596111948">"ବିଚ୍ଛିନ୍ନ ହେଉଛି…"</item>
+    <item msgid="1634960474403853625">"ବିଚ୍ଛିନ୍ନ"</item>
+    <item msgid="746097431216080650">"ଅସଫଳ"</item>
+    <item msgid="6367044185730295334">"ଅବରୋଧିତ"</item>
+    <item msgid="503942654197908005">"ସାମୟିକ ଭାବେ ଖରାପ ସଂଯୋଜନାକୁ ଏଡାଉଛି"</item>
+  </string-array>
+  <string-array name="wifi_status_with_ssid">
+    <item msgid="7714855332363650812"></item>
+    <item msgid="8878186979715711006">"ସ୍କାନ୍‌ କରୁଛି…"</item>
+    <item msgid="355508996603873860">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>କୁ ସଂଯୋଗ କରାଯାଉଛି…"</item>
+    <item msgid="554971459996405634">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> ସହ ପ୍ରମାଣିତ ହେଉଛି…"</item>
+    <item msgid="7928343808033020343">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>ରୁ IP ଠିକଣା ହାସଲ କରୁଛି…"</item>
+    <item msgid="8937994881315223448">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> ସହ ସଂଯୁକ୍ତ"</item>
+    <item msgid="1330262655415760617">"କଟିଯାଇଛି"</item>
+    <item msgid="7698638434317271902">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g>ରୁ ବିଚ୍ଛିନ୍ନ ହେଉଛି…"</item>
+    <item msgid="197508606402264311">"ସଂଯୁକ୍ତ ନାହିଁ"</item>
+    <item msgid="8578370891960825148">"ଅସଫଳ"</item>
+    <item msgid="5660739516542454527">"ଅବରୋଧିତ"</item>
+    <item msgid="1805837518286731242">"ଦୁର୍ବଳ ସଂଯୋଗକୂ ସାମୟିକ ଭାବେ ଏଡ଼ାଉଛି"</item>
+  </string-array>
+  <string-array name="hdcp_checking_titles">
+    <item msgid="441827799230089869">"ଆଦୌ ଯାଞ୍ଚ କରନାହିଁ"</item>
+    <item msgid="6042769699089883931">"କେବଳ DRM କଣ୍ଟେଣ୍ଟ ଠାବ କର"</item>
+    <item msgid="9174900380056846820">"ସର୍ବଦା ଠାବ କର"</item>
+  </string-array>
+  <string-array name="hdcp_checking_summaries">
+    <item msgid="505558545611516707">"କଦାପି HDCP ଯାଞ୍ଚ କରିବା ବ୍ୟବହାର କରନ୍ତୁ ନାହିଁ"</item>
+    <item msgid="3878793616631049349">"କେବଳ DRM ବିଷୟବସ୍ତୁ ପାଇଁ HDCP ଯାଞ୍ଚ ବ୍ୟବହାର କରନ୍ତୁ"</item>
+    <item msgid="45075631231212732">"ସର୍ବଦା HDCP ଯାଞ୍ଚ ବ୍ୟବହାର କରନ୍ତୁ"</item>
+  </string-array>
+  <string-array name="bluetooth_avrcp_versions">
+    <item msgid="5347678900838034763">"AVRCP 1.4 (ଡିଫଲ୍ଟ)"</item>
+    <item msgid="2809759619990248160">"AVRCP 1.3"</item>
+    <item msgid="6199178154704729352">"AVRCP 1.5"</item>
+    <item msgid="5172170854953034852">"AVRCP 1.6"</item>
+  </string-array>
+  <string-array name="bluetooth_avrcp_version_values">
+    <item msgid="2838624067805073303">"avrcp14"</item>
+    <item msgid="3011533352527449572">"avrcp13"</item>
+    <item msgid="8837606198371920819">"avrcp15"</item>
+    <item msgid="3422726142222090896">"avrcp16"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_titles">
+    <item msgid="7065842274271279580">"ସିଷ୍ଟମ୍ ଚୟନ ବ୍ୟବହାର କରନ୍ତୁ (ଡିଫଲ୍ଟ)"</item>
+    <item msgid="7539690996561263909">"SBC"</item>
+    <item msgid="686685526567131661">"AAC"</item>
+    <item msgid="5254942598247222737">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ଅଡିଓ"</item>
+    <item msgid="2091430979086738145">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ଅଡିଓ"</item>
+    <item msgid="6751080638867012696">"LDAC"</item>
+    <item msgid="723675059572222462">"ବିକଳ୍ପ କୋଡେକ୍ସକୁ ସକ୍ଷମ କରନ୍ତୁ"</item>
+    <item msgid="3304843301758635896">"ବିକଳ୍ପ କୋଡେକ୍‌ଗୁଡ଼ିକୁ ଅକ୍ଷମ କରନ୍ତୁ"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_summaries">
+    <item msgid="5062108632402595000">"ସିଷ୍ଟମ୍‌ର ଚୟନ (ପୂର୍ବ-ନିର୍ଦ୍ଧାରିତ) ବ୍ୟବହାର କରନ୍ତୁ"</item>
+    <item msgid="6898329690939802290">"SBC"</item>
+    <item msgid="6839647709301342559">"AAC"</item>
+    <item msgid="7848030269621918608">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ଅଡିଓ"</item>
+    <item msgid="298198075927343893">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ଅଡିଓ"</item>
+    <item msgid="7950781694447359344">"LDAC"</item>
+    <item msgid="2209680154067241740">"ବିକଳ୍ପ କୋଡେକ୍ସ ସକ୍ଷମ କରନ୍ତୁ"</item>
+    <item msgid="741805482892725657">"ବିକଳ୍ପ କୋଡେକ୍ସ ଅକ୍ଷମ କରନ୍ତୁ"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
+    <item msgid="3093023430402746802">"ସିଷ୍ଟମ୍‌ର ଚୟନ (ପୂର୍ବ-ନିର୍ଦ୍ଧାରିତ) ବ୍ୟବହାର କରନ୍ତୁ"</item>
+    <item msgid="8895532488906185219">"44.1 kHz"</item>
+    <item msgid="2909915718994807056">"48.0 kHz"</item>
+    <item msgid="3347287377354164611">"88.2 kHz"</item>
+    <item msgid="1234212100239985373">"96.0 kHz"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_sample_rate_summaries">
+    <item msgid="3214516120190965356">"ସିଷ୍ଟମ୍‌ ଚୟନ ବ୍ୟବହାର କରନ୍ତୁ (ପୂର୍ବ-ନିର୍ଦ୍ଧାରିତ)"</item>
+    <item msgid="4482862757811638365">"44.1 kHz"</item>
+    <item msgid="354495328188724404">"48.0 kHz"</item>
+    <item msgid="7329816882213695083">"88.2 kHz"</item>
+    <item msgid="6967397666254430476">"96.0 kHz"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_bits_per_sample_titles">
+    <item msgid="2684127272582591429">"ସିଷ୍ଟମ୍‌ର ଚୟନ (ପୂର୍ବ-ନିର୍ଦ୍ଧାରିତ) ବ୍ୟବହାର କରନ୍ତୁ"</item>
+    <item msgid="5618929009984956469">"16 ବିଟ୍ସ/ସାମ୍ପଲ୍‌"</item>
+    <item msgid="3412640499234627248">"24 ବିଟ୍ସ/ନମୁନା"</item>
+    <item msgid="121583001492929387">"32 ବିଟସ୍‌/ନମୂନା"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_bits_per_sample_summaries">
+    <item msgid="1081159789834584363">"ସିଷ୍ଟମ୍‌ ମନୋନୟନ (ଡିଫଲ୍ଟ) ବ୍ୟବହାର କରନ୍ତୁ"</item>
+    <item msgid="4726688794884191540">"୧୬ ବିଟସ୍‌/ନମୁନା"</item>
+    <item msgid="305344756485516870">"24 ବିଟସ୍‌/ନମୂନା"</item>
+    <item msgid="244568657919675099">"32 ବିଟସ୍‌/ନମୁନା"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_channel_mode_titles">
+    <item msgid="5226878858503393706">"ସିଷ୍ଟମ୍ ଚୟନ ବ୍ୟବହାର କରନ୍ତୁ (ଡିଫଲ୍ଟ)"</item>
+    <item msgid="4106832974775067314">"ମୋନୋ"</item>
+    <item msgid="5571632958424639155">"ଷ୍ଟେରିଓ"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_channel_mode_summaries">
+    <item msgid="4118561796005528173">"ସିଷ୍ଟମ୍ ଚୟନ ବ୍ୟବହାର କରନ୍ତୁ(ପୂର୍ବ-ନିର୍ଦ୍ଧାରିତ)"</item>
+    <item msgid="8900559293912978337">"ମୋନୋ"</item>
+    <item msgid="8883739882299884241">"ଷ୍ଟେରିଓ"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
+    <item msgid="7158319962230727476">"ଅଡିଓ ଗୁଣବତ୍ତା ପାଇଁ ଅନୁକୂଳିତ(990kbps/909kbps)"</item>
+    <item msgid="2921767058740704969">"ସନ୍ତୁଳିତ ଅଡିଓ ଓ ସଂଯୋଗ ଗୁଣବତ୍ତା (660kbps/606kbps)"</item>
+    <item msgid="8860982705384396512">"ସଂଯୋଗର ଗୁଣବତ୍ତା (330kbps/303kbps) ପାଇଁ ଉପଯୁକ୍ତ କରାଯାଇଛି"</item>
+    <item msgid="4414060457677684127">"ସର୍ବୋତ୍ତମ ପ୍ରୟାସ (ଅନୁକୁଳ ବିଟ୍‌ ରେଟ୍‌)"</item>
+  </string-array>
+  <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
+    <item msgid="6398189564246596868">"ଅଡିଓର ଗୁଣବତ୍ତା ପାଇଁ ଅନୁକୂଳିତ"</item>
+    <item msgid="4327143584633311908">"ସନ୍ତୁଳିତ ଅଡିଓ ଓ ସଂଯୋଗ କ୍ୱାଲିଟୀ"</item>
+    <item msgid="4681409244565426925">"ସଂଯୋଗର ଗୁଣବତ୍ତା ପାଇଁ ଅନୁକୂଳିତ"</item>
+    <item msgid="364670732877872677">"ସର୍ବୋତ୍ତମ ପ୍ରୟାସ (ଅନୁକୂଳ ବିଟ୍‌ ରେଟ୍‌)"</item>
+  </string-array>
+  <string-array name="select_logd_size_titles">
+    <item msgid="8665206199209698501">"ଅଫ୍"</item>
+    <item msgid="1593289376502312923">"64K"</item>
+    <item msgid="487545340236145324">"256K"</item>
+    <item msgid="2423528675294333831">"1M"</item>
+    <item msgid="180883774509476541">"4M"</item>
+    <item msgid="2803199102589126938">"16M"</item>
+  </string-array>
+  <string-array name="select_logd_size_lowram_titles">
+    <item msgid="6089470720451068364">"ବନ୍ଦ"</item>
+    <item msgid="4622460333038586791">"64K"</item>
+    <item msgid="2212125625169582330">"256K"</item>
+    <item msgid="1704946766699242653">"1M"</item>
+  </string-array>
+  <string-array name="select_logd_size_summaries">
+    <item msgid="6921048829791179331">"ବନ୍ଦ"</item>
+    <item msgid="2969458029344750262">"64K ପିଛା ଲଗ୍‌ ବଫର୍‌"</item>
+    <item msgid="1342285115665698168">"256K ଲଗ୍‌ ପ୍ରତି ବଫର୍‌"</item>
+    <item msgid="1314234299552254621">"ଲଗ୍‌ ବଫର୍‌ ପ୍ରତି 1M"</item>
+    <item msgid="3606047780792894151">"ଲଗ୍‌ ବଫର୍‌ ପ୍ରତି 4M"</item>
+    <item msgid="5431354956856655120">"16M ଲଗ ପିଛା ବଫର୍‌"</item>
+  </string-array>
+  <string-array name="select_logpersist_titles">
+    <item msgid="1744840221860799971">"ବନ୍ଦ"</item>
+    <item msgid="3054662377365844197">"ସମସ୍ତ"</item>
+    <item msgid="688870735111627832">"ରେଡିଓ ଛଡ଼ା ଅନ୍ୟ ସବୁ"</item>
+    <item msgid="2850427388488887328">"କେବଳ କର୍ନେଲ୍"</item>
+  </string-array>
+  <string-array name="select_logpersist_summaries">
+    <item msgid="2216470072500521830">"ଅଫ"</item>
+    <item msgid="172978079776521897">"ସମସ୍ତ ଲଗ୍‌ ବଫର୍‌"</item>
+    <item msgid="3873873912383879240">"ରେଡିଓ ଲଗ୍‌ ବଫର୍‌‌ଗୁଡିକ ଛଡ଼ା ଅନ୍ୟ ସବୁ"</item>
+    <item msgid="8489661142527693381">"କେବଳ କର୍ନେଲ୍‌ ଲଗ୍‌ ବଫର୍‌"</item>
+  </string-array>
+  <string-array name="window_animation_scale_entries">
+    <item msgid="8134156599370824081">"ଆନିମେଶନ୍‌ ବନ୍ଦ କରନ୍ତୁ"</item>
+    <item msgid="6624864048416710414">"ଆନିମେଶନ ସ୍କେଲ .5x"</item>
+    <item msgid="2219332261255416635">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ 1x"</item>
+    <item msgid="3544428804137048509">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ 1.5x"</item>
+    <item msgid="3110710404225974514">"ଆନିମେଶନ ସ୍କେଲ 2x"</item>
+    <item msgid="4402738611528318731">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ 5x"</item>
+    <item msgid="6189539267968330656">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ 10x"</item>
+  </string-array>
+  <string-array name="transition_animation_scale_entries">
+    <item msgid="8464255836173039442">"ଆନିମେଶନ୍‌ ବନ୍ଦ କରନ୍ତୁ"</item>
+    <item msgid="3375781541913316411">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ .5x"</item>
+    <item msgid="1991041427801869945">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ 1x"</item>
+    <item msgid="4012689927622382874">"ଆନିମେସନ୍‌ ସ୍କେଲ 1.5x"</item>
+    <item msgid="3289156759925947169">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ 2x"</item>
+    <item msgid="7705857441213621835">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ 5x"</item>
+    <item msgid="6660750935954853365">"ଆନିମେସନ୍‌ ସ୍କେଲ୍‌ 10x"</item>
+  </string-array>
+  <string-array name="animator_duration_scale_entries">
+    <item msgid="6039901060648228241">"ଆନିମେଶନ୍ ବନ୍ଦ"</item>
+    <item msgid="1138649021950863198">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ .5x"</item>
+    <item msgid="4394388961370833040">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ 1x"</item>
+    <item msgid="8125427921655194973">"ଆନିମେଶନ୍ ସ୍କେଲ୍ 1.5x"</item>
+    <item msgid="3334024790739189573">"ଆନିମେଶନ୍ ସ୍କେଲ୍ 2x"</item>
+    <item msgid="3170120558236848008">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ 5x"</item>
+    <item msgid="1069584980746680398">"ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌ 10x"</item>
+  </string-array>
+  <string-array name="overlay_display_devices_entries">
+    <item msgid="1606809880904982133">"କିଛି ନାହିଁ"</item>
+    <item msgid="9033194758688161545">"480p"</item>
+    <item msgid="1025306206556583600">"480p (ସୁରକ୍ଷିତ)"</item>
+    <item msgid="1853913333042744661">"p"</item>
+    <item msgid="3414540279805870511">"720p (ସୁରକ୍ଷିତ)"</item>
+    <item msgid="9039818062847141551">"1080p"</item>
+    <item msgid="4939496949750174834">"1080p (ସୁରକ୍ଷିତ)"</item>
+    <item msgid="1833612718524903568">"4K"</item>
+    <item msgid="238303513127879234">"4K (ସୁରକ୍ଷିତ)"</item>
+    <item msgid="3547211260846843098">"4K (ଅପ୍‌ସ୍କେଲ୍‌ କରାଯାଇଛି)"</item>
+    <item msgid="5411365648951414254">"4K (ଉତ୍ତମ, ସୁରକ୍ଷିତ)"</item>
+    <item msgid="1311305077526792901">"720p, 1080p (ଡୁଆଲ୍ ସ୍କ୍ରୀନ୍‌)"</item>
+  </string-array>
+  <string-array name="enable_opengl_traces_entries">
+    <item msgid="3191973083884253830">"କିଛିନାହିଁ"</item>
+    <item msgid="9089630089455370183">"Logcat"</item>
+    <item msgid="5397807424362304288">"Systrace (ଗ୍ରାଫିକ୍ସ)"</item>
+    <item msgid="1340692776955662664">"glGetError ରେ କଲ୍‌ ଷ୍ଟାକ୍"</item>
+  </string-array>
+  <string-array name="show_non_rect_clip_entries">
+    <item msgid="993742912147090253">"ଅଫ୍"</item>
+    <item msgid="675719912558941285">"ଅଣ-ଆୟତାକାର କ୍ଲିପ୍ କ୍ଷେତ୍ର ନୀଳ ରଙ୍ଗରେ ଆଙ୍କନ୍ତୁ"</item>
+    <item msgid="1064373276095698656">"ଟେଷ୍ଟ ହୋଇଥିବା ଅଙ୍କନ କମାଣ୍ଡଗୁଡ଼ିକୁ ସବୁଜରେ ଚିହ୍ନିତ କରନ୍ତୁ"</item>
+  </string-array>
+  <string-array name="track_frame_time_entries">
+    <item msgid="2193584639058893150">"ବନ୍ଦ"</item>
+    <item msgid="2751513398307949636">"ସ୍କ୍ରୀନ୍‌ରେ ବାର୍‌ ପରି"</item>
+    <item msgid="2355151170975410323">"ରେ <xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g>"</item>
+  </string-array>
+  <string-array name="debug_hw_overdraw_entries">
+    <item msgid="8190572633763871652">"ଅଫ୍"</item>
+    <item msgid="7688197031296835369">"ଓଭର୍‌ ଡ୍ର କ୍ଷେତ୍ରଗୁଡ଼ିକୁ ଦେଖାଅ"</item>
+    <item msgid="2290859360633824369">"ଡିଉଟେରାନୋମାଲୀ ପାଇଁ କ୍ଷେତ୍ର ଦେଖନ୍ତୁ"</item>
+  </string-array>
+  <string-array name="app_process_limit_entries">
+    <item msgid="3401625457385943795">"ମାନକ ସୀମା"</item>
+    <item msgid="4071574792028999443">"କୌଣସି ବ୍ୟାକ୍‌ଗ୍ରାଉଣ୍ଡ ପ୍ରୋସେସ୍ ଚାଲୁନାହିଁ"</item>
+    <item msgid="4810006996171705398">"ସର୍ବାଧିକ 1ଟି ପ୍ରକ୍ରିୟା"</item>
+    <item msgid="8586370216857360863">"ସର୍ବାଧିକ 2 ଟି ପ୍ରକ୍ରିୟା"</item>
+    <item msgid="836593137872605381">"ଅତିବେଶୀରେ 3ଟି ପ୍ରକ୍ରିୟା"</item>
+    <item msgid="7899496259191969307">"ସର୍ବାଧିକ 4 ଟି ପ୍ରକ୍ରିୟା"</item>
+  </string-array>
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"ଚାର୍ଜ ହେଉଛି"</item>
+    <item msgid="5220695614993094977">"MTP (ମିଡିଆ ସ୍ଥାନାନ୍ତର ପ୍ରୋଟୋକଲ୍‌)"</item>
+    <item msgid="2086000968159047375">"PTP (ପିକଚର୍‌ ଟ୍ରାନ୍ସଫର୍‌ ପ୍ରୋଟୋକଲ୍‌)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB ଏଥରନେଟ)"</item>
+    <item msgid="1718924214939774352">"ଅଡିଓ ଉତ୍ସ"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
+</resources>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
new file mode 100644
index 0000000..0c2cbda
--- /dev/null
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -0,0 +1,466 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wifi_fail_to_scan" msgid="1265540342578081461">"ନେଟ୍‌ୱର୍କଗୁଡ଼ିକୁ ଖୋଜିପାରୁନାହିଁ"</string>
+    <string name="wifi_security_none" msgid="7985461072596594400">"କିଛି ନାହିଁ"</string>
+    <string name="wifi_remembered" msgid="4955746899347821096">"ସେଭ୍‌ ହୋଇଗଲା"</string>
+    <string name="wifi_disabled_generic" msgid="4259794910584943386">"ଅକ୍ଷମ ହୋଇଛି"</string>
+    <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP କନଫିଗରେଶନ ବିଫଳ ହୋଇଛି"</string>
+    <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"ନିମ୍ନ ମାନର ନେଟ୍‌ୱର୍କ କାରଣରୁ ସଂଯୁକ୍ତ ହୋଇନାହିଁ"</string>
+    <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"ୱାଇଫାଇ ସଂଯୋଗ ବିଫଳ ହୋଇଛି"</string>
+    <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"ସତ୍ୟାପନରେ ସମସ୍ୟା"</string>
+    <string name="wifi_cant_connect" msgid="5410016875644565884">"ସଂଯୋଗ କରିପାରିବ ନାହିଁ"</string>
+    <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"\'<xliff:g id="AP_NAME">%1$s</xliff:g>\' ସହିତ ସଂଯୁକ୍ତ ହୋଇପାରୁନାହିଁ"</string>
+    <string name="wifi_check_password_try_again" msgid="516958988102584767">"ପାସ୍‌ୱର୍ଡ ଯାଞ୍ଚ କରନ୍ତୁ ଏବଂ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
+    <string name="wifi_not_in_range" msgid="1136191511238508967">"ପରିସୀମାରେ ନାହିଁ"</string>
+    <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"ସ୍ୱଚାଳିତ ଭାବେ ସଂଯୁକ୍ତ ହେବନାହିଁ"</string>
+    <string name="wifi_no_internet" msgid="4663834955626848401">"ଇଣ୍ଟରନେଟ୍‌ର କୌଣସି ଆକ୍‌ସେସ୍‌ ନାହିଁ"</string>
+    <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> ଦ୍ୱାରା ସେଭ କରାଯାଇଛି"</string>
+    <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s ମାଧ୍ୟମରେ ଅଟୋମେଟିକାଲୀ ସଂଯୁକ୍ତ"</string>
+    <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"ନେଟୱର୍କ ମୂଲ୍ୟାୟନ ପ୍ରଦାତାଙ୍କ ମାଧ୍ୟମରେ ଅଟୋମେଟିକାଲ୍ୟ ସଂଯୁକ୍ତ"</string>
+    <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s ମାଧ୍ୟମରେ ସଂଯୁକ୍ତ"</string>
+    <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s ମାଧ୍ୟମରେ ଉପଲବ୍ଧ"</string>
+    <string name="wifi_connected_no_internet" msgid="8202906332837777829">"ସଂଯୁକ୍ତ, ଇଣ୍ଟର୍‌ନେଟ୍‌ ନାହିଁ"</string>
+    <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ଆକ୍ସେସ୍ ପଏଣ୍ଟ ସାମୟିକ ଭାବେ ପୂର୍ଣ୍ଣ"</string>
+    <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s ମାଧ୍ୟମରେ ସଂଯୁକ୍ତ"</string>
+    <string name="available_via_carrier" msgid="1469036129740799053">"%1$s ମାଧ୍ୟମରେ ଉପଲବ୍ଧ"</string>
+    <string name="speed_label_very_slow" msgid="1867055264243608530">"ବହୁତ ମନ୍ଥର"</string>
+    <string name="speed_label_slow" msgid="813109590815810235">"କମ୍‌ ବେଗ"</string>
+    <string name="speed_label_okay" msgid="2331665440671174858">"ଠିକ୍‌ ଅଛି"</string>
+    <string name="speed_label_medium" msgid="3175763313268941953">"ମଧ୍ୟମ"</string>
+    <string name="speed_label_fast" msgid="7715732164050975057">"ଦ୍ରୁତ"</string>
+    <string name="speed_label_very_fast" msgid="2265363430784523409">"ଅତି ଦ୍ରୁତ"</string>
+    <string name="preference_summary_default_combination" msgid="8532964268242666060">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
+    <string name="bluetooth_disconnected" msgid="6557104142667339895">"ବିଛିନ୍ନ ହେଲା"</string>
+    <string name="bluetooth_disconnecting" msgid="8913264760027764974">"ବିଚ୍ଛିନ୍ନ କରୁଛି…"</string>
+    <string name="bluetooth_connecting" msgid="8555009514614320497">"ସଂଯୋଗ କରାଯାଉଛି…"</string>
+    <!-- no translation found for bluetooth_connected (5427152882755735944) -->
+    <skip />
+    <string name="bluetooth_pairing" msgid="1426882272690346242">"ପେୟାର୍‌ କରୁଛି…"</string>
+    <!-- no translation found for bluetooth_connected_no_headset (616068069034994802) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_a2dp (3736431800395923868) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_map (3200033913678466453) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp (2047403011284187056) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_battery_level (5162924691231307748) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_headset_battery_level (1610296229139400266) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_a2dp_battery_level (3908466636369853652) -->
+    <skip />
+    <!-- no translation found for bluetooth_connected_no_headset_no_a2dp_battery_level (1163440823807659316) -->
+    <skip />
+    <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"ମିଡିଆ ଅଡିଓ"</string>
+    <string name="bluetooth_profile_headset" msgid="7815495680863246034">"ଫୋନ୍‌ କଲ୍‌‌ଗୁଡ଼ିକ"</string>
+    <string name="bluetooth_profile_opp" msgid="9168139293654233697">"ଫାଇଲ୍‌ ଟ୍ରାନ୍ସଫର୍‌"</string>
+    <string name="bluetooth_profile_hid" msgid="3680729023366986480">"ଇନ୍‌ପୁଟ୍‌ ଡିଭାଇସ୍"</string>
+    <string name="bluetooth_profile_pan" msgid="3391606497945147673">"ଇଣ୍ଟର୍‌ନେଟ୍‌ ଆକ୍ସେସ୍"</string>
+    <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"ଯୋଗାଯୋଗ ଶେୟାରିଙ୍ଗ"</string>
+    <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"ଯୋଗାଯୋଗ ଶେୟାର୍‌ କରିବା ପାଇଁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"ଇଣ୍ଟର୍‌ନେଟ୍‌ ସଂଯୋଗ ଶେୟାରିଙ୍ଗ"</string>
+    <string name="bluetooth_profile_map" msgid="1019763341565580450">"ଟେକ୍ସଟ୍ ମେସେଜ୍"</string>
+    <string name="bluetooth_profile_sap" msgid="5764222021851283125">"ସିମ୍‌ ଆକ୍ସେସ୍‌"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ଅଡିଓ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ଅଡିଓ"</string>
+    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
+    <skip />
+    <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"ମିଡିଆ ଅଡିଓ ସହ ସଂଯୁକ୍ତ"</string>
+    <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ଫୋନ୍‌ ଅଡିଓ ସହିତ ସଂଯୁକ୍ତ"</string>
+    <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ଫାଇଲ୍‌ ଟ୍ରାନ୍ସଫର୍‌ ସର୍ଭର୍‌ ସହ ସଂଯୁକ୍ତ"</string>
+    <string name="bluetooth_map_profile_summary_connected" msgid="8191407438851351713">"ମାନଚିତ୍ର ସହିତ ସଂଯୁକ୍ତ"</string>
+    <string name="bluetooth_sap_profile_summary_connected" msgid="8561765057453083838">"SAP ସହିତ ସଂଯୁକ୍ତ"</string>
+    <string name="bluetooth_opp_profile_summary_not_connected" msgid="1267091356089086285">"ଫାଇଲ୍‌ ଟ୍ରାନ୍ସଫର୍ ସର୍ଭର୍‍ ସହ ସଂଯୁକ୍ତ ହୋଇନାହିଁ"</string>
+    <string name="bluetooth_hid_profile_summary_connected" msgid="3381760054215168689">"ଇନ୍‌ପୁଟ୍‌ ଡିଇଭାସ୍‌ ସହ ସଂଯୁକ୍ତ"</string>
+    <string name="bluetooth_pan_user_profile_summary_connected" msgid="6436258151814414028">"ଆଭ୍ୟନ୍ତରୀଣ ଆକ୍ସେସ୍ ପାଇଁ ଡିଭାଇସ୍‌ ସହିତ ସଂଯୁକ୍ତ"</string>
+    <string name="bluetooth_pan_nap_profile_summary_connected" msgid="1322694224800769308">"ଡିଭାଇସ୍‌‌ ସହ ସ୍ଥାନୀୟ ଇଣ୍ଟରନେଟ୍‌ ସଂଯୋଗ ଶେୟାର୍‌ କରାଯାଉଛି"</string>
+    <string name="bluetooth_pan_profile_summary_use_for" msgid="5736111170225304239">"ଇଣ୍ଟର୍‌ନେଟ୍‌ ଆକ୍ସେସ୍‌ ପାଇଁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="bluetooth_map_profile_summary_use_for" msgid="5154200119919927434">"ମାନଚିତ୍ର ପାଇଁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"SIM ଆକସେସ୍‌ ପାଇଁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"ମିଡିଆ ଅଡିଓ ପାଇଁ ବ୍ୟବହାର କର"</string>
+    <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ଫୋନ୍‌ ଅଡିଓ ପାଇଁ ବ୍ୟବହାର କର"</string>
+    <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ଫାଇଲ୍‌ ଟ୍ରାନ୍ସଫର୍‌ ପାଇଁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ଇନ୍‌ପୁଟ୍‌ ପାଇଁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
+    <skip />
+    <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"ପେୟାର୍‌"</string>
+    <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ପେୟାର୍‌"</string>
+    <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"କ୍ୟାନ୍ସଲ୍‌ କରନ୍ତୁ"</string>
+    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"ପେୟାରିଂ ଫଳରେ ସଂଯୁକ୍ତ ଥିବା ବେଳେ ଆପଣଙ୍କ ସମ୍ପର୍କଗୁଡ଼ିକୁ ଏବଂ କଲ୍‌ର ଇତିବୃତିକୁ ଆକସେସ୍‌ ମଞ୍ଜୁର ହୁଏ।"</string>
+    <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ସହ ପେୟାର୍‌ କରିହେଲା ନାହିଁ।"</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"ଏକ ଭୁଲ୍‌ PIN କିମ୍ବା ପାସକୀ କାରଣରୁ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ସହ ପେୟାର୍‌ କରିପାରିଲା ନାହିଁ।"</string>
+    <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ସହ ଯୋଗାଯୋଗ ସ୍ଥାପନା କରିପାରୁନାହିଁ।"</string>
+    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ଦ୍ୱାରା ପେୟାରିଙ୍ଗ ପାଇଁ ପ୍ରତ୍ୟାଖ୍ୟାନ କରିଦିଆଗଲା।"</string>
+    <string name="bluetooth_talkback_computer" msgid="4875089335641234463">"କମ୍ପ୍ୟୁଟର୍"</string>
+    <string name="bluetooth_talkback_headset" msgid="5140152177885220949">"ହେଡ୍‌ସେଟ୍‌"</string>
+    <string name="bluetooth_talkback_phone" msgid="4260255181240622896">"ଫୋନ୍‌"</string>
+    <string name="bluetooth_talkback_imaging" msgid="551146170554589119">"ଇମେଜିଙ୍ଗ"</string>
+    <string name="bluetooth_talkback_headphone" msgid="26580326066627664">"ହେଡ୍‌ଫୋନ୍‌"</string>
+    <string name="bluetooth_talkback_input_peripheral" msgid="5165842622743212268">"ଇନ୍‌ପୁଟ୍‌ ଉପକରଣ"</string>
+    <string name="bluetooth_talkback_bluetooth" msgid="5615463912185280812">"ବ୍ଲୁଟୂଥ୍‌"</string>
+    <string name="accessibility_wifi_off" msgid="1166761729660614716">"ୱାଇ-ଫାଇ ବନ୍ଦ।"</string>
+    <string name="accessibility_no_wifi" msgid="8834610636137374508">"ୱାଇଫାଇ ବିଚ୍ଛିନ୍ନ କରାଗଲା।"</string>
+    <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wifiର 1 ବାର"</string>
+    <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"ୱାଇ-ଫାଇର ଦୁଇଟି ବାର୍‌ ଅଛି।"</string>
+    <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"ୱାଇ-ଫାଇର ତିନୋଟି ବାର୍।"</string>
+    <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"ୱାଇ-ଫାଇର ସଙ୍କେତ ସର୍ବୋଚ୍ଚ।"</string>
+    <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"ଖୋଲା ନେଟୱର୍କ"</string>
+    <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"ସୁରକ୍ଷିତ ନେଟ୍‌ୱର୍କ"</string>
+    <string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
+    <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"କଢ଼ାଯାଇଥିବା ଆପ୍‌ଗୁଡ଼ିକ"</string>
+    <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"ଆପ୍‌ ଏବଂ ଉପଯୋଗକର୍ତ୍ତା ବାହାର କରାଗଲା"</string>
+    <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB ଟିଥରିଙ୍ଗ"</string>
+    <string name="tether_settings_title_wifi" msgid="3277144155960302049">"ପୋର୍ଟବଲ୍‌ ହଟସ୍ପଟ୍‌"</string>
+    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"ବ୍ଲୁଟୂଥ ଟିଥରିଙ୍ଗ"</string>
+    <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"ଟିଥର୍‌ କରୁଛି"</string>
+    <string name="tether_settings_title_all" msgid="8356136101061143841">"ଟିଥରିଙ୍ଗ ଓ ପୋର୍ଟବଲ୍ ହଟ୍‌ସ୍ପଟ୍‌"</string>
+    <string name="managed_user_title" msgid="8109605045406748842">"ସମସ୍ତ କାର୍ଯ୍ୟ ଆପ୍‌"</string>
+    <string name="user_guest" msgid="8475274842845401871">"ଅତିଥି"</string>
+    <string name="unknown" msgid="1592123443519355854">"ଅଜଣା"</string>
+    <string name="running_process_item_user_label" msgid="3129887865552025943">"ଉପଯୋଗକର୍ତ୍ତା: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
+    <string name="launch_defaults_some" msgid="313159469856372621">"କିଛି ପୂର୍ବ-ନିର୍ଦ୍ଧାରିତ ମାନ ସେଟ୍‌ ହୋଇଛି"</string>
+    <string name="launch_defaults_none" msgid="4241129108140034876">"କୌଣସି ପୂର୍ବ-ନିର୍ଦ୍ଧାରଣ ସେଟ୍‍ ହୋଇନାହିଁ"</string>
+    <string name="tts_settings" msgid="8186971894801348327">"ଲେଖା-ରୁ-କଥା ସେଟିଙ୍ଗ୍‌"</string>
+    <string name="tts_settings_title" msgid="1237820681016639683">"ଲେଖା-ରୁ-କଥା ଆଉଟ୍‌ପୁଟ୍‌"</string>
+    <string name="tts_default_rate_title" msgid="6030550998379310088">"ସ୍ପୀଚ୍‌ ଦର"</string>
+    <string name="tts_default_rate_summary" msgid="4061815292287182801">"ଲେଖା ପଢ଼ିବାର ବେଗ"</string>
+    <string name="tts_default_pitch_title" msgid="6135942113172488671">"ପିଚ୍‌"</string>
+    <string name="tts_default_pitch_summary" msgid="1944885882882650009">"ସଂଶ୍ଳେଷିତ ସ୍ପିଚ୍‌‌ର ଟୋନ୍‌ରେ ପ୍ରଭାବ ପକାଏ"</string>
+    <string name="tts_default_lang_title" msgid="8018087612299820556">"ଭାଷା"</string>
+    <string name="tts_lang_use_system" msgid="2679252467416513208">"ସିଷ୍ଟମ୍‌ ଭାଷା ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="tts_lang_not_selected" msgid="7395787019276734765">"ଭାଷା ମନୋନୀତ ନୁହେଁ"</string>
+    <string name="tts_default_lang_summary" msgid="5219362163902707785">"ପଢ଼ାଯାଇଥିବା ଲେଖା ପାଇଁ ଭାଷା-ନିର୍ଦ୍ଦିଷ୍ଟ ସ୍ୱର ସେଟ୍‌ କରେ"</string>
+    <string name="tts_play_example_title" msgid="7094780383253097230">"ଗୋଟିଏ ଉଦାହରଣକୁ ଶୁଣନ୍ତୁ"</string>
+    <string name="tts_play_example_summary" msgid="8029071615047894486">"ସ୍ପୀଚ୍‌ ସିନ୍ଥେସିସ୍‌ର ଏକ ଛୋଟ ନମୁନା ଶୁଣନ୍ତୁ"</string>
+    <string name="tts_install_data_title" msgid="4264378440508149986">"ଭଏସ୍‌ ଡାଟା ଇନ୍‌ଷ୍ଟଲ୍ କରନ୍ତୁ"</string>
+    <string name="tts_install_data_summary" msgid="5742135732511822589">"ସ୍ପୀଚ୍‌ ସିନ୍ଥେସିସ୍‌ ପାଇଁ ଆବଶ୍ୟକ ଭଏସ୍‌ ଡାଟା ଇନ୍‌ଷ୍ଟଲ୍‌ କରନ୍ତୁ"</string>
+    <string name="tts_engine_security_warning" msgid="8786238102020223650">"ପାସ୍‌ୱର୍ଡ ଓ କ୍ରେଡିଟ୍‌ କାର୍ଡ ନମ୍ୱର୍‌ଗୁଡ଼ିକ ଭଳି ବ୍ୟକ୍ତିଗତ ତଥ୍ୟ ସମେତ କୁହାଯିବାକୁ ଥିବା ସମସ୍ତ ଲେଖାକୁ, ସ୍ପୀଚ୍‌ ସିନ୍ଥେସିସ୍‌ ଇଞ୍ଜିନ୍‌ ସଂଗ୍ରହ କରିପାରେ। ଏହା, <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> ଇଞ୍ଜିନ୍‌ରୁ ଆସିଛି। ଏହି ସ୍ପୀଚ୍‌ ସିନ୍ଥେସିସ୍‌ ଇଞ୍ଜିନ୍‌ର ବ୍ୟବହାରକୁ ସକ୍ଷମ କରିବେ?"</string>
+    <string name="tts_engine_network_required" msgid="1190837151485314743">"ଟେକ୍ସଟ୍-ରୁ-କଥା ଆଉଟପୁଟ୍‌ ପାଇଁ ଏହି ଭାଷା ଏକ କାମକରୁଥିବା ନେଟୱାର୍କ ସଂଯୋଗ ଆବଶ୍ୟକ କରେ।"</string>
+    <string name="tts_default_sample_string" msgid="4040835213373086322">"ଏହା ହେଉଛି ସ୍ପୀଚ୍‌ ସିନ୍ଥେସିସ୍‌ର ଏକ ଉଦାହରଣ"</string>
+    <string name="tts_status_title" msgid="7268566550242584413">"ଡିଫଲ୍ଟ ଭାଷା ଷ୍ଟାଟସ୍"</string>
+    <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> ପୂର୍ଣ୍ଣରୂପେ ସମର୍ଥିତ"</string>
+    <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> ନେଟ୍‌ୱର୍କ ସଂଯୋଜନା ଆବଶ୍ୟକ କରେ"</string>
+    <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> ସପୋର୍ଟ କରୁ ନାହିଁ"</string>
+    <string name="tts_status_checking" msgid="5339150797940483592">"ଯାଞ୍ଚ କରାଯାଉଛି…"</string>
+    <string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> ପାଇଁ ସେଟିଙ୍ଗ"</string>
+    <string name="tts_engine_settings_button" msgid="1030512042040722285">"ଇଞ୍ଜିନ୍‌ ସେଟିଙ୍ଗ ଆରମ୍ଭ କରନ୍ତୁ"</string>
+    <string name="tts_engine_preference_section_title" msgid="448294500990971413">"ନିଜ ପସନ୍ଦର ଇଞ୍ଜିନ୍‌"</string>
+    <string name="tts_general_section_title" msgid="4402572014604490502">"ସାଧାରଣ"</string>
+    <string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"ସ୍ପୀଚ୍‌ର ପିଚ୍‌ ରିସେଟ୍‌ କରନ୍ତୁ"</string>
+    <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"ପିଚକୁ ରିସେଟ କରନ୍ତୁ, ଯେଉଁଠାରେ ଲେଖା, ଡିଫଲ୍ଟ ଭାବେ କୁହାଯାଏ।"</string>
+  <string-array name="tts_rate_entries">
+    <item msgid="6695494874362656215">"ବହୁତ ମନ୍ଥର"</item>
+    <item msgid="4795095314303559268">"ମନ୍ଥର"</item>
+    <item msgid="8903157781070679765">"ସାମାନ୍ୟ"</item>
+    <item msgid="164347302621392996">"ଦ୍ରୁତ"</item>
+    <item msgid="5794028588101562009">"ଦ୍ରୁତତର"</item>
+    <item msgid="7163942783888652942">"ଅତି ଦ୍ରୁତ"</item>
+    <item msgid="7831712693748700507">"ଦ୍ରୁତ"</item>
+    <item msgid="5194774745031751806">"ଅତି ତୀବ୍ର"</item>
+    <item msgid="9085102246155045744">"ଦ୍ରୁତତ୍ତମ"</item>
+  </string-array>
+    <string name="choose_profile" msgid="6921016979430278661">"ପ୍ରୋଫାଇଲ୍‌ ବାଛନ୍ତୁ"</string>
+    <string name="category_personal" msgid="1299663247844969448">"ବ୍ୟକ୍ତିଗତ"</string>
+    <string name="category_work" msgid="8699184680584175622">"କାମ"</string>
+    <string name="development_settings_title" msgid="215179176067683667">"ଡେଭଲପର୍‌ଙ୍କ ପାଇଁ ବିକଳ୍ପମାନ"</string>
+    <string name="development_settings_enable" msgid="542530994778109538">"ଡେଭଲପର୍‌ ବିକଳ୍ପଗୁଡ଼ିକ ସକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="development_settings_summary" msgid="1815795401632854041">"ଆପ୍‌ର ବିକାଶ ପାଇଁ ବିକଳ୍ପମାନ ସେଟ୍‌ କରନ୍ତୁ"</string>
+    <string name="development_settings_not_available" msgid="4308569041701535607">"ଏହି ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ପାଇଁ ଡେଭଲପରଙ୍କ ବିକଳ୍ପସମୂହ ଉପଲବ୍ଧ ନୁହେଁ"</string>
+    <string name="vpn_settings_not_available" msgid="956841430176985598">"VPN ସେଟିଙ୍ଗ ଏହି ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ପାଇଁ ଉପଲବ୍ଧ ନୁହେଁ"</string>
+    <string name="tethering_settings_not_available" msgid="6765770438438291012">"ଏହି ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ପାଇଁ ଟିଥରିଙ୍ଗ ସେଟିଙ୍ଗ ଉପଲବ୍ଧ ନାହିଁ"</string>
+    <string name="apn_settings_not_available" msgid="7873729032165324000">"ଆକ୍ସେସ୍‌ ପଏଣ୍ଟ ନାମର ସେଟିଙ୍ଗ ଏହି ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ପାଇଁ ଉପଲବ୍ଧ ନାହିଁ"</string>
+    <string name="enable_adb" msgid="7982306934419797485">"USB ଡିବଗ୍‌ ହେଉଛି"</string>
+    <string name="enable_adb_summary" msgid="4881186971746056635">"USB ସଂଯୁକ୍ତ ହେବାବେଳେ ଡିବଗ୍‌ ମୋଡ୍‌"</string>
+    <string name="clear_adb_keys" msgid="4038889221503122743">"USB ଡିବଗିଙ୍ଗ ଅଧିକାରକୁ କାଢ଼ିଦିଅନ୍ତୁ"</string>
+    <string name="bugreport_in_power" msgid="7923901846375587241">"ବଗ୍‌ ରିପୋର୍ଟ ଶର୍ଟକଟ୍‌"</string>
+    <string name="bugreport_in_power_summary" msgid="1778455732762984579">"ତ୍ରୁଟି ରିପୋର୍ଟ ଦେବାପାଇଁ ପାୱର୍‌ ମେନୁରେ ଏକ ବଟନ୍‌ ଦେଖନ୍ତୁ"</string>
+    <string name="keep_screen_on" msgid="1146389631208760344">"ଜାଗ୍ରତ ରଖନ୍ତୁ"</string>
+    <string name="keep_screen_on_summary" msgid="2173114350754293009">"ଚାର୍ଜ ହେବାବେଳେ ସ୍କ୍ରୀନ୍‌ ଆଦୌ ବନ୍ଦ ହେବନାହିଁ"</string>
+    <string name="bt_hci_snoop_log" msgid="3340699311158865670">"ବ୍ଲୁଟୁଥ୍‌ HCI ସ୍ନୁପ୍‌ ଲଗ୍‌ ସକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="bt_hci_snoop_log_summary" msgid="730247028210113851">"ଗୋଟିଏ ଫାଇଲ୍‌ରେ ସମସ୍ତ ବ୍ଲୁଟୂଥ୍‌ HCI ପ୍ୟାକେଟ୍‌ଗୁଡିକୁ କ୍ୟାପଚର୍‌ କରନ୍ତୁ"</string>
+    <string name="oem_unlock_enable" msgid="6040763321967327691">"OEM ଅନଲକ୍‌ କରିବା"</string>
+    <string name="oem_unlock_enable_summary" msgid="4720281828891618376">"bootloaderକୁ ଅନ୍‌ଲକ୍‌ ହେବାର ଅନୁମତି ଦିଅନ୍ତୁ"</string>
+    <string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM ଅନଲକ୍‌ କରିବା ଅନୁମତି ଦେବେ?"</string>
+    <string name="confirm_enable_oem_unlock_text" msgid="5517144575601647022">"ଚେତାବନୀ: ଏହି ସେଟିଙ୍ଗ ଚାଲୁ ଥିବାବେଳେ ଡିଭାଇସ୍‌ର ସୁରକ୍ଷା ବୈଶିଷ୍ଟ୍ୟ କାମ କରିବ ନାହିଁ"</string>
+    <string name="mock_location_app" msgid="7966220972812881854">"ନକଲି ଲୋକେଶନ୍‌ ଆପ୍‌ର ଚୟନ କରନ୍ତୁ"</string>
+    <string name="mock_location_app_not_set" msgid="809543285495344223">"କୌଣସି ନକଲି ଲୋକେଶନ ଏପ ସେଟ କରାଯାଇନାହିଁ"</string>
+    <string name="mock_location_app_set" msgid="8966420655295102685">"ନକଲି ଲୋକେଶନ୍‌ ଆପ୍‌: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="debug_networking_category" msgid="7044075693643009662">"ନେଟ୍‌ୱର୍କିଙ୍ଗ"</string>
+    <string name="wifi_display_certification" msgid="8611569543791307533">"ୱାୟର୍‌ଲେସ୍‌ ଡିସ୍‌ପ୍ଲେ ସର୍ଟିଫିକେଶନ୍‌"</string>
+    <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi ଭରବୋସ୍‌ ଲଗିଙ୍ଗ ସକ୍ଷମ କରନ୍ତୁ"</string>
+    <!-- no translation found for wifi_connected_mac_randomization (3168165236877957767) -->
+    <skip />
+    <string name="mobile_data_always_on" msgid="8774857027458200434">"ମୋବାଇଲ୍‌ ଡାଟା ସର୍ବଦା ସକ୍ରିୟ"</string>
+    <string name="tethering_hardware_offload" msgid="7470077827090325814">"ଟିଥରିଙ୍ଗ ହାର୍ଡୱେର ବେଗ"</string>
+    <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"ବ୍ଲୁଟୂଥ୍‌ ଡିଭାଇସ୍‌ଗୁଡ଼ିକୁ ନାମ ବିନା ଦେଖନ୍ତୁ"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ପୂର୍ଣ୍ଣ ଭଲ୍ୟୁମ୍‌ ଅକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="bluetooth_select_avrcp_version_string" msgid="3750059931120293633">"ବ୍ଲୁଟୂଥ୍‌ AVRCP ଭର୍ସନ୍"</string>
+    <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7277329668298705702">"ବ୍ଲୁଟୂଥ୍‌ AVRCP ଭର୍ସନ୍‌"</string>
+    <string name="bluetooth_select_a2dp_codec_type" msgid="90597356942154882">"ବ୍ଲୁଟୁଥ୍‌ ଅଡିଓ କୋଡେକ୍‌"</string>
+    <string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="4558347981670553665">"ବ୍ଲୁଟୁଥ୍‌ ଅଡିଓ କୋଡେକ୍‌ ଚୟନ କରନ୍ତୁ"</string>
+    <string name="bluetooth_select_a2dp_codec_sample_rate" msgid="4788245703824623062">"ବ୍ଲୁଟୂଥ୍‌ ଅଡିଓ ସାମ୍ପଲ୍‌ ରେଟ୍‌"</string>
+    <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title" msgid="5628790207448471613">"ବ୍ଲୁଟୁଥ୍‌ ଅଡିଓ କୋଡେକ୍ ଚୟନ କରନ୍ତୁ: \n ନମୁନା ଦର"</string>
+    <string name="bluetooth_select_a2dp_codec_bits_per_sample" msgid="2099645202720164141">"ନମୁନା ପିଛା ବ୍ଲୁଟୁଥ୍‌ ଅଡିଓ ବିଟ୍ସ"</string>
+    <string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4546131401358681321">"ବ୍ଲୁଟୂଥ ଅଡିଓ କୋଡେକ୍‌ ବାଛନ୍ତୁ:\nନମୂନା ପ୍ରତି ବିଟସ୍‌"</string>
+    <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="884855779449390540">"ବ୍ଲୁଟୂଥ୍‌ ଅଡିଓ ଚ୍ୟାନେଲ୍‌ ମୋଡ୍"</string>
+    <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="9133545781346216071">"ବ୍ଲୁଟୂଥ୍‌ ଅଡ଼ିଓ କୋଡେକ୍‌:\nଚାନେଲ୍‌ ମୋଡ୍‌ ବାଛନ୍ତୁ"</string>
+    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"ବ୍ଲୁଟୁଥ୍‌ ଅଡିଓ LDAC କୋଡେକ୍‌: ପ୍ଲେବ୍ୟାକ୍‌ ଗୁଣବତ୍ତା"</string>
+    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="3181967377574368400">"ବ୍ଲୁଟୂଥ୍‌ ଅଡିଓ LDAC କୋଡେକ୍‌ ବାଛନ୍ତୁ:\nପ୍ଲେବ୍ୟାକ୍‌ କ୍ୱାଲିଟୀ"</string>
+    <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ଷ୍ଟ୍ରିମ୍ କରୁଛି: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
+    <string name="select_private_dns_configuration_title" msgid="3700456559305263922">"ବ୍ୟକ୍ତିଗତ DNS"</string>
+    <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"ବ୍ୟକ୍ତିଗତ DNS ମୋଡ୍‌ ବାଛନ୍ତୁ"</string>
+    <string name="private_dns_mode_off" msgid="8236575187318721684">"ଅଫ୍"</string>
+    <string name="private_dns_mode_opportunistic" msgid="7608409735589131766">"ସୁଯୋଗବାଦୀ"</string>
+    <string name="private_dns_mode_provider" msgid="8354935160639360804">"ବ୍ୟକ୍ତିଗତ DNS ପ୍ରଦାତା ହୋଷ୍ଟନାମ"</string>
+    <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"DNS ପ୍ରଦାନକାରୀଙ୍କ ହୋଷ୍ଟନାମ ପ୍ରବେଶ କରନ୍ତୁ"</string>
+    <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ୱେୟାରଲେସ୍‌ ପ୍ରଦର୍ଶନ ସାର୍ଟିଫିକେସନ୍‌ ପାଇଁ ବିକଳ୍ପଗୁଡିକ ଦେଖାନ୍ତୁ"</string>
+    <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ୱାଇ-ଫାଇ ଲଗିଙ୍ଗ ସ୍ତର ବଢ଼ାନ୍ତୁ, ୱାଇ-ଫାଇ ପିକର୍‌ରେ ପ୍ରତି SSID RSSI ଦେଖାନ୍ତୁ"</string>
+    <!-- no translation found for wifi_connected_mac_randomization_summary (1743059848752201485) -->
+    <skip />
+    <string name="select_logd_size_title" msgid="7433137108348553508">"ଲଗର୍‌ ବଫର୍‌ ଆକାରଗୁଡ଼ିକ"</string>
+    <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"ଲଗ୍‌ ବଫର୍‌ ପିଛା ଲଗର୍‌ ଆକାରଗୁଡିକର ଚୟନ କରନ୍ତୁ"</string>
+    <string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"ଲଗର୍‌ ରୋଧି ଷ୍ଟୋରେଜ୍‌ ଖାଲି କରିବେ?"</string>
+    <string name="dev_logpersist_clear_warning_message" msgid="2256582531342994562">"ଯଦି ଆମେ ଦୃଢ ଲଗର୍‌ ସହିତ ଆଉ ତଦାରଖ କରୁନଥିବୁ, ତେବେ ଆମକୁ ଆପଣଙ୍କ ଡିଭାଇସ୍‌ରେ ଥିବା ଲଗର୍‌ ଡାଟାକୁ ଲିଭାଇବାକୁ ପଡ଼ିବ।"</string>
+    <string name="select_logpersist_title" msgid="7530031344550073166">"ଡିଭାଇସ୍‌ରେ ଲଗାତର ଲଗର୍‌ ଡାଟା ଷ୍ଟୋର୍‌ କରନ୍ତୁ"</string>
+    <string name="select_logpersist_dialog_title" msgid="4003400579973269060">"ଡିଭାଇସ୍‌ରେ ଲଗାତର ଷ୍ଟୋର୍‌ କରିବାକୁ ଲଗ୍‌ ବଫର୍‌ ଚୟନ କରନ୍ତୁ"</string>
+    <string name="select_usb_configuration_title" msgid="2649938511506971843">"USB କନଫିଗ୍ୟୁରେସନ୍‌ ଚୟନ କରନ୍ତୁ"</string>
+    <string name="select_usb_configuration_dialog_title" msgid="6385564442851599963">"USB କନଫିଗ୍ୟୁରେସନ୍‌ ଚୟନ କରନ୍ତୁ"</string>
+    <string name="allow_mock_location" msgid="2787962564578664888">"ନକଲି ଲୋକେଶନ୍‌ର ଅନୁମତି ଦିଅନ୍ତୁ"</string>
+    <string name="allow_mock_location_summary" msgid="317615105156345626">"ନକଲି ଲୋକେଶନ୍‌ର ଅନୁମତି ଦିଅନ୍ତୁ"</string>
+    <string name="debug_view_attributes" msgid="6485448367803310384">"ବିଶେଷତା ଯାଞ୍ଚ ଦର୍ଶନ ସକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"ୱାଇ-ଫାଇ ସକ୍ରିୟ ଥିଲେ ମଧ୍ୟ ସର୍ବଦା ମୋବାଇଲ୍‌ ଡାଟାକୁ ସକ୍ରିୟ ରଖନ୍ତୁ (ଦ୍ରୁତ ନେଟ୍‌ୱର୍କ ସ୍ୱିଚିଙ୍ଗ ପାଇଁ)।"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"ଯଦି ଉପଲବ୍ଧ ଥାଏ, ଟିଥରିଙ୍ଗ ହାର୍ଡୱେର୍‌ ଆକ୍ସଲରେଶନ୍‌ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="adb_warning_title" msgid="6234463310896563253">"USB ଡିବଗିଙ୍ଗ କରିବେ?"</string>
+    <string name="adb_warning_message" msgid="7316799925425402244">"USB ଡିବଗିଂ କେବଳ ଡେଭଲପମେଣ୍ଟ ଉଦ୍ଦେଶ୍ୟ ପାଇଁ ଉଦ୍ଦିଷ୍ଟ ଅଟେ। ଆପଣଙ୍କ କମ୍ପ୍ୟୁଟର ଏବଂ ଡିଭାଇସ୍‌ ମଧ୍ୟରେ ଡାଟା କପି କରିବାକୁ, ବିନା ବିଜ୍ଞପ୍ତିରେ ଆପଣଙ୍କ ଡିଭାଇସରେ ଆପସ୍‌ ସଂସ୍ଥାପନ କରିବାକୁ, ଏବଂ ଲଗ୍‌ ଡାଟା ପଢିବାକୁ ଏହା ବ୍ୟବହାର କରନ୍ତୁ।"</string>
+    <string name="adb_keys_warning_message" msgid="5659849457135841625">"ଅଧିକୃତ ସମସ୍ତ କମ୍ପ୍ୟୁଟରରୁ USB ଡିବଗ୍‌ କରିବା ଆକ୍ସେସ୍‌ ପ୍ରତ୍ୟାହାର କରିବେ କି?"</string>
+    <string name="dev_settings_warning_title" msgid="7244607768088540165">"ଡେଭଲପମେଣ୍ଟ ସେଟିଙ୍ଗ ଅନୁମତି ଦେବେ?"</string>
+    <string name="dev_settings_warning_message" msgid="2298337781139097964">"ଏହି ସେଟିଙ୍ଗଗୁଡ଼ିକ କେବଳ ବିକାଶ ବ୍ୟବହାର ପାଇଁ ଉଦ୍ଦିଷ୍ଟ। ସେଗୁଡ଼ିକ କାରଣରୁ ଆପଣଙ୍କ ଡିଭାଇସ୍‌ ଓ ଆପ୍ଲିକେଶନ୍‍‍ଗୁଡ଼ିକ ଠିକ୍‌ ଭାବେ କାମ ନକରିପାରେ।"</string>
+    <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB ଜରିଆରେ ଆପ୍‌ଗୁଡ଼ିକୁ ଯାଞ୍ଚ କରନ୍ତୁ"</string>
+    <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ADB/ADT ମାଧ୍ୟମରେ ଇନଷ୍ଟଲ ହୋଇଥିବା ଆପ୍‌ଗୁଡ଼ିକ ହାନିକାରକ କାର୍ଯ୍ୟକଳାପ କରୁଛି କି ନାହିଁ ଯାଞ୍ଚ କରନ୍ତୁ।"</string>
+    <string name="bluetooth_show_devices_without_names_summary" msgid="2351196058115755520">"(କେବଳ MAC ଠିକଣା ଥାଇ) ନାମ ବିନା ବ୍ଲୁଟୂଥ ଡିଭାଇସଗୁଡ଼ିକ ପ୍ରଦର୍ଶିତ ହେବ"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"ରିମୋଟ୍‌ ଡିଭାଇସ୍‌ଗୁଡ଼ିକରେ ଯଦି ଅସ୍ୱୀକାର୍ଯ୍ୟ ଭାବେ ଉଚ୍ଚ ଭଲ୍ୟୁମ କିମ୍ବା ନିୟନ୍ତ୍ରଣର ଅଭାବ ପରି ଭଲ୍ୟୁମ ସମସ୍ୟା ଥାଏ ବ୍ଲୁଟୁଥ୍‌ ଆବସଲ୍ୟୁଟ୍‌ ଭଲ୍ୟୁମ ବୈଶିଷ୍ଟ୍ୟ ଅକ୍ଷମ କରେ।"</string>
+    <string name="enable_terminal_title" msgid="95572094356054120">"ସ୍ଥାନୀୟ ଟର୍ମିନାଲ୍‌"</string>
+    <string name="enable_terminal_summary" msgid="67667852659359206">"ସ୍ଥାନୀୟ ଶେଲ୍‌କୁ ଆକ‌ସେସ୍‌ ଦେଉଥିବା ଟର୍ମିନଲ୍‌ ଆପ୍‌କୁ ସକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP ଯାଞ୍ଚ କରୁଛି"</string>
+    <string name="hdcp_checking_dialog_title" msgid="5141305530923283">"HDCPର ଯାଞ୍ଚ ଗତିବିଧି ସେଟ୍‍ କରନ୍ତୁ"</string>
+    <string name="debug_debugging_category" msgid="6781250159513471316">"ଡିବଗ୍‌ କରୁଛି"</string>
+    <string name="debug_app" msgid="8349591734751384446">"ଡିବଗ୍‌ ଆପ୍‌ ବାଛି ନିଅନ୍ତୁ"</string>
+    <string name="debug_app_not_set" msgid="718752499586403499">"କୌଣସି ଡିବଗ୍‌ ଆପ୍ଲିକେଶନ୍‌ ସେଟ୍‌ ହୋଇନାହିଁ"</string>
+    <string name="debug_app_set" msgid="2063077997870280017">"ଆପ୍ଲିକେଶନ୍‌ ଡିବଗ୍‌ କରୁଛି: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="select_application" msgid="5156029161289091703">"ଆପ୍ଲିକେଶନ୍‌ ବାଛନ୍ତୁ"</string>
+    <string name="no_application" msgid="2813387563129153880">"କିଛି ନୁହେଁ"</string>
+    <string name="wait_for_debugger" msgid="1202370874528893091">"ଡିବଗର୍‌ ପାଇଁ ଅପେକ୍ଷା କରନ୍ତୁ"</string>
+    <string name="wait_for_debugger_summary" msgid="1766918303462746804">"ଡିବଗ୍‌ ହୋଇଥିବା ଆପ୍ଲିକେଶନ୍‍, ନିଷ୍ପାଦନ ପୂର୍ବରୁ ଆଟାଚ୍‌ କରିବା ପାଇଁ ଡିବଗର୍‌କୁ ଅପେକ୍ଷା କରେ"</string>
+    <string name="debug_input_category" msgid="1811069939601180246">"ଇନପୁଟ୍"</string>
+    <string name="debug_drawing_category" msgid="6755716469267367852">"ଅଙ୍କନ"</string>
+    <string name="debug_hw_drawing_category" msgid="6220174216912308658">"ହାର୍ଡୱେର୍‌ ଆକ୍ସଲରେଟେଡ୍ ରେଣ୍ଡରିଙ୍ଗ"</string>
+    <string name="media_category" msgid="4388305075496848353">"ମିଡିଆ"</string>
+    <string name="debug_monitoring_category" msgid="7640508148375798343">"ତଦାରାଖ କରିବା"</string>
+    <string name="strict_mode" msgid="1938795874357830695">"କଡ଼ା ମୋଡ୍ ସକ୍ଷମ କରାଯାଇଛି"</string>
+    <string name="strict_mode_summary" msgid="142834318897332338">"ମୁଖ୍ୟ ଥ୍ରେଡ୍‌ରେ ଆପ୍‌ ଦୀର୍ଘ ସମୟ କାର୍ଯ୍ୟ କରିବା ବେଳେ ସ୍କ୍ରିନ୍‌ ଫ୍ଲାସ୍‌ କରନ୍ତୁ"</string>
+    <string name="pointer_location" msgid="6084434787496938001">"ପଏଣ୍ଟର୍‌ ଲୋକେଶନ୍‌"</string>
+    <string name="pointer_location_summary" msgid="840819275172753713">"ଏବେର ଟଚ୍‌ ଡାଟା ଦେଖାଉଥିବା ସ୍କ୍ରୀନ୍‌ ଓଭର୍‌ଲେ"</string>
+    <string name="show_touches" msgid="2642976305235070316">"ଟାପ୍‌ଗୁଡ଼ିକୁ ଦେଖାଅ"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"ଟାପ୍ସ ପାଇଁ ଦୃଶ୍ୟ ମତାମତ ଦେଖାଅ"</string>
+    <string name="show_screen_updates" msgid="5470814345876056420">"ସର୍ଫେସ୍‌ ଅପ୍‌ଡେଟ୍‌ ଦେଖାଅ"</string>
+    <string name="show_screen_updates_summary" msgid="2569622766672785529">"ସମଗ୍ର ୱିଣ୍ଡୋ ପୃଷ୍ଠ ଅପଡେଟ୍‌ ହେବା ବେଳେ ସେଗୁଡ଼ିକ ଫ୍ଲାସ୍‌ କରନ୍ତୁ"</string>
+    <string name="show_hw_screen_updates" msgid="5036904558145941590">"GPU ଭ୍ୟୁ ଅପଡେଟ୍‌ ଦେଖନ୍ତୁ"</string>
+    <string name="show_hw_screen_updates_summary" msgid="1115593565980196197">"GPU ସହ ଅଙ୍କାଯାଇଥିବା ବେଳେ ୱିଣ୍ଡୋ ଭିତରେ ଦୃଶ୍ୟଗୁଡ଼ିକ ଫ୍ଲାଶ କରନ୍ତୁ"</string>
+    <string name="show_hw_layers_updates" msgid="5645728765605699821">"ହାର୍ଡୱେର୍‌ ଲେୟର୍‌ର ଅପଡେଟଗୁଡ଼ିକ ଦେଖାନ୍ତୁ"</string>
+    <string name="show_hw_layers_updates_summary" msgid="5296917233236661465">"ହାର୍ଡୱେୟାର ଲେୟାରଗୁଡିକ ଅପଡେଟ୍‌ ହେବା ବେଳେ ସେଗୁଡିକ ସବୁଜ ଫ୍ଲାସ୍‌ କରନ୍ତୁ"</string>
+    <string name="debug_hw_overdraw" msgid="2968692419951565417">"GPU ଓଭର୍‌ଡ୍ର ଡିବଗ୍‌ କର"</string>
+    <string name="disable_overlays" msgid="2074488440505934665">"HW ଓଭରଲେସ ଅକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="disable_overlays_summary" msgid="3578941133710758592">"ସ୍କ୍ରୀନ୍‌ କମ୍ପୋଜିଟିଙ୍ଗ ପାଇଁ ସର୍ବଦା GPU ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="simulate_color_space" msgid="6745847141353345872">"ରଙ୍ଗ ସ୍ଥାନ ଅନୁକରଣ କରନ୍ତୁ"</string>
+    <string name="enable_opengl_traces_title" msgid="6790444011053219871">"OpenGL ଟ୍ରେସ୍‌ ସକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="usb_audio_disable_routing" msgid="8114498436003102671">"USB ଅଡିଓ ରାଉଟିଙ୍ଗ ଅକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="usb_audio_disable_routing_summary" msgid="980282760277312264">"USB ଅଡିଓ ଉପକରଣଗୁଡ଼ିକୁ ଅଟୋମେଟିକ୍ ରୂଟିଙ୍ଗ ଅକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="debug_layout" msgid="5981361776594526155">"ଲେଆଉଟ୍‌ ବାଉଣ୍ଡ ଦେଖାଅ"</string>
+    <string name="debug_layout_summary" msgid="2001775315258637682">"କ୍ଲିପ୍‌ ବାଉଣ୍ଡ, ମାର୍ଜିନ୍‌ ଆଦି ଦେଖନ୍ତୁ"</string>
+    <string name="force_rtl_layout_all_locales" msgid="2259906643093138978">"RTL ଲେଆଉଟ୍ ଦିଗ ବାଧ୍ୟ କରନ୍ତୁ"</string>
+    <string name="force_rtl_layout_all_locales_summary" msgid="9192797796616132534">"ସମସ୍ତ ଲୋକେଲ୍‌ ପାଇଁ ସ୍କ୍ରିନ୍‌ ଲେଆଉଟ୍‌ ଦିଗ ଡାହାଣରୁ ବାମକୁ ବାଧ୍ୟ କରନ୍ତୁ"</string>
+    <string name="force_hw_ui" msgid="6426383462520888732">"GPU ରେଣ୍ଡରିଂ ବାଧ୍ୟ କରନ୍ତୁ"</string>
+    <string name="force_hw_ui_summary" msgid="5535991166074861515">"2D ଅଙ୍କନ ପାଇଁ ଜିପିୟୁର ବ୍ୟବହାର ଉପରେ ଜୋର ଦେବା"</string>
+    <string name="force_msaa" msgid="7920323238677284387">"4x MSAA ବାଧ୍ୟ କରନ୍ତୁ"</string>
+    <string name="force_msaa_summary" msgid="9123553203895817537">"OpenGL ES 2.0 ଆପ୍‌ରେ 4x MSAA ସକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="show_non_rect_clip" msgid="505954950474595172">"ଅଣ-ଆୟତାକାର କ୍ଲିପ୍‌ କାର୍ଯ୍ୟକୁ ଡିବଗ୍‌ କରନ୍ତୁ"</string>
+    <string name="track_frame_time" msgid="6146354853663863443">"ପ୍ରୋଫାଇଲ୍‌ GPU ରେଣ୍ଡରିଂ"</string>
+    <string name="enable_gpu_debug_layers" msgid="3848838293793255097">"GPU ଡିବଗ୍‌ ଲେୟର୍‌ ସକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="enable_gpu_debug_layers_summary" msgid="8009136940671194940">"ଡିବଗ୍‌ ଆପ୍‌ଗୁଡ଼ିକ ପାଇଁ GPU ଡିବଗ୍‌ ଲେୟର୍‌ ଲୋଡ୍ କରିବାର ଅନୁମତି ଦିଅନ୍ତୁ"</string>
+    <string name="window_animation_scale_title" msgid="6162587588166114700">"ୱିଣ୍ଡୋ ଆନିମେଶନ୍‌ ସ୍କେଲ୍‌"</string>
+    <string name="transition_animation_scale_title" msgid="387527540523595875">"ଟ୍ରାଞ୍ଜିସନ୍‌ ଆନିମେସନ୍‌ ସ୍କେଲ୍‌"</string>
+    <string name="animator_duration_scale_title" msgid="3406722410819934083">"ଆନିମେଟର୍‌ ଅବଧି ସ୍କେଲ୍‌"</string>
+    <string name="overlay_display_devices_title" msgid="5364176287998398539">"ମଧ୍ୟମ ଡିସ୍‌ପ୍ଲେର ଛଳନା କରନ୍ତୁ"</string>
+    <string name="debug_applications_category" msgid="4206913653849771549">"ଆପ୍‌ଗୁଡ଼ିକ"</string>
+    <string name="immediately_destroy_activities" msgid="1579659389568133959">"କାର୍ଯ୍ୟକଳାପଗୁଡ଼ିକୁ ରଖନ୍ତୁ ନାହିଁ"</string>
+    <string name="immediately_destroy_activities_summary" msgid="3592221124808773368">"ଉପଯୋଗକର୍ତ୍ତା ଏହାକୁ ଛାଡ଼ିବା କ୍ଷଣି ସମସ୍ତ କାର୍ଯ୍ୟକଳାପକୁ ନଷ୍ଟ କରିଦିଅନ୍ତୁ"</string>
+    <string name="app_process_limit_title" msgid="4280600650253107163">"ପୃଷ୍ଠପଟ ପ୍ରକ୍ରିୟା ସୀମା"</string>
+    <string name="show_all_anrs" msgid="28462979638729082">"ସମସ୍ତ ANRs ଦେଖାଦେଉ"</string>
+    <string name="show_all_anrs_summary" msgid="641908614413544127">"ବ୍ୟାକ୍‌ଗ୍ରାଉଣ୍ଡ ଆପ୍‌ଗୁଡ଼ିକ ପାଇଁ \"ଆପ୍‌ ଉତ୍ତର ଦେଉନାହିଁ\" ଡାୟଲଗ୍‌ ଦେଖାଅ"</string>
+    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"ବିଜ୍ଞପ୍ତି ଚାନେଲ୍‌ ଚେତାବନୀ ଦେଖାଦେଉ"</string>
+    <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"ଏକ ବୈଧ ଚ୍ୟାନେଲ୍‌ ବିନା ଏକ ଆପ୍‌ ଗୋଟିଏ ବିଜ୍ଞପ୍ତି ପୋଷ୍ଠ କରିବା ବେଳେ ଅନ୍‌-ସ୍କ୍ରୀନ୍‌ ସତର୍କତା ଦେଖାଏ"</string>
+    <string name="force_allow_on_external" msgid="3215759785081916381">"ଏକ୍ସଟର୍ନଲ୍ ଆପ୍‌ଗୁଡ଼ିକୁ ଜବରଦସ୍ତି ଅନୁମତି ଦିଅନ୍ତୁ"</string>
+    <string name="force_allow_on_external_summary" msgid="3640752408258034689">"ଯେକୌଣସି ଆପ୍‌କୁ ଏକ୍ସଟର୍ନଲ୍ ଷ୍ଟୋରେଜ୍‌ରେ ଲେଖାଯୋଗ୍ୟ କରନ୍ତୁ, ମେନିଫେଷ୍ଟ ମୂଲ୍ୟ ଯାହା ହୋଇଥାଉ ନା କାହିଁକି"</string>
+    <string name="force_resizable_activities" msgid="8615764378147824985">"ଆକାର ବଦଳାଇବା ପାଇଁ କାର୍ଯ୍ୟକଳାପକୁ ବାଧ୍ୟ କରନ୍ତୁ"</string>
+    <string name="force_resizable_activities_summary" msgid="6667493494706124459">"ସ୍ପଷ୍ଟ ଭାଲ୍ୟୁର ଚିନ୍ତା ନକରି ମଲ୍ଟୀ-ୱିଣ୍ଡୋ ପାଇଁ ସମସ୍ତ କାର୍ଯ୍ୟ ବଦଳାଇବାଯୋଗ୍ୟ କରନ୍ତୁ"</string>
+    <string name="enable_freeform_support" msgid="1461893351278940416">"ଫ୍ରୀଫର୍ମ ୱିଣ୍ଡୋ ସକ୍ଷମ କର"</string>
+    <string name="enable_freeform_support_summary" msgid="8247310463288834487">"ପରୀକ୍ଷାମୂଳକ ଫ୍ରୀଫର୍ମ ୱିଣ୍ଡୋସ୍‌ ପାଇଁ ସପୋର୍ଟ ସକ୍ଷମ କରନ୍ତୁ।"</string>
+    <string name="local_backup_password_title" msgid="3860471654439418822">"ଡେସ୍କଟପ୍‌ ବ୍ୟାକ୍‌ଅପ୍‌ର ପାସ୍‌ୱର୍ଡ"</string>
+    <string name="local_backup_password_summary_none" msgid="6951095485537767956">"ଡେସ୍କଟପ୍‌ ପୂର୍ଣ୍ଣ ବ୍ୟାକ୍‌ଅପ୍‌ଗୁଡ଼ିକ ବର୍ତ୍ତମାନ ସୁରକ୍ଷିତ ନୁହେଁ"</string>
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"ଡେସ୍କଟପ୍‌ର ସମ୍ପୂର୍ଣ୍ଣ ବ୍ୟାକ୍‌ଅପ୍‌ ପାଇଁ ପାସ୍‌ୱର୍ଡ ବଦଳାଇବା କିମ୍ୱା କାଢ଼ିଦେବା ନିମନ୍ତେ ଟାପ୍‌ କରନ୍ତୁ"</string>
+    <string name="local_backup_password_toast_success" msgid="582016086228434290">"ନୂଆ ବ୍ୟାକ୍‌ଅପ୍‌ ପାସ୍‌ୱର୍ଡ ସେଟ୍‌ କରିଦିଆଗଲା"</string>
+    <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"ନୂଆ ପାସ୍‌ୱର୍ଡ ଓ ସୁନିଶ୍ଚିତତା ମେଳ ହେଉନାହିଁ"</string>
+    <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"ବ୍ୟାକ୍‌ଅପ୍‌ ପାସ୍‌ୱର୍ଡ ସେଟିଙ୍ଗ ବିଫଳ ହୋଇଛି"</string>
+  <string-array name="color_mode_names">
+    <item msgid="2425514299220523812">"ଜୀବନ୍ତ (ପୂର୍ବ-ନିର୍ଦ୍ଧାରିତ)"</item>
+    <item msgid="8446070607501413455">"ପ୍ରାକୃତିକ"</item>
+    <item msgid="6553408765810699025">"ମାନକ"</item>
+  </string-array>
+  <string-array name="color_mode_descriptions">
+    <item msgid="4979629397075120893">"ବର୍ଦ୍ଧିତ ରଙ୍ଗ"</item>
+    <item msgid="8280754435979370728">"ଆଖି ଦ୍ୱାରା ଦେଖାଯାଇଥିବା ପରି ପ୍ରାକୃତିକ ରଙ୍ଗ"</item>
+    <item msgid="5363960654009010371">"ଡିଜିଟାଲ୍‌ କଣ୍ଟେଣ୍ଟ ପାଇଁ ରଙ୍ଗଗୁଡ଼ିକ ଅନୁକୂଳିତ ହୋଇଛି"</item>
+  </string-array>
+    <!-- no translation found for inactive_apps_title (9042996804461901648) -->
+    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"ନିଷ୍କ୍ରିୟ। ଟୋଗଲ୍‌ କରିବାକୁ ଟାପ୍‌ କରନ୍ତୁ।"</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"ସକ୍ରିୟ। ବଦଳାଇବା ପାଇଁ ଟାପ୍‌ କରନ୍ତୁ"</string>
+    <!-- no translation found for standby_bucket_summary (6567835350910684727) -->
+    <skip />
+    <string name="runningservices_settings_title" msgid="8097287939865165213">"ଚାଲୁଥିବା ସେବାଗୁଡ଼ିକ"</string>
+    <string name="runningservices_settings_summary" msgid="854608995821032748">"ଏବେ ଚାଲୁଥିବା ସେବାଗୁଡ଼ିକୁ ଦେଖନ୍ତୁ ଓ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ"</string>
+    <string name="select_webview_provider_title" msgid="4628592979751918907">"ୱେବ୍‌ଦୃଶ୍ୟ ପ୍ରୟୋଗ"</string>
+    <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView କାର୍ଯ୍ୟକାରିତାକୁ ସେଟ୍‍ କରନ୍ତୁ"</string>
+    <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"ଏହି ପସନ୍ଦ ଆଉ ମାନ୍ୟ ନାହିଁ। ପୁଣିଥରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
+    <string name="convert_to_file_encryption" msgid="3060156730651061223">"ଫାଇଲ ଏନକ୍ରିପ୍ସନକୁ ବଦଳାଅ"</string>
+    <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"ବଦଳାନ୍ତୁ…"</string>
+    <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"ଫାଇଲ୍‌ ଏନ୍‌କ୍ରିପ୍ଟ ହୋଇସାରିଲାଣି"</string>
+    <string name="title_convert_fbe" msgid="1263622876196444453">"ଫାଇଲ୍‌ ଭିତ୍ତିକ ଏନ୍‌କ୍ରିପ୍ସନ୍‌ ପାଇଁ ବଦଳାଉଛି"</string>
+    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"ଫାଇଲ୍‌ ଭିତ୍ତିକ ଏନ୍‌କ୍ରିପ୍ସନ୍‌ରେ ଡାଟା ପାର୍ଟିଶନ୍‌ ବଦଳାନ୍ତୁ।\n !!ଚେତାବନୀ!! ଏହା ଆପଣଙ୍କର ସମସ୍ତ ଡାଟା ଉଡ଼ାଇଦେବ।\n ଏହି ବୈଶିଷ୍ଟ୍ୟ ହେଉଛି ଆଲ୍‌ଫା ଏବଂ ଠିକ ଭାବେ କାମ କରିନପାରେ।\n ଜାରି ରଖିବା ପାଇଁ \"ୱାଇପ୍‌ ଓ କନ୍‌ଭର୍ଟ…\" ଦାବନ୍ତୁ"</string>
+    <string name="button_convert_fbe" msgid="5152671181309826405">"ଲିଭାନ୍ତୁ ଏବଂ ବଦଳାନ୍ତୁ…"</string>
+    <string name="picture_color_mode" msgid="4560755008730283695">"ପିକ୍‌ଚର୍‌ ରଙ୍ଗ ମୋଡ୍"</string>
+    <string name="picture_color_mode_desc" msgid="1141891467675548590">"sRGB ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="daltonizer_mode_disabled" msgid="7482661936053801862">"ଅକ୍ଷମ ହୋଇଛି"</string>
+    <string name="daltonizer_mode_monochromacy" msgid="8485709880666106721">"ସମ୍ପୂର୍ଣ୍ଣ ବର୍ଣ୍ଣାନ୍ଧତା"</string>
+    <string name="daltonizer_mode_deuteranomaly" msgid="5475532989673586329">"ବର୍ଣ୍ଣାନ୍ଧତା (ନାଲି-ସବୁଜ)"</string>
+    <string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"ପ୍ରୋଟାନୋମାଲି (ଲାଲ୍‌-ସବୁଜ)"</string>
+    <string name="daltonizer_mode_tritanomaly" msgid="481725854987912389">"Tritanomaly (ନୀଳ-ହଳଦିଆ)"</string>
+    <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ରଙ୍ଗ ସଠିକତା"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ଏହି ପରୀକ୍ଷାମୂଳକ ବୈଶିଷ୍ଟ୍ୟ ପର୍ଫର୍ମେନ୍ସକୁ ପ୍ରଭାବିତ କରିପାରେ।"</string>
+    <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ଦ୍ୱାରା ଓଭର୍‌ରାଇଡ୍‌ କରାଯାଇଛି"</string>
+    <string name="power_remaining_duration_only" msgid="845431008899029842">"ପ୍ରାୟ <xliff:g id="TIME">%1$s</xliff:g> ଅବଶିଷ୍ଟ ରହିଛି"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="5992456722677973678">"ଆପଣଙ୍କ ବ୍ୟବହାରକୁ ଆଧାର କରି ପ୍ରାୟ <xliff:g id="TIME">%1$s</xliff:g> ଅବଶିଷ୍ଟ"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"ସମ୍ପୂର୍ଣ୍ଣ ଚାର୍ଜ ହେବାପାଇଁ <xliff:g id="TIME">%1$s</xliff:g> ଅବଶିଷ୍ଟ ଅଛି"</string>
+    <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> ଅବଶିଷ୍ଟ"</string>
+    <!-- no translation found for power_remaining_less_than_duration_only (5996752448813295329) -->
+    <skip />
+    <!-- no translation found for power_remaining_less_than_duration (7967078125657859046) -->
+    <skip />
+    <!-- no translation found for power_remaining_more_than_subtext (6846716609975752316) -->
+    <skip />
+    <!-- no translation found for power_remaining_only_more_than_subtext (8884488700395194194) -->
+    <skip />
+    <!-- no translation found for power_remaining_duration_only_shutdown_imminent (8168317165722752881) -->
+    <skip />
+    <!-- no translation found for power_remaining_duration_only_shutdown_imminent (5957064378548718872) -->
+    <skip />
+    <!-- no translation found for power_remaining_duration_only_shutdown_imminent (9055596817716471373) -->
+    <skip />
+    <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ପ୍ରାୟ <xliff:g id="TIME">%2$s</xliff:g> ଅବଶିଷ୍ଟ ରହିଛି"</string>
+    <string name="power_discharging_duration_enhanced" msgid="4401782117770255046">"<xliff:g id="LEVEL">%1$s</xliff:g> - ଆପଣଙ୍କ ବ୍ୟବହାରକୁ ଆଧାର କରି ପ୍ରାୟ <xliff:g id="TIME">%2$s</xliff:g> ଅବଶିଷ୍ଟ"</string>
+    <!-- no translation found for power_remaining_duration_shutdown_imminent (7679005631124015335) -->
+    <skip />
+    <!-- no translation found for power_remaining_duration_shutdown_imminent (261050880878965621) -->
+    <skip />
+    <!-- no translation found for power_remaining_duration_shutdown_imminent (2020049829798578618) -->
+    <skip />
+    <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ପୂର୍ଣ୍ଣ ଚାର୍ଜ ହେବା ପର୍ଯ୍ୟନ୍ତ"</string>
+    <string name="battery_info_status_unknown" msgid="196130600938058547">"ଅଜ୍ଞାତ"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"ଚାର୍ଜ ହେଉଛି"</string>
+    <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ଚାର୍ଜ ହେଉଛି"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"ଚାର୍ଜ ହେଉନାହିଁ"</string>
+    <string name="battery_info_status_not_charging" msgid="8523453668342598579">"ପ୍ଲଗ୍‌ରେ ଲାଗିଛି, ହେଲେ ଏବେ ଚାର୍ଜ କରିପାରିବ ନାହିଁ"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"ସମ୍ପୂର୍ଣ୍ଣ"</string>
+    <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"ଆଡ୍‌ମିନ୍‌ ଦ୍ୱାରା ନିୟନ୍ତ୍ରିତ"</string>
+    <string name="enabled_by_admin" msgid="5302986023578399263">"ଆଡମିନ୍‌ଙ୍କ ଦ୍ୱାରା ସକ୍ଷମ କରାଯାଇଛି"</string>
+    <string name="disabled_by_admin" msgid="8505398946020816620">"ଆଡ୍‌ମିନ୍‌ ଦ୍ଵାରା ଅକ୍ଷମ କରାଯାଇଛି"</string>
+    <string name="disabled" msgid="9206776641295849915">"ଅକ୍ଷମ ହୋଇଛି"</string>
+    <string name="external_source_trusted" msgid="2707996266575928037">"ଅନୁମୋଦିତ"</string>
+    <string name="external_source_untrusted" msgid="2677442511837596726">"ଅନୁମତି ନାହିଁ"</string>
+    <string name="install_other_apps" msgid="6986686991775883017">"ଅଜଣା ଆପ୍‌ଗୁଡଡ଼ିକ ଇନ୍‌ଷ୍ଟଲ୍‌ କର"</string>
+    <string name="home" msgid="3256884684164448244">"ସେଟିଙ୍ଗ ହୋମ୍‌"</string>
+  <string-array name="battery_labels">
+    <item msgid="8494684293649631252">"0%"</item>
+    <item msgid="8934126114226089439">"୫୦%"</item>
+    <item msgid="1286113608943010849">"୧୦୦%"</item>
+  </string-array>
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> ପୂର୍ବେ"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> ଅବଶିଷ୍ଟ"</string>
+    <string name="screen_zoom_summary_small" msgid="5867245310241621570">"ଛୋଟ"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ଡିଫଲ୍ଟ"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"ବଡ"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"ବୃହତ୍ତମ"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"ବୃହତ୍ତମ"</string>
+    <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"କଷ୍ଟମ୍‌ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
+    <string name="help_feedback_label" msgid="6815040660801785649">"ସହାୟତା ଓ ମତାମତ"</string>
+    <string name="content_description_menu_button" msgid="8182594799812351266">"ମେନୁ"</string>
+    <string name="retail_demo_reset_message" msgid="118771671364131297">"ଡେମୋ ମୋଡ୍‌ରେ ଫ୍ୟାକ୍ଟୋରୀ ରିସେଟ୍‌ କରିବାକୁ ପାସ୍‌ୱାର୍ଡ ଲେଖନ୍ତୁ"</string>
+    <string name="retail_demo_reset_next" msgid="8356731459226304963">"ପରବର୍ତ୍ତୀ"</string>
+    <string name="retail_demo_reset_title" msgid="696589204029930100">"ପାସ୍‌ୱର୍ଡ ଆବଶ୍ୟକ"</string>
+    <string name="active_input_method_subtypes" msgid="3596398805424733238">"ସକ୍ରିୟ ଇନପୁଟ୍‌-ପଦ୍ଧତିଗୁଡ଼ିକ"</string>
+    <string name="use_system_language_to_select_input_method_subtypes" msgid="5747329075020379587">"ସିଷ୍ଟମ୍‌ ଭାଷା ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="failed_to_open_app_settings_toast" msgid="1251067459298072462">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> ପାଇଁ ସେଟିଙ୍ଗ ଖୋଲିବାରେ ବିଫଳ"</string>
+    <string name="ime_security_warning" msgid="4135828934735934248">"ଏହି ଇନ୍‌ପୁଟ୍‌ ପଦ୍ଧତି, ପାସ୍‌ୱର୍ଡ ଓ କ୍ରେଡିଟ୍‌ କାର୍ଡ ନମ୍ୱର୍‌ ଭଳି ବ୍ୟକ୍ତିଗତ ଡାଟା ସମେତ ଆପଣ ଟାଇପ୍‌ କରିଥିବା ସମସ୍ତ ଅକ୍ଷର ସଂଗହ କରିପାରେ।ଏହା, <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> ଆପ୍‌ରୁ ଆସିଛି| ଏହି ଇନ୍‌ପୁଟ୍‌ ପଦ୍ଧତି ବ୍ୟବହାର କରିବେ?"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7870273558547549125">"ଧ୍ୟାନଦିଅନ୍ତୁ: ରିବୁଟ୍‌ କରିବା ପରେ, ଆପଣଙ୍କ ଫୋନ୍‌ ଅନଲକ୍‌ ନହେବା ପର୍ଯ୍ୟନ୍ତ ଏହି ଆପ୍‌ ଆରମ୍ଭ ହୋଇପାରିବ ନାହିଁ"</string>
+    <string name="ims_reg_title" msgid="7609782759207241443">"IMS ପଞ୍ଜିକରଣ ସ୍ଥିତି"</string>
+    <string name="ims_reg_status_registered" msgid="933003316932739188">"ପଞ୍ଜିକୃତ"</string>
+    <string name="ims_reg_status_not_registered" msgid="6529783773485229486">"ପଞ୍ଜିକୃତ ହୋଇନାହିଁ"</string>
+    <string name="status_unavailable" msgid="7862009036663793314">"ଉପଲବ୍ଧ ନାହିଁ"</string>
+    <!-- no translation found for wifi_tether_connected_summary (3871603864314407780) -->
+    <!-- no translation found for accessibility_manual_zen_more_time (1636187409258564291) -->
+    <skip />
+    <!-- no translation found for accessibility_manual_zen_less_time (6590887204171164991) -->
+    <skip />
+    <!-- no translation found for zen_mode_enable_dialog_turn_on (8287824809739581837) -->
+    <skip />
+    <string name="cancel" msgid="6859253417269739139">"କ୍ୟାନ୍ସଲ୍"</string>
+    <!-- no translation found for zen_mode_settings_turn_on_dialog_title (2297134204747331078) -->
+    <skip />
+    <string name="zen_mode_settings_summary_off" msgid="6119891445378113334">"କଦାପି ନୁହେଁ"</string>
+    <!-- no translation found for zen_interruption_level_priority (2078370238113347720) -->
+    <skip />
+    <!-- no translation found for zen_mode_and_condition (4927230238450354412) -->
+    <skip />
+    <!-- no translation found for zen_alarm_warning_indef (3007988140196673193) -->
+    <skip />
+    <!-- no translation found for zen_alarm_warning (6236690803924413088) -->
+    <skip />
+    <!-- no translation found for alarm_template (4996153414057676512) -->
+    <skip />
+    <!-- no translation found for alarm_template_far (3779172822607461675) -->
+    <skip />
+</resources>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index bfea9a8..6549861 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"ਸਿਮ ਪਹੁੰਚ"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ਆਡੀਓ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ਆਡੀਓ"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"ਸੁਣਨ ਦਾ ਸਾਧਨ"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"ਸੁਣਨ ਦੇ ਸਾਧਨ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"ਮੀਡੀਆ  ਆਡੀਓ  ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ਫ਼ੋਨ ਔਡੀਓ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ਫਾਈਲ ਟ੍ਰਾਂਸਫ਼ਰ ਸਰਵਰ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ਫ਼ੋਨ ਔਡੀਓ ਲਈ ਵਰਤੋ"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ਫਾਈਲ ਟ੍ਰਾਂਸਫਰ ਲਈ ਵਰਤੋ"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ਇਨਪੁਟ ਲਈ ਵਰਤੋ"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"ਸੁਣਨ ਦੇ ਸਾਧਨ ਲਈ ਵਰਤੋ"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"ਪੇਅਰ ਕਰੋ"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ਪੇਅਰ ਕਰੋ"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"ਰੱਦ ਕਰੋ"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index fd177e5..55e43089 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Dostop do kartice SIM"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Zvok visoke kakovosti: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Zvok visoke kakovosti"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Slušni pripomoček"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Povezava s slušnim pripomočkom je vzpostavljena"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Povezan s profilom za predstavnostni zvok"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Povezava s profilom za zvok telefona vzpostavljena"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Povezava s strežnikom za prenos datotek je vzpostavljena"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Uporabi za zvok telefona"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Uporabi za prenos datotek"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Uporabi za vnos"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Uporaba za slušni pripomoček"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Seznani"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"SEZNANI"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Prekliči"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index cf0fe12..5524e2c 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Qasje në kartën SIM"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Audio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Audio HD"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Aparati i dëgjimit"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Lidhur me aparatin e dëgjimit"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"U lidh me audion e medias"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"U lidh me audion e telefonit"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"U lidh me serverin e transferimit të skedarëve"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Përdor për audion e telefonit"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Përdor për transferimin e skedarëve"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Përdore për hyrjen"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Përdore për aparatin e dëgjimit"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Çifto"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ÇIFTO"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Anulo"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 4509470..d8c6e4d 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM-åtkomst"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD-ljud: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD-ljud"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Hörapparat"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Ansluten till hörapparat"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Ansluten till medialjud"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Ansluten till telefonens ljud"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Ansluten till filöverföringsserver"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Använd för telefonens ljud"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Använd för filöverföring"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Använd för inmatning"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Använd med hörapparat"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Parkoppling"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"PARKOPPLA"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Avbryt"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 274222b..b417cfb 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"சிம் அணுகல்"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ஆடியோ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ஆடியோ"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"செவித்துணைக் கருவி"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"செவித்துணைக் கருவியுடன் இணைக்கப்பட்டிருக்கும்போது"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"மீடியா ஆடியோவுடன் இணைக்கப்பட்டது"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"மொபைல் ஆடியோவுடன் இணைக்கப்பட்டது"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"கோப்பைப் பரிமாற்றும் சேவையகத்துடன் இணைக்கப்பட்டது"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"மொபைல் ஆடியோவைப் பயன்படுத்து"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"கோப்பு பரிமாற்றத்திற்காகப் பயன்படுத்து"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"உள்ளீட்டுக்குப் பயன்படுத்து"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"செவித்துணைக் கருவிக்காகப் பயன்படுத்து"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"இணை"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"இணை"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"ரத்துசெய்"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 31f0cdf..99a35a3 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM యాక్సెస్"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ఆడియో: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ఆడియో"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"వినికిడి పరికరం"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"వినికిడి పరికరానికి కనెక్ట్ చేస్తోంది"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"మీడియా ఆడియోకు కనెక్ట్ చేయబడింది"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"ఫోన్ ఆడియోకు కనెక్ట్ చేయబడింది"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"ఫైల్ బదిలీ సర్వర్‌కు కనెక్ట్ చేయబడింది"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"ఫోన్ ఆడియో కోసం ఉపయోగించు"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"ఫైల్ బదిలీ కోసం ఉపయోగించు"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ఇన్‌పుట్ కోసం ఉపయోగించు"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"వినికిడి పరికరం కోసం ఉపయోగించు"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"జత చేయి"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"జత చేయి"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"రద్దు చేయి"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 1985bda..9fdeb4a 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM Erişimi"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ses: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ses"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"İşitme Cihazı"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"İşitme Cihazına bağlandı"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Medya sesine bağlanıldı"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Telefon sesine bağlandı"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Dosya aktarım sunucusuna bağlandı"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Telefon sesi için kullan"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Dosya aktarımı için kullan"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Giriş için kullan"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"İşitme Cihazı için kullan"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Eşle"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"EŞLE"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"İptal"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 90c77741..7c221d7 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"‏SIM رسائی"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"‏HD آڈیو: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"‏HD آڈیو"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"سماعتی آلہ"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"سماعتی آلے سے منسلک"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"میڈیا آڈیو سے مربوط"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"فون آڈیو سے مربوط"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"فائل منتقلی سرور سے مربوط ہو گیا ہے"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"فون آڈیو کیلئے استعمال کریں"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"فائل منتقل کرنے کیلئے استعمال کریں"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"ان پٹ کیلئے استعمال"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"سماعتی آلے کیلئے استعمال کریں"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"جوڑا بنائیں"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"جوڑا بنائیں"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"منسوخ کریں"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index e37ab74..74bac0a 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Quyền truy cập SIM"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Âm thanh HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Âm thanh HD"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Trợ thính"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"Đã kết nối với thiết bị trợ thính"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Đã kết nối với âm thanh phương tiện"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Đã kết nối với âm thanh điện thoại"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Đã kết nối với máy chủ chuyển tệp"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Sử dụng cho âm thanh điện thoại"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Sử dụng để chuyển tệp"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Sử dụng để nhập"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"Sử dụng cho thiết bị trợ thính"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Ghép nối"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"GHÉP NỐI"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Hủy"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 89edf54..3590ace 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM 卡存取权限"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD 音频:<xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD 音频"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"助听器"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"已连接到助听器"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"已连接到媒体音频"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"已连接到手机音频"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"已连接到文件传输服务器"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"用于手机音频"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"用于文件传输"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"用于输入"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"用于助听器"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"配对"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"配对"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"取消"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 9b0ec86..f2162f4 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM 卡存取"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"高清音訊:<xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"高清音訊"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"助聽器"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"已連線至助聽器"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"已連接媒體音頻裝置"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"已連接手機耳機"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"已連線至檔案傳輸伺服器"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"用於手機音效"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"用於傳輸檔案"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"用於輸入"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"用於助聽器"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"配對"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"配對"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"取消"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 1d6b4b9..fa3001a 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -75,10 +75,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM 卡存取權"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD 高解析音訊:<xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD 高解析音訊"</string>
-    <!-- no translation found for bluetooth_profile_hearing_aid (7999237886427812595) -->
-    <skip />
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_connected (7188282786730266159) -->
-    <skip />
+    <string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"助聽器"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="7188282786730266159">"已連接到助聽器"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"連接至媒體音訊"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"連接至電話音訊"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"已連線到檔案傳輸伺服器"</string>
@@ -95,8 +93,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"用於電話音訊"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"用於傳輸檔案"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"用於輸入"</string>
-    <!-- no translation found for bluetooth_hearing_aid_profile_summary_use_for (908775281788309484) -->
-    <skip />
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="908775281788309484">"用於助聽器"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"配對"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"配對"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"取消"</string>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index c78f454..a75b147 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -553,7 +553,7 @@
     <string name="select_private_dns_configuration_title">Private DNS</string>
     <string name="select_private_dns_configuration_dialog_title">Select Private DNS Mode</string>
     <string name="private_dns_mode_off">Off</string>
-    <string name="private_dns_mode_opportunistic">Opportunistic</string>
+    <string name="private_dns_mode_opportunistic">Automatic</string>
     <string name="private_dns_mode_provider">Private DNS provider hostname</string>
     <string name="private_dns_mode_provider_hostname_hint">Enter hostname of DNS provider</string>
 
@@ -876,47 +876,53 @@
     <!-- Summary shown for color space correction preference when its value is overridden by another preference [CHAR LIMIT=35] -->
     <string name="daltonizer_type_overridden">Overridden by <xliff:g id="title" example="Simulate color space">%1$s</xliff:g></string>
 
-  <!-- [CHAR_LIMIT=40] Label for estimated remaining duration of battery discharging -->
-  <string name="power_remaining_duration_only">About <xliff:g id="time">%1$s</xliff:g> left</string>
-  <!-- [CHAR_LIMIT=60] Label for estimated remaining duration of battery discharging -->
-  <string name="power_remaining_duration_only_enhanced">About <xliff:g id="time">%1$s</xliff:g> left based on your usage</string>
-  <!-- [CHAR_LIMIT=40] Label for estimated remaining duration of battery charging -->
-  <string name="power_remaining_charging_duration_only"><xliff:g id="time">%1$s</xliff:g> left until fully charged</string>
+    <!-- [CHAR_LIMIT=40] Label for estimated remaining duration of battery discharging -->
+    <string name="power_remaining_duration_only">About <xliff:g id="time">%1$s</xliff:g> left</string>
+    <!-- [CHAR_LIMIT=40] Label for battery level chart when discharging with duration -->
+    <string name="power_discharging_duration">About <xliff:g id="time">%1$s</xliff:g> left (<xliff:g id="level">%2$s</xliff:g>)</string>
+    <!-- [CHAR_LIMIT=60] Label for estimated remaining duration of battery discharging -->
+    <string name="power_remaining_duration_only_enhanced">About <xliff:g id="time">%1$s</xliff:g> left based on your usage</string>
+    <!-- [CHAR_LIMIT=60] Label for battery level chart when discharging with duration and using enhanced estimate -->
+    <string name="power_discharging_duration_enhanced">About <xliff:g id="time">%1$s</xliff:g> left based on your usage (<xliff:g id="level">%2$s</xliff:g>)</string>
+    <!-- [CHAR_LIMIT=40] Short label for estimated remaining duration of battery charging/discharging -->
+    <string name="power_remaining_duration_only_short"><xliff:g id="time">%1$s</xliff:g> left</string>
 
-  <!-- [CHAR_LIMIT=40] Short label for estimated remaining duration of battery charging/discharging -->
-  <string name="power_remaining_duration_only_short"><xliff:g id="time">%1$s</xliff:g> left</string>
+    <!-- [CHAR_LIMIT=100] Label for enhanced estimated time that phone will run out of battery -->
+    <string name="power_discharge_by_enhanced">Will last until about about <xliff:g id="time">%1$s</xliff:g> based on your usage (<xliff:g id="level">%2$s</xliff:g>)</string>
+    <!-- [CHAR_LIMIT=100] Label for enhanced estimated time that phone will run out of battery with no percentage -->
+    <string name="power_discharge_by_only_enhanced">Will last until about about <xliff:g id="time">%1$s</xliff:g> based on your usage</string>
+    <!-- [CHAR_LIMIT=100] Label for estimated time that phone will run out of battery -->
+    <string name="power_discharge_by">Will last until about about <xliff:g id="time">%1$s</xliff:g> (<xliff:g id="level">%2$s</xliff:g>)</string>
+    <!-- [CHAR_LIMIT=100] Label for estimated time that phone will run out of battery -->
+    <string name="power_discharge_by_only">Will last until about about <xliff:g id="time">%1$s</xliff:g></string>
 
-  <!-- [CHAR_LIMIT=60] label for estimated remaining duration of battery when under a certain amount -->
-  <string name="power_remaining_less_than_duration_only">Less than <xliff:g id="threshold">%1$s</xliff:g> remaining</string>
-  <!-- [CHAR_LIMIT=60] label for estimated remaining duration of battery when under a certain amount with the percentage -->
-  <string name="power_remaining_less_than_duration"><xliff:g id="level">%1$s</xliff:g> - Less than <xliff:g id="threshold">%2$s</xliff:g> remaining</string>
+    <!-- [CHAR_LIMIT=60] label for estimated remaining duration of battery when under a certain amount -->
+    <string name="power_remaining_less_than_duration_only">Less than <xliff:g id="threshold">%1$s</xliff:g> remaining</string>
+    <!-- [CHAR_LIMIT=60] label for estimated remaining duration of battery when under a certain amount with the percentage -->
+    <string name="power_remaining_less_than_duration">Less than <xliff:g id="threshold">%1$s</xliff:g> remaining (<xliff:g id="level">%2$s</xliff:g>)</string>
 
-  <!-- Used to let users know that they have more than some amount of battery life remaining with percentage. ex: 75% - more than 1 day remaining [CHAR LIMIT = 80] -->
-  <string name="power_remaining_more_than_subtext"><xliff:g id="level">%1$s</xliff:g>more than <xliff:g id="time_remaining">%2$s</xliff:g> remaining</string>
-  <!-- Used to let users know that they have more than some amount of battery life remaining. ex: more than 1 day remaining [CHAR LIMIT = 40] -->
-  <string name="power_remaining_only_more_than_subtext">more than <xliff:g id="time_remaining">%1$s</xliff:g> remaining</string>
+    <!-- Used to let users know that they have more than some amount of battery life remaining with percentage. ex: 75% - more than 1 day remaining [CHAR LIMIT = 80] -->
+    <string name="power_remaining_more_than_subtext">More than <xliff:g id="time_remaining">%1$s</xliff:g> remaining (<xliff:g id="level">%2$s</xliff:g>)</string>
+    <!-- Used to let users know that they have more than some amount of battery life remaining. ex: more than 1 day remaining [CHAR LIMIT = 40] -->
+    <string name="power_remaining_only_more_than_subtext">More than <xliff:g id="time_remaining">%1$s</xliff:g> remaining</string>
 
-  <!-- [CHAR_LIMIT=50] Short label for imminent shutdown warning of device -->
-  <string name="power_remaining_duration_only_shutdown_imminent" product="default">phone may shutdown soon</string>
-  <!-- [CHAR_LIMIT=50] Short label for imminent shutdown warning of device -->
-  <string name="power_remaining_duration_only_shutdown_imminent" product="tablet">tablet may shutdown soon</string>
-  <!-- [CHAR_LIMIT=50] Short label for imminent shutdown warning of device -->
-  <string name="power_remaining_duration_only_shutdown_imminent" product="device">device may shutdown soon</string>
-
-  <!-- [CHAR_LIMIT=40] Label for battery level chart when discharging with duration -->
-  <string name="power_discharging_duration"><xliff:g id="level">%1$s</xliff:g> - about <xliff:g id="time">%2$s</xliff:g> left</string>
-  <!-- [CHAR_LIMIT=60] Label for battery level chart when discharging with duration and using enhanced estimate -->
-  <string name="power_discharging_duration_enhanced"><xliff:g id="level">%1$s</xliff:g> - about <xliff:g id="time">%2$s</xliff:g> left based on your usage</string>
-
-  <!-- [CHAR_LIMIT=60] Label for battery level chart when shutdown is imminent-->
-  <string name="power_remaining_duration_shutdown_imminent" product="default"><xliff:g id="level">%1$s</xliff:g> - phone may shutdown soon</string>
-  <!-- [CHAR_LIMIT=60] Label for battery level chart when shutdown is imminent-->
-  <string name="power_remaining_duration_shutdown_imminent" product="tablet"><xliff:g id="level">%1$s</xliff:g> - tablet may shutdown soon</string>
-  <!-- [CHAR_LIMIT=60] Label for battery level chart when shutdown is imminent-->
-  <string name="power_remaining_duration_shutdown_imminent" product="device"><xliff:g id="level">%1$s</xliff:g> - device may shutdown soon</string>
+    <!-- [CHAR_LIMIT=50] Short label for imminent shutdown warning of device -->
+    <string name="power_remaining_duration_only_shutdown_imminent" product="default">Phone may shutdown soon</string>
+    <!-- [CHAR_LIMIT=50] Short label for imminent shutdown warning of device -->
+    <string name="power_remaining_duration_only_shutdown_imminent" product="tablet">Tablet may shutdown soon</string>
+    <!-- [CHAR_LIMIT=50] Short label for imminent shutdown warning of device -->
+    <string name="power_remaining_duration_only_shutdown_imminent" product="device">Device may shutdown soon</string>
+    <!-- [CHAR_LIMIT=60] Label for battery level chart when shutdown is imminent-->
+    <string name="power_remaining_duration_shutdown_imminent" product="default">Phone may shutdown soon (<xliff:g id="level">%1$s</xliff:g>)</string>
+    <!-- [CHAR_LIMIT=60] Label for battery level chart when shutdown is imminent-->
+    <string name="power_remaining_duration_shutdown_imminent" product="tablet">Tablet may shutdown soon (<xliff:g id="level">%1$s</xliff:g>)</string>
+    <!-- [CHAR_LIMIT=60] Label for battery level chart when shutdown is imminent-->
+    <string name="power_remaining_duration_shutdown_imminent" product="device">Device may shutdown soon (<xliff:g id="level">%1$s</xliff:g>)</string>
 
     <!-- [CHAR_LIMIT=40] Label for battery level chart when charging -->
     <string name="power_charging"><xliff:g id="level">%1$s</xliff:g> - <xliff:g id="state">%2$s</xliff:g></string>
+    <!-- [CHAR_LIMIT=40] Label for estimated remaining duration of battery charging -->
+    <string name="power_remaining_charging_duration_only"><xliff:g id="time">%1$s</xliff:g> left until fully charged</string>
     <!-- [CHAR_LIMIT=40] Label for battery level chart when charging with duration -->
     <string name="power_charging_duration"><xliff:g id="level">%1$s</xliff:g> - <xliff:g id="time">%2$s</xliff:g> until fully charged</string>
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index 9947dec..61e113b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -142,7 +142,7 @@
     public static Drawable getUserIcon(Context context, UserManager um, UserInfo user) {
         final int iconSize = UserIconDrawable.getSizeForList(context);
         if (user.isManagedProfile()) {
-            Drawable drawable = context.getDrawable(com.android.internal.R.drawable.ic_corp_badge);
+            Drawable drawable =  UserIconDrawable.getManagedUserBadgeDrawable(context);
             drawable.setBounds(0, 0, iconSize, iconSize);
             return drawable;
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/DefaultAppInfo.java b/packages/SettingsLib/src/com/android/settingslib/applications/DefaultAppInfo.java
new file mode 100644
index 0000000..246ca47
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/DefaultAppInfo.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.applications;
+
+import android.app.AppGlobals;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ComponentInfo;
+import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.IconDrawableFactory;
+
+import com.android.settingslib.widget.CandidateInfo;
+import com.android.settingslib.wrapper.PackageManagerWrapper;
+
+/**
+ * Data model representing an app in DefaultAppPicker UI.
+ */
+public class DefaultAppInfo extends CandidateInfo {
+
+    public final int userId;
+    public final ComponentName componentName;
+    public final PackageItemInfo packageItemInfo;
+    public final String summary;
+    protected final PackageManagerWrapper mPm;
+    private final Context mContext;
+
+    public DefaultAppInfo(Context context, PackageManagerWrapper pm, int uid, ComponentName cn) {
+        this(context, pm, uid, cn, null /* summary */, true /* enabled */);
+    }
+
+    public DefaultAppInfo(Context context, PackageManagerWrapper pm, PackageItemInfo info) {
+        this(context, pm, info, null /* summary */, true /* enabled */);
+    }
+
+    public DefaultAppInfo(Context context, PackageManagerWrapper pm, int uid, ComponentName cn,
+                          String summary, boolean enabled) {
+        super(enabled);
+        mContext = context;
+        mPm = pm;
+        packageItemInfo = null;
+        userId = uid;
+        componentName = cn;
+        this.summary = summary;
+    }
+
+    public DefaultAppInfo(Context context, PackageManagerWrapper pm, PackageItemInfo info,
+                          String summary, boolean enabled) {
+        super(enabled);
+        mContext = context;
+        mPm = pm;
+        userId = UserHandle.myUserId();
+        packageItemInfo = info;
+        componentName = null;
+        this.summary = summary;
+    }
+
+    @Override
+    public CharSequence loadLabel() {
+        if (componentName != null) {
+            try {
+                final ComponentInfo componentInfo = getComponentInfo();
+                if (componentInfo != null) {
+                    return componentInfo.loadLabel(mPm.getPackageManager());
+                } else {
+                    final ApplicationInfo appInfo = mPm.getApplicationInfoAsUser(
+                            componentName.getPackageName(), 0, userId);
+                    return appInfo.loadLabel(mPm.getPackageManager());
+                }
+            } catch (PackageManager.NameNotFoundException e) {
+                return null;
+            }
+        } else if (packageItemInfo != null) {
+            return packageItemInfo.loadLabel(mPm.getPackageManager());
+        } else {
+            return null;
+        }
+
+    }
+
+    @Override
+    public Drawable loadIcon() {
+        final IconDrawableFactory factory = IconDrawableFactory.newInstance(mContext);
+        if (componentName != null) {
+            try {
+                final ComponentInfo componentInfo = getComponentInfo();
+                final ApplicationInfo appInfo = mPm.getApplicationInfoAsUser(
+                        componentName.getPackageName(), 0, userId);
+                if (componentInfo != null) {
+                    return factory.getBadgedIcon(componentInfo, appInfo, userId);
+                } else {
+                    return factory.getBadgedIcon(appInfo);
+                }
+            } catch (PackageManager.NameNotFoundException e) {
+                return null;
+            }
+        }
+        if (packageItemInfo != null) {
+            try {
+                final ApplicationInfo appInfo = mPm.getApplicationInfoAsUser(
+                        packageItemInfo.packageName, 0, userId);
+                return factory.getBadgedIcon(packageItemInfo, appInfo, userId);
+            } catch (PackageManager.NameNotFoundException e) {
+                return null;
+            }
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public String getKey() {
+        if (componentName != null) {
+            return componentName.flattenToString();
+        } else if (packageItemInfo != null) {
+            return packageItemInfo.packageName;
+        } else {
+            return null;
+        }
+    }
+
+    private ComponentInfo getComponentInfo() {
+        try {
+            ComponentInfo componentInfo = AppGlobals.getPackageManager().getActivityInfo(
+                    componentName, 0, userId);
+            if (componentInfo == null) {
+                componentInfo = AppGlobals.getPackageManager().getServiceInfo(
+                        componentName, 0, userId);
+            }
+            return componentInfo;
+        } catch (RemoteException e) {
+            return null;
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
old mode 100755
new mode 100644
index 3cda9c9..784c714
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
@@ -444,6 +444,7 @@
 
     private void dispatchActiveDeviceChanged(CachedBluetoothDevice activeDevice,
                                              int bluetoothProfile) {
+        mDeviceManager.onActiveDeviceChanged(activeDevice, bluetoothProfile);
         synchronized (mCallbacks) {
             for (BluetoothCallback callback : mCallbacks) {
                 callback.onActiveDeviceChanged(activeDevice, bluetoothProfile);
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index e1ebbc4..f6ec6a8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -27,6 +27,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.bluetooth.BluetoothAdapter;
+import android.support.annotation.VisibleForTesting;
 
 import com.android.settingslib.R;
 
@@ -461,12 +462,12 @@
     }
 
     /**
-     * Set the device status as active or non-active per Bluetooth profile.
+     * Update the device status as active or non-active per Bluetooth profile.
      *
      * @param isActive true if the device is active
      * @param bluetoothProfile the Bluetooth profile
      */
-    public void setActiveDevice(boolean isActive, int bluetoothProfile) {
+    public void onActiveDeviceChanged(boolean isActive, int bluetoothProfile) {
         boolean changed = false;
         switch (bluetoothProfile) {
         case BluetoothProfile.A2DP:
@@ -478,7 +479,7 @@
             mIsActiveDeviceHeadset = isActive;
             break;
         default:
-            Log.w(TAG, "setActiveDevice: unknown profile " + bluetoothProfile +
+            Log.w(TAG, "onActiveDeviceChanged: unknown profile " + bluetoothProfile +
                     " isActive " + isActive);
             break;
         }
@@ -487,6 +488,26 @@
         }
     }
 
+    /**
+     * Get the device status as active or non-active per Bluetooth profile.
+     *
+     * @param bluetoothProfile the Bluetooth profile
+     * @return true if the device is active
+     */
+    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+    public boolean isActiveDevice(int bluetoothProfile) {
+        switch (bluetoothProfile) {
+            case BluetoothProfile.A2DP:
+                return mIsActiveDeviceA2dp;
+            case BluetoothProfile.HEADSET:
+                return mIsActiveDeviceHeadset;
+            default:
+                Log.w(TAG, "getActiveDevice: unknown profile " + bluetoothProfile);
+                break;
+        }
+        return false;
+    }
+
     void setRssi(short rssi) {
         if (mRssi != rssi) {
             mRssi = rssi;
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
old mode 100755
new mode 100644
index c3ff617..a8e0039
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
@@ -24,6 +24,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * CachedBluetoothDeviceManager manages the set of remote Bluetooth devices.
@@ -167,6 +168,15 @@
             }
         }
     }
+
+    public synchronized void onActiveDeviceChanged(CachedBluetoothDevice activeDevice,
+                                                   int bluetoothProfile) {
+        for (CachedBluetoothDevice cachedDevice : mCachedDevices) {
+            boolean isActive = Objects.equals(cachedDevice, activeDevice);
+            cachedDevice.onActiveDeviceChanged(isActive, bluetoothProfile);
+        }
+    }
+
     private void log(String msg) {
         if (DEBUG) {
             Log.d(TAG, msg);
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
index d14b53b..660521e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
@@ -37,7 +37,16 @@
      * Updates the current status of preference (summary, switch state, etc)
      */
     public void updateState(Preference preference) {
-
+        if (preference == null) {
+            return;
+        }
+        final CharSequence summary = getSummary();
+        if (summary == null) {
+            // Default getSummary returns null. If subclass didn't override this, there is nothing
+            // we need to do.
+            return;
+        }
+        preference.setSummary(summary);
     }
 
     /**
@@ -72,9 +81,9 @@
 
 
     /**
-     * @return a String for the summary of the preference.
+     * @return a {@link CharSequence} for the summary of the preference.
      */
-    public String getSummary() {
+    public CharSequence getSummary() {
         return null;
     }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/development/DeveloperOptionsPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/development/DeveloperOptionsPreferenceController.java
index f68c04f..d3dc8aa 100644
--- a/packages/SettingsLib/src/com/android/settingslib/development/DeveloperOptionsPreferenceController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/development/DeveloperOptionsPreferenceController.java
@@ -17,6 +17,8 @@
 package com.android.settingslib.development;
 
 import android.content.Context;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
 
 import com.android.settingslib.core.AbstractPreferenceController;
 
@@ -26,8 +28,9 @@
  * All Preference Controllers that are a part of the developer options page should inherit this
  * class.
  */
-public abstract class DeveloperOptionsPreferenceController extends
-        AbstractPreferenceController {
+public abstract class DeveloperOptionsPreferenceController extends AbstractPreferenceController {
+
+    protected Preference mPreference;
 
     public DeveloperOptionsPreferenceController(Context context) {
         super(context);
@@ -43,6 +46,12 @@
         return true;
     }
 
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = screen.findPreference(getPreferenceKey());
+    }
+
     /**
      * Called when developer options is enabled
      */
@@ -65,12 +74,14 @@
      * Called when developer options is enabled and the preference is available
      */
     protected void onDeveloperOptionsSwitchEnabled() {
+        mPreference.setEnabled(true);
     }
 
     /**
      * Called when developer options is disabled and the preference is available
      */
     protected void onDeveloperOptionsSwitchDisabled() {
+        mPreference.setEnabled(false);
     }
 
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
old mode 100755
new mode 100644
diff --git a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionController.java b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionController.java
index f740f7c..b0451b7 100644
--- a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionController.java
@@ -107,7 +107,7 @@
         } catch (NullPointerException e) {
             Log.w(TAG, "mRemote service detached before able to query", e);
             return null;
-        } catch (RemoteException e) {
+        } catch (RemoteException | RuntimeException e) {
             Log.w(TAG, "Error when calling getSuggestion()", e);
             return null;
         }
@@ -120,7 +120,7 @@
         }
         try {
             mRemoteService.dismissSuggestion(suggestion);
-        } catch (RemoteException e) {
+        } catch (RemoteException | RuntimeException e) {
             Log.w(TAG, "Error when calling dismissSuggestion()", e);
         }
     }
@@ -133,7 +133,7 @@
 
         try {
             mRemoteService.launchSuggestion(suggestion);
-        } catch (RemoteException e) {
+        } catch (RemoteException | RuntimeException e) {
             Log.w(TAG, "Error when calling launchSuggestion()", e);
         }
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/utils/IconCache.java b/packages/SettingsLib/src/com/android/settingslib/utils/IconCache.java
new file mode 100644
index 0000000..3d55c4f
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/utils/IconCache.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.utils;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
+import android.support.annotation.VisibleForTesting;
+import android.support.v4.util.ArrayMap;
+
+
+/**
+ * Icon cache to avoid multiple loads on the same icon.
+ */
+public class IconCache {
+    private final Context mContext;
+    @VisibleForTesting
+    final ArrayMap<Icon, Drawable> mMap = new ArrayMap<>();
+
+    public IconCache(Context context) {
+        mContext = context;
+    }
+
+    public Drawable getIcon(Icon icon) {
+        if (icon == null) {
+            return null;
+        }
+        Drawable drawable = mMap.get(icon);
+        if (drawable == null) {
+            drawable = icon.loadDrawable(mContext);
+            updateIcon(icon, drawable);
+        }
+        return drawable;
+    }
+
+    public void updateIcon(Icon icon, Drawable drawable) {
+        mMap.put(icon, drawable);
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java b/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java
index 346ca66..8b3da39 100644
--- a/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java
@@ -17,22 +17,30 @@
 package com.android.settingslib.utils;
 
 import android.content.Context;
+import android.icu.text.DateFormat;
 import android.icu.text.MeasureFormat;
 import android.icu.text.MeasureFormat.FormatWidth;
 import android.icu.util.Measure;
 import android.icu.util.MeasureUnit;
 import android.support.annotation.Nullable;
 import android.text.TextUtils;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.settingslib.R;
-import com.android.settingslib.utils.StringUtil;
+import java.time.Clock;
+import java.time.Instant;
+import java.util.Calendar;
+import java.util.Date;
 import java.util.Locale;
 import java.util.concurrent.TimeUnit;
 
 /** Utility class for keeping power related strings consistent**/
 public class PowerUtil {
+
     private static final long SEVEN_MINUTES_MILLIS = TimeUnit.MINUTES.toMillis(7);
     private static final long FIFTEEN_MINUTES_MILLIS = TimeUnit.MINUTES.toMillis(15);
     private static final long ONE_DAY_MILLIS = TimeUnit.DAYS.toMillis(1);
+    private static final long TWO_DAYS_MILLIS = TimeUnit.DAYS.toMillis(2);
+    private static final long ONE_HOUR_MILLIS = TimeUnit.HOURS.toMillis(1);
 
     /**
      * This method produces the text used in various places throughout the system to describe the
@@ -57,11 +65,15 @@
                         FIFTEEN_MINUTES_MILLIS,
                         false /* withSeconds */);
                 return getUnderFifteenString(context, timeString, percentageString);
+            } else if (drainTimeMs >= TWO_DAYS_MILLIS) {
+                // just say more than two day if over 48 hours
+                return getMoreThanTwoDaysString(context, percentageString);
             } else if (drainTimeMs >= ONE_DAY_MILLIS) {
-                // just say more than one day if over 24 hours
-                return getMoreThanOneDayString(context, percentageString);
+                // show remaining days & hours if more than a day
+                return getMoreThanOneDayString(context, drainTimeMs,
+                        percentageString, basedOnUsage);
             } else {
-                // show a regular time remaining string
+                // show the time of day we think you'll run out
                 return getRegularTimeRemainingString(context, drainTimeMs,
                         percentageString, basedOnUsage);
             }
@@ -83,34 +95,18 @@
                 ? context.getString(R.string.power_remaining_less_than_duration_only, timeString)
                 : context.getString(
                         R.string.power_remaining_less_than_duration,
-                        percentageString,
-                        timeString);
+                        timeString,
+                        percentageString);
 
     }
 
-    private static String getMoreThanOneDayString(Context context, String percentageString) {
-        final Locale currentLocale = context.getResources().getConfiguration().getLocales().get(0);
-        final MeasureFormat frmt = MeasureFormat.getInstance(currentLocale, FormatWidth.SHORT);
-
-        final Measure daysMeasure = new Measure(1, MeasureUnit.DAY);
-
-        return TextUtils.isEmpty(percentageString)
-                ? context.getString(R.string.power_remaining_only_more_than_subtext,
-                        frmt.formatMeasures(daysMeasure))
-                : context.getString(
-                        R.string.power_remaining_more_than_subtext,
-                        percentageString,
-                        frmt.formatMeasures(daysMeasure));
-    }
-
-    private static String getRegularTimeRemainingString(Context context, long drainTimeMs,
+    private static String getMoreThanOneDayString(Context context, long drainTimeMs,
             String percentageString, boolean basedOnUsage) {
-        // round to the nearest 15 min to not appear oversly precise
-        final long roundedTimeMs = roundToNearestThreshold(drainTimeMs,
-                FIFTEEN_MINUTES_MILLIS);
+        final long roundedTimeMs = roundToNearestThreshold(drainTimeMs, ONE_HOUR_MILLIS);
         CharSequence timeString = StringUtil.formatElapsedTime(context,
                 roundedTimeMs,
                 false /* withSeconds */);
+
         if (TextUtils.isEmpty(percentageString)) {
             int id = basedOnUsage
                     ? R.string.power_remaining_duration_only_enhanced
@@ -120,7 +116,48 @@
             int id = basedOnUsage
                     ? R.string.power_discharging_duration_enhanced
                     : R.string.power_discharging_duration;
-            return context.getString(id, percentageString, timeString);
+            return context.getString(id, timeString, percentageString);
+        }
+    }
+
+    private static String getMoreThanTwoDaysString(Context context, String percentageString) {
+        final Locale currentLocale = context.getResources().getConfiguration().getLocales().get(0);
+        final MeasureFormat frmt = MeasureFormat.getInstance(currentLocale, FormatWidth.SHORT);
+
+        final Measure daysMeasure = new Measure(2, MeasureUnit.DAY);
+
+        return TextUtils.isEmpty(percentageString)
+                ? context.getString(R.string.power_remaining_only_more_than_subtext,
+                        frmt.formatMeasures(daysMeasure))
+                : context.getString(
+                        R.string.power_remaining_more_than_subtext,
+                        frmt.formatMeasures(daysMeasure),
+                        percentageString);
+    }
+
+    private static String getRegularTimeRemainingString(Context context, long drainTimeMs,
+            String percentageString, boolean basedOnUsage) {
+        // Get the time of day we think device will die rounded to the nearest 15 min.
+        final long roundedTimeOfDayMs =
+                roundToNearestThreshold(
+                        System.currentTimeMillis() + drainTimeMs,
+                        FIFTEEN_MINUTES_MILLIS);
+
+        // convert the time to a properly formatted string.
+        DateFormat fmt = DateFormat.getTimeInstance(DateFormat.SHORT);
+        Date date = Date.from(Instant.ofEpochMilli(roundedTimeOfDayMs));
+        CharSequence timeString = fmt.format(date);
+
+        if (TextUtils.isEmpty(percentageString)) {
+            int id = basedOnUsage
+                    ? R.string.power_discharge_by_only_enhanced
+                    : R.string.power_discharge_by_only;
+            return context.getString(id, timeString);
+        } else {
+            int id = basedOnUsage
+                    ? R.string.power_discharge_by_enhanced
+                    : R.string.power_discharge_by;
+            return context.getString(id, timeString, percentageString);
         }
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java b/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java
index 45fdd78..68be2b4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java
@@ -33,74 +33,74 @@
 /** Utility class for generally useful string methods **/
 public class StringUtil {
 
-  public static final int SECONDS_PER_MINUTE = 60;
-  public static final int SECONDS_PER_HOUR = 60 * 60;
-  public static final int SECONDS_PER_DAY = 24 * 60 * 60;
+    public static final int SECONDS_PER_MINUTE = 60;
+    public static final int SECONDS_PER_HOUR = 60 * 60;
+    public static final int SECONDS_PER_DAY = 24 * 60 * 60;
 
-  /**
-   * Returns elapsed time for the given millis, in the following format:
-   * 2d 5h 40m 29s
-   * @param context the application context
-   * @param millis the elapsed time in milli seconds
-   * @param withSeconds include seconds?
-   * @return the formatted elapsed time
-   */
-  public static CharSequence formatElapsedTime(Context context, double millis,
-          boolean withSeconds) {
-      SpannableStringBuilder sb = new SpannableStringBuilder();
-      int seconds = (int) Math.floor(millis / 1000);
-      if (!withSeconds) {
-          // Round up.
-          seconds += 30;
-      }
+    /**
+    * Returns elapsed time for the given millis, in the following format:
+    * 2d 5h 40m 29s
+    * @param context the application context
+     * @param millis the elapsed time in milli seconds
+     * @param withSeconds include seconds?
+     * @return the formatted elapsed time
+     */
+    public static CharSequence formatElapsedTime(Context context, double millis,
+            boolean withSeconds) {
+        SpannableStringBuilder sb = new SpannableStringBuilder();
+        int seconds = (int) Math.floor(millis / 1000);
+        if (!withSeconds) {
+            // Round up.
+            seconds += 30;
+        }
 
-      int days = 0, hours = 0, minutes = 0;
-      if (seconds >= SECONDS_PER_DAY) {
-          days = seconds / SECONDS_PER_DAY;
-          seconds -= days * SECONDS_PER_DAY;
-      }
-      if (seconds >= SECONDS_PER_HOUR) {
-          hours = seconds / SECONDS_PER_HOUR;
-          seconds -= hours * SECONDS_PER_HOUR;
-      }
-      if (seconds >= SECONDS_PER_MINUTE) {
-          minutes = seconds / SECONDS_PER_MINUTE;
-          seconds -= minutes * SECONDS_PER_MINUTE;
-      }
+        int days = 0, hours = 0, minutes = 0;
+        if (seconds >= SECONDS_PER_DAY) {
+            days = seconds / SECONDS_PER_DAY;
+            seconds -= days * SECONDS_PER_DAY;
+        }
+        if (seconds >= SECONDS_PER_HOUR) {
+            hours = seconds / SECONDS_PER_HOUR;
+            seconds -= hours * SECONDS_PER_HOUR;
+        }
+        if (seconds >= SECONDS_PER_MINUTE) {
+            minutes = seconds / SECONDS_PER_MINUTE;
+            seconds -= minutes * SECONDS_PER_MINUTE;
+        }
 
-      final ArrayList<Measure> measureList = new ArrayList(4);
-      if (days > 0) {
-          measureList.add(new Measure(days, MeasureUnit.DAY));
-      }
-      if (hours > 0) {
-          measureList.add(new Measure(hours, MeasureUnit.HOUR));
-      }
-      if (minutes > 0) {
-          measureList.add(new Measure(minutes, MeasureUnit.MINUTE));
-      }
-      if (withSeconds && seconds > 0) {
-          measureList.add(new Measure(seconds, MeasureUnit.SECOND));
-      }
-      if (measureList.size() == 0) {
-          // Everything addable was zero, so nothing was added. We add a zero.
-          measureList.add(new Measure(0, withSeconds ? MeasureUnit.SECOND : MeasureUnit.MINUTE));
-      }
-      final Measure[] measureArray = measureList.toArray(new Measure[measureList.size()]);
+        final ArrayList<Measure> measureList = new ArrayList(4);
+        if (days > 0) {
+            measureList.add(new Measure(days, MeasureUnit.DAY));
+        }
+        if (hours > 0) {
+            measureList.add(new Measure(hours, MeasureUnit.HOUR));
+        }
+        if (minutes > 0) {
+            measureList.add(new Measure(minutes, MeasureUnit.MINUTE));
+        }
+        if (withSeconds && seconds > 0) {
+            measureList.add(new Measure(seconds, MeasureUnit.SECOND));
+        }
+        if (measureList.size() == 0) {
+            // Everything addable was zero, so nothing was added. We add a zero.
+            measureList.add(new Measure(0, withSeconds ? MeasureUnit.SECOND : MeasureUnit.MINUTE));
+        }
+        final Measure[] measureArray = measureList.toArray(new Measure[measureList.size()]);
 
-      final Locale locale = context.getResources().getConfiguration().locale;
-      final MeasureFormat measureFormat = MeasureFormat.getInstance(
-              locale, FormatWidth.NARROW);
-      sb.append(measureFormat.formatMeasures(measureArray));
+        final Locale locale = context.getResources().getConfiguration().locale;
+        final MeasureFormat measureFormat = MeasureFormat.getInstance(
+                locale, FormatWidth.NARROW);
+        sb.append(measureFormat.formatMeasures(measureArray));
 
-      if (measureArray.length == 1 && MeasureUnit.MINUTE.equals(measureArray[0].getUnit())) {
-          // Add ttsSpan if it only have minute value, because it will be read as "meters"
-          final TtsSpan ttsSpan = new TtsSpan.MeasureBuilder().setNumber(minutes)
-                  .setUnit("minute").build();
-          sb.setSpan(ttsSpan, 0, sb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-      }
+        if (measureArray.length == 1 && MeasureUnit.MINUTE.equals(measureArray[0].getUnit())) {
+            // Add ttsSpan if it only have minute value, because it will be read as "meters"
+            final TtsSpan ttsSpan = new TtsSpan.MeasureBuilder().setNumber(minutes)
+                    .setUnit("minute").build();
+            sb.setSpan(ttsSpan, 0, sb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        }
 
-      return sb;
-  }
+        return sb;
+    }
 
     /**
      * Returns relative time for the given millis in the past, in a short format such as "2 days
diff --git a/packages/SettingsLib/src/com/android/settingslib/widget/CandidateInfo.java b/packages/SettingsLib/src/com/android/settingslib/widget/CandidateInfo.java
new file mode 100644
index 0000000..cdb4ffd
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/widget/CandidateInfo.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.widget;
+
+import android.graphics.drawable.Drawable;
+
+/**
+ * Base class for defining a selectable item in UI.
+ */
+public abstract class CandidateInfo {
+
+    public final boolean enabled;
+
+    public CandidateInfo(boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    public abstract CharSequence loadLabel();
+
+    public abstract Drawable loadIcon();
+
+    public abstract String getKey();
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/widget/FooterPreference.java b/packages/SettingsLib/src/com/android/settingslib/widget/FooterPreference.java
index 0c3a5e9..e693551 100644
--- a/packages/SettingsLib/src/com/android/settingslib/widget/FooterPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/widget/FooterPreference.java
@@ -33,7 +33,7 @@
 public class FooterPreference extends Preference {
 
     static final int ORDER_FOOTER = Integer.MAX_VALUE - 1;
-    static final String KEY_FOOTER = "footer_preference";
+    public static final String KEY_FOOTER = "footer_preference";
 
     public FooterPreference(Context context, AttributeSet attrs) {
         super(context, attrs, TypedArrayUtils.getAttr(
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index ae544dd..2482095 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -37,7 +37,6 @@
 import android.net.wifi.WifiNetworkScoreCache.CacheListener;
 import android.os.Handler;
 import android.os.HandlerThread;
-import android.os.Looper;
 import android.os.Message;
 import android.os.Process;
 import android.os.SystemClock;
@@ -104,7 +103,6 @@
     // TODO: Allow control of this?
     // Combo scans can take 5-6s to complete - set to 10s.
     private static final int WIFI_RESCAN_INTERVAL_MS = 10 * 1000;
-    private static final int NUM_SCANS_TO_CONFIRM_AP_LOSS = 3;
 
     private final Context mContext;
     private final WifiManager mWifiManager;
@@ -112,30 +110,38 @@
     private final ConnectivityManager mConnectivityManager;
     private final NetworkRequest mNetworkRequest;
     private final AtomicBoolean mConnected = new AtomicBoolean(false);
-    private final WifiListener mListener;
-    @VisibleForTesting WorkHandler mWorkHandler;
+    private final WifiListenerExecutor mListener;
+    @VisibleForTesting Handler mWorkHandler;
     private HandlerThread mWorkThread;
 
     private WifiTrackerNetworkCallback mNetworkCallback;
 
-    @GuardedBy("mLock")
-    private boolean mRegistered;
+    /**
+     * Synchronization lock for managing concurrency between main and worker threads.
+     *
+     * <p>This lock should be held for all modifications to {@link #mInternalAccessPoints}.
+     */
+    private final Object mLock = new Object();
 
     /** The list of AccessPoints, aggregated visible ScanResults with metadata. */
     @GuardedBy("mLock")
     private final List<AccessPoint> mInternalAccessPoints = new ArrayList<>();
 
+    @GuardedBy("mLock")
+    private final Set<NetworkKey> mRequestedScores = new ArraySet<>();
+
     /**
-    * Synchronization lock for managing concurrency between main and worker threads.
-    *
-    * <p>This lock should be held for all modifications to {@link #mInternalAccessPoints}.
-    */
-    private final Object mLock = new Object();
+     * Tracks whether fresh scan results have been received since scanning start.
+     *
+     * <p>If this variable is false, we will not evict the scan result cache or invoke callbacks
+     * so that we do not update the UI with stale data / clear out existing UI elements prematurely.
+     */
+    private boolean mStaleScanResults = true;
 
-    private final HashMap<String, Integer> mSeenBssids = new HashMap<>();
-
-    // TODO(sghuman): Change this to be keyed on AccessPoint.getKey
+    // Does not need to be locked as it only updated on the worker thread, with the exception of
+    // during onStart, which occurs before the receiver is registered on the work handler.
     private final HashMap<String, ScanResult> mScanResultCache = new HashMap<>();
+    private boolean mRegistered;
 
     private NetworkInfo mLastNetworkInfo;
     private WifiInfo mLastInfo;
@@ -145,21 +151,11 @@
     private boolean mNetworkScoringUiEnabled;
     private long mMaxSpeedLabelScoreCacheAge;
 
-    @GuardedBy("mLock")
-    private final Set<NetworkKey> mRequestedScores = new ArraySet<>();
+
 
     @VisibleForTesting
     Scanner mScanner;
 
-    /**
-     * Tracks whether fresh scan results have been received since scanning start.
-     *
-     * <p>If this variable is false, we will not evict the scan result cache or invoke callbacks
-     * so that we do not update the UI with stale data / clear out existing UI elements prematurely.
-     */
-    @GuardedBy("mLock")
-    private boolean mStaleScanResults = true;
-
     private static IntentFilter newIntentFilter() {
         IntentFilter filter = new IntentFilter();
         filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
@@ -180,7 +176,7 @@
     @Deprecated
     public WifiTracker(Context context, WifiListener wifiListener,
             boolean includeSaved, boolean includeScans) {
-        this(context, wifiListener,
+        this(context, new WifiListenerExecutor(wifiListener),
                 context.getSystemService(WifiManager.class),
                 context.getSystemService(ConnectivityManager.class),
                 context.getSystemService(NetworkScoreManager.class),
@@ -191,7 +187,7 @@
     // calling apps once IC window is complete
     public WifiTracker(Context context, WifiListener wifiListener,
             @NonNull Lifecycle lifecycle, boolean includeSaved, boolean includeScans) {
-        this(context, wifiListener,
+        this(context, new WifiListenerExecutor(wifiListener),
                 context.getSystemService(WifiManager.class),
                 context.getSystemService(ConnectivityManager.class),
                 context.getSystemService(NetworkScoreManager.class),
@@ -200,13 +196,13 @@
     }
 
     @VisibleForTesting
-    WifiTracker(Context context, WifiListener wifiListener,
+    WifiTracker(Context context, WifiListenerExecutor wifiListenerExecutor,
             WifiManager wifiManager, ConnectivityManager connectivityManager,
             NetworkScoreManager networkScoreManager,
             IntentFilter filter) {
         mContext = context;
         mWifiManager = wifiManager;
-        mListener = new WifiListenerWrapper(wifiListener);
+        mListener = wifiListenerExecutor;
         mConnectivityManager = connectivityManager;
 
         // check if verbose logging developer option has been turned on or off
@@ -238,13 +234,11 @@
     // during construction
     void setWorkThread(HandlerThread workThread) {
         mWorkThread = workThread;
-        mWorkHandler = new WorkHandler(workThread.getLooper());
+        mWorkHandler = new Handler(workThread.getLooper());
         mScoreCache = new WifiNetworkScoreCache(mContext, new CacheListener(mWorkHandler) {
             @Override
             public void networkCacheUpdated(List<ScoredNetwork> networks) {
-                synchronized (mLock) {
-                    if (!mRegistered) return;
-                }
+                if (!mRegistered) return;
 
                 if (Log.isLoggable(TAG, Log.VERBOSE)) {
                     Log.v(TAG, "Score cache was updated with networks: " + networks);
@@ -259,25 +253,6 @@
         mWorkThread.quit();
     }
 
-    /** Synchronously update the list of access points with the latest information. */
-    @MainThread
-    public void forceUpdate() {
-        synchronized (mLock) {
-            mWorkHandler.removeMessages(WorkHandler.MSG_UPDATE_ACCESS_POINTS);
-            mLastInfo = mWifiManager.getConnectionInfo();
-            mLastNetworkInfo = mConnectivityManager.getNetworkInfo(mWifiManager.getCurrentNetwork());
-
-            final List<ScanResult> newScanResults = mWifiManager.getScanResults();
-            if (isVerboseLoggingEnabled()) {
-                Log.i(TAG, "Fetched scan results: " + newScanResults);
-            }
-
-            List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
-            mInternalAccessPoints.clear();
-            updateAccessPointsLocked(newScanResults, configs);
-        }
-    }
-
     /**
      * Temporarily stop scanning for wifi networks.
      *
@@ -288,9 +263,7 @@
             mScanner.pause();
             mScanner = null;
         }
-        synchronized (mLock) {
-            mStaleScanResults = true;
-        }
+        mStaleScanResults = true;
     }
 
     /**
@@ -303,7 +276,6 @@
             mScanner = new Scanner();
         }
 
-        mWorkHandler.sendEmptyMessage(WorkHandler.MSG_RESUME);
         if (mWifiManager.isWifiEnabled()) {
             mScanner.resume();
         }
@@ -318,31 +290,46 @@
     @Override
     @MainThread
     public void onStart() {
-        synchronized (mLock) {
-            registerScoreCache();
+        // fetch current ScanResults instead of waiting for broadcast of fresh results
+        forceUpdate();
 
-            mNetworkScoringUiEnabled =
-                    Settings.Global.getInt(
-                            mContext.getContentResolver(),
-                            Settings.Global.NETWORK_SCORING_UI_ENABLED, 0) == 1;
+        registerScoreCache();
 
-            mMaxSpeedLabelScoreCacheAge =
-                    Settings.Global.getLong(
-                            mContext.getContentResolver(),
-                            Settings.Global.SPEED_LABEL_CACHE_EVICTION_AGE_MILLIS,
-                            DEFAULT_MAX_CACHED_SCORE_AGE_MILLIS);
+        mNetworkScoringUiEnabled =
+                Settings.Global.getInt(
+                        mContext.getContentResolver(),
+                        Settings.Global.NETWORK_SCORING_UI_ENABLED, 0) == 1;
 
-            resumeScanning();
-            if (!mRegistered) {
-                mContext.registerReceiver(mReceiver, mFilter);
-                // NetworkCallback objects cannot be reused. http://b/20701525 .
-                mNetworkCallback = new WifiTrackerNetworkCallback();
-                mConnectivityManager.registerNetworkCallback(mNetworkRequest, mNetworkCallback);
-                mRegistered = true;
-            }
+        mMaxSpeedLabelScoreCacheAge =
+                Settings.Global.getLong(
+                        mContext.getContentResolver(),
+                        Settings.Global.SPEED_LABEL_CACHE_EVICTION_AGE_MILLIS,
+                        DEFAULT_MAX_CACHED_SCORE_AGE_MILLIS);
+
+        resumeScanning();
+        if (!mRegistered) {
+            mContext.registerReceiver(mReceiver, mFilter, null /* permission */, mWorkHandler);
+            // NetworkCallback objects cannot be reused. http://b/20701525 .
+            mNetworkCallback = new WifiTrackerNetworkCallback();
+            mConnectivityManager.registerNetworkCallback(mNetworkRequest, mNetworkCallback);
+            mRegistered = true;
         }
     }
 
+
+    /**
+     * Synchronously update the list of access points with the latest information.
+     *
+     * <p>Intended to only be invoked within {@link #onStart()}.
+     */
+    @MainThread
+    private void forceUpdate() {
+        mLastInfo = mWifiManager.getConnectionInfo();
+        mLastNetworkInfo = mConnectivityManager.getNetworkInfo(mWifiManager.getCurrentNetwork());
+
+        fetchScansAndConfigsAndUpdateAccessPoints();
+    }
+
     private void registerScoreCache() {
         mNetworkScoreManager.registerNetworkScoreCache(
                 NetworkKey.TYPE_WIFI,
@@ -375,17 +362,15 @@
     @Override
     @MainThread
     public void onStop() {
-        synchronized (mLock) {
-            if (mRegistered) {
-                mContext.unregisterReceiver(mReceiver);
-                mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
-                mRegistered = false;
-            }
-            unregisterScoreCache();
-            pauseScanning(); // and set mStaleScanResults
-
-            mWorkHandler.removePendingMessages();
+        if (mRegistered) {
+            mContext.unregisterReceiver(mReceiver);
+            mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
+            mRegistered = false;
         }
+        unregisterScoreCache();
+        pauseScanning(); // and set mStaleScanResults
+
+        mWorkHandler.removeCallbacksAndMessages(null /* remove all */);
     }
 
     private void unregisterScoreCache() {
@@ -409,9 +394,6 @@
      */
     @AnyThread
     public List<AccessPoint> getAccessPoints() {
-        // TODO(sghuman): Investigate how to eliminate or reduce the need for locking now that we
-        // have transitioned to a single worker thread model.
-
         synchronized (mLock) {
             return new ArrayList<>(mInternalAccessPoints);
         }
@@ -446,15 +428,10 @@
         }
     }
 
-    private void handleResume() {
-        // TODO(sghuman): Investigate removing this and replacing it with a cache eviction call
-        // instead.
-        mScanResultCache.clear();
-        mSeenBssids.clear();
-    }
-
-    private Collection<ScanResult> updateScanResultCache(final List<ScanResult> newResults) {
-        // TODO(sghuman): Delete this and replace it with the Map of Ap Keys to ScanResults
+    private ArrayMap<String, List<ScanResult>> updateScanResultCache(
+            final List<ScanResult> newResults) {
+        // TODO(sghuman): Delete this and replace it with the Map of Ap Keys to ScanResults for
+        // memory efficiency
         for (ScanResult newResult : newResults) {
             if (newResult.SSID == null || newResult.SSID.isEmpty()) {
                 continue;
@@ -467,10 +444,27 @@
             evictOldScans();
         }
 
-        // TODO(sghuman): Update a Map<ApKey, List<ScanResults>> variable to be reused later after
-        // double threads have been removed.
+        ArrayMap<String, List<ScanResult>> scanResultsByApKey = new ArrayMap<>();
+        for (ScanResult result : mScanResultCache.values()) {
+            // Ignore hidden and ad-hoc networks.
+            if (result.SSID == null || result.SSID.length() == 0 ||
+                    result.capabilities.contains("[IBSS]")) {
+                continue;
+            }
 
-        return mScanResultCache.values();
+            String apKey = AccessPoint.getKey(result);
+            List<ScanResult> resultList;
+            if (scanResultsByApKey.containsKey(apKey)) {
+                resultList = scanResultsByApKey.get(apKey);
+            } else {
+                resultList = new ArrayList<>();
+                scanResultsByApKey.put(apKey, resultList);
+            }
+
+            resultList.add(result);
+        }
+
+        return scanResultsByApKey;
     }
 
     /**
@@ -504,93 +498,56 @@
     }
 
     /**
-     * Safely modify {@link #mInternalAccessPoints} by acquiring {@link #mLock} first.
-     *
-     * <p>Will not perform the update if {@link #mStaleScanResults} is true
+     * Retrieves latest scan results and wifi configs, then calls
+     * {@link #updateAccessPoints(List, List)}.
      */
-    private void updateAccessPoints() {
-        List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+    private void fetchScansAndConfigsAndUpdateAccessPoints() {
         final List<ScanResult> newScanResults = mWifiManager.getScanResults();
         if (isVerboseLoggingEnabled()) {
             Log.i(TAG, "Fetched scan results: " + newScanResults);
         }
 
-        synchronized (mLock) {
-            if(!mStaleScanResults) {
-                updateAccessPointsLocked(newScanResults, configs);
-            }
-        }
+        List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+        updateAccessPoints(newScanResults, configs);
     }
 
-    /**
-     * Update the internal list of access points.
-     *
-     * <p>Do not call directly (except for forceUpdate), use {@link #updateAccessPoints()} which
-     * acquires the lock first.
-     */
-    @GuardedBy("mLock")
-    private void updateAccessPointsLocked(final List<ScanResult> newScanResults,
+    /** Update the internal list of access points. */
+    private void updateAccessPoints(final List<ScanResult> newScanResults,
             List<WifiConfiguration> configs) {
-        // TODO(sghuman): Reduce the synchronization time by only holding the lock when
-        // modifying lists exposed to operations on the MainThread (getAccessPoints, stopTracking,
-        // startTracking, etc).
 
-        WifiConfiguration connectionConfig = null;
-        if (mLastInfo != null) {
-            connectionConfig = getWifiConfigurationForNetworkId(
-                    mLastInfo.getNetworkId(), configs);
-        }
-
-        // Swap the current access points into a cached list.
-        List<AccessPoint> cachedAccessPoints = new ArrayList<>(mInternalAccessPoints);
-        ArrayList<AccessPoint> accessPoints = new ArrayList<>();
-
-        // Clear out the configs so we don't think something is saved when it isn't.
-        for (AccessPoint accessPoint : cachedAccessPoints) {
-            accessPoint.clearConfig();
-        }
-
-        final Collection<ScanResult> results = updateScanResultCache(newScanResults);
-
+        // Map configs and scan results necessary to make AccessPoints
         final Map<String, WifiConfiguration> configsByKey = new ArrayMap(configs.size());
         if (configs != null) {
             for (WifiConfiguration config : configs) {
                 configsByKey.put(AccessPoint.getKey(config), config);
             }
         }
+        ArrayMap<String, List<ScanResult>> scanResultsByApKey =
+                updateScanResultCache(newScanResults);
 
-        final List<NetworkKey> scoresToRequest = new ArrayList<>();
-        if (results != null) {
-            // TODO(sghuman): Move this loop to updateScanResultCache and make instance variable
-            // after double handlers are removed.
-            ArrayMap<String, List<ScanResult>> scanResultsByApKey = new ArrayMap<>();
-            for (ScanResult result : results) {
-                // Ignore hidden and ad-hoc networks.
-                if (result.SSID == null || result.SSID.length() == 0 ||
-                        result.capabilities.contains("[IBSS]")) {
-                    continue;
-                }
+        WifiConfiguration connectionConfig = null;
+        if (mLastInfo != null) {
+            connectionConfig = getWifiConfigurationForNetworkId(mLastInfo.getNetworkId(), configs);
+        }
 
-                NetworkKey key = NetworkKey.createFromScanResult(result);
-                if (key != null && !mRequestedScores.contains(key)) {
-                    scoresToRequest.add(key);
-                }
+        // Rather than dropping and reacquiring the lock multiple times in this method, we lock
+        // once for efficiency of lock acquisition time and readability
+        synchronized (mLock) {
+            // Swap the current access points into a cached list for maintaining AP listeners
+            List<AccessPoint> cachedAccessPoints;
+            cachedAccessPoints = new ArrayList<>(mInternalAccessPoints);
 
-                String apKey = AccessPoint.getKey(result);
-                List<ScanResult> resultList;
-                if (scanResultsByApKey.containsKey(apKey)) {
-                    resultList = scanResultsByApKey.get(apKey);
-                } else {
-                    resultList = new ArrayList<>();
-                    scanResultsByApKey.put(apKey, resultList);
-                }
+            ArrayList<AccessPoint> accessPoints = new ArrayList<>();
 
-                resultList.add(result);
-            }
+            final List<NetworkKey> scoresToRequest = new ArrayList<>();
 
             for (Map.Entry<String, List<ScanResult>> entry : scanResultsByApKey.entrySet()) {
-                // List can not be empty as it is dynamically constructed on each iteration
-                ScanResult firstResult = entry.getValue().get(0);
+                for (ScanResult result : entry.getValue()) {
+                    NetworkKey key = NetworkKey.createFromScanResult(result);
+                    if (key != null && !mRequestedScores.contains(key)) {
+                        scoresToRequest.add(key);
+                    }
+                }
 
                 AccessPoint accessPoint =
                         getCachedOrCreate(entry.getValue(), cachedAccessPoints);
@@ -599,46 +556,54 @@
                 }
 
                 // Update the matching config if there is one, to populate saved network info
-                WifiConfiguration config = configsByKey.get(entry.getKey());
-                if (config != null) {
-                    accessPoint.update(config);
-                }
+                accessPoint.update(configsByKey.get(entry.getKey()));
 
                 accessPoints.add(accessPoint);
             }
-        }
 
-        requestScoresForNetworkKeys(scoresToRequest);
-        for (AccessPoint ap : accessPoints) {
-            ap.update(mScoreCache, mNetworkScoringUiEnabled, mMaxSpeedLabelScoreCacheAge);
-        }
-
-        // Pre-sort accessPoints to speed preference insertion
-        Collections.sort(accessPoints);
-
-        // Log accesspoints that were deleted
-        if (DBG()) {
-            Log.d(TAG, "------ Dumping SSIDs that were not seen on this scan ------");
-            for (AccessPoint prevAccessPoint : mInternalAccessPoints) {
-                if (prevAccessPoint.getSsid() == null)
-                    continue;
-                String prevSsid = prevAccessPoint.getSsidStr();
-                boolean found = false;
-                for (AccessPoint newAccessPoint : accessPoints) {
-                    if (newAccessPoint.getSsidStr() != null && newAccessPoint.getSsidStr()
-                            .equals(prevSsid)) {
-                        found = true;
-                        break;
-                    }
-                }
-                if (!found)
-                    Log.d(TAG, "Did not find " + prevSsid + " in this scan");
+            // If there were no scan results, create an AP for the currently connected network (if
+            // it exists).
+            // TODO(sghuman): Investigate if this works for an ephemeral (auto-connected) network
+            // when there are no scan results, as it may not have a valid WifiConfiguration
+            if (accessPoints.isEmpty() && connectionConfig != null) {
+                AccessPoint activeAp = new AccessPoint(mContext, connectionConfig);
+                activeAp.update(connectionConfig, mLastInfo, mLastNetworkInfo);
+                accessPoints.add(activeAp);
+                scoresToRequest.add(NetworkKey.createFromWifiInfo(mLastInfo));
             }
-            Log.d(TAG, "---- Done dumping SSIDs that were not seen on this scan ----");
-        }
 
-        mInternalAccessPoints.clear();
-        mInternalAccessPoints.addAll(accessPoints);
+            requestScoresForNetworkKeys(scoresToRequest);
+            for (AccessPoint ap : accessPoints) {
+                ap.update(mScoreCache, mNetworkScoringUiEnabled, mMaxSpeedLabelScoreCacheAge);
+            }
+
+            // Pre-sort accessPoints to speed preference insertion
+            Collections.sort(accessPoints);
+
+            // Log accesspoints that are being removed
+            if (DBG()) {
+                Log.d(TAG, "------ Dumping SSIDs that were not seen on this scan ------");
+                for (AccessPoint prevAccessPoint : mInternalAccessPoints) {
+                    if (prevAccessPoint.getSsid() == null)
+                        continue;
+                    String prevSsid = prevAccessPoint.getSsidStr();
+                    boolean found = false;
+                    for (AccessPoint newAccessPoint : accessPoints) {
+                        if (newAccessPoint.getSsidStr() != null && newAccessPoint.getSsidStr()
+                                .equals(prevSsid)) {
+                            found = true;
+                            break;
+                        }
+                    }
+                    if (!found)
+                        Log.d(TAG, "Did not find " + prevSsid + " in this scan");
+                }
+                Log.d(TAG, "---- Done dumping SSIDs that were not seen on this scan ----");
+            }
+
+            mInternalAccessPoints.clear();
+            mInternalAccessPoints.addAll(accessPoints);
+        }
 
         conditionallyNotifyListeners();
     }
@@ -659,21 +624,6 @@
         return accessPoint;
     }
 
-    @VisibleForTesting
-    AccessPoint getCachedOrCreate(WifiConfiguration config, List<AccessPoint> cache) {
-        final int N = cache.size();
-        for (int i = 0; i < N; i++) {
-            if (cache.get(i).matches(config)) {
-                AccessPoint ret = cache.remove(i);
-                ret.loadConfig(config);
-
-                return ret;
-            }
-        }
-        final AccessPoint accessPoint = new AccessPoint(mContext, config);
-        return accessPoint;
-    }
-
     private void updateNetworkInfo(NetworkInfo networkInfo) {
 
         /* Sticky broadcasts can call this when wifi is disabled */
@@ -739,7 +689,7 @@
         synchronized (mLock) {
             if (!mInternalAccessPoints.isEmpty()) {
                 mInternalAccessPoints.clear();
-                mListener.onAccessPointsChanged();
+                conditionallyNotifyListeners();
             }
         }
     }
@@ -767,126 +717,82 @@
         }
     }
 
+    /**
+     *  Receiver for handling broadcasts.
+     *
+     *  This receiver is registered on the WorkHandler.
+     */
     @VisibleForTesting
     final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            // No work should be performed in this Receiver, instead all operations should be passed
-            // off to the WorkHandler to avoid concurrent modification exceptions.
-
             String action = intent.getAction();
 
             if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
-                mWorkHandler.obtainMessage(
-                        WorkHandler.MSG_UPDATE_WIFI_STATE,
+                updateWifiState(
                         intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
-                            WifiManager.WIFI_STATE_UNKNOWN),
-                        0).sendToTarget();
+                                WifiManager.WIFI_STATE_UNKNOWN));
             } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) {
-                mWorkHandler
-                        .obtainMessage(
-                            WorkHandler.MSG_UPDATE_ACCESS_POINTS,
-                            WorkHandler.CLEAR_STALE_SCAN_RESULTS,
-                            0)
-                        .sendToTarget();
+                mStaleScanResults = false;
+
+                fetchScansAndConfigsAndUpdateAccessPoints();
             } else if (WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(action)
                     || WifiManager.LINK_CONFIGURATION_CHANGED_ACTION.equals(action)) {
-                mWorkHandler.sendEmptyMessage(WorkHandler.MSG_UPDATE_ACCESS_POINTS);
+                fetchScansAndConfigsAndUpdateAccessPoints();
             } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
+                // TODO(sghuman): Refactor these methods so they cannot result in duplicate
+                // onAccessPointsChanged updates being called from this intent.
                 NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
-                mWorkHandler.obtainMessage(WorkHandler.MSG_UPDATE_NETWORK_INFO, info)
-                        .sendToTarget();
-                mWorkHandler.sendEmptyMessage(WorkHandler.MSG_UPDATE_ACCESS_POINTS);
+                updateNetworkInfo(info);
+                fetchScansAndConfigsAndUpdateAccessPoints();
             } else if (WifiManager.RSSI_CHANGED_ACTION.equals(action)) {
                 NetworkInfo info =
                         mConnectivityManager.getNetworkInfo(mWifiManager.getCurrentNetwork());
-                mWorkHandler.obtainMessage(WorkHandler.MSG_UPDATE_NETWORK_INFO, info)
-                        .sendToTarget();
+                updateNetworkInfo(info);
             }
         }
     };
 
+    /**
+     * Handles updates to WifiState.
+     *
+     * <p>If Wifi is not enabled in the enabled state, {@link #mStaleScanResults} will be set to
+     * true.
+     */
+    private void updateWifiState(int state) {
+        if (state == WifiManager.WIFI_STATE_ENABLED) {
+            if (mScanner != null) {
+                // We only need to resume if mScanner isn't null because
+                // that means we want to be scanning.
+                mScanner.resume();
+            }
+        } else {
+            clearAccessPointsAndConditionallyUpdate();
+            mLastInfo = null;
+            mLastNetworkInfo = null;
+            if (mScanner != null) {
+                mScanner.pause();
+            }
+            mStaleScanResults = true;
+        }
+        mListener.onWifiStateChanged(state);
+    }
+
     private final class WifiTrackerNetworkCallback extends ConnectivityManager.NetworkCallback {
         public void onCapabilitiesChanged(Network network, NetworkCapabilities nc) {
             if (network.equals(mWifiManager.getCurrentNetwork())) {
+                // TODO(sghuman): Investigate whether this comment still holds true and if it makes
+                // more sense fetch the latest network info here:
+
                 // We don't send a NetworkInfo object along with this message, because even if we
                 // fetch one from ConnectivityManager, it might be older than the most recent
                 // NetworkInfo message we got via a WIFI_STATE_CHANGED broadcast.
-                mWorkHandler.sendEmptyMessage(WorkHandler.MSG_UPDATE_NETWORK_INFO);
+                mWorkHandler.post(() -> updateNetworkInfo(null));
             }
         }
     }
 
     @VisibleForTesting
-    final class WorkHandler extends Handler {
-        @VisibleForTesting static final int MSG_UPDATE_ACCESS_POINTS = 0;
-        private static final int MSG_UPDATE_NETWORK_INFO = 1;
-        private static final int MSG_RESUME = 2;
-        private static final int MSG_UPDATE_WIFI_STATE = 3;
-
-        private static final int CLEAR_STALE_SCAN_RESULTS = 1;
-
-        public WorkHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            // TODO(sghuman): Clean up synchronization to only be used when modifying collections
-            // exposed to the MainThread (through onStart, onStop, forceUpdate).
-            synchronized (mLock) {
-                processMessage(msg);
-            }
-        }
-
-        private void processMessage(Message msg) {
-            if (!mRegistered) return;
-
-            switch (msg.what) {
-                case MSG_UPDATE_ACCESS_POINTS:
-                    if (msg.arg1 == CLEAR_STALE_SCAN_RESULTS) {
-                        mStaleScanResults = false;
-                    }
-                    updateAccessPoints();
-                    break;
-                case MSG_UPDATE_NETWORK_INFO:
-                    updateNetworkInfo((NetworkInfo) msg.obj);
-                    break;
-                case MSG_RESUME:
-                    handleResume();
-                    break;
-                case MSG_UPDATE_WIFI_STATE:
-                    if (msg.arg1 == WifiManager.WIFI_STATE_ENABLED) {
-                        if (mScanner != null) {
-                            // We only need to resume if mScanner isn't null because
-                            // that means we want to be scanning.
-                            mScanner.resume();
-                        }
-                    } else {
-                        clearAccessPointsAndConditionallyUpdate();
-                        mLastInfo = null;
-                        mLastNetworkInfo = null;
-                        if (mScanner != null) {
-                            mScanner.pause();
-                        }
-                        synchronized (mLock) {
-                            mStaleScanResults = true;
-                        }
-                    }
-                    mListener.onWifiStateChanged(msg.arg1);
-                    break;
-            }
-        }
-
-        private void removePendingMessages() {
-            removeMessages(MSG_UPDATE_ACCESS_POINTS);
-            removeMessages(MSG_UPDATE_NETWORK_INFO);
-            removeMessages(MSG_RESUME);
-            removeMessages(MSG_UPDATE_WIFI_STATE);
-        }
-    }
-
-    @VisibleForTesting
     class Scanner extends Handler {
         static final int MSG_SCAN = 0;
 
@@ -944,19 +850,16 @@
     }
 
     /**
-     * Wraps the given {@link WifiListener} instance and executes it's methods on the Main Thread.
+     * Wraps the given {@link WifiListener} instance and executes its methods on the Main Thread.
      *
-     * <p>This mechanism allows us to no longer need a separate MainHandler and WorkHandler, which
-     * were previously both performing work, while avoiding errors which occur from executing
-     * callbacks which manipulate UI elements from a different thread than the MainThread.
+     * <p>Also logs all callbacks invocations when verbose logging is enabled.
      */
-    private static class WifiListenerWrapper implements WifiListener {
+    @VisibleForTesting
+    public static class WifiListenerExecutor implements WifiListener {
 
-        private final Handler mHandler;
         private final WifiListener mDelegatee;
 
-        public WifiListenerWrapper(WifiListener listener) {
-            mHandler = new Handler(Looper.getMainLooper());
+        public WifiListenerExecutor(WifiListener listener) {
             mDelegatee = listener;
         }
 
@@ -966,7 +869,7 @@
                 Log.i(TAG,
                         String.format("Invoking onWifiStateChanged callback with state %d", state));
             }
-            mHandler.post(() -> mDelegatee.onWifiStateChanged(state));
+            ThreadUtils.postOnMainThread(() -> mDelegatee.onWifiStateChanged(state));
         }
 
         @Override
@@ -974,7 +877,7 @@
             if (isVerboseLoggingEnabled()) {
                 Log.i(TAG, "Invoking onConnectedChanged callback");
             }
-            mHandler.post(() -> mDelegatee.onConnectedChanged());
+            ThreadUtils.postOnMainThread(() -> mDelegatee.onConnectedChanged());
         }
 
         @Override
@@ -982,10 +885,15 @@
             if (isVerboseLoggingEnabled()) {
                 Log.i(TAG, "Invoking onAccessPointsChanged callback");
             }
-            mHandler.post(() -> mDelegatee.onAccessPointsChanged());
+            ThreadUtils.postOnMainThread(() -> mDelegatee.onAccessPointsChanged());
         }
     }
 
+    /**
+     * WifiListener interface that defines callbacks indicating state changes in WifiTracker.
+     *
+     * <p>All callbacks are invoked on the MainThread.
+     */
     public interface WifiListener {
         /**
          * Called when the state of Wifi has changed, the state will be one of
@@ -1016,7 +924,7 @@
     }
 
     /**
-     * Invokes {@link WifiListenerWrapper#onAccessPointsChanged()} if {@link #mStaleScanResults}
+     * Invokes {@link WifiListenerExecutor#onAccessPointsChanged()} iif {@link #mStaleScanResults}
      * is false.
      */
     private void conditionallyNotifyListeners() {
@@ -1024,6 +932,6 @@
             return;
         }
 
-        ThreadUtils.postOnMainThread(() -> mListener.onAccessPointsChanged());
+        mListener.onAccessPointsChanged();
     }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/wrapper/PackageManagerWrapper.java b/packages/SettingsLib/src/com/android/settingslib/wrapper/PackageManagerWrapper.java
index b1f3f3c..235daf2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wrapper/PackageManagerWrapper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wrapper/PackageManagerWrapper.java
@@ -130,6 +130,13 @@
     }
 
     /**
+     * Calls {@code PackageManager.queryIntentServices}
+     */
+    public List<ResolveInfo> queryIntentServices(Intent intent, int i) {
+        return mPm.queryIntentServices(intent, i);
+    }
+
+    /**
      * Calls {@code PackageManager.replacePreferredActivity}
      */
     public void replacePreferredActivity(IntentFilter homeFilter, int matchCategoryEmpty,
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
index 0c49bb6..ca965f3 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
@@ -21,18 +21,15 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.atMost;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
@@ -58,7 +55,6 @@
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
@@ -76,12 +72,10 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.BitSet;
-import java.util.Collections;
 import java.util.List;
-import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 // TODO(sghuman): Change these to robolectric tests b/35766684.
 
@@ -141,7 +135,7 @@
     @Mock private RssiCurve mockBadgeCurve1;
     @Mock private RssiCurve mockBadgeCurve2;
     @Mock private WifiManager mockWifiManager;
-    @Mock private WifiTracker.WifiListener mockWifiListener;
+    @Mock private WifiTracker.WifiListenerExecutor mockWifiListenerExecutor;
 
     private final List<NetworkKey> mRequestedKeys = new ArrayList<>();
 
@@ -153,6 +147,7 @@
 
     private int mOriginalScoringUiSettingValue;
 
+    @SuppressWarnings("VisibleForTests")
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
@@ -203,17 +198,14 @@
                     }
                 }).when(mockNetworkScoreManager).requestScores(Matchers.<NetworkKey[]>any());
 
-        doAnswer(
-                new Answer<Void>() {
-                  @Override
-                  public Void answer (InvocationOnMock invocation) throws Throwable {
+        // We use a latch to detect callbacks as Tracker initialization state often invokes
+        // callbacks
+        doAnswer(invocation -> {
                     if (mAccessPointsChangedLatch != null) {
                       mAccessPointsChangedLatch.countDown();
                     }
-
                     return null;
-                  }
-                }).when(mockWifiListener).onAccessPointsChanged();
+                }).when(mockWifiListenerExecutor).onAccessPointsChanged();
 
         // Turn on Scoring UI features
         mOriginalScoringUiSettingValue = Settings.Global.getInt(
@@ -271,8 +263,7 @@
             tracker.mReceiver.onReceive(mContext, intent);
         }
 
-        sendScanResultsAndProcess(tracker);
-        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
+        sendScanResults(tracker);
 
         return tracker;
     }
@@ -280,7 +271,7 @@
     private WifiTracker createMockedWifiTracker() {
         final WifiTracker wifiTracker = new WifiTracker(
                 mContext,
-                mockWifiListener,
+                mockWifiListenerExecutor,
                 mockWifiManager,
                 mockConnectivityManager,
                 mockNetworkScoreManager,
@@ -291,26 +282,19 @@
 
     private void startTracking(WifiTracker tracker)  throws InterruptedException {
         CountDownLatch latch = new CountDownLatch(1);
-        mScannerHandler.post(new Runnable() {
-            @Override
-            public void run() {
+        mScannerHandler.post(() -> {
                 tracker.onStart();
                 latch.countDown();
-            }
         });
         assertTrue("Latch timed out", latch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
     }
 
-    private void sendScanResultsAndProcess(WifiTracker tracker) throws InterruptedException {
-        mAccessPointsChangedLatch = new CountDownLatch(1);
+    private void sendScanResults(WifiTracker tracker) throws InterruptedException {
         Intent i = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
         tracker.mReceiver.onReceive(mContext, i);
-
-        assertTrue("Latch timed out",
-                mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
     }
 
-    private void updateScores() {
+    private void sendUpdatedScores() throws InterruptedException {
         Bundle attr1 = new Bundle();
         attr1.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, mockBadgeCurve1);
         ScoredNetwork sc1 =
@@ -356,12 +340,8 @@
 
     private void waitForHandlersToProcessCurrentlyEnqueuedMessages(WifiTracker tracker)
             throws InterruptedException {
-        // TODO(sghuman): This should no longer be necessary in a single work handler model
-
         CountDownLatch workerLatch = new CountDownLatch(1);
-        tracker.mWorkHandler.post(() -> {
-            workerLatch.countDown();
-        });
+        tracker.mWorkHandler.post(() -> workerLatch.countDown());
         assertTrue("Latch timed out while waiting for WorkerHandler",
                 workerLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
     }
@@ -381,7 +361,6 @@
         Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
         intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
         tracker.mReceiver.onReceive(mContext, intent);
-        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
     }
 
     @Test
@@ -457,7 +436,6 @@
 
         mRequestScoresLatch = new CountDownLatch(1);
         startTracking(tracker);
-        tracker.forceUpdate();
         assertTrue("Latch timed out",
                 mRequestScoresLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
 
@@ -470,7 +448,7 @@
             throws InterruptedException {
         // Start the tracker and inject the initial scan results and then stop tracking
         WifiTracker tracker =  createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
-        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
+        updateScoresAndWaitForCacheListenerToProcess(tracker);
         tracker.onStop();
 
         assertThat(mScoreCacheCaptor.getValue().getScoredNetwork(NETWORK_KEY_1)).isNotNull();
@@ -481,19 +459,18 @@
             throws InterruptedException {
         WifiTracker tracker = createMockedWifiTracker();
         startTracking(tracker);
-        sendScanResultsAndProcess(tracker);
+        sendScanResults(tracker);
 
-        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
+        updateScoresAndWaitForCacheListenerToProcess(tracker);
     }
 
-    private void updateScoresAndWaitForAccessPointsChangedCallback(WifiTracker tracker)
+    private void updateScoresAndWaitForCacheListenerToProcess(WifiTracker tracker)
             throws InterruptedException {
-        // Updating scores can happen together or one after the other, so the latch countdown is set
-        // to 2.
-        mAccessPointsChangedLatch = new CountDownLatch(1);
-        updateScores();
-        assertTrue("onAccessPointChanged was not called after updating scores",
-            mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
+        // Scores are updated via the cache listener hence we need to wait for the work handler
+        // to finish before proceeding.
+        sendUpdatedScores();
+
+        // Ensure the work handler has processed the scores inside the cache listener of WifiTracker
         waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
     }
 
@@ -505,7 +482,7 @@
         assertEquals(aps.get(0).getSsidStr(), SSID_1);
         assertEquals(aps.get(1).getSsidStr(), SSID_2);
 
-        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
+        updateScoresAndWaitForCacheListenerToProcess(tracker);
 
         aps = tracker.getAccessPoints();
         assertTrue(aps.size() == 2);
@@ -527,7 +504,7 @@
         assertEquals(aps.get(0).getSsidStr(), SSID_1);
         assertEquals(aps.get(1).getSsidStr(), SSID_2);
 
-        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
+        updateScoresAndWaitForCacheListenerToProcess(tracker);
 
         aps = tracker.getAccessPoints();
         assertTrue(aps.size() == 2);
@@ -535,12 +512,11 @@
         assertEquals(aps.get(1).getSsidStr(), SSID_2);
     }
 
-    @FlakyTest
     @Test
     public void scoreCacheUpdateScoresShouldInsertSpeedIntoAccessPoint()
             throws InterruptedException {
         WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
-        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
+        updateScoresAndWaitForCacheListenerToProcess(tracker);
 
         List<AccessPoint> aps = tracker.getAccessPoints();
 
@@ -557,7 +533,7 @@
     public void scoreCacheUpdateMeteredShouldUpdateAccessPointMetering()
             throws InterruptedException {
         WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
-        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
+        updateScoresAndWaitForCacheListenerToProcess(tracker);
 
         List<AccessPoint> aps = tracker.getAccessPoints();
 
@@ -579,7 +555,7 @@
                 0 /* disabled */);
 
         WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
-        updateScoresAndWaitForAccessPointsChangedCallback(tracker);
+        updateScoresAndWaitForCacheListenerToProcess(tracker);
 
         List<AccessPoint> aps = tracker.getAccessPoints();
 
@@ -617,7 +593,7 @@
                 .thenReturn(Arrays.asList(buildScanResult1(), buildScanResult2(), newResult));
 
         mRequestScoresLatch = new CountDownLatch(1);
-        sendScanResultsAndProcess(tracker);
+        sendScanResults(tracker);
         assertTrue(mRequestScoresLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
 
         assertEquals(1, mRequestedKeys.size());
@@ -636,7 +612,7 @@
         // Verify listener is unregistered so updating a score does not throw an error by posting
         // a message to the dead work handler
         mWorkerThread.quit();
-        updateScores();
+        sendUpdatedScores();
     }
 
     /**
@@ -670,7 +646,8 @@
         when(mockWifiManager.getConfiguredNetworks())
                 .thenReturn(new ArrayList<WifiConfiguration>());
         when(mockWifiManager.getScanResults()).thenReturn(results);
-        tracker.forceUpdate();
+
+        startTracking(tracker);
     }
 
     @Test
@@ -682,26 +659,19 @@
         WifiInfo info = new WifiInfo(CONNECTED_AP_1_INFO);
         info.setRssi(newRssi);
 
-        CountDownLatch latch = new CountDownLatch(1);
-
         // Once the new info has been fetched, we need to wait for the access points to be copied
         mAccessPointsChangedLatch = new CountDownLatch(1);
-        doAnswer(invocation -> {
-                    latch.countDown();
-                    return info;
-                }).when(mockWifiManager).getConnectionInfo();
+        doAnswer(invocation -> info).when(mockWifiManager).getConnectionInfo();
 
         tracker.mReceiver.onReceive(mContext, new Intent(WifiManager.RSSI_CHANGED_ACTION));
-        assertTrue("New connection info never retrieved",
-                latch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
+
         assertTrue("onAccessPointsChanged never called",
                 mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
-
         assertThat(tracker.getAccessPoints().get(0).getRssi()).isEqualTo(newRssi);
     }
 
     @Test
-    public void forceUpdateShouldSynchronouslyFetchLatestInformation() throws Exception {
+    public void onStartShouldSynchronouslyFetchLatestInformation() throws Exception {
         Network mockNetwork = mock(Network.class);
         when(mockWifiManager.getCurrentNetwork()).thenReturn(mockNetwork);
 
@@ -713,19 +683,50 @@
         when(mockConnectivityManager.getNetworkInfo(any(Network.class))).thenReturn(networkInfo);
 
         WifiTracker tracker = createMockedWifiTracker();
-        tracker.forceUpdate();
+        startTracking(tracker);
 
         verify(mockWifiManager).getConnectionInfo();
         verify(mockWifiManager, times(1)).getConfiguredNetworks();
         verify(mockConnectivityManager).getNetworkInfo(any(Network.class));
 
-        verify(mockWifiListener, never()).onAccessPointsChanged(); // mStaleAccessPoints is true
+        // mStaleAccessPoints is true
+        verify(mockWifiListenerExecutor, never()).onAccessPointsChanged();
         assertThat(tracker.getAccessPoints().size()).isEqualTo(2);
         assertThat(tracker.getAccessPoints().get(0).isActive()).isTrue();
     }
 
     @Test
-    public void stopTrackingShouldRemoveWifiListenerCallbacks() throws Exception {
+    public void onStartShouldDisplayConnectedAccessPointWhenThereAreNoScanResults()
+            throws Exception {
+        Network mockNetwork = mock(Network.class);
+        when(mockWifiManager.getCurrentNetwork()).thenReturn(mockNetwork);
+
+        when(mockWifiManager.getConnectionInfo()).thenReturn(CONNECTED_AP_1_INFO);
+
+        NetworkInfo networkInfo = new NetworkInfo(
+                ConnectivityManager.TYPE_WIFI, 0, "Type Wifi", "subtype");
+        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "connected", "test");
+        when(mockConnectivityManager.getNetworkInfo(any(Network.class))).thenReturn(networkInfo);
+
+        // Don't return any scan results
+        when(mockWifiManager.getScanResults()).thenReturn(new ArrayList<>());
+
+        WifiTracker tracker = createMockedWifiTracker();
+        startTracking(tracker);
+
+        verify(mockWifiManager).getConnectionInfo();
+        verify(mockWifiManager, times(1)).getConfiguredNetworks();
+        verify(mockConnectivityManager).getNetworkInfo(any(Network.class));
+
+        // mStaleAccessPoints is true
+        verify(mockWifiListenerExecutor, never()).onAccessPointsChanged();
+
+        assertThat(tracker.getAccessPoints().size()).isEqualTo(1);
+        assertThat(tracker.getAccessPoints().get(0).isActive()).isTrue();
+    }
+
+    @Test
+    public void stopTrackingShouldRemoveAllPendingWork() throws Exception {
         WifiTracker tracker = createMockedWifiTracker();
         startTracking(tracker);
 
@@ -743,25 +744,21 @@
         });
 
         // Enqueue messages
-        tracker.mWorkHandler.sendEmptyMessage(WifiTracker.WorkHandler.MSG_UPDATE_ACCESS_POINTS);
+        final AtomicBoolean executed = new AtomicBoolean(false);
+        tracker.mWorkHandler.post(() -> executed.set(true));
 
         try {
             ready.await(); // Make sure we have entered the first message handler
         } catch (InterruptedException e) {}
         tracker.onStop();
 
-        verify(mockWifiListener, atMost(1)).onAccessPointsChanged();
-        verify(mockWifiListener, atMost(1)).onConnectedChanged();
-        verify(mockWifiListener, atMost(1)).onWifiStateChanged(anyInt());
-
         lock.countDown();
         assertTrue("Latch timed out", latch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
 
-        assertThat(tracker.mWorkHandler.hasMessages(
-                WifiTracker.WorkHandler.MSG_UPDATE_ACCESS_POINTS)).isFalse();
-        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
+        // In case the method was already executing
+        assertThat(tracker.mWorkHandler.hasMessagesOrCallbacks()).isFalse();
 
-        verifyNoMoreInteractions(mockWifiListener);
+        assertThat(executed.get()).isFalse();
     }
 
     @Test
@@ -769,10 +766,8 @@
             throws Exception {
         WifiTracker tracker = createMockedWifiTracker();
         startTracking(tracker);
-        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
 
         tracker.onStop();
-        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
 
         startTracking(tracker);
 
@@ -782,11 +777,10 @@
         tracker.mReceiver.onReceive(
                 mContext, new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION));
 
-        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
 
-        verify(mockWifiListener, never()).onAccessPointsChanged();
+        verify(mockWifiListenerExecutor, never()).onAccessPointsChanged();
 
-        sendScanResultsAndProcess(tracker); // verifies onAccessPointsChanged is invoked
+        sendScanResults(tracker); // verifies onAccessPointsChanged is invoked
     }
 
     @Test
@@ -794,7 +788,6 @@
             throws Exception {
         WifiTracker tracker = createMockedWifiTracker();
         startTracking(tracker);
-        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
 
         tracker.mReceiver.onReceive(mContext, new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
         tracker.mReceiver.onReceive(
@@ -802,10 +795,9 @@
         tracker.mReceiver.onReceive(
                 mContext, new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION));
 
-        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
-        verify(mockWifiListener, never()).onAccessPointsChanged();
+        verify(mockWifiListenerExecutor, never()).onAccessPointsChanged();
 
-        sendScanResultsAndProcess(tracker); // verifies onAccessPointsChanged is invoked
+        sendScanResults(tracker); // verifies onAccessPointsChanged is invoked
     }
 
     @Test
@@ -813,11 +805,10 @@
         WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
 
         when(mockWifiManager.isWifiEnabled()).thenReturn(false);
+
         mAccessPointsChangedLatch = new CountDownLatch(1);
         tracker.mReceiver.onReceive(mContext, new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
-
-        assertTrue(mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
-        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
+        assertThat(mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS)).isTrue();
 
         assertThat(tracker.getAccessPoints()).isEmpty();
     }
@@ -825,7 +816,7 @@
     @Test
     public void onConnectedChangedCallback_shouldNotBeInvokedWhenNoStateChange() throws Exception {
         WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
-        verify(mockWifiListener, times(1)).onConnectedChanged();
+        verify(mockWifiListenerExecutor, times(1)).onConnectedChanged();
 
         NetworkInfo networkInfo = new NetworkInfo(
                 ConnectivityManager.TYPE_WIFI, 0, "Type Wifi", "subtype");
@@ -835,14 +826,13 @@
         intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
         tracker.mReceiver.onReceive(mContext, intent);
 
-        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
-        verify(mockWifiListener, times(1)).onConnectedChanged();
+        verify(mockWifiListenerExecutor, times(1)).onConnectedChanged();
     }
 
     @Test
     public void onConnectedChangedCallback_shouldBeInvokedWhenStateChanges() throws Exception {
         WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
-        verify(mockWifiListener, times(1)).onConnectedChanged();
+        verify(mockWifiListenerExecutor, times(1)).onConnectedChanged();
 
         NetworkInfo networkInfo = new NetworkInfo(
                 ConnectivityManager.TYPE_WIFI, 0, "Type Wifi", "subtype");
@@ -853,9 +843,8 @@
         intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
         tracker.mReceiver.onReceive(mContext, intent);
 
-        waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
         assertThat(tracker.isConnected()).isFalse();
-        verify(mockWifiListener, times(2)).onConnectedChanged();
+        verify(mockWifiListenerExecutor, times(2)).onConnectedChanged();
     }
 
     @Test
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/DefaultAppInfoTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/DefaultAppInfoTest.java
new file mode 100644
index 0000000..6a161d0
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/DefaultAppInfoTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.applications;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+
+import com.android.settingslib.SettingsLibRobolectricTestRunner;
+import com.android.settingslib.wrapper.PackageManagerWrapper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsLibRobolectricTestRunner.class)
+public class DefaultAppInfoTest {
+
+    @Mock
+    private PackageItemInfo mPackageItemInfo;
+    @Mock
+    private ComponentName mComponentName;
+    @Mock
+    private PackageManager mPackageManager;
+    @Mock
+    private PackageManagerWrapper mPackageManagerWrapper;
+    @Mock
+    private ApplicationInfo mApplicationInfo;
+    @Mock
+    private Drawable mIcon;
+
+    private Context mContext;
+    private DefaultAppInfo mInfo;
+
+    @Before
+    public void setUp() throws PackageManager.NameNotFoundException {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application);
+        doReturn(mPackageManager).when(mContext).getPackageManager();
+        when(mPackageManagerWrapper.getPackageManager()).thenReturn(mPackageManager);
+        when(mPackageManagerWrapper.getApplicationInfoAsUser(anyString(), anyInt(),
+                anyInt())).thenReturn(mApplicationInfo);
+        when(mPackageManager.loadUnbadgedItemIcon(mPackageItemInfo, mApplicationInfo)).thenReturn(
+                mIcon);
+    }
+
+    @Test
+    public void initInfoWithActivityInfo_shouldLoadInfo() {
+        mPackageItemInfo.packageName = "test";
+        mInfo = new DefaultAppInfo(mContext, mPackageManagerWrapper, mPackageItemInfo);
+        mInfo.loadLabel();
+        Drawable icon = mInfo.loadIcon();
+
+        assertThat(mInfo.getKey()).isEqualTo(mPackageItemInfo.packageName);
+        assertThat(icon).isNotNull();
+        verify(mPackageItemInfo).loadLabel(mPackageManager);
+    }
+
+    @Test
+    public void initInfoWithComponent_shouldLoadInfo() {
+        when(mComponentName.getPackageName()).thenReturn("com.android.settings");
+
+        mInfo = new DefaultAppInfo(mContext, mPackageManagerWrapper, 0 /* uid */, mComponentName);
+        mInfo.getKey();
+
+        verify(mComponentName).flattenToString();
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
new file mode 100644
index 0000000..d6b2006
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settingslib.bluetooth;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+
+import com.android.settingslib.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.util.Collection;
+
+@RunWith(RobolectricTestRunner.class)
+public class CachedBluetoothDeviceManagerTest {
+    private final static String DEVICE_NAME_1 = "TestName_1";
+    private final static String DEVICE_NAME_2 = "TestName_2";
+    private final static String DEVICE_ALIAS_1 = "TestAlias_1";
+    private final static String DEVICE_ALIAS_2 = "TestAlias_2";
+    private final static String DEVICE_ADDRESS_1 = "AA:BB:CC:DD:EE:11";
+    private final static String DEVICE_ADDRESS_2 = "AA:BB:CC:DD:EE:22";
+    private final BluetoothClass DEVICE_CLASS_1 =
+        new BluetoothClass(BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES);
+    private final BluetoothClass DEVICE_CLASS_2 =
+        new BluetoothClass(BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE);
+    @Mock
+    private LocalBluetoothAdapter mLocalAdapter;
+    @Mock
+    private LocalBluetoothProfileManager mLocalProfileManager;
+    @Mock
+    private LocalBluetoothManager mLocalBluetoothManager;
+    @Mock
+    private BluetoothEventManager mBluetoothEventManager;
+    @Mock
+    private HeadsetProfile mHfpProfile;
+    @Mock
+    private A2dpProfile mA2dpProfile;
+    @Mock
+    private PanProfile mPanProfile;
+    @Mock
+    private BluetoothDevice mDevice1;
+    @Mock
+    private BluetoothDevice mDevice2;
+    private CachedBluetoothDeviceManager mCachedDeviceManager;
+    private Context mContext;
+    private String[] mActiveDeviceStringsArray;
+    private String mActiveDeviceStringNone;
+    private String mActiveDeviceStringAll;
+    private String mActiveDeviceStringMedia;
+    private String mActiveDeviceStringPhone;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        when(mDevice1.getAddress()).thenReturn(DEVICE_ADDRESS_1);
+        when(mDevice2.getAddress()).thenReturn(DEVICE_ADDRESS_2);
+        when(mDevice1.getName()).thenReturn(DEVICE_NAME_1);
+        when(mDevice2.getName()).thenReturn(DEVICE_NAME_2);
+        when(mDevice1.getAliasName()).thenReturn(DEVICE_ALIAS_1);
+        when(mDevice2.getAliasName()).thenReturn(DEVICE_ALIAS_2);
+        when(mDevice1.getBluetoothClass()).thenReturn(DEVICE_CLASS_1);
+        when(mDevice2.getBluetoothClass()).thenReturn(DEVICE_CLASS_2);
+
+        when(mLocalBluetoothManager.getEventManager()).thenReturn(mBluetoothEventManager);
+        when(mLocalAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON);
+        when(mHfpProfile.isProfileReady()).thenReturn(true);
+        when(mA2dpProfile.isProfileReady()).thenReturn(true);
+        when(mPanProfile.isProfileReady()).thenReturn(true);
+        mCachedDeviceManager = new CachedBluetoothDeviceManager(mContext, mLocalBluetoothManager);
+    }
+
+    /**
+     * Test to verify addDevice().
+     */
+    @Test
+    public void testAddDevice_validCachedDevices_devicesAdded() {
+        CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
+                mLocalProfileManager, mDevice1);
+        assertThat(cachedDevice1).isNotNull();
+        CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
+                mLocalProfileManager, mDevice2);
+        assertThat(cachedDevice2).isNotNull();
+
+        Collection<CachedBluetoothDevice> devices = mCachedDeviceManager.getCachedDevicesCopy();
+        assertThat(devices).contains(cachedDevice1);
+        assertThat(devices).contains(cachedDevice2);
+
+        assertThat(mCachedDeviceManager.findDevice(mDevice1)).isEqualTo(cachedDevice1);
+        assertThat(mCachedDeviceManager.findDevice(mDevice2)).isEqualTo(cachedDevice2);
+    }
+
+    /**
+     * Test to verify getName().
+     */
+    @Test
+    public void testGetName_validCachedDevice_nameFound() {
+        CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
+                mLocalProfileManager, mDevice1);
+        assertThat(cachedDevice1).isNotNull();
+        assertThat(mCachedDeviceManager.getName(mDevice1)).isEqualTo(DEVICE_ALIAS_1);
+    }
+
+    /**
+     * Test to verify onDeviceNameUpdated().
+     */
+    @Test
+    public void testOnDeviceNameUpdated_validName_nameUpdated() {
+        CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
+                mLocalProfileManager, mDevice1);
+        assertThat(cachedDevice1).isNotNull();
+        assertThat(cachedDevice1.getName()).isEqualTo(DEVICE_ALIAS_1);
+
+        final String newAliasName = "NewAliasName";
+        when(mDevice1.getAliasName()).thenReturn(newAliasName);
+        mCachedDeviceManager.onDeviceNameUpdated(mDevice1);
+        assertThat(cachedDevice1.getName()).isEqualTo(newAliasName);
+    }
+
+    /**
+     * Test to verify clearNonBondedDevices().
+     */
+    @Test
+    public void testClearNonBondedDevices_bondedAndNonBondedDevices_nonBondedDevicesCleared() {
+        CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
+                mLocalProfileManager, mDevice1);
+        assertThat(cachedDevice1).isNotNull();
+        CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
+                mLocalProfileManager, mDevice2);
+        assertThat(cachedDevice2).isNotNull();
+
+        when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+        when(mDevice2.getBondState()).thenReturn(BluetoothDevice.BOND_BONDING);
+        mCachedDeviceManager.clearNonBondedDevices();
+        Collection<CachedBluetoothDevice> devices = mCachedDeviceManager.getCachedDevicesCopy();
+        assertThat(devices).contains(cachedDevice1);
+        assertThat(devices).contains(cachedDevice2);
+
+        when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+        when(mDevice2.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
+        mCachedDeviceManager.clearNonBondedDevices();
+        devices = mCachedDeviceManager.getCachedDevicesCopy();
+        assertThat(devices).contains(cachedDevice1);
+        assertThat(devices).doesNotContain(cachedDevice2);
+
+        when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
+        when(mDevice2.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
+        mCachedDeviceManager.clearNonBondedDevices();
+        devices = mCachedDeviceManager.getCachedDevicesCopy();
+        assertThat(devices).doesNotContain(cachedDevice1);
+        assertThat(devices).doesNotContain(cachedDevice2);
+    }
+
+    /**
+     * Test to verify onBtClassChanged().
+     */
+    @Test
+    public void testOnBtClassChanged_validBtClass_classChanged() {
+        CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
+                mLocalProfileManager, mDevice1);
+        assertThat(cachedDevice1).isNotNull();
+        assertThat(cachedDevice1.getBtClass()).isEqualTo(DEVICE_CLASS_1);
+
+        final BluetoothClass newBluetoothClass = DEVICE_CLASS_2;
+        when(mDevice1.getBluetoothClass()).thenReturn(newBluetoothClass);
+        mCachedDeviceManager.onBtClassChanged(mDevice1);
+        assertThat(cachedDevice1.getBtClass()).isEqualTo(newBluetoothClass);
+    }
+
+    /**
+     * Test to verify onDeviceDisappeared().
+     */
+    @Test
+    public void testOnDeviceDisappeared_deviceBondedUnbonded_unbondedDeviceDisappeared() {
+        CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
+                mLocalProfileManager, mDevice1);
+        assertThat(cachedDevice1).isNotNull();
+
+        when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+        assertThat(mCachedDeviceManager.onDeviceDisappeared(cachedDevice1)).isFalse();
+
+        when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
+        assertThat(mCachedDeviceManager.onDeviceDisappeared(cachedDevice1)).isTrue();
+    }
+
+    /**
+     * Test to verify onActiveDeviceChanged().
+     */
+    @Test
+    public void testOnActiveDeviceChanged_connectedDevices_activeDeviceChanged() {
+        CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
+                mLocalProfileManager, mDevice1);
+        assertThat(cachedDevice1).isNotNull();
+        CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
+                mLocalProfileManager, mDevice2);
+        assertThat(cachedDevice2).isNotNull();
+
+        when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+        when(mDevice2.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+
+        // Connect both devices for A2DP and HFP
+        cachedDevice1.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+        cachedDevice2.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+        cachedDevice1.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+        cachedDevice2.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+
+        // Verify that both devices are connected and none is Active
+        assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
+        assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
+        assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
+        assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
+
+        // The first device is active for A2DP, the second device is active for HFP
+        mCachedDeviceManager.onActiveDeviceChanged(cachedDevice1, BluetoothProfile.A2DP);
+        mCachedDeviceManager.onActiveDeviceChanged(cachedDevice2, BluetoothProfile.HEADSET);
+        assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.A2DP)).isTrue();
+        assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
+        assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
+        assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEADSET)).isTrue();
+
+        // The first device is active for A2DP and HFP
+        mCachedDeviceManager.onActiveDeviceChanged(cachedDevice1, BluetoothProfile.HEADSET);
+        assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.A2DP)).isTrue();
+        assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.HEADSET)).isTrue();
+        assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
+        assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
+
+        // The second device is active for A2DP and HFP
+        mCachedDeviceManager.onActiveDeviceChanged(cachedDevice2, BluetoothProfile.A2DP);
+        mCachedDeviceManager.onActiveDeviceChanged(cachedDevice2, BluetoothProfile.HEADSET);
+        assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
+        assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
+        assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.A2DP)).isTrue();
+        assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEADSET)).isTrue();
+
+        // No active device for A2DP
+        mCachedDeviceManager.onActiveDeviceChanged(null, BluetoothProfile.A2DP);
+        assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
+        assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
+        assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
+        assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEADSET)).isTrue();
+
+        // No active device for HFP
+        mCachedDeviceManager.onActiveDeviceChanged(null, BluetoothProfile.HEADSET);
+        assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
+        assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
+        assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
+        assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
index 92c68e6..0775727 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -147,7 +147,7 @@
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected");
 
         // Set device as Active for A2DP and test connection state summary
-        mCachedDevice.setActiveDevice(true, BluetoothProfile.A2DP);
+        mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(media)");
 
         // Test with battery level
@@ -163,7 +163,7 @@
         mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
         // Set A2DP profile to be connected, Active and test connection state summary
         mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
-        mCachedDevice.setActiveDevice(true, BluetoothProfile.A2DP);
+        mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(media)");
 
         // Set A2DP profile to be disconnected and test connection state summary
@@ -179,7 +179,7 @@
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected");
 
         // Set device as Active for HFP and test connection state summary
-        mCachedDevice.setActiveDevice(true, BluetoothProfile.HEADSET);
+        mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(phone)");
 
         // Test with battery level
@@ -195,7 +195,7 @@
         mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
         // Set HFP profile to be connected, Active and test connection state summary
         mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
-        mCachedDevice.setActiveDevice(true, BluetoothProfile.HEADSET);
+        mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(phone)");
 
         // Set HFP profile to be disconnected and test connection state summary
@@ -212,8 +212,8 @@
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected");
 
         // Set device as Active for A2DP and HFP and test connection state summary
-        mCachedDevice.setActiveDevice(true, BluetoothProfile.A2DP);
-        mCachedDevice.setActiveDevice(true, BluetoothProfile.HEADSET);
+        mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
+        mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active");
 
         // Test with battery level
@@ -222,16 +222,16 @@
                 "Connected, battery 10%, active");
 
         // Disconnect A2DP only and test connection state summary
-        mCachedDevice.setActiveDevice(false, BluetoothProfile.A2DP);
+        mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.A2DP);
         mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
                 "Connected (no media), battery 10%, active(phone)");
 
         // Disconnect HFP only and test connection state summary
-        mCachedDevice.setActiveDevice(false, BluetoothProfile.HEADSET);
+        mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.HEADSET);
         mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
         mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
-        mCachedDevice.setActiveDevice(true, BluetoothProfile.A2DP);
+        mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
                 "Connected (no phone), battery 10%, active(media)");
 
@@ -240,8 +240,8 @@
         // Set A2DP and HFP profiles to be connected, Active and test connection state summary
         mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
         mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
-        mCachedDevice.setActiveDevice(true, BluetoothProfile.A2DP);
-        mCachedDevice.setActiveDevice(true, BluetoothProfile.HEADSET);
+        mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
+        mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active");
 
         // Set A2DP and HFP profiles to be disconnected and test connection state summary
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/AbstractPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/AbstractPreferenceControllerTest.java
index 8767923..393fd02 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/AbstractPreferenceControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/AbstractPreferenceControllerTest.java
@@ -82,8 +82,17 @@
         assertThat(mPreference.isVisible()).isFalse();
     }
 
-    private class TestPrefController extends AbstractPreferenceController {
+    @Test
+    public void updateState_hasSummary_shouldSetSummary() {
+        mTestPrefController.updateState(mPreference);
+
+        assertThat(mPreference.getSummary()).isEqualTo(TestPrefController.TEST_SUMMARY);
+    }
+
+    private static class TestPrefController extends AbstractPreferenceController {
         private static final String KEY_PREF = "test_pref";
+        private static final CharSequence TEST_SUMMARY = "Test";
+
         public boolean isAvailable;
 
         public TestPrefController(Context context) {
@@ -104,6 +113,11 @@
         public String getPreferenceKey() {
             return KEY_PREF;
         }
+
+        @Override
+        public CharSequence getSummary() {
+            return TEST_SUMMARY;
+        }
     }
 
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/DeveloperOptionsPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/DeveloperOptionsPreferenceControllerTest.java
new file mode 100644
index 0000000..7820fd2
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/DeveloperOptionsPreferenceControllerTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.development;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settingslib.SettingsLibRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsLibRobolectricTestRunner.class)
+public class DeveloperOptionsPreferenceControllerTest {
+
+    private static final String TEST_KEY = "Test_pref_key";
+
+    @Mock
+    private Preference mPreference;
+    @Mock
+    private PreferenceScreen mPreferenceScreen;
+
+    private DeveloperOptionsPreferenceController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mController = new DeveloperOptionsPreferenceControllerTestable();
+        doReturn(mPreference).when(mPreferenceScreen).findPreference(TEST_KEY);
+        mController.displayPreference(mPreferenceScreen);
+    }
+
+    @Test
+    public void onDeveloperOptionsEnabled_shouldEnablePreference() {
+        mController.onDeveloperOptionsEnabled();
+
+        verify(mPreference).setEnabled(true);
+    }
+
+    @Test
+    public void onDeveloperOptionsDisabled_shouldDisablePreference() {
+        mController.onDeveloperOptionsDisabled();
+
+        verify(mPreference).setEnabled(false);
+    }
+
+    private class DeveloperOptionsPreferenceControllerTestable extends
+            DeveloperOptionsPreferenceController {
+        DeveloperOptionsPreferenceControllerTestable() {
+            super(RuntimeEnvironment.application);
+        }
+
+        @Override
+        public String getPreferenceKey() {
+            return TEST_KEY;
+        }
+    }
+}
+
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/IconCacheTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/IconCacheTest.java
new file mode 100644
index 0000000..026ad47
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/IconCacheTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.utils;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class IconCacheTest {
+    private Icon mIcon;
+    private Context mContext;
+    private IconCache mIconCache;
+
+    @Before
+    public void setUp() {
+        mContext = spy(RuntimeEnvironment.application);
+        mIcon = mock(Icon.class);
+        Drawable drawable = mock(Drawable.class);
+        doReturn(drawable).when(mIcon).loadDrawable(mContext);
+        mIconCache = new IconCache(mContext);
+    }
+
+    @Test
+    public void testGetIcon_iconisNull() {
+        assertThat(mIconCache.getIcon(null)).isNull();
+    }
+
+    @Test
+    public void testGetIcon_iconAlreadyLoaded() {
+        mIconCache.getIcon(mIcon);
+        verify(mIcon, times(1)).loadDrawable(mContext);
+        mIconCache.getIcon(mIcon);
+        verify(mIcon, times(1)).loadDrawable(mContext);
+    }
+
+    @Test
+    public void testGetIcon_iconLoadedFirstTime() {
+        mIconCache.getIcon(mIcon);
+        assertTrue(mIconCache.mMap.containsKey(mIcon));
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java
index 9285148f..c42ff08 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java
@@ -24,13 +24,18 @@
 import com.android.settingslib.R;
 import com.android.settingslib.SettingsLibRobolectricTestRunner;
 
+import java.time.Clock;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RuntimeEnvironment;
 
 import java.time.Duration;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowSettings.ShadowSystem;
+import org.robolectric.shadows.ShadowSystemClock;
 
 @RunWith(SettingsLibRobolectricTestRunner.class)
 public class PowerUtilTest {
@@ -39,8 +44,12 @@
     public static final long SEVENTEEN_MIN_MILLIS = Duration.ofMinutes(17).toMillis();
     public static final long FIVE_MINUTES_MILLIS = Duration.ofMinutes(5).toMillis();
     public static final long TEN_MINUTES_MILLIS = Duration.ofMinutes(10).toMillis();
-    public static final long TWO_DAYS_MILLIS = Duration.ofDays(2).toMillis();
-    public static final String ONE_DAY_FORMATTED = "1 day";
+    public static final long THREE_DAYS_MILLIS = Duration.ofDays(3).toMillis();
+    public static final long THIRTY_HOURS_MILLIS = Duration.ofHours(30).toMillis();
+    public static final String TWO_DAYS_FORMATTED = "2 days";
+    public static final String THIRTY_HOURS_FORMATTED = "1d 6h";
+    public static final String NORMAL_CASE_EXPECTED_PREFIX = "Will last until about";
+    public static final String ENHANCED_SUFFIX = "based on your usage";
 
     private Context mContext;
 
@@ -51,6 +60,7 @@
     }
 
     @Test
+    @Config(shadows = {ShadowSystemClock.class})
     public void testGetBatteryRemainingStringFormatted_moreThanFifteenMinutes_withPercentage() {
         String info = PowerUtil.getBatteryRemainingStringFormatted(mContext,
                 SEVENTEEN_MIN_MILLIS,
@@ -62,15 +72,13 @@
                 false /* basedOnUsage */);
 
         // We only add special mention for the long string
-        assertThat(info).isEqualTo(mContext.getString(
-                R.string.power_discharging_duration_enhanced,
-                TEST_BATTERY_LEVEL_10,
-                FIFTEEN_MIN_FORMATTED));
+        assertThat(info).contains(NORMAL_CASE_EXPECTED_PREFIX);
+        assertThat(info).contains(ENHANCED_SUFFIX);
+        assertThat(info).contains("%");
         // shortened string should not have extra text
-        assertThat(info2).isEqualTo(mContext.getString(
-                R.string.power_discharging_duration,
-                TEST_BATTERY_LEVEL_10,
-                FIFTEEN_MIN_FORMATTED));
+        assertThat(info2).contains(NORMAL_CASE_EXPECTED_PREFIX);
+        assertThat(info2).doesNotContain(ENHANCED_SUFFIX);
+        assertThat(info2).contains("%");
     }
 
     @Test
@@ -84,14 +92,14 @@
                 null /* percentageString */,
                 false /* basedOnUsage */);
 
-        // We only add special mention for the long string
-        assertThat(info).isEqualTo(mContext.getString(
-                R.string.power_remaining_duration_only_enhanced,
-                FIFTEEN_MIN_FORMATTED));
+        // We only have % when it is provided
+        assertThat(info).contains(NORMAL_CASE_EXPECTED_PREFIX);
+        assertThat(info).contains(ENHANCED_SUFFIX);
+        assertThat(info).doesNotContain("%");
         // shortened string should not have extra text
-        assertThat(info2).isEqualTo(mContext.getString(
-                R.string.power_remaining_duration_only,
-                FIFTEEN_MIN_FORMATTED));
+        assertThat(info2).contains(NORMAL_CASE_EXPECTED_PREFIX);
+        assertThat(info2).doesNotContain(ENHANCED_SUFFIX);
+        assertThat(info2).doesNotContain("%");
     }
 
 
@@ -107,12 +115,9 @@
                 true /* basedOnUsage */);
 
         // additional battery percentage in this string
-        assertThat(info).isEqualTo(mContext.getString(
-                R.string.power_remaining_duration_shutdown_imminent,
-                TEST_BATTERY_LEVEL_10));
+        assertThat(info).isEqualTo("Phone may shutdown soon (10%)");
         // shortened string should not have percentage
-        assertThat(info2).isEqualTo(mContext.getString(
-                R.string.power_remaining_duration_only_shutdown_imminent));
+        assertThat(info2).isEqualTo("Phone may shutdown soon");
     }
 
     @Test
@@ -127,35 +132,42 @@
                 true /* basedOnUsage */);
 
         // shortened string should not have percentage
-        assertThat(info).isEqualTo(mContext.getString(
-                R.string.power_remaining_less_than_duration_only,
-                FIFTEEN_MIN_FORMATTED));
+        assertThat(info).isEqualTo("Less than 15m remaining");
         // Add percentage to string when provided
-        assertThat(info2).isEqualTo(mContext.getString(
-                R.string.power_remaining_less_than_duration,
-                TEST_BATTERY_LEVEL_10,
-                FIFTEEN_MIN_FORMATTED));
+        assertThat(info2).isEqualTo("Less than 15m remaining (10%)");
     }
 
     @Test
-    public void testGetBatteryRemainingStringFormatted_moreThanOneDay_usesCorrectString() {
+    public void testGetBatteryRemainingStringFormatted_betweenOneAndTwoDays_usesCorrectString() {
         String info = PowerUtil.getBatteryRemainingStringFormatted(mContext,
-                TWO_DAYS_MILLIS,
+                THIRTY_HOURS_MILLIS,
                 null /* percentageString */,
                 true /* basedOnUsage */);
         String info2 = PowerUtil.getBatteryRemainingStringFormatted(mContext,
-                TWO_DAYS_MILLIS,
+                THIRTY_HOURS_MILLIS,
+                TEST_BATTERY_LEVEL_10 /* percentageString */,
+                false /* basedOnUsage */);
+
+        // We only add special mention for the long string
+        assertThat(info).isEqualTo("About 1d 6h left based on your usage");
+        // shortened string should not have extra text
+        assertThat(info2).isEqualTo("About 1d 6h left (10%)");
+    }
+
+    @Test
+    public void testGetBatteryRemainingStringFormatted_moreThanTwoDays_usesCorrectString() {
+        String info = PowerUtil.getBatteryRemainingStringFormatted(mContext,
+                THREE_DAYS_MILLIS,
+                null /* percentageString */,
+                true /* basedOnUsage */);
+        String info2 = PowerUtil.getBatteryRemainingStringFormatted(mContext,
+                THREE_DAYS_MILLIS,
                 TEST_BATTERY_LEVEL_10 /* percentageString */,
                 true /* basedOnUsage */);
 
         // shortened string should not have percentage
-        assertThat(info).isEqualTo(mContext.getString(
-                R.string.power_remaining_only_more_than_subtext,
-                ONE_DAY_FORMATTED));
+        assertThat(info).isEqualTo("More than 2 days remaining");
         // Add percentage to string when provided
-        assertThat(info2).isEqualTo(mContext.getString(
-                R.string.power_remaining_more_than_subtext,
-                TEST_BATTERY_LEVEL_10,
-                ONE_DAY_FORMATTED));
+        assertThat(info2).isEqualTo("More than 2 days remaining (10%)");
     }
 }
diff --git a/packages/SettingsProvider/Android.mk b/packages/SettingsProvider/Android.mk
index 0f2c5ab..db57fd1 100644
--- a/packages/SettingsProvider/Android.mk
+++ b/packages/SettingsProvider/Android.mk
@@ -10,6 +10,7 @@
 LOCAL_STATIC_JAVA_LIBRARIES := junit
 
 LOCAL_PACKAGE_NAME := SettingsProvider
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_CERTIFICATE := platform
 LOCAL_PRIVILEGED_MODULE := true
 
diff --git a/packages/SettingsProvider/res/values-as/defaults.xml b/packages/SettingsProvider/res/values-as/defaults.xml
new file mode 100644
index 0000000..ea05c92
--- /dev/null
+++ b/packages/SettingsProvider/res/values-as/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">
+    <string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
+    <string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+    <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
+    <string name="def_backup_manager_constants" msgid="75273734665044867"></string>
+    <string name="def_backup_local_transport_parameters" msgid="303005414813191641"></string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-as/strings.xml b/packages/SettingsProvider/res/values-as/strings.xml
new file mode 100644
index 0000000..233253e
--- /dev/null
+++ b/packages/SettingsProvider/res/values-as/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"ছেটিংছসমূহৰ সঞ্চয়াগাৰ"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-or/defaults.xml b/packages/SettingsProvider/res/values-or/defaults.xml
new file mode 100644
index 0000000..ea05c92
--- /dev/null
+++ b/packages/SettingsProvider/res/values-or/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">
+    <string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
+    <string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+    <string name="def_nfc_payment_component" msgid="5861297439873026958"></string>
+    <string name="def_backup_manager_constants" msgid="75273734665044867"></string>
+    <string name="def_backup_local_transport_parameters" msgid="303005414813191641"></string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-or/strings.xml b/packages/SettingsProvider/res/values-or/strings.xml
new file mode 100644
index 0000000..04f68c8
--- /dev/null
+++ b/packages/SettingsProvider/res/values-or/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"ସେଟିଙ୍ଗ ଷ୍ଟୋରେଜ୍‌"</string>
+</resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index dd89df1..2b181dc 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -858,7 +858,10 @@
                 out.writeInt(NETWORK_POLICIES_BACKUP_VERSION);
                 out.writeInt(policies.length);
                 for (NetworkPolicy policy : policies) {
-                    if (policy != null) {
+                    // We purposefully only backup policies that the user has
+                    // defined; any inferred policies might include
+                    // carrier-protected data that we can't export.
+                    if (policy != null && !policy.inferred) {
                         byte[] marshaledPolicy = policy.getBytesForBackup();
                         out.writeByte(BackupUtils.NOT_NULL);
                         out.writeInt(marshaledPolicy.length);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 0fee81be..b000d84 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -448,6 +448,9 @@
                 Settings.Global.CARRIER_APP_WHITELIST,
                 GlobalSettingsProto.CARRIER_APP_WHITELIST);
         dumpSetting(s, p,
+                Settings.Global.CARRIER_APP_NAMES,
+                GlobalSettingsProto.CARRIER_APP_NAMES);
+        dumpSetting(s, p,
                 Settings.Global.USB_MASS_STORAGE_ENABLED,
                 GlobalSettingsProto.USB_MASS_STORAGE_ENABLED);
         dumpSetting(s, p,
diff --git a/packages/SettingsProvider/test/Android.mk b/packages/SettingsProvider/test/Android.mk
index 902f1c7..bd5b1f2 100644
--- a/packages/SettingsProvider/test/Android.mk
+++ b/packages/SettingsProvider/test/Android.mk
@@ -15,6 +15,7 @@
 LOCAL_JAVA_LIBRARIES := android.test.base
 
 LOCAL_PACKAGE_NAME := SettingsProviderTest
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_MODULE_TAGS := tests
 
diff --git a/packages/SharedStorageBackup/Android.mk b/packages/SharedStorageBackup/Android.mk
index a213965f..2e07ab1 100644
--- a/packages/SharedStorageBackup/Android.mk
+++ b/packages/SharedStorageBackup/Android.mk
@@ -24,6 +24,7 @@
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 
 LOCAL_PACKAGE_NAME := SharedStorageBackup
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_CERTIFICATE := platform
 LOCAL_PRIVILEGED_MODULE := true
 
diff --git a/packages/Shell/Android.mk b/packages/Shell/Android.mk
index 935d09b..5713dc6 100644
--- a/packages/Shell/Android.mk
+++ b/packages/Shell/Android.mk
@@ -15,6 +15,7 @@
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4
 
 LOCAL_PACKAGE_NAME := Shell
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_CERTIFICATE := platform
 LOCAL_PRIVILEGED_MODULE := true
 
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index d919d6a..d284bf9 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -145,6 +145,8 @@
         android:name="android.permission.MANAGE_WIFI_WHEN_PERMISSION_REVIEW_REQUIRED" />
     <uses-permission android:name="android.permission.WATCH_APPOPS" />
 
+    <uses-permission android:name="android.permission.CONTROL_KEYGUARD" />
+
     <application android:label="@string/app_label"
                  android:defaultToDeviceProtectedStorage="true"
                  android:directBootAware="true">
diff --git a/packages/Shell/res/values-as/strings.xml b/packages/Shell/res/values-as/strings.xml
new file mode 100644
index 0000000..9d6c37a
--- /dev/null
+++ b/packages/Shell/res/values-as/strings.xml
@@ -0,0 +1,73 @@
+<?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">
+    <string name="app_label" msgid="3701846017049540910">"শ্বেল"</string>
+    <string name="bugreport_notification_channel" msgid="2574150205913861141">"বাগ সম্পৰ্কীয় প্ৰতিবেদন"</string>
+    <!-- no translation found for bugreport_in_progress_title (4311705936714972757) -->
+    <skip />
+    <!-- no translation found for bugreport_finished_title (4429132808670114081) -->
+    <skip />
+    <!-- no translation found for bugreport_updating_title (4423539949559634214) -->
+    <skip />
+    <!-- no translation found for bugreport_updating_wait (3322151947853929470) -->
+    <skip />
+    <!-- no translation found for bugreport_finished_text (1223616207145252689) -->
+    <skip />
+    <!-- no translation found for bugreport_finished_text (5758325479058638893) -->
+    <skip />
+    <!-- no translation found for bugreport_finished_text (8353769438382138847) -->
+    <skip />
+    <!-- no translation found for bugreport_finished_pending_screenshot_text (2343263822812016950) -->
+    <skip />
+    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
+    <skip />
+    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
+    <skip />
+    <!-- no translation found for bugreport_confirm (5917407234515812495) -->
+    <skip />
+    <!-- no translation found for bugreport_confirm_dont_repeat (6179945398364357318) -->
+    <skip />
+    <!-- no translation found for bugreport_storage_title (5332488144740527109) -->
+    <skip />
+    <!-- no translation found for bugreport_unreadable_text (586517851044535486) -->
+    <skip />
+    <!-- no translation found for bugreport_add_details_to_zip_failed (1302931926486712371) -->
+    <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 (5684211273096253120) -->
+    <skip />
+    <!-- no translation found for bugreport_screenshot_failed (5853049140806834601) -->
+    <skip />
+    <!-- no translation found for bugreport_info_dialog_title (1355948594292983332) -->
+    <skip />
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (2306030793918239804) -->
+    <skip />
+    <!-- no translation found for bugreport_info_description (5072835127481627722) -->
+    <skip />
+    <!-- no translation found for save (4781509040564835759) -->
+    <skip />
+    <!-- no translation found for bugreport_intent_chooser_title (7605709494790894076) -->
+    <skip />
+</resources>
diff --git a/packages/Shell/res/values-or/strings.xml b/packages/Shell/res/values-or/strings.xml
new file mode 100644
index 0000000..bfb3b53
--- /dev/null
+++ b/packages/Shell/res/values-or/strings.xml
@@ -0,0 +1,73 @@
+<?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">
+    <string name="app_label" msgid="3701846017049540910">"ଶେଲ୍‍"</string>
+    <!-- no translation found for bugreport_notification_channel (2574150205913861141) -->
+    <skip />
+    <!-- no translation found for bugreport_in_progress_title (4311705936714972757) -->
+    <skip />
+    <!-- no translation found for bugreport_finished_title (4429132808670114081) -->
+    <skip />
+    <!-- no translation found for bugreport_updating_title (4423539949559634214) -->
+    <skip />
+    <!-- no translation found for bugreport_updating_wait (3322151947853929470) -->
+    <skip />
+    <!-- no translation found for bugreport_finished_text (1223616207145252689) -->
+    <skip />
+    <!-- no translation found for bugreport_finished_text (5758325479058638893) -->
+    <skip />
+    <!-- no translation found for bugreport_finished_text (8353769438382138847) -->
+    <skip />
+    <!-- no translation found for bugreport_finished_pending_screenshot_text (2343263822812016950) -->
+    <skip />
+    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
+    <skip />
+    <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) -->
+    <skip />
+    <!-- no translation found for bugreport_confirm (5917407234515812495) -->
+    <skip />
+    <!-- no translation found for bugreport_confirm_dont_repeat (6179945398364357318) -->
+    <skip />
+    <string name="bugreport_storage_title" msgid="5332488144740527109">"ବଗ୍ ରିପୋର୍ଟ"</string>
+    <!-- no translation found for bugreport_unreadable_text (586517851044535486) -->
+    <skip />
+    <!-- no translation found for bugreport_add_details_to_zip_failed (1302931926486712371) -->
+    <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 (5684211273096253120) -->
+    <skip />
+    <!-- no translation found for bugreport_screenshot_failed (5853049140806834601) -->
+    <skip />
+    <!-- no translation found for bugreport_info_dialog_title (1355948594292983332) -->
+    <skip />
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (2306030793918239804) -->
+    <skip />
+    <!-- no translation found for bugreport_info_description (5072835127481627722) -->
+    <skip />
+    <!-- no translation found for save (4781509040564835759) -->
+    <skip />
+    <!-- no translation found for bugreport_intent_chooser_title (7605709494790894076) -->
+    <skip />
+</resources>
diff --git a/packages/Shell/src/com/android/shell/BugreportStorageProvider.java b/packages/Shell/src/com/android/shell/BugreportStorageProvider.java
index 1bb36fb..0734e0d 100644
--- a/packages/Shell/src/com/android/shell/BugreportStorageProvider.java
+++ b/packages/Shell/src/com/android/shell/BugreportStorageProvider.java
@@ -60,7 +60,7 @@
         final MatrixCursor result = new MatrixCursor(resolveRootProjection(projection));
         final RowBuilder row = result.newRow();
         row.add(Root.COLUMN_ROOT_ID, DOC_ID_ROOT);
-        row.add(Root.COLUMN_FLAGS, Root.FLAG_LOCAL_ONLY | Root.FLAG_ADVANCED);
+        row.add(Root.COLUMN_FLAGS, Root.FLAG_LOCAL_ONLY);
         row.add(Root.COLUMN_ICON, android.R.mipmap.sym_def_app_icon);
         row.add(Root.COLUMN_TITLE, getContext().getString(R.string.bugreport_storage_title));
         row.add(Root.COLUMN_DOCUMENT_ID, DOC_ID_ROOT);
diff --git a/packages/Shell/tests/Android.mk b/packages/Shell/tests/Android.mk
index 7f24a38..b93ddde 100644
--- a/packages/Shell/tests/Android.mk
+++ b/packages/Shell/tests/Android.mk
@@ -15,6 +15,7 @@
     junit \
 
 LOCAL_PACKAGE_NAME := ShellTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_COMPATIBILITY_SUITE := device-tests
 LOCAL_INSTRUMENTATION_FOR := Shell
 
diff --git a/packages/StatementService/Android.mk b/packages/StatementService/Android.mk
index 470d824..b9b29e7 100644
--- a/packages/StatementService/Android.mk
+++ b/packages/StatementService/Android.mk
@@ -22,6 +22,7 @@
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 
 LOCAL_PACKAGE_NAME := StatementService
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_PRIVILEGED_MODULE := true
 
 LOCAL_JAVA_LIBRARIES += org.apache.http.legacy
diff --git a/packages/SystemUI/README.md b/packages/SystemUI/README.md
index ae0a362..d80e4ff 100644
--- a/packages/SystemUI/README.md
+++ b/packages/SystemUI/README.md
@@ -1,5 +1,172 @@
-# SystemUI Documentation
+# SystemUI
+
+“Everything you see in Android that's not an app”
+
+SystemUI is a persistent process that provides UI for the system but outside
+of the system_server process.
+
+The starting point for most of sysui code is a list of services that extend
+SystemUI that are started up by SystemUIApplication. These services then depend
+on some custom dependency injection provided by Dependency.
+
+Inputs directed at sysui (as opposed to general listeners) generally come in
+through IStatusBar. Outputs from sysui are through a variety of private APIs to
+the android platform all over.
+
+## SystemUIApplication
+
+When SystemUIApplication starts up, it will start up the services listed in
+config_systemUIServiceComponents or config_systemUIServiceComponentsPerUser.
+
+Each of these services extend SystemUI. SystemUI provides them with a Context
+and gives them callbacks for onConfigurationChanged (this historically was
+the main path for onConfigurationChanged, now also happens through
+ConfigurationController). They also receive a callback for onBootCompleted
+since these objects may be started before the device has finished booting.
+
+SystemUI and SystemUIApplication also have methods for putComponent and
+getComponent which were existing systems to get a hold of other parts of
+sysui before Dependency existed. Generally new things should not be added
+to putComponent, instead Dependency and other refactoring is preferred to
+make sysui structure cleaner.
+
+Each SystemUI service is expected to be a major part of system ui and the
+goal is to minimize communication between them. So in general they should be
+relatively silo'd.
+
+## Dependencies
+
+The first SystemUI service that is started should always be Dependency.
+Dependency provides a static method for getting a hold of dependencies that
+have a lifecycle that spans sysui. Dependency has code for how to create all
+dependencies manually added. SystemUIFactory is also capable of
+adding/replacing these dependencies.
+
+Dependencies are lazily initialized, so if a Dependency is never referenced at
+runtime, it will never be created.
+
+If an instantiated dependency implements Dumpable it will be included in dumps
+of sysui (and bug reports), allowing it to include current state information.
+This is how \*Controllers dump state to bug reports.
+
+If an instantiated dependency implements ConfigurationChangeReceiver it will
+receive onConfigurationChange callbacks when the configuration changes.
+
+## IStatusBar
+
+CommandQueue is the object that receives all of the incoming events from the
+system_server. It extends IStatusBar and dispatches those callbacks back any
+number of listeners. The system_server gets a hold of the IStatusBar when
+StatusBar calls IStatusBarService#registerStatusBar, so if StatusBar is not
+included in the XML service list, it will not be registered with the OS.
+
+CommandQueue posts all incoming callbacks to a handler and then dispatches
+those messages to each callback that is currently registered. CommandQueue
+also tracks the current value of disable flags and will call #disable
+immediately for any callbacks added.
+
+There are a few places where CommandQueue is used as a bus to communicate
+across sysui. Such as when StatusBar calls CommandQueue#recomputeDisableFlags.
+This is generally used a shortcut to directly trigger CommandQueue rather than
+calling StatusManager and waiting for the call to come back to IStatusBar.
+
+## Default SystemUI services list
+
+### [com.android.systemui.Dependency](/packages/SystemUI/src/com/android/systemui/Dependency.java)
+
+Provides custom dependency injection.
+
+### [com.android.systemui.util.NotificationChannels](/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java)
+
+Creates/initializes the channels sysui uses when posting notifications.
+
+### [com.android.systemui.statusbar.CommandQueue$CommandQueueStart](/packages/SystemUI/src/com/android/systemui/sstatusbar/CommandQueue.java)
+
+Creates CommandQueue and calls putComponent because its always been there
+and sysui expects it to be there :/
+
+### [com.android.systemui.keyguard.KeyguardViewMediator](/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java)
+
+Manages keyguard view state.
+
+### [com.android.systemui.recents.Recents](/packages/SystemUI/src/com/android/systemui/recents/Recents.java)
+
+Recents tracks all the data needed for recents and starts/stops the recents
+activity. It provides this cached data to RecentsActivity when it is started.
+
+### [com.android.systemui.volume.VolumeUI](/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java)
+
+Registers all the callbacks/listeners required to show the Volume dialog when
+it should be shown.
+
+### [com.android.systemui.stackdivider.Divider](/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java)
+
+Shows the drag handle for the divider between two apps when in split screen
+mode.
+
+### [com.android.systemui.SystemBars](/packages/SystemUI/src/com/android/systemui/SystemBars.java)
+
+This is a proxy to the actual SystemUI for the status bar. This loads from
+config_statusBarComponent which defaults to StatusBar. (maybe this should be
+removed and copy how config_systemUiVendorServiceComponent works)
+
+### [com.android.systemui.status.phone.StatusBar](/packages/SystemUI/src/com/android/systemui/status/phone/StatusBar.java)
+
+This shows the UI for the status bar and the notification shade it contains.
+It also contains a significant amount of other UI that interacts with these
+surfaces (keyguard, AOD, etc.). StatusBar also contains a notification listener
+to receive notification callbacks.
+
+### [com.android.systemui.usb.StorageNotification](/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java)
+
+Tracks USB status and sends notifications for it.
+
+### [com.android.systemui.power.PowerUI](/packages/SystemUI/src/com/android/systemui/power/PowerUI.java)
+
+Tracks power status and sends notifications for low battery/power saver.
+
+### [com.android.systemui.media.RingtonePlayer](/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java)
+
+Plays ringtones.
+
+### [com.android.systemui.keyboard.KeyboardUI](/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java)
+
+Shows UI for keyboard shortcuts (triggered by keyboard shortcut).
+
+### [com.android.systemui.pip.PipUI](/packages/SystemUI/src/com/android/systemui/pip/PipUI.java)
+
+Shows the overlay controls when Pip is showing.
+
+### [com.android.systemui.shortcut.ShortcutKeyDispatcher](/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java)
+
+Dispatches shortcut to System UI components.
+
+### @string/config_systemUIVendorServiceComponent
+
+Component allowing the vendor/OEM to inject a custom component.
+
+### [com.android.systemui.util.leak.GarbageMonitor$Service](/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java)
+
+Tracks large objects in sysui to see if there are leaks.
+
+### [com.android.systemui.LatencyTester](/packages/SystemUI/src/com/android/systemui/LatencyTester.java)
+
+Class that only runs on debuggable builds that listens to broadcasts that
+simulate actions in the system that are used for testing the latency.
+
+### [com.android.systemui.globalactions.GlobalActionsComponent](/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java)
+
+Shows the global actions dialog (long-press power).
+
+### [com.android.systemui.ScreenDecorations](/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java)
+
+Draws decorations about the screen in software (e.g. rounded corners, cutouts).
+
+### [com.android.systemui.fingerprint.FingerprintDialogImpl](/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogImpl.java)
+
+Fingerprint UI.
 
 ---
 
+ * [Plugins](/packages/SystemUI/docs/plugins.md)
  * [Demo Mode](/packages/SystemUI/docs/demo_mode.md)
diff --git a/packages/SystemUI/docs/plugin_hooks.md b/packages/SystemUI/docs/plugin_hooks.md
new file mode 100644
index 0000000..5b08bfc
--- /dev/null
+++ b/packages/SystemUI/docs/plugin_hooks.md
@@ -0,0 +1,60 @@
+# Plugin hooks
+### Action: com.android.systemui.action.PLUGIN_OVERLAY
+Expected interface: [OverlayPlugin](/packages/SystemUI/plugin/src/com/android/systemui/plugins/OverlayPlugin.java)
+
+Use: Allows plugin access to the status bar and nav bar window for whatever nefarious purposes you can imagine.
+
+### Action: com.android.systemui.action.PLUGIN_QS
+Expected interface: [QS](/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java)
+
+Use: Allows the entire QS panel to be replaced with something else that is optionally expandable.
+
+Notes: To not mess up the notification panel interaction, much of the QSContainer interface needs to actually be implemented.
+
+### Action: com.android.systemui.action.PLUGIN_QS_FACTORY
+Expected interface: [QSFactory](/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSFactory.java)
+
+Use: Controls the creation of QS Tiles and their views, can used to add or change system QS tiles, can also be used to change the layout/interaction of the tile views.
+
+### Action: com.android.systemui.action.PLUGIN_NAV_BUTTON
+Expected interface: [NavBarButtonProvider](/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavBarButtonProvider.java)
+
+Use: Allows a plugin to create a new nav bar button, or override an existing one with a view of its own.
+
+### Action: com.android.systemui.action.PLUGIN_NAV_GESTURE
+Expected interface: [NavGesture](/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java)
+
+Use: Allows touch events from the nav bar to be intercepted and used for other gestures.
+
+### Action: com.android.systemui.action.PLUGIN_LOCKSCREEN_RIGHT_BUTTON
+Expected interface: [IntentButtonProvider](/packages/SystemUI/plugin/src/com/android/systemui/plugins/IntentButtonProvider.java)
+
+Use: Allows a plugin to specify the icon for the bottom right lock screen button, and the intent that gets launched when it is activated.
+
+### Action: com.android.systemui.action.PLUGIN_LOCKSCREEN_LEFT_BUTTON
+Expected interface: [IntentButtonProvider](/packages/SystemUI/plugin/src/com/android/systemui/plugins/IntentButtonProvider.java)
+
+Use: Allows a plugin to specify the icon for the bottom left lock screen button, and the intent that gets launched when it is activated.
+
+### Action: com.android.systemui.action.PLUGIN_GLOBAL_ACTIONS
+Expected interface: [GlobalActions](/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java)
+
+Use: Allows the long-press power menu to be completely replaced.
+
+### Action: com.android.systemui.action.PLUGIN_VOLUME
+Expected interface: [VolumeDialog](/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialog.java)
+
+Use: Allows replacement of the volume dialog.
+
+### Action: com.android.systemui.action.PLUGIN_NOTIFICATION_SWIPE_ACTION
+Expected interface: [NotificationSwipeActionHelper](/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationSwipeActionHelper.java)
+
+Use: Control over swipes/input for notification views, can be used to control what happens when you swipe/long-press
+
+
+# Global plugin dependencies
+These classes can be accessed by any plugin using PluginDependency as long as they @Requires them.
+
+[VolumeDialogController](/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java) - Mostly just API for the volume plugin
+
+[ActivityStarter](/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java) - Allows starting of intents while co-operating with keyguard unlocks.
diff --git a/packages/SystemUI/docs/plugins.md b/packages/SystemUI/docs/plugins.md
new file mode 100644
index 0000000..ed91f3d
--- /dev/null
+++ b/packages/SystemUI/docs/plugins.md
@@ -0,0 +1,227 @@
+# SystemUI Plugins
+
+Plugins provide an easy way to rapidly prototype SystemUI features.  Plugins are APKs that will be installable only on Build.IS_DEBUGGABLE (dogfood) builds, that can change the behavior of SystemUI at runtime.  This is done by creating a basic set of interfaces that the plugins can expect to be in SysUI, then the portion of code controlled by the interface can be iterated on faster than currently.
+
+Plugins keep the experimental and turbulent code outside of master and only on the devices which need to use the prototype.  You can distribute early prototype directly to those that need to see it either through drive or email, and only show it to dogfooders when ready.
+
+## Adding Plugin Hooks
+
+Existing plugin hooks can be found [here](/packages/SystemUI/docs/plugin_hooks.md).
+
+### Writing the Interface(s)
+
+The first step of adding a plugin hook to SysUI is to define the interface layer between the plugin and SysUI.  This interface should be relatively stable so that many different plugins will work across multiple different builds.
+
+All interfaces need to be independent and not reference classes from SysUI.  They should be placed in the plugin library, under com.android.systemui.plugin or sub-packages.  The main interface (entry point) for the plugin should extend the interface Plugin so that you can listen for it.
+
+
+The most important part of interfaces is the version included in them.  Every time the interface changes in an incompatible way, the version should be incremented.  Incompatible changes are changes to the signature of any of the interface methods, or the addition of a new method that doesn’t have a default implementation.  All classes that are in the plugin library should be tagged with a version, they should also be tagged with an action if they are the root interface for the Plugin. If a plugin makes use of the other versioned interface, they can use DependsOn to indicate their dependence. They are tagged using annotations like the following.
+
+
+```java
+@ProvidesInterface(action = MyPlugin.ACTION, version = MyPlugin.VERSION)
+@DependsOn(target = OtherInterface.class)
+public interface MyPlugin extends Plugin {
+    String ACTION = "com.android.systemui.action.PLUGIN_MY_PLUGIN";
+    int VERSION = 1;
+    ...
+}
+```
+
+### Plugin Listener
+
+To actually listen for plugins, you implement a plugin listener that has the following interface.
+
+```java
+public interface PluginListener<T extends Plugin> {
+    /**
+     * Called when the plugin has been loaded and is ready to be used.
+     * This may be called multiple times if multiple plugins are allowed.
+     * It may also be called in the future if the plugin package changes
+     * and needs to be reloaded.
+     */
+    void onPluginConnected(T plugin);
+
+    /**
+     * Called when a plugin has been uninstalled/updated and should be removed
+     * from use.
+     */
+    default void onPluginDisconnected(T plugin) {
+        // Optional.
+    }
+}
+```
+
+Then you register the PluginListener with the PluginManager.  The constants for action and version should be defined on class T.  If allowMultiple is false, the plugin listener will only be connected to one plugin at a time.
+
+```java
+void addPluginListener(String action, PluginListener<T> listener,
+            int version, boolean allowMultiple);
+```
+
+### Examples
+[Allow quick settings panel to be replaced with another view](/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java)
+
+[Allow plugins to create new nav bar buttons](/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavBarButtonProvider.java)
+
+[Allow lockscreen camera/phone/assistant buttons to be replaced](/packages/SystemUI/plugin/src/com/android/systemui/plugins/IntentButtonProvider.java)
+
+## Writing Plugins
+### Make Files and Manifests
+
+When compiling plugins there are a couple vital pieces required.
+1. They must be signed with the platform cert
+2. They must include SystemUIPluginLib in LOCAL_JAVA_LIBRARIES (NOT LOCAL_STATIC_JAVA_LIBRARIES)
+
+Basically just copy the [example file](/packages/SystemUI/plugin/ExamplePlugin/Android.mk).
+
+To declare a plugin, you add a service to your manifest.  Add an intent filter to match the action for the plugin, and set the name to point at the class that implements the plugin interface.
+
+```xml
+       <service android:name=".SampleOverlayPlugin"
+            android:label="@string/plugin_label">
+            <intent-filter>
+                <action android:name="com.android.systemui.action.PLUGIN_OVERLAY" />
+            </intent-filter>
+        </service>
+```
+
+Plugins must also hold the plugin permission.
+
+```xml
+   <uses-permission android:name="com.android.systemui.permission.PLUGIN" />
+ ```
+
+
+### Implementing the interface
+
+Implementing the interface is generally pretty straightforward.  The version of the plugin should tagged with an annotation to declare its dependency on each of the plugin classes it depends on.  This ensures that the latest version will be included in the plugin APK when it is compiled.
+
+```java
+@Requires(target = OverlayPlugin.class, version = OverlayPlugin.VERSION)
+public class SampleOverlayPlugin implements OverlayPlugin {
+    ...
+}
+```
+
+After the plugin is created and passes all permission/security checks, then the plugin will receive the onCreate callback.  The pluginContext is pregenerated for the plugin and can be used to inflate or get any resources included in the plugin APK.
+
+```java
+public void onCreate(Context sysuiContext, Context pluginContext);
+```
+
+When the plugin is being removed, the plugin will receive the onDestroy callback.  At this point the plugin should ensure that all its resources and static references are cleaned up.
+
+```java
+public void onDestroy();
+```
+
+### Adding Settings
+
+A plugin can provide plugin-specific settings that will be surfaced as a gear button on the plugin tuner screen where plugins can be enabled or disabled.  To add settings just add an activity to receive the PLUGIN_SETTINGS action.
+
+```xml
+        <activity android:name=".PluginSettings"
+            android:label="@string/plugin_label">
+            <intent-filter>
+                <action android:name="com.android.systemui.action.PLUGIN_SETTINGS" />
+            </intent-filter>
+        </activity>
+ ```
+
+The plugin settings activity does not run in SysUI like the rest of the plugin, so it cannot reference any of the classes from SystemUIPluginLib.
+
+## Examples
+[The definitive ExamplePlugin](/packages/SystemUI/plugin/ExamplePlugin)
+
+[Replace lock screen camera button with a settings trigger](todo)
+
+[A nav button that launches an action](todo)
+
+
+## Writing plugins in Android Studio
+
+As long as the plugin doesn’t depend on any hidden APIs (which plugins should avoid anyway) and only uses Plugin APIs, you can be setup to build in android studio with only a couple steps.
+
+### Signing
+
+Plugins need to be signed with the platform cert, so you’ll need a copy of the keystore that contains the same cert.  You might find one at http://go/plugin-keystore, you can copy it to the root directory of your project.  Then you can tell your module to be signed with it by adding the following to the android section of your module’s build.gradle.
+
+```groovy
+android {
+    ...
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+        debug {
+            signingConfig signingConfigs.debug
+        }
+     }
+     signingConfigs {
+        debug {
+            keyAlias 'platform'
+            keyPassword 'android'
+            storeFile file('../platform.keystore')
+            storePassword 'android'
+        }
+     }
+   ...
+}
+```
+
+
+### Compiling against Plugin APIs
+
+To be able to implement a plugin, you’ll need a jar file that contains the plugin classes for compilation.  Generally you can grab a recent plugin lib from jmonk’s experimental directory.  However if you recently changed one of the plugin interfaces, you might want to build an updated version, you can use the following script to do so.
+
+```
+$ frameworks/base/packages/SystemUI/plugin/update_plugin_lib.sh
+```
+
+Once you have the jar you are going to compile against, you need to include it in your android studio project as a file dependency.  Once it is included change its scope from Compile to Provided in the project structure (you may need to build once before changing to provided).  This is required to ensure you don’t actually include the plugin library in your plugin APK.
+
+## Implementation Details
+
+Plugins are APKs that contain code and resources that can be dynamically loaded into SystemUI.  The plugins are compiled against a set of relatively stable (and version tagged) interfaces, that the implementations are provided by SysUI.  This figure shows an overview of how the plugin compiling/loading flow works.
+
+![How plugins work](sysui-plugins.png)
+
+### Security
+
+Whenever loading a code from another APK into a privileged process like SysUI, there are serious security concerns to be addressed.  To handle this, plugins have a couple lines of defense to ensure these don’t create any security holes.
+
+The first line of defense is Build.IS_DEBUGGABLE checks.  In 2 different places, SysUI checks to ensure that the build is debuggable before even scanning or loading any plugins on the device.  There are even tests in place to help ensure these checks are not lost.
+
+The second line of defense is a signature permission.  This ensures that plugins are always provided by the source of the android build.  All plugins must hold this permission for any of their code to be loaded, otherwise the infraction will be logged, and the plugin ignored.
+
+```xml
+   <permission android:name="com.android.systemui.permission.PLUGIN"
+            android:protectionLevel="signature" />
+ ```
+
+### Plugin Management
+
+Plugins are scanned for by intent filters of services.  A plugin is not actually a service, but the benefits of declaring it as a service makes it worth it.  Each plugin listener in SysUI simply specifies an action to look for, and the PluginManager scans for services declaring that action and uses that to know the class to instantiate.
+
+
+The other major advantage to declaring plugins through components in a manifest is management of enabled state.  Whether a plugin is enabled or disabled is managed by the package manager component enabled state.  When a device has had a plugin installed on it, an extra section is added to the SystemUI Tuner, it lists all of the plugins on the device and allows the components to be easily enabled and disabled.
+
+### Versioning
+
+When a plugin listener is registered in SysUI, the interface version is specified.  Whenever a plugin is detected, the first thing that is done after instantiation is the version is checked.  If the version of the interface the plugin was compiled with does not match the version SysUI contains, then the plugin will be ignored.
+
+### Class loading
+
+When plugins are loaded, they are done so by creating a PathClassLoader that points at the plugin APK.  The parent of the classloader is a special classloader based on SysUI’s that only includes the classes within the package com.android.systemui.plugin and its sub-packages.
+
+Having SysUI provide the implementations of the interfaces allows them to be more stable.  Some version changes can be avoided by adding defaults to the interfaces, and not requiring older plugins to implement new functionality.  The plugin library can also have static utility methods that plugins compile against, but the implementations are in sync with the platform builds.
+
+The class filtering in the parent classloader allows plugins to include any classes they want without worrying about collisions with SysUI.  Plugins can include SettingsLib, or copy classes directly out of SysUI to facilitate faster prototyping.
+
+### Crashing
+
+Whether it be from accidental reference of hidden APIs, unstable prototypes, or other unexpected reasons, plugins will inevitably cause SysUI to crash.  When this happens it needs to ensure a bad acting plugin do not stop the phone from being usable.
+
+When a plugin crashes, the PluginManager catches it and tries to determine the plugin that caused the crash.  If any of the classes in the stack trace are from the package of the plugin APK, then the plugin is disabled.  If no plugins can be identified as the source of the crash, then all plugins are disabled, just to be sure they aren’t causing future crashes.
diff --git a/packages/SystemUI/docs/sysui-plugins.png b/packages/SystemUI/docs/sysui-plugins.png
new file mode 100644
index 0000000..283d6d2
--- /dev/null
+++ b/packages/SystemUI/docs/sysui-plugins.png
Binary files differ
diff --git a/packages/SystemUI/docs/sysui-plugins.svg b/packages/SystemUI/docs/sysui-plugins.svg
new file mode 100644
index 0000000..0014dda
--- /dev/null
+++ b/packages/SystemUI/docs/sysui-plugins.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" standalone="yes"?>
+
+<svg version="1.1" viewBox="0.0 0.0 800.0 600.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l800.0 0l0 600.0l-800.0 0l0 -600.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l800.0 0l0 600.0l-800.0 0z" fill-rule="evenodd"></path><path fill="#cfe2f3" d="m554.9921 190.7559l220.0 0l0 218.48817l-220.0 0z" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m554.9921 190.7559l220.0 0l0 218.48817l-220.0 0z" fill-rule="evenodd"></path><path fill="#000000" d="m619.24243 306.92l0 -13.359375l5.046875 0q1.328125 0 2.03125 0.125q0.96875 0.171875 1.640625 0.640625q0.671875 0.453125 1.078125 1.28125q0.40625 0.828125 0.40625 1.828125q0 1.703125 -1.09375 2.890625q-1.078125 1.171875 -3.921875 1.171875l-3.421875 0l0 5.421875l-1.765625 0zm1.765625 -7.0l3.453125 0q1.71875 0 2.4375 -0.640625q0.71875 -0.640625 0.71875 -1.796875q0 -0.84375 -0.421875 -1.4375q-0.421875 -0.59375 -1.125 -0.78125q-0.4375 -0.125 -1.640625 -0.125l-3.421875 0l0 4.78125zm10.4279175 7.0l0 -13.359375l1.640625 0l0 13.359375l-1.640625 0zm10.519836 0l0 -1.421875q-1.125 1.640625 -3.0625 1.640625q-0.859375 0 -1.609375 -0.328125q-0.734375 -0.328125 -1.09375 -0.828125q-0.359375 -0.5 -0.5 -1.21875q-0.109375 -0.46875 -0.109375 -1.53125l0 -5.984375l1.640625 0l0 5.359375q0 1.28125 0.109375 1.734375q0.15625 0.640625 0.65625 1.015625q0.5 0.375 1.234375 0.375q0.734375 0 1.375 -0.375q0.65625 -0.390625 0.921875 -1.03125q0.265625 -0.65625 0.265625 -1.890625l0 -5.1875l1.640625 0l0 9.671875l-1.46875 0zm3.7351074 0.796875l1.59375 0.234375q0.109375 0.75 0.5625 1.078125q0.609375 0.453125 1.671875 0.453125q1.140625 0 1.75 -0.453125q0.625 -0.453125 0.84375 -1.265625q0.125 -0.5 0.109375 -2.109375q-1.0625 1.265625 -2.671875 1.265625q-2.0 0 -3.09375 -1.4375q-1.09375 -1.4375 -1.09375 -3.453125q0 -1.390625 0.5 -2.5625q0.515625 -1.171875 1.453125 -1.796875q0.953125 -0.640625 2.25 -0.640625q1.703125 0 2.8125 1.375l0 -1.15625l1.515625 0l0 8.359375q0 2.265625 -0.46875 3.203125q-0.453125 0.9375 -1.453125 1.484375q-0.984375 0.546875 -2.453125 0.546875q-1.71875 0 -2.796875 -0.78125q-1.0625 -0.765625 -1.03125 -2.34375zm1.359375 -5.8125q0 1.90625 0.75 2.78125q0.765625 0.875 1.90625 0.875q1.125 0 1.890625 -0.859375q0.765625 -0.875 0.765625 -2.734375q0 -1.78125 -0.796875 -2.671875q-0.78125 -0.90625 -1.890625 -0.90625q-1.09375 0 -1.859375 0.890625q-0.765625 0.875 -0.765625 2.625zm9.328857 -6.453125l0 -1.890625l1.640625 0l0 1.890625l-1.640625 0zm0 11.46875l0 -9.671875l1.640625 0l0 9.671875l-1.640625 0zm4.1447754 0l0 -9.671875l1.46875 0l0 1.375q1.0625 -1.59375 3.078125 -1.59375q0.875 0 1.609375 0.3125q0.734375 0.3125 1.09375 0.828125q0.375 0.5 0.515625 1.203125q0.09375 0.453125 0.09375 1.59375l0 5.953125l-1.640625 0l0 -5.890625q0 -1.0 -0.203125 -1.484375q-0.1875 -0.5 -0.671875 -0.796875q-0.484375 -0.296875 -1.140625 -0.296875q-1.046875 0 -1.8125 0.671875q-0.75 0.65625 -0.75 2.515625l0 5.28125l-1.640625 0zm14.293396 0l5.125 -13.359375l1.90625 0l5.46875 13.359375l-2.015625 0l-1.546875 -4.046875l-5.59375 0l-1.46875 4.046875l-1.875 0zm3.859375 -5.484375l4.53125 0l-1.40625 -3.703125q-0.625 -1.6875 -0.9375 -2.765625q-0.265625 1.28125 -0.71875 2.546875l-1.46875 3.921875zm10.0529785 5.484375l0 -13.359375l5.046875 0q1.328125 0 2.03125 0.125q0.96875 0.171875 1.640625 0.640625q0.671875 0.453125 1.078125 1.28125q0.40625 0.828125 0.40625 1.828125q0 1.703125 -1.09375 2.890625q-1.078125 1.171875 -3.921875 1.171875l-3.421875 0l0 5.421875l-1.765625 0zm1.765625 -7.0l3.453125 0q1.71875 0 2.4375 -0.640625q0.71875 -0.640625 0.71875 -1.796875q0 -0.84375 -0.421875 -1.4375q-0.421875 -0.59375 -1.125 -0.78125q-0.4375 -0.125 -1.640625 -0.125l-3.421875 0l0 4.78125zm10.5997925 7.0l0 -13.359375l1.78125 0l0 6.625l6.625 -6.625l2.390625 0l-5.59375 5.421875l5.84375 7.9375l-2.328125 0l-4.765625 -6.765625l-2.171875 2.140625l0 4.625l-1.78125 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m73.0 119.49606l333.00787 0l0 361.00787l-333.00787 0z" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m73.0 119.49606l333.00787 0l0 361.00787l-333.00787 0z" fill-rule="evenodd"></path><path fill="#000000" d="m194.21265 142.11919l1.65625 -0.140625q0.125 1.0 0.546875 1.640625q0.4375 0.640625 1.34375 1.046875q0.921875 0.390625 2.0625 0.390625q1.0 0 1.78125 -0.296875q0.78125 -0.296875 1.15625 -0.8125q0.375 -0.53125 0.375 -1.15625q0 -0.625 -0.375 -1.09375q-0.359375 -0.46875 -1.1875 -0.796875q-0.546875 -0.203125 -2.390625 -0.640625q-1.828125 -0.453125 -2.5625 -0.84375q-0.96875 -0.5 -1.4375 -1.234375q-0.46875 -0.75 -0.46875 -1.671875q0 -1.0 0.578125 -1.875q0.578125 -0.890625 1.671875 -1.34375q1.109375 -0.453125 2.453125 -0.453125q1.484375 0 2.609375 0.484375q1.140625 0.46875 1.75 1.40625q0.609375 0.921875 0.65625 2.09375l-1.6875 0.125q-0.140625 -1.265625 -0.9375 -1.90625q-0.78125 -0.65625 -2.3125 -0.65625q-1.609375 0 -2.34375 0.59375q-0.734375 0.59375 -0.734375 1.421875q0 0.71875 0.53125 1.171875q0.5 0.46875 2.65625 0.96875q2.15625 0.484375 2.953125 0.84375q1.171875 0.53125 1.71875 1.359375q0.5625 0.828125 0.5625 1.90625q0 1.0625 -0.609375 2.015625q-0.609375 0.9375 -1.75 1.46875q-1.140625 0.515625 -2.578125 0.515625q-1.8125 0 -3.046875 -0.53125q-1.21875 -0.53125 -1.921875 -1.59375q-0.6875 -1.0625 -0.71875 -2.40625zm12.756073 8.015625l-0.1875 -1.53125q0.546875 0.140625 0.9375 0.140625q0.546875 0 0.875 -0.1875q0.328125 -0.171875 0.546875 -0.5q0.15625 -0.25 0.5 -1.21875q0.046875 -0.140625 0.140625 -0.40625l-3.671875 -9.6875l1.765625 0l2.015625 5.59375q0.390625 1.078125 0.703125 2.25q0.28125 -1.125 0.671875 -2.203125l2.078125 -5.640625l1.640625 0l-3.6875 9.828125q-0.59375 1.609375 -0.921875 2.203125q-0.4375 0.8125 -1.0 1.1875q-0.5625 0.375 -1.34375 0.375q-0.484375 0 -1.0625 -0.203125zm8.75 -6.609375l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.90625q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.453125 2.4375 0.75q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125zm18.953125 -10.46875l1.765625 0l0 7.71875q0 2.015625 -0.453125 3.203125q-0.453125 1.1875 -1.640625 1.9375q-1.1875 0.734375 -3.125 0.734375q-1.875 0 -3.078125 -0.640625q-1.1875 -0.65625 -1.703125 -1.875q-0.5 -1.234375 -0.5 -3.359375l0 -7.71875l1.765625 0l0 7.71875q0 1.734375 0.3125 2.5625q0.328125 0.8125 1.109375 1.265625q0.796875 0.453125 1.9375 0.453125q1.953125 0 2.78125 -0.890625q0.828125 -0.890625 0.828125 -3.390625l0 -7.71875zm5.004181 13.359375l0 -13.359375l1.765625 0l0 13.359375l-1.765625 0zm8.600983 0l5.125 -13.359375l1.90625 0l5.46875 13.359375l-2.015625 0l-1.546875 -4.046875l-5.59375 0l-1.46875 4.046875l-1.875 0zm3.859375 -5.484375l4.53125 0l-1.40625 -3.703125q-0.625 -1.6875 -0.9375 -2.765625q-0.265625 1.28125 -0.71875 2.546875l-1.46875 3.921875zm10.052948 5.484375l0 -13.359375l5.046875 0q1.328125 0 2.03125 0.125q0.96875 0.171875 1.640625 0.640625q0.671875 0.453125 1.078125 1.28125q0.40625 0.828125 0.40625 1.828125q0 1.703125 -1.09375 2.890625q-1.078125 1.171875 -3.921875 1.171875l-3.421875 0l0 5.421875l-1.765625 0zm1.765625 -7.0l3.453125 0q1.71875 0 2.4375 -0.640625q0.71875 -0.640625 0.71875 -1.796875q0 -0.84375 -0.421875 -1.4375q-0.421875 -0.59375 -1.125 -0.78125q-0.4375 -0.125 -1.640625 -0.125l-3.421875 0l0 4.78125zm10.599823 7.0l0 -13.359375l1.78125 0l0 6.625l6.625 -6.625l2.390625 0l-5.59375 5.421875l5.84375 7.9375l-2.328125 0l-4.765625 -6.765625l-2.171875 2.140625l0 4.625l-1.78125 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m131.50394 359.5042l0 0c0 -7.456726 6.044861 -13.501587 13.501587 -13.501587l192.99683 0c3.580841 0 7.0150146 1.4224854 9.547058 3.9545288c2.5320435 2.5320435 3.9545288 5.966217 3.9545288 9.547058l0 54.0047c0 7.456726 -6.044861 13.501587 -13.501587 13.501587l-192.99683 0c-7.456726 0 -13.501587 -6.044861 -13.501587 -13.501587z" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m131.50394 359.5042l0 0c0 -7.456726 6.044861 -13.501587 13.501587 -13.501587l192.99683 0c3.580841 0 7.0150146 1.4224854 9.547058 3.9545288c2.5320435 2.5320435 3.9545288 5.966217 3.9545288 9.547058l0 54.0047c0 7.456726 -6.044861 13.501587 -13.501587 13.501587l-192.99683 0c-7.456726 0 -13.501587 -6.044861 -13.501587 -13.501587z" fill-rule="evenodd"></path><path fill="#000000" d="m217.46965 389.1297l1.65625 -0.140625q0.125 1.0 0.546875 1.640625q0.4375 0.640625 1.34375 1.046875q0.921875 0.390625 2.0625 0.390625q1.0 0 1.78125 -0.296875q0.78125 -0.296875 1.15625 -0.8125q0.375 -0.53125 0.375 -1.15625q0 -0.625 -0.375 -1.09375q-0.359375 -0.46875 -1.1875 -0.796875q-0.546875 -0.203125 -2.390625 -0.640625q-1.828125 -0.453125 -2.5625 -0.84375q-0.96875 -0.5 -1.4375 -1.234375q-0.46875 -0.75 -0.46875 -1.671875q0 -1.0 0.578125 -1.875q0.578125 -0.890625 1.671875 -1.34375q1.109375 -0.453125 2.453125 -0.453125q1.484375 0 2.609375 0.484375q1.140625 0.46875 1.75 1.40625q0.609375 0.921875 0.65625 2.09375l-1.6875 0.125q-0.140625 -1.265625 -0.9375 -1.90625q-0.78125 -0.65625 -2.3125 -0.65625q-1.609375 0 -2.34375 0.59375q-0.734375 0.59375 -0.734375 1.421875q0 0.71875 0.53125 1.171875q0.5 0.46875 2.65625 0.96875q2.15625 0.484375 2.953125 0.84375q1.171875 0.53125 1.71875 1.359375q0.5625 0.828125 0.5625 1.90625q0 1.0625 -0.609375 2.015625q-0.609375 0.9375 -1.75 1.46875q-1.140625 0.515625 -2.578125 0.515625q-1.8125 0 -3.046875 -0.53125q-1.21875 -0.53125 -1.921875 -1.59375q-0.6875 -1.0625 -0.71875 -2.40625zm12.756073 8.015625l-0.1875 -1.53125q0.546875 0.140625 0.9375 0.140625q0.546875 0 0.875 -0.1875q0.328125 -0.171875 0.546875 -0.5q0.15625 -0.25 0.5 -1.21875q0.046875 -0.140625 0.140625 -0.40625l-3.671875 -9.6875l1.765625 0l2.015625 5.59375q0.390625 1.078125 0.703125 2.25q0.28125 -1.125 0.671875 -2.203125l2.078125 -5.640625l1.640625 0l-3.6875 9.828125q-0.59375 1.609375 -0.921875 2.203125q-0.4375 0.8125 -1.0 1.1875q-0.5625 0.375 -1.34375 0.375q-0.484375 0 -1.0625 -0.203125zm8.75 -6.609375l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.90625q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.453125 2.4375 0.75q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125zm18.95314 -10.46875l1.765625 0l0 7.71875q0 2.015625 -0.453125 3.203125q-0.453125 1.1875 -1.640625 1.9375q-1.1875 0.734375 -3.1250153 0.734375q-1.875 0 -3.078125 -0.640625q-1.1875 -0.65625 -1.703125 -1.875q-0.5 -1.234375 -0.5 -3.359375l0 -7.71875l1.765625 0l0 7.71875q0 1.734375 0.3125 2.5625q0.328125 0.8125 1.109375 1.265625q0.796875 0.453125 1.9375 0.453125q1.9531403 0 2.7812653 -0.890625q0.828125 -0.890625 0.828125 -3.390625l0 -7.71875zm5.004181 13.359375l0 -13.359375l1.765625 0l0 13.359375l-1.765625 0z" fill-rule="nonzero"></path><path fill="#cfe2f3" d="m133.0 207.33095l0 0c0 -6.810196 5.520752 -12.330948 12.330948 -12.330948l192.34596 0c3.2703857 0 6.4067993 1.2991486 8.719299 3.6116486c2.3125 2.3125 3.6116638 5.448929 3.6116638 8.719299l0 49.322342c0 6.810211 -5.520752 12.330963 -12.330963 12.330963l-192.34596 0c-6.810196 0 -12.330948 -5.520752 -12.330948 -12.330963z" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m133.0 207.33095l0 0c0 -6.810196 5.520752 -12.330948 12.330948 -12.330948l192.34596 0c3.2703857 0 6.4067993 1.2991486 8.719299 3.6116486c2.3125 2.3125 3.6116638 5.448929 3.6116638 8.719299l0 49.322342c0 6.810211 -5.520752 12.330963 -12.330963 12.330963l-192.34596 0c-6.810196 0 -12.330948 -5.520752 -12.330948 -12.330963z" fill-rule="evenodd"></path><path fill="#000000" d="m204.56313 238.91212l0 -13.359375l5.046875 0q1.328125 0 2.03125 0.125q0.96875 0.171875 1.640625 0.640625q0.671875 0.453125 1.078125 1.28125q0.40625 0.828125 0.40625 1.828125q0 1.703125 -1.09375 2.890625q-1.078125 1.171875 -3.921875 1.171875l-3.421875 0l0 5.421875l-1.765625 0zm1.765625 -7.0l3.453125 0q1.71875 0 2.4375 -0.640625q0.71875 -0.640625 0.71875 -1.796875q0 -0.84375 -0.421875 -1.4375q-0.421875 -0.59375 -1.125 -0.78125q-0.4375 -0.125 -1.640625 -0.125l-3.421875 0l0 4.78125zm10.427948 7.0l0 -13.359375l1.640625 0l0 13.359375l-1.640625 0zm10.519821 0l0 -1.421875q-1.125 1.640625 -3.0625 1.640625q-0.859375 0 -1.609375 -0.328125q-0.734375 -0.328125 -1.09375 -0.828125q-0.359375 -0.5 -0.5 -1.21875q-0.109375 -0.46875 -0.109375 -1.53125l0 -5.984375l1.640625 0l0 5.359375q0 1.28125 0.109375 1.734375q0.15625 0.640625 0.65625 1.015625q0.5 0.375 1.234375 0.375q0.734375 0 1.375 -0.375q0.65625 -0.390625 0.921875 -1.03125q0.265625 -0.65625 0.265625 -1.890625l0 -5.1875l1.640625 0l0 9.671875l-1.46875 0zm3.7350922 0.796875l1.59375 0.234375q0.109375 0.75 0.5625 1.078125q0.609375 0.453125 1.671875 0.453125q1.140625 0 1.75 -0.453125q0.625 -0.453125 0.84375 -1.265625q0.125 -0.5 0.109375 -2.109375q-1.0625 1.265625 -2.671875 1.265625q-2.0 0 -3.09375 -1.4375q-1.09375 -1.4375 -1.09375 -3.453125q0 -1.390625 0.5 -2.5625q0.515625 -1.171875 1.453125 -1.796875q0.953125 -0.640625 2.25 -0.640625q1.703125 0 2.8125 1.375l0 -1.15625l1.515625 0l0 8.359375q0 2.265625 -0.46875 3.203125q-0.453125 0.9375 -1.453125 1.484375q-0.984375 0.546875 -2.453125 0.546875q-1.71875 0 -2.796875 -0.78125q-1.0625 -0.765625 -1.03125 -2.34375zm1.359375 -5.8125q0 1.90625 0.75 2.78125q0.765625 0.875 1.90625 0.875q1.125 0 1.890625 -0.859375q0.765625 -0.875 0.765625 -2.734375q0 -1.78125 -0.796875 -2.671875q-0.78125 -0.90625 -1.890625 -0.90625q-1.09375 0 -1.859375 0.890625q-0.765625 0.875 -0.765625 2.625zm9.328842 -6.453125l0 -1.890625l1.640625 0l0 1.890625l-1.640625 0zm0 11.46875l0 -9.671875l1.640625 0l0 9.671875l-1.640625 0zm4.144821 0l0 -9.671875l1.46875 0l0 1.375q1.0625 -1.59375 3.078125 -1.59375q0.875 0 1.609375 0.3125q0.734375 0.3125 1.09375 0.828125q0.375 0.5 0.515625 1.203125q0.09375 0.453125 0.09375 1.59375l0 5.953125l-1.640625 0l0 -5.890625q0 -1.0 -0.203125 -1.484375q-0.1875 -0.5 -0.671875 -0.796875q-0.484375 -0.296875 -1.140625 -0.296875q-1.046875 0 -1.8125 0.671875q-0.75 0.65625 -0.75 2.515625l0 5.28125l-1.640625 0zm10.500717 0l0 -13.359375l1.78125 0l0 11.78125l6.5625 0l0 1.578125l-8.34375 0zm10.250702 -11.46875l0 -1.890625l1.640625 0l0 1.890625l-1.640625 0zm0 11.46875l0 -9.671875l1.640625 0l0 9.671875l-1.640625 0zm5.6448364 0l-1.515625 0l0 -13.359375l1.640625 0l0 4.765625q1.046875 -1.296875 2.65625 -1.296875q0.890625 0 1.6875 0.359375q0.796875 0.359375 1.3125 1.015625q0.515625 0.640625 0.796875 1.5625q0.296875 0.921875 0.296875 1.96875q0 2.484375 -1.234375 3.84375q-1.21875 1.359375 -2.953125 1.359375q-1.703125 0 -2.6875 -1.4375l0 1.21875zm-0.015625 -4.90625q0 1.734375 0.484375 2.515625q0.765625 1.265625 2.09375 1.265625q1.078125 0 1.859375 -0.9375q0.78125 -0.9375 0.78125 -2.78125q0 -1.890625 -0.75 -2.796875q-0.75 -0.90625 -1.828125 -0.90625q-1.0625 0 -1.859375 0.9375q-0.78125 0.9375 -0.78125 2.703125z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m550.98425 233.0l-200.97638 -1.0078735" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m550.98425 233.0l-194.97647 -0.97779846" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m356.01608 230.3705l-4.5463257 1.628952l4.5297546 1.674469z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m406.00787 133.0l145.98425 0l0 98.99213l-145.98425 0z" fill-rule="evenodd"></path><path fill="#000000" d="m416.44537 159.92l0 -13.359375l5.046875 0q1.328125 0 2.03125 0.125q0.96875 0.171875 1.640625 0.640625q0.671875 0.453125 1.078125 1.28125q0.40625 0.828125 0.40625 1.828125q0 1.703125 -1.09375 2.890625q-1.078125 1.171875 -3.921875 1.171875l-3.421875 0l0 5.421875l-1.765625 0zm1.765625 -7.0l3.453125 0q1.71875 0 2.4375 -0.640625q0.71875 -0.640625 0.71875 -1.796875q0 -0.84375 -0.421875 -1.4375q-0.421875 -0.59375 -1.125 -0.78125q-0.4375 -0.125 -1.640625 -0.125l-3.421875 0l0 4.78125zm10.427948 7.0l0 -13.359375l1.640625 0l0 13.359375l-1.640625 0zm10.519836 0l0 -1.421875q-1.125 1.640625 -3.0625 1.640625q-0.859375 0 -1.609375 -0.328125q-0.734375 -0.328125 -1.09375 -0.828125q-0.359375 -0.5 -0.5 -1.21875q-0.109375 -0.46875 -0.109375 -1.53125l0 -5.984375l1.640625 0l0 5.359375q0 1.28125 0.109375 1.734375q0.15625 0.640625 0.65625 1.015625q0.5 0.375 1.234375 0.375q0.734375 0 1.375 -0.375q0.65625 -0.390625 0.921875 -1.03125q0.265625 -0.65625 0.265625 -1.890625l0 -5.1875l1.640625 0l0 9.671875l-1.46875 0zm3.735077 0.796875l1.59375 0.234375q0.109375 0.75 0.5625 1.078125q0.609375 0.453125 1.671875 0.453125q1.140625 0 1.75 -0.453125q0.625 -0.453125 0.84375 -1.265625q0.125 -0.5 0.109375 -2.109375q-1.0625 1.265625 -2.671875 1.265625q-2.0 0 -3.09375 -1.4375q-1.09375 -1.4375 -1.09375 -3.453125q0 -1.390625 0.5 -2.5625q0.515625 -1.171875 1.453125 -1.796875q0.953125 -0.640625 2.25 -0.640625q1.703125 0 2.8125 1.375l0 -1.15625l1.515625 0l0 8.359375q0 2.265625 -0.46875 3.203125q-0.453125 0.9375 -1.453125 1.484375q-0.984375 0.546875 -2.453125 0.546875q-1.71875 0 -2.796875 -0.78125q-1.0625 -0.765625 -1.03125 -2.34375zm1.359375 -5.8125q0 1.90625 0.75 2.78125q0.765625 0.875 1.90625 0.875q1.125 0 1.890625 -0.859375q0.765625 -0.875 0.765625 -2.734375q0 -1.78125 -0.796875 -2.671875q-0.78125 -0.90625 -1.890625 -0.90625q-1.09375 0 -1.859375 0.890625q-0.765625 0.875 -0.765625 2.625zm9.328857 -6.453125l0 -1.890625l1.640625 0l0 1.890625l-1.640625 0zm0 11.46875l0 -9.671875l1.640625 0l0 9.671875l-1.640625 0zm4.144806 0l0 -9.671875l1.46875 0l0 1.375q1.0625 -1.59375 3.078125 -1.59375q0.875 0 1.609375 0.3125q0.734375 0.3125 1.09375 0.828125q0.375 0.5 0.515625 1.203125q0.09375 0.453125 0.09375 1.59375l0 5.953125l-1.640625 0l0 -5.890625q0 -1.0 -0.203125 -1.484375q-0.1875 -0.5 -0.671875 -0.796875q-0.484375 -0.296875 -1.140625 -0.296875q-1.046875 0 -1.8125 0.671875q-0.75 0.65625 -0.75 2.515625l0 5.28125l-1.640625 0zm15.559021 0l0 -13.359375l1.640625 0l0 4.796875q1.140625 -1.328125 2.890625 -1.328125q1.078125 0 1.859375 0.421875q0.796875 0.421875 1.140625 1.171875q0.34375 0.75 0.34375 2.171875l0 6.125l-1.640625 0l0 -6.125q0 -1.234375 -0.53125 -1.796875q-0.53125 -0.5625 -1.515625 -0.5625q-0.71875 0 -1.359375 0.390625q-0.640625 0.375 -0.921875 1.015625q-0.265625 0.640625 -0.265625 1.78125l0 5.296875l-1.640625 0zm16.688232 -1.1875q-0.921875 0.765625 -1.765625 1.09375q-0.828125 0.3125 -1.796875 0.3125q-1.59375 0 -2.453125 -0.78125q-0.859375 -0.78125 -0.859375 -1.984375q0 -0.71875 0.328125 -1.296875q0.328125 -0.59375 0.84375 -0.9375q0.53125 -0.359375 1.1875 -0.546875q0.46875 -0.125 1.453125 -0.25q1.984375 -0.234375 2.921875 -0.5625q0.015625 -0.34375 0.015625 -0.421875q0 -1.0 -0.46875 -1.421875q-0.625 -0.546875 -1.875 -0.546875q-1.15625 0 -1.703125 0.40625q-0.546875 0.40625 -0.8125 1.421875l-1.609375 -0.21875q0.21875 -1.015625 0.71875 -1.640625q0.5 -0.640625 1.453125 -0.984375q0.953125 -0.34375 2.1875 -0.34375q1.25 0 2.015625 0.296875q0.78125 0.28125 1.140625 0.734375q0.375 0.4375 0.515625 1.109375q0.078125 0.421875 0.078125 1.515625l0 2.1875q0 2.28125 0.109375 2.890625q0.109375 0.59375 0.40625 1.15625l-1.703125 0q-0.265625 -0.515625 -0.328125 -1.1875zm-0.140625 -3.671875q-0.890625 0.375 -2.671875 0.625q-1.015625 0.140625 -1.4375 0.328125q-0.421875 0.1875 -0.65625 0.53125q-0.21875 0.34375 -0.21875 0.78125q0 0.65625 0.5 1.09375q0.5 0.4375 1.453125 0.4375q0.9375 0 1.671875 -0.40625q0.75 -0.421875 1.09375 -1.140625q0.265625 -0.5625 0.265625 -1.640625l0 -0.609375zm3.547577 1.96875l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.90625q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.453125 2.4375 0.75q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125z" fill-rule="nonzero"></path><path fill="#000000" d="m416.24225 181.92l0 -9.671875l1.46875 0l0 1.375q1.0625 -1.59375 3.078125 -1.59375q0.875 0 1.609375 0.3125q0.734375 0.3125 1.09375 0.828125q0.375 0.5 0.515625 1.203125q0.09375 0.453125 0.09375 1.59375l0 5.953125l-1.640625 0l0 -5.890625q0 -1.0 -0.203125 -1.484375q-0.1875 -0.5 -0.671875 -0.796875q-0.484375 -0.296875 -1.140625 -0.296875q-1.046875 0 -1.8125 0.671875q-0.75 0.65625 -0.75 2.515625l0 5.28125l-1.640625 0zm9.766357 -4.84375q0 -2.6875 1.484375 -3.96875q1.25 -1.078125 3.046875 -1.078125q2.0 0 3.265625 1.3125q1.265625 1.296875 1.265625 3.609375q0 1.859375 -0.5625 2.9375q-0.5625 1.0625 -1.640625 1.65625q-1.0625 0.59375 -2.328125 0.59375q-2.03125 0 -3.28125 -1.296875q-1.25 -1.3125 -1.25 -3.765625zm1.6875 0q0 1.859375 0.796875 2.796875q0.8125 0.921875 2.046875 0.921875q1.21875 0 2.03125 -0.921875q0.8125 -0.9375 0.8125 -2.84375q0 -1.796875 -0.8125 -2.71875q-0.8125 -0.921875 -2.03125 -0.921875q-1.234375 0 -2.046875 0.921875q-0.796875 0.90625 -0.796875 2.765625zm9.297577 4.84375l0 -9.671875l1.46875 0l0 1.375q1.0625 -1.59375 3.078125 -1.59375q0.875 0 1.609375 0.3125q0.734375 0.3125 1.09375 0.828125q0.375 0.5 0.515625 1.203125q0.09375 0.453125 0.09375 1.59375l0 5.953125l-1.640625 0l0 -5.890625q0 -1.0 -0.203125 -1.484375q-0.1875 -0.5 -0.671875 -0.796875q-0.484375 -0.296875 -1.140625 -0.296875q-1.046875 0 -1.8125 0.671875q-0.75 0.65625 -0.75 2.515625l0 5.28125l-1.640625 0zm9.735107 -4.015625l0 -1.640625l5.03125 0l0 1.640625l-5.03125 0zm6.197052 1.125l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.90625q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.453125 2.4375 0.75q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125zm13.5625 1.421875l0.234375 1.453125q-0.6875 0.140625 -1.234375 0.140625q-0.890625 0 -1.390625 -0.28125q-0.484375 -0.28125 -0.6875 -0.734375q-0.203125 -0.46875 -0.203125 -1.9375l0 -5.578125l-1.203125 0l0 -1.265625l1.203125 0l0 -2.390625l1.625 -0.984375l0 3.375l1.65625 0l0 1.265625l-1.65625 0l0 5.671875q0 0.6875 0.078125 0.890625q0.09375 0.203125 0.28125 0.328125q0.203125 0.109375 0.578125 0.109375q0.265625 0 0.71875 -0.0625zm7.9176636 0.28125q-0.921875 0.765625 -1.765625 1.09375q-0.828125 0.3125 -1.796875 0.3125q-1.59375 0 -2.453125 -0.78125q-0.859375 -0.78125 -0.859375 -1.984375q0 -0.71875 0.328125 -1.296875q0.328125 -0.59375 0.84375 -0.9375q0.53125 -0.359375 1.1875 -0.546875q0.46875 -0.125 1.453125 -0.25q1.984375 -0.234375 2.921875 -0.5625q0.015625 -0.34375 0.015625 -0.421875q0 -1.0 -0.46875 -1.421875q-0.625 -0.546875 -1.875 -0.546875q-1.15625 0 -1.703125 0.40625q-0.546875 0.40625 -0.8125 1.421875l-1.609375 -0.21875q0.21875 -1.015625 0.71875 -1.640625q0.5 -0.640625 1.453125 -0.984375q0.953125 -0.34375 2.1875 -0.34375q1.25 0 2.015625 0.296875q0.78125 0.28125 1.140625 0.734375q0.375 0.4375 0.515625 1.109375q0.078125 0.421875 0.078125 1.515625l0 2.1875q0 2.28125 0.109375 2.890625q0.109375 0.59375 0.40625 1.15625l-1.703125 0q-0.265625 -0.515625 -0.328125 -1.1875zm-0.140625 -3.671875q-0.890625 0.375 -2.671875 0.625q-1.015625 0.140625 -1.4375 0.328125q-0.421875 0.1875 -0.65625 0.53125q-0.21875 0.34375 -0.21875 0.78125q0 0.65625 0.5 1.09375q0.5 0.4375 1.453125 0.4375q0.9375 0 1.671875 -0.40625q0.75 -0.421875 1.09375 -1.140625q0.265625 -0.5625 0.265625 -1.640625l0 -0.609375zm7.7819824 3.390625l0.234375 1.453125q-0.6875 0.140625 -1.234375 0.140625q-0.890625 0 -1.390625 -0.28125q-0.484375 -0.28125 -0.6875 -0.734375q-0.203125 -0.46875 -0.203125 -1.9375l0 -5.578125l-1.203125 0l0 -1.265625l1.203125 0l0 -2.390625l1.625 -0.984375l0 3.375l1.65625 0l0 1.265625l-1.65625 0l0 5.671875q0 0.6875 0.078125 0.890625q0.09375 0.203125 0.28125 0.328125q0.203125 0.109375 0.578125 0.109375q0.265625 0 0.71875 -0.0625zm1.6051636 -10.0l0 -1.890625l1.640625 0l0 1.890625l-1.640625 0zm0 11.46875l0 -9.671875l1.640625 0l0 9.671875l-1.640625 0zm10.457336 -3.546875l1.609375 0.21875q-0.265625 1.65625 -1.359375 2.609375q-1.078125 0.9375 -2.671875 0.9375q-1.984375 0 -3.1875 -1.296875q-1.203125 -1.296875 -1.203125 -3.71875q0 -1.578125 0.515625 -2.75q0.515625 -1.171875 1.578125 -1.75q1.0625 -0.59375 2.3125 -0.59375q1.578125 0 2.578125 0.796875q1.0 0.796875 1.28125 2.265625l-1.59375 0.234375q-0.234375 -0.96875 -0.8125 -1.453125q-0.578125 -0.5 -1.390625 -0.5q-1.234375 0 -2.015625 0.890625q-0.78125 0.890625 -0.78125 2.8125q0 1.953125 0.75 2.84375q0.75 0.875 1.953125 0.875q0.96875 0 1.609375 -0.59375q0.65625 -0.59375 0.828125 -1.828125z" fill-rule="nonzero"></path><path fill="#000000" d="m422.50787 203.92l0 -1.21875q-0.90625 1.4375 -2.703125 1.4375q-1.15625 0 -2.125 -0.640625q-0.96875 -0.640625 -1.5 -1.78125q-0.53125 -1.140625 -0.53125 -2.625q0 -1.453125 0.484375 -2.625q0.484375 -1.1875 1.4375 -1.8125q0.96875 -0.625 2.171875 -0.625q0.875 0 1.546875 0.375q0.6875 0.359375 1.109375 0.953125l0 -4.796875l1.640625 0l0 13.359375l-1.53125 0zm-5.171875 -4.828125q0 1.859375 0.78125 2.78125q0.78125 0.921875 1.84375 0.921875q1.078125 0 1.828125 -0.875q0.75 -0.890625 0.75 -2.6875q0 -1.984375 -0.765625 -2.90625q-0.765625 -0.9375 -1.890625 -0.9375q-1.078125 0 -1.8125 0.890625q-0.734375 0.890625 -0.734375 2.8125zm15.906982 1.71875l1.6875 0.203125q-0.40625 1.484375 -1.484375 2.3125q-1.078125 0.8125 -2.765625 0.8125q-2.125 0 -3.375 -1.296875q-1.234375 -1.3125 -1.234375 -3.671875q0 -2.453125 1.25 -3.796875q1.265625 -1.34375 3.265625 -1.34375q1.9375 0 3.15625 1.328125q1.234375 1.3125 1.234375 3.703125q0 0.15625 0 0.4375l-7.21875 0q0.09375 1.59375 0.90625 2.453125q0.8125 0.84375 2.015625 0.84375q0.90625 0 1.546875 -0.46875q0.640625 -0.484375 1.015625 -1.515625zm-5.390625 -2.65625l5.40625 0q-0.109375 -1.21875 -0.625 -1.828125q-0.78125 -0.953125 -2.03125 -0.953125q-1.125 0 -1.90625 0.765625q-0.765625 0.75 -0.84375 2.015625zm9.141327 9.46875l0 -13.375l1.484375 0l0 1.25q0.53125 -0.734375 1.1875 -1.09375q0.671875 -0.375 1.625 -0.375q1.234375 0 2.171875 0.640625q0.953125 0.625 1.4375 1.796875q0.484375 1.15625 0.484375 2.546875q0 1.484375 -0.53125 2.671875q-0.53125 1.1875 -1.546875 1.828125q-1.015625 0.625 -2.140625 0.625q-0.8125 0 -1.46875 -0.34375q-0.65625 -0.34375 -1.0625 -0.875l0 4.703125l-1.640625 0zm1.484375 -8.484375q0 1.859375 0.75 2.765625q0.765625 0.890625 1.828125 0.890625q1.09375 0 1.875 -0.921875q0.78125 -0.9375 0.78125 -2.875q0 -1.84375 -0.765625 -2.765625q-0.75 -0.921875 -1.8125 -0.921875q-1.046875 0 -1.859375 0.984375q-0.796875 0.96875 -0.796875 2.84375zm15.516357 1.671875l1.6875 0.203125q-0.40625 1.484375 -1.484375 2.3125q-1.078125 0.8125 -2.765625 0.8125q-2.125 0 -3.375 -1.296875q-1.234375 -1.3125 -1.234375 -3.671875q0 -2.453125 1.25 -3.796875q1.265625 -1.34375 3.265625 -1.34375q1.9375 0 3.15625 1.328125q1.234375 1.3125 1.234375 3.703125q0 0.15625 0 0.4375l-7.21875 0q0.09375 1.59375 0.90625 2.453125q0.8125 0.84375 2.015625 0.84375q0.90625 0 1.546875 -0.46875q0.640625 -0.484375 1.015625 -1.515625zm-5.390625 -2.65625l5.40625 0q-0.109375 -1.21875 -0.625 -1.828125q-0.78125 -0.953125 -2.03125 -0.953125q-1.125 0 -1.90625 0.765625q-0.765625 0.75 -0.84375 2.015625zm9.141327 5.765625l0 -9.671875l1.46875 0l0 1.375q1.0625 -1.59375 3.078125 -1.59375q0.875 0 1.609375 0.3125q0.734375 0.3125 1.09375 0.828125q0.375 0.5 0.515625 1.203125q0.09375 0.453125 0.09375 1.59375l0 5.953125l-1.640625 0l0 -5.890625q0 -1.0 -0.203125 -1.484375q-0.1875 -0.5 -0.671875 -0.796875q-0.484375 -0.296875 -1.140625 -0.296875q-1.046875 0 -1.8125 0.671875q-0.75 0.65625 -0.75 2.515625l0 5.28125l-1.640625 0zm16.641357 0l0 -1.21875q-0.90625 1.4375 -2.703125 1.4375q-1.15625 0 -2.125 -0.640625q-0.96875 -0.640625 -1.5 -1.78125q-0.53125 -1.140625 -0.53125 -2.625q0 -1.453125 0.484375 -2.625q0.484375 -1.1875 1.4375 -1.8125q0.96875 -0.625 2.171875 -0.625q0.875 0 1.546875 0.375q0.6875 0.359375 1.109375 0.953125l0 -4.796875l1.640625 0l0 13.359375l-1.53125 0zm-5.171875 -4.828125q0 1.859375 0.78125 2.78125q0.78125 0.921875 1.84375 0.921875q1.078125 0 1.828125 -0.875q0.75 -0.890625 0.75 -2.6875q0 -1.984375 -0.765625 -2.90625q-0.765625 -0.9375 -1.890625 -0.9375q-1.078125 0 -1.8125 0.890625q-0.734375 0.890625 -0.734375 2.8125zm15.906952 1.71875l1.6875 0.203125q-0.40625 1.484375 -1.484375 2.3125q-1.078125 0.8125 -2.765625 0.8125q-2.125 0 -3.375 -1.296875q-1.234375 -1.3125 -1.234375 -3.671875q0 -2.453125 1.25 -3.796875q1.265625 -1.34375 3.265625 -1.34375q1.9375 0 3.15625 1.328125q1.234375 1.3125 1.234375 3.703125q0 0.15625 0 0.4375l-7.21875 0q0.09375 1.59375 0.90625 2.453125q0.8125 0.84375 2.015625 0.84375q0.90625 0 1.546875 -0.46875q0.640625 -0.484375 1.015625 -1.515625zm-5.390625 -2.65625l5.40625 0q-0.109375 -1.21875 -0.625 -1.828125q-0.78125 -0.953125 -2.03125 -0.953125q-1.125 0 -1.90625 0.765625q-0.765625 0.75 -0.84375 2.015625zm9.141357 5.765625l0 -9.671875l1.46875 0l0 1.375q1.0625 -1.59375 3.078125 -1.59375q0.875 0 1.609375 0.3125q0.734375 0.3125 1.09375 0.828125q0.375 0.5 0.515625 1.203125q0.09375 0.453125 0.09375 1.59375l0 5.953125l-1.640625 0l0 -5.890625q0 -1.0 -0.203125 -1.484375q-0.1875 -0.5 -0.671875 -0.796875q-0.484375 -0.296875 -1.140625 -0.296875q-1.046875 0 -1.8125 0.671875q-0.75 0.65625 -0.75 2.515625l0 5.28125l-1.640625 0zm16.688202 -3.546875l1.609375 0.21875q-0.265625 1.65625 -1.359375 2.609375q-1.078125 0.9375 -2.671875 0.9375q-1.984375 0 -3.1875 -1.296875q-1.203125 -1.296875 -1.203125 -3.71875q0 -1.578125 0.515625 -2.75q0.515625 -1.171875 1.578125 -1.75q1.0625 -0.59375 2.3125 -0.59375q1.578125 0 2.578125 0.796875q1.0 0.796875 1.28125 2.265625l-1.59375 0.234375q-0.234375 -0.96875 -0.8125 -1.453125q-0.578125 -0.5 -1.390625 -0.5q-1.234375 0 -2.015625 0.890625q-0.78125 0.890625 -0.78125 2.8125q0 1.953125 0.75 2.84375q0.75 0.875 1.953125 0.875q0.96875 0 1.609375 -0.59375q0.65625 -0.59375 0.828125 -1.828125zm2.9375 7.265625l-0.1875 -1.53125q0.546875 0.140625 0.9375 0.140625q0.546875 0 0.875 -0.1875q0.328125 -0.171875 0.546875 -0.5q0.15625 -0.25 0.5 -1.21875q0.046875 -0.140625 0.140625 -0.40625l-3.671875 -9.6875l1.765625 0l2.015625 5.59375q0.390625 1.078125 0.703125 2.25q0.28125 -1.125 0.671875 -2.203125l2.078125 -5.640625l1.640625 0l-3.6875 9.828125q-0.59375 1.609375 -0.921875 2.203125q-0.4375 0.8125 -1.0 1.1875q-0.5625 0.375 -1.34375 0.375q-0.484375 0 -1.0625 -0.203125zm13.980164 -8.5625q0 -2.6875 1.484375 -3.96875q1.25 -1.078125 3.046875 -1.078125q2.0 0 3.265625 1.3125q1.265625 1.296875 1.265625 3.609375q0 1.859375 -0.5625 2.9375q-0.5625 1.0625 -1.640625 1.65625q-1.0625 0.59375 -2.328125 0.59375q-2.03125 0 -3.28125 -1.296875q-1.25 -1.3125 -1.25 -3.765625zm1.6875 0q0 1.859375 0.796875 2.796875q0.8125 0.921875 2.046875 0.921875q1.21875 0 2.03125 -0.921875q0.8125 -0.9375 0.8125 -2.84375q0 -1.796875 -0.8125 -2.71875q-0.8125 -0.921875 -2.03125 -0.921875q-1.234375 0 -2.046875 0.921875q-0.796875 0.90625 -0.796875 2.765625zm9.297607 4.84375l0 -9.671875l1.46875 0l0 1.375q1.0625 -1.59375 3.078125 -1.59375q0.875 0 1.609375 0.3125q0.734375 0.3125 1.09375 0.828125q0.375 0.5 0.515625 1.203125q0.09375 0.453125 0.09375 1.59375l0 5.953125l-1.640625 0l0 -5.890625q0 -1.0 -0.203125 -1.484375q-0.1875 -0.5 -0.671875 -0.796875q-0.484375 -0.296875 -1.140625 -0.296875q-1.046875 0 -1.8125 0.671875q-0.75 0.65625 -0.75 2.515625l0 5.28125l-1.640625 0z" fill-rule="nonzero"></path><path fill="#000000" d="m416.44537 225.92l0 -13.359375l5.046875 0q1.328125 0 2.03125 0.125q0.96875 0.171875 1.640625 0.640625q0.671875 0.453125 1.078125 1.28125q0.40625 0.828125 0.40625 1.828125q0 1.703125 -1.09375 2.890625q-1.078125 1.171875 -3.921875 1.171875l-3.421875 0l0 5.421875l-1.765625 0zm1.765625 -7.0l3.453125 0q1.71875 0 2.4375 -0.640625q0.71875 -0.640625 0.71875 -1.796875q0 -0.84375 -0.421875 -1.4375q-0.421875 -0.59375 -1.125 -0.78125q-0.4375 -0.125 -1.640625 -0.125l-3.421875 0l0 4.78125zm10.427948 7.0l0 -13.359375l1.640625 0l0 13.359375l-1.640625 0zm10.519836 0l0 -1.421875q-1.125 1.640625 -3.0625 1.640625q-0.859375 0 -1.609375 -0.328125q-0.734375 -0.328125 -1.09375 -0.828125q-0.359375 -0.5 -0.5 -1.21875q-0.109375 -0.46875 -0.109375 -1.53125l0 -5.984375l1.640625 0l0 5.359375q0 1.28125 0.109375 1.734375q0.15625 0.640625 0.65625 1.015625q0.5 0.375 1.234375 0.375q0.734375 0 1.375 -0.375q0.65625 -0.390625 0.921875 -1.03125q0.265625 -0.65625 0.265625 -1.890625l0 -5.1875l1.640625 0l0 9.671875l-1.46875 0zm3.735077 0.796875l1.59375 0.234375q0.109375 0.75 0.5625 1.078125q0.609375 0.453125 1.671875 0.453125q1.140625 0 1.75 -0.453125q0.625 -0.453125 0.84375 -1.265625q0.125 -0.5 0.109375 -2.109375q-1.0625 1.265625 -2.671875 1.265625q-2.0 0 -3.09375 -1.4375q-1.09375 -1.4375 -1.09375 -3.453125q0 -1.390625 0.5 -2.5625q0.515625 -1.171875 1.453125 -1.796875q0.953125 -0.640625 2.25 -0.640625q1.703125 0 2.8125 1.375l0 -1.15625l1.515625 0l0 8.359375q0 2.265625 -0.46875 3.203125q-0.453125 0.9375 -1.453125 1.484375q-0.984375 0.546875 -2.453125 0.546875q-1.71875 0 -2.796875 -0.78125q-1.0625 -0.765625 -1.03125 -2.34375zm1.359375 -5.8125q0 1.90625 0.75 2.78125q0.765625 0.875 1.90625 0.875q1.125 0 1.890625 -0.859375q0.765625 -0.875 0.765625 -2.734375q0 -1.78125 -0.796875 -2.671875q-0.78125 -0.90625 -1.890625 -0.90625q-1.09375 0 -1.859375 0.890625q-0.765625 0.875 -0.765625 2.625zm9.328857 -6.453125l0 -1.890625l1.640625 0l0 1.890625l-1.640625 0zm0 11.46875l0 -9.671875l1.640625 0l0 9.671875l-1.640625 0zm4.144806 0l0 -9.671875l1.46875 0l0 1.375q1.0625 -1.59375 3.078125 -1.59375q0.875 0 1.609375 0.3125q0.734375 0.3125 1.09375 0.828125q0.375 0.5 0.515625 1.203125q0.09375 0.453125 0.09375 1.59375l0 5.953125l-1.640625 0l0 -5.890625q0 -1.0 -0.203125 -1.484375q-0.1875 -0.5 -0.671875 -0.796875q-0.484375 -0.296875 -1.140625 -0.296875q-1.046875 0 -1.8125 0.671875q-0.75 0.65625 -0.75 2.515625l0 5.28125l-1.640625 0zm10.500732 0l0 -13.359375l1.78125 0l0 11.78125l6.5625 0l0 1.578125l-8.34375 0zm10.250702 -11.46875l0 -1.890625l1.640625 0l0 1.890625l-1.640625 0zm0 11.46875l0 -9.671875l1.640625 0l0 9.671875l-1.640625 0zm5.6448364 0l-1.515625 0l0 -13.359375l1.640625 0l0 4.765625q1.046875 -1.296875 2.65625 -1.296875q0.890625 0 1.6875 0.359375q0.796875 0.359375 1.3125 1.015625q0.515625 0.640625 0.796875 1.5625q0.296875 0.921875 0.296875 1.96875q0 2.484375 -1.234375 3.84375q-1.21875 1.359375 -2.953125 1.359375q-1.703125 0 -2.6875 -1.4375l0 1.21875zm-0.015625 -4.90625q0 1.734375 0.484375 2.515625q0.765625 1.265625 2.09375 1.265625q1.078125 0 1.859375 -0.9375q0.78125 -0.9375 0.78125 -2.78125q0 -1.890625 -0.75 -2.796875q-0.75 -0.90625 -1.828125 -0.90625q-1.0625 0 -1.859375 0.9375q-0.78125 0.9375 -0.78125 2.703125z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m351.50394 386.50656l204.00003 1.4803162" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m351.50394 386.50656l198.00015 1.4367676" fill-rule="evenodd"></path><path fill="#000000" stroke="#000000" stroke-width="1.0" stroke-linecap="butt" d="m549.4921 389.59503l4.5499268 -1.6187744l-4.526001 -1.6846008z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m409.0 325.0l133.00787 0l0 61.51181l-133.00787 0z" fill-rule="evenodd"></path><path fill="#000000" d="m418.84375 347.6231l1.65625 -0.140625q0.125 1.0 0.546875 1.640625q0.4375 0.640625 1.34375 1.046875q0.921875 0.390625 2.0625 0.390625q1.0 0 1.78125 -0.296875q0.78125 -0.296875 1.15625 -0.8125q0.375 -0.53125 0.375 -1.15625q0 -0.625 -0.375 -1.09375q-0.359375 -0.46875 -1.1875 -0.796875q-0.546875 -0.203125 -2.390625 -0.640625q-1.828125 -0.453125 -2.5625 -0.84375q-0.96875 -0.5 -1.4375 -1.234375q-0.46875 -0.75 -0.46875 -1.671875q0 -1.0 0.578125 -1.875q0.578125 -0.890625 1.671875 -1.34375q1.109375 -0.453125 2.453125 -0.453125q1.484375 0 2.609375 0.484375q1.140625 0.46875 1.75 1.40625q0.609375 0.921875 0.65625 2.09375l-1.6875 0.125q-0.140625 -1.265625 -0.9375 -1.90625q-0.78125 -0.65625 -2.3125 -0.65625q-1.609375 0 -2.34375 0.59375q-0.734375 0.59375 -0.734375 1.421875q0 0.71875 0.53125 1.171875q0.5 0.46875 2.65625 0.96875q2.15625 0.484375 2.953125 0.84375q1.171875 0.53125 1.71875 1.359375q0.5625 0.828125 0.5625 1.90625q0 1.0625 -0.609375 2.015625q-0.609375 0.9375 -1.75 1.46875q-1.140625 0.515625 -2.578125 0.515625q-1.8125 0 -3.046875 -0.53125q-1.21875 -0.53125 -1.921875 -1.59375q-0.6875 -1.0625 -0.71875 -2.40625zm12.756073 8.015625l-0.1875 -1.53125q0.546875 0.140625 0.9375 0.140625q0.546875 0 0.875 -0.1875q0.328125 -0.171875 0.546875 -0.5q0.15625 -0.25 0.5 -1.21875q0.046875 -0.140625 0.140625 -0.40625l-3.671875 -9.6875l1.765625 0l2.015625 5.59375q0.390625 1.078125 0.703125 2.25q0.28125 -1.125 0.671875 -2.203125l2.078125 -5.640625l1.640625 0l-3.6875 9.828125q-0.59375 1.609375 -0.921875 2.203125q-0.4375 0.8125 -1.0 1.1875q-0.5625 0.375 -1.34375 0.375q-0.484375 0 -1.0625 -0.203125zm8.75 -6.609375l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.90625q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.453125 2.4375 0.75q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125zm18.953125 -10.46875l1.765625 0l0 7.71875q0 2.015625 -0.453125 3.203125q-0.453125 1.1875 -1.640625 1.9375q-1.1875 0.734375 -3.125 0.734375q-1.875 0 -3.078125 -0.640625q-1.1875 -0.65625 -1.703125 -1.875q-0.5 -1.234375 -0.5 -3.359375l0 -7.71875l1.765625 0l0 7.71875q0 1.734375 0.3125 2.5625q0.328125 0.8125 1.109375 1.265625q0.796875 0.453125 1.9375 0.453125q1.953125 0 2.78125 -0.890625q0.828125 -0.890625 0.828125 -3.390625l0 -7.71875zm5.004181 13.359375l0 -13.359375l1.765625 0l0 13.359375l-1.765625 0zm9.819763 0l0 -13.359375l1.640625 0l0 13.359375l-1.640625 0zm3.582306 -4.84375q0 -2.6875 1.484375 -3.96875q1.25 -1.078125 3.046875 -1.078125q2.0 0 3.265625 1.3125q1.265625 1.296875 1.265625 3.609375q0 1.859375 -0.5625 2.9375q-0.5625 1.0625 -1.640625 1.65625q-1.0625 0.59375 -2.328125 0.59375q-2.03125 0 -3.28125 -1.296875q-1.25 -1.3125 -1.25 -3.765625zm1.6875 0q0 1.859375 0.796875 2.796875q0.8125 0.921875 2.046875 0.921875q1.21875 0 2.03125 -0.921875q0.8125 -0.9375 0.8125 -2.84375q0 -1.796875 -0.8125 -2.71875q-0.8125 -0.921875 -2.03125 -0.921875q-1.234375 0 -2.046875 0.921875q-0.796875 0.90625 -0.796875 2.765625zm15.610077 3.65625q-0.921875 0.765625 -1.765625 1.09375q-0.828125 0.3125 -1.796875 0.3125q-1.59375 0 -2.453125 -0.78125q-0.859375 -0.78125 -0.859375 -1.984375q0 -0.71875 0.328125 -1.296875q0.328125 -0.59375 0.84375 -0.9375q0.53125 -0.359375 1.1875 -0.546875q0.46875 -0.125 1.453125 -0.25q1.984375 -0.234375 2.921875 -0.5625q0.015625 -0.34375 0.015625 -0.421875q0 -1.0 -0.46875 -1.421875q-0.625 -0.546875 -1.875 -0.546875q-1.15625 0 -1.703125 0.40625q-0.546875 0.40625 -0.8125 1.421875l-1.609375 -0.21875q0.21875 -1.015625 0.71875 -1.640625q0.5 -0.640625 1.453125 -0.984375q0.953125 -0.34375 2.1875 -0.34375q1.25 0 2.015625 0.296875q0.78125 0.28125 1.140625 0.734375q0.375 0.4375 0.515625 1.109375q0.078125 0.421875 0.078125 1.515625l0 2.1875q0 2.28125 0.109375 2.890625q0.109375 0.59375 0.40625 1.15625l-1.703125 0q-0.265625 -0.515625 -0.328125 -1.1875zm-0.140625 -3.671875q-0.890625 0.375 -2.671875 0.625q-1.015625 0.140625 -1.4375 0.328125q-0.421875 0.1875 -0.65625 0.53125q-0.21875 0.34375 -0.21875 0.78125q0 0.65625 0.5 1.09375q0.5 0.4375 1.453125 0.4375q0.9375 0 1.671875 -0.40625q0.75 -0.421875 1.09375 -1.140625q0.265625 -0.5625 0.265625 -1.640625l0 -0.609375zm10.469482 4.859375l0 -1.21875q-0.90625 1.4375 -2.703125 1.4375q-1.15625 0 -2.125 -0.640625q-0.96875 -0.640625 -1.5 -1.78125q-0.53125 -1.140625 -0.53125 -2.625q0 -1.453125 0.484375 -2.625q0.484375 -1.1875 1.4375 -1.8125q0.96875 -0.625 2.171875 -0.625q0.875 0 1.546875 0.375q0.6875 0.359375 1.109375 0.953125l0 -4.796875l1.640625 0l0 13.359375l-1.53125 0zm-5.171875 -4.828125q0 1.859375 0.78125 2.78125q0.78125 0.921875 1.84375 0.921875q1.078125 0 1.828125 -0.875q0.75 -0.890625 0.75 -2.6875q0 -1.984375 -0.765625 -2.90625q-0.765625 -0.9375 -1.890625 -0.9375q-1.078125 0 -1.8125 0.890625q-0.734375 0.890625 -0.734375 2.8125zm8.625732 1.9375l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.90625q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.453125 2.4375 0.75q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125z" fill-rule="nonzero"></path><path fill="#000000" d="m419.4375 373.91998l0 -13.359375l5.046875 0q1.328125 0 2.03125 0.125q0.96875 0.171875 1.640625 0.640625q0.671875 0.453125 1.078125 1.28125q0.40625 0.828125 0.40625 1.828125q0 1.703125 -1.09375 2.890625q-1.078125 1.171875 -3.921875 1.171875l-3.421875 0l0 5.421875l-1.765625 0zm1.765625 -7.0l3.453125 0q1.71875 0 2.4375 -0.640625q0.71875 -0.640625 0.71875 -1.796875q0 -0.84375 -0.421875 -1.4375q-0.421875 -0.59375 -1.125 -0.78125q-0.4375 -0.125 -1.640625 -0.125l-3.421875 0l0 4.78125zm10.427948 7.0l0 -13.359375l1.640625 0l0 13.359375l-1.640625 0zm10.519806 0l0 -1.421875q-1.125 1.640625 -3.0625 1.640625q-0.859375 0 -1.609375 -0.328125q-0.734375 -0.328125 -1.09375 -0.828125q-0.359375 -0.5 -0.5 -1.21875q-0.109375 -0.46875 -0.109375 -1.53125l0 -5.984375l1.640625 0l0 5.359375q0 1.28125 0.109375 1.734375q0.15625 0.640625 0.65625 1.015625q0.5 0.375 1.234375 0.375q0.734375 0 1.375 -0.375q0.65625 -0.390625 0.921875 -1.03125q0.265625 -0.65625 0.265625 -1.890625l0 -5.1875l1.640625 0l0 9.671875l-1.46875 0zm3.7351074 0.796875l1.59375 0.234375q0.109375 0.75 0.5625 1.078125q0.609375 0.453125 1.671875 0.453125q1.140625 0 1.75 -0.453125q0.625 -0.453125 0.84375 -1.265625q0.125 -0.5 0.109375 -2.109375q-1.0625 1.265625 -2.671875 1.265625q-2.0 0 -3.09375 -1.4375q-1.09375 -1.4375 -1.09375 -3.453125q0 -1.390625 0.5 -2.5625q0.515625 -1.171875 1.453125 -1.796875q0.953125 -0.640625 2.25 -0.640625q1.703125 0 2.8125 1.375l0 -1.15625l1.515625 0l0 8.359375q0 2.265625 -0.46875 3.203125q-0.453125 0.9375 -1.453125 1.484375q-0.984375 0.546875 -2.453125 0.546875q-1.71875 0 -2.796875 -0.78125q-1.0625 -0.765625 -1.03125 -2.34375zm1.359375 -5.8125q0 1.90625 0.75 2.78125q0.765625 0.875 1.90625 0.875q1.125 0 1.890625 -0.859375q0.765625 -0.875 0.765625 -2.734375q0 -1.78125 -0.796875 -2.671875q-0.78125 -0.90625 -1.890625 -0.90625q-1.09375 0 -1.859375 0.890625q-0.765625 0.875 -0.765625 2.625zm9.328857 -6.453125l0 -1.890625l1.640625 0l0 1.890625l-1.640625 0zm0 11.46875l0 -9.671875l1.640625 0l0 9.671875l-1.640625 0zm4.144806 0l0 -9.671875l1.46875 0l0 1.375q1.0625 -1.59375 3.078125 -1.59375q0.875 0 1.609375 0.3125q0.734375 0.3125 1.09375 0.828125q0.375 0.5 0.515625 1.203125q0.09375 0.453125 0.09375 1.59375l0 5.953125l-1.640625 0l0 -5.890625q0 -1.0 -0.203125 -1.484375q-0.1875 -0.5 -0.671875 -0.796875q-0.484375 -0.296875 -1.140625 -0.296875q-1.046875 0 -1.8125 0.671875q-0.75 0.65625 -0.75 2.515625l0 5.28125l-1.640625 0zm21.871521 -3.546875l1.609375 0.21875q-0.265625 1.65625 -1.359375 2.609375q-1.078125 0.9375 -2.671875 0.9375q-1.984375 0 -3.1875 -1.296875q-1.203125 -1.296875 -1.203125 -3.71875q0 -1.578125 0.515625 -2.75q0.515625 -1.171875 1.578125 -1.75q1.0625 -0.59375 2.3125 -0.59375q1.578125 0 2.578125 0.796875q1.0 0.796875 1.28125 2.265625l-1.59375 0.234375q-0.234375 -0.96875 -0.8125 -1.453125q-0.578125 -0.5 -1.390625 -0.5q-1.234375 0 -2.015625 0.890625q-0.78125 0.890625 -0.78125 2.8125q0 1.953125 0.75 2.84375q0.75 0.875 1.953125 0.875q0.96875 0 1.609375 -0.59375q0.65625 -0.59375 0.828125 -1.828125zm2.40625 -1.296875q0 -2.6875 1.484375 -3.96875q1.25 -1.078125 3.046875 -1.078125q2.0 0 3.265625 1.3125q1.265625 1.296875 1.265625 3.609375q0 1.859375 -0.5625 2.9375q-0.5625 1.0625 -1.640625 1.65625q-1.0625 0.59375 -2.328125 0.59375q-2.03125 0 -3.28125 -1.296875q-1.25 -1.3125 -1.25 -3.765625zm1.6875 0q0 1.859375 0.796875 2.796875q0.8125 0.921875 2.046875 0.921875q1.21875 0 2.03125 -0.921875q0.8125 -0.9375 0.8125 -2.84375q0 -1.796875 -0.8125 -2.71875q-0.8125 -0.921875 -2.03125 -0.921875q-1.234375 0 -2.046875 0.921875q-0.796875 0.90625 -0.796875 2.765625zm15.563202 4.84375l0 -1.21875q-0.90625 1.4375 -2.703125 1.4375q-1.15625 0 -2.125 -0.640625q-0.96875 -0.640625 -1.5 -1.78125q-0.53125 -1.140625 -0.53125 -2.625q0 -1.453125 0.484375 -2.625q0.484375 -1.1875 1.4375 -1.8125q0.96875 -0.625 2.171875 -0.625q0.875 0 1.546875 0.375q0.6875 0.359375 1.109375 0.953125l0 -4.796875l1.640625 0l0 13.359375l-1.53125 0zm-5.171875 -4.828125q0 1.859375 0.78125 2.78125q0.78125 0.921875 1.84375 0.921875q1.078125 0 1.828125 -0.875q0.75 -0.890625 0.75 -2.6875q0 -1.984375 -0.765625 -2.90625q-0.765625 -0.9375 -1.890625 -0.9375q-1.078125 0 -1.8125 0.890625q-0.734375 0.890625 -0.734375 2.8125zm15.906982 1.71875l1.6875 0.203125q-0.40625 1.484375 -1.484375 2.3125q-1.078125 0.8125 -2.765625 0.8125q-2.125 0 -3.375 -1.296875q-1.234375 -1.3125 -1.234375 -3.671875q0 -2.453125 1.25 -3.796875q1.265625 -1.34375 3.265625 -1.34375q1.9375 0 3.15625 1.328125q1.234375 1.3125 1.234375 3.703125q0 0.15625 0 0.4375l-7.21875 0q0.09375 1.59375 0.90625 2.453125q0.8125 0.84375 2.015625 0.84375q0.90625 0 1.546875 -0.46875q0.640625 -0.484375 1.015625 -1.515625zm-5.390625 -2.65625l5.40625 0q-0.109375 -1.21875 -0.625 -1.828125q-0.78125 -0.953125 -2.03125 -0.953125q-1.125 0 -1.90625 0.765625q-0.765625 0.75 -0.84375 2.015625z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m241.50394 346.00262l0 -77.00787" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m241.50394 346.00262l0 -77.00787" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m241.51181 273.88583l145.98425 0l0 67.212585l-145.98425 0z" fill-rule="evenodd"></path><path fill="#000000" d="m251.35556 296.50894l1.65625 -0.140625q0.125 1.0 0.546875 1.640625q0.4375 0.640625 1.34375 1.046875q0.921875 0.390625 2.0625 0.390625q1.0 0 1.78125 -0.296875q0.78125 -0.296875 1.15625 -0.8125q0.375 -0.53125 0.375 -1.15625q0 -0.625 -0.375 -1.09375q-0.359375 -0.46875 -1.1875 -0.796875q-0.546875 -0.203125 -2.390625 -0.640625q-1.828125 -0.453125 -2.5625 -0.84375q-0.96875 -0.5 -1.4375 -1.234375q-0.46875 -0.75 -0.46875 -1.671875q0 -1.0 0.578125 -1.875q0.578125 -0.890625 1.671875 -1.34375q1.109375 -0.453125 2.453125 -0.453125q1.484375 0 2.609375 0.484375q1.140625 0.46875 1.75 1.40625q0.609375 0.921875 0.65625 2.09375l-1.6875 0.125q-0.140625 -1.265625 -0.9375 -1.90625q-0.78125 -0.65625 -2.3125 -0.65625q-1.609375 0 -2.34375 0.59375q-0.734375 0.59375 -0.734375 1.421875q0 0.71875 0.53125 1.171875q0.5 0.46875 2.65625 0.96875q2.15625 0.484375 2.953125 0.84375q1.171875 0.53125 1.71875 1.359375q0.5625 0.828125 0.5625 1.90625q0 1.0625 -0.609375 2.015625q-0.609375 0.9375 -1.75 1.46875q-1.140625 0.515625 -2.578125 0.515625q-1.8125 0 -3.046875 -0.53125q-1.21875 -0.53125 -1.921875 -1.59375q-0.6875 -1.0625 -0.71875 -2.40625zm12.756073 8.015625l-0.1875 -1.53125q0.546875 0.140625 0.9375 0.140625q0.546875 0 0.875 -0.1875q0.328125 -0.171875 0.546875 -0.5q0.15625 -0.25 0.5 -1.21875q0.046875 -0.140625 0.140625 -0.40625l-3.671875 -9.6875l1.765625 0l2.015625 5.59375q0.390625 1.078125 0.703125 2.25q0.28125 -1.125 0.671875 -2.203125l2.078125 -5.640625l1.640625 0l-3.6875 9.828125q-0.59375 1.609375 -0.921875 2.203125q-0.4375 0.8125 -1.0 1.1875q-0.5625 0.375 -1.34375 0.375q-0.484375 0 -1.0625 -0.203125zm8.75 -6.609375l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.90625q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.453125 2.4375 0.75q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125zm18.953125 -10.46875l1.765625 0l0 7.71875q0 2.015625 -0.453125 3.203125q-0.453125 1.1875 -1.640625 1.9375q-1.1875 0.734375 -3.125 0.734375q-1.875 0 -3.078125 -0.640625q-1.1875 -0.65625 -1.703125 -1.875q-0.5 -1.234375 -0.5 -3.359375l0 -7.71875l1.765625 0l0 7.71875q0 1.734375 0.3125 2.5625q0.328125 0.8125 1.109375 1.265625q0.796875 0.453125 1.9375 0.453125q1.953125 0 2.78125 -0.890625q0.828125 -0.890625 0.828125 -3.390625l0 -7.71875zm5.0042114 13.359375l0 -13.359375l1.765625 0l0 13.359375l-1.765625 0zm9.210358 -2.890625l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.90625q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.453125 2.4375 0.75q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125zm13.5625 1.421875l0.234375 1.453125q-0.6875 0.140625 -1.234375 0.140625q-0.890625 0 -1.390625 -0.28125q-0.484375 -0.28125 -0.6875 -0.734375q-0.203125 -0.46875 -0.203125 -1.9375l0 -5.578125l-1.203125 0l0 -1.265625l1.203125 0l0 -2.390625l1.625 -0.984375l0 3.375l1.65625 0l0 1.265625l-1.65625 0l0 5.671875q0 0.6875 0.078125 0.890625q0.09375 0.203125 0.28125 0.328125q0.203125 0.109375 0.578125 0.109375q0.265625 0 0.71875 -0.0625zm7.9176636 0.28125q-0.921875 0.765625 -1.765625 1.09375q-0.828125 0.3125 -1.796875 0.3125q-1.59375 0 -2.453125 -0.78125q-0.859375 -0.78125 -0.859375 -1.984375q0 -0.71875 0.328125 -1.296875q0.328125 -0.59375 0.84375 -0.9375q0.53125 -0.359375 1.1875 -0.546875q0.46875 -0.125 1.453125 -0.25q1.984375 -0.234375 2.921875 -0.5625q0.015625 -0.34375 0.015625 -0.421875q0 -1.0 -0.46875 -1.421875q-0.625 -0.546875 -1.875 -0.546875q-1.15625 0 -1.703125 0.40625q-0.546875 0.40625 -0.8125 1.421875l-1.609375 -0.21875q0.21875 -1.015625 0.71875 -1.640625q0.5 -0.640625 1.453125 -0.984375q0.953125 -0.34375 2.1875 -0.34375q1.25 0 2.015625 0.296875q0.78125 0.28125 1.140625 0.734375q0.375 0.4375 0.515625 1.109375q0.078125 0.421875 0.078125 1.515625l0 2.1875q0 2.28125 0.109375 2.890625q0.109375 0.59375 0.40625 1.15625l-1.703125 0q-0.265625 -0.515625 -0.328125 -1.1875zm-0.140625 -3.671875q-0.890625 0.375 -2.671875 0.625q-1.015625 0.140625 -1.4375 0.328125q-0.421875 0.1875 -0.65625 0.53125q-0.21875 0.34375 -0.21875 0.78125q0 0.65625 0.5 1.09375q0.5 0.4375 1.453125 0.4375q0.9375 0 1.671875 -0.40625q0.75 -0.421875 1.09375 -1.140625q0.265625 -0.5625 0.265625 -1.640625l0 -0.609375zm7.7819824 3.390625l0.234375 1.453125q-0.6875 0.140625 -1.234375 0.140625q-0.890625 0 -1.390625 -0.28125q-0.484375 -0.28125 -0.6875 -0.734375q-0.203125 -0.46875 -0.203125 -1.9375l0 -5.578125l-1.203125 0l0 -1.265625l1.203125 0l0 -2.390625l1.625 -0.984375l0 3.375l1.65625 0l0 1.265625l-1.65625 0l0 5.671875q0 0.6875 0.078125 0.890625q0.09375 0.203125 0.28125 0.328125q0.203125 0.109375 0.578125 0.109375q0.265625 0 0.71875 -0.0625zm1.6051636 -10.0l0 -1.890625l1.640625 0l0 1.890625l-1.640625 0zm0 11.46875l0 -9.671875l1.640625 0l0 9.671875l-1.640625 0zm10.457336 -3.546875l1.609375 0.21875q-0.265625 1.65625 -1.359375 2.609375q-1.078125 0.9375 -2.671875 0.9375q-1.984375 0 -3.1875 -1.296875q-1.203125 -1.296875 -1.203125 -3.71875q0 -1.578125 0.515625 -2.75q0.515625 -1.171875 1.578125 -1.75q1.0625 -0.59375 2.3125 -0.59375q1.578125 0 2.578125 0.796875q1.0 0.796875 1.28125 2.265625l-1.59375 0.234375q-0.234375 -0.96875 -0.8125 -1.453125q-0.578125 -0.5 -1.390625 -0.5q-1.234375 0 -2.015625 0.890625q-0.78125 0.890625 -0.78125 2.8125q0 1.953125 0.75 2.84375q0.75 0.875 1.953125 0.875q0.96875 0 1.609375 -0.59375q0.65625 -0.59375 0.828125 -1.828125zm9.328125 2.359375q-0.921875 0.765625 -1.765625 1.09375q-0.828125 0.3125 -1.796875 0.3125q-1.59375 0 -2.453125 -0.78125q-0.859375 -0.78125 -0.859375 -1.984375q0 -0.71875 0.328125 -1.296875q0.328125 -0.59375 0.84375 -0.9375q0.53125 -0.359375 1.1875 -0.546875q0.46875 -0.125 1.453125 -0.25q1.984375 -0.234375 2.921875 -0.5625q0.015625 -0.34375 0.015625 -0.421875q0 -1.0 -0.46875 -1.421875q-0.625 -0.546875 -1.875 -0.546875q-1.15625 0 -1.703125 0.40625q-0.546875 0.40625 -0.8125 1.421875l-1.609375 -0.21875q0.21875 -1.015625 0.71875 -1.640625q0.5 -0.640625 1.453125 -0.984375q0.953125 -0.34375 2.1875 -0.34375q1.25 0 2.015625 0.296875q0.78125 0.28125 1.140625 0.734375q0.375 0.4375 0.515625 1.109375q0.078125 0.421875 0.078125 1.515625l0 2.1875q0 2.28125 0.109375 2.890625q0.109375 0.59375 0.40625 1.15625l-1.703125 0q-0.265625 -0.515625 -0.328125 -1.1875zm-0.140625 -3.671875q-0.890625 0.375 -2.671875 0.625q-1.015625 0.140625 -1.4375 0.328125q-0.421875 0.1875 -0.65625 0.53125q-0.21875 0.34375 -0.21875 0.78125q0 0.65625 0.5 1.09375q0.5 0.4375 1.453125 0.4375q0.9375 0 1.671875 -0.40625q0.75 -0.421875 1.09375 -1.140625q0.265625 -0.5625 0.265625 -1.640625l0 -0.609375zm4.156952 4.859375l0 -13.359375l1.640625 0l0 13.359375l-1.640625 0zm4.1448364 0l0 -13.359375l1.640625 0l0 13.359375l-1.640625 0zm4.113556 3.71875l-0.1875 -1.53125q0.546875 0.140625 0.9375 0.140625q0.546875 0 0.875 -0.1875q0.328125 -0.171875 0.546875 -0.5q0.15625 -0.25 0.5 -1.21875q0.046875 -0.140625 0.140625 -0.40625l-3.671875 -9.6875l1.765625 0l2.015625 5.59375q0.390625 1.078125 0.703125 2.25q0.28125 -1.125 0.671875 -2.203125l2.078125 -5.640625l1.640625 0l-3.6875 9.828125q-0.59375 1.609375 -0.921875 2.203125q-0.4375 0.8125 -1.0 1.1875q-0.5625 0.375 -1.34375 0.375q-0.484375 0 -1.0625 -0.203125z" fill-rule="nonzero"></path><path fill="#000000" d="m251.69931 322.80582l0 -13.359375l1.640625 0l0 13.359375l-1.640625 0zm4.191696 -11.46875l0 -1.890625l1.6406403 0l0 1.890625l-1.6406403 0zm0 11.46875l0 -9.671875l1.6406403 0l0 9.671875l-1.6406403 0zm4.144821 0l0 -9.671875l1.46875 0l0 1.375q1.0625 -1.59375 3.078125 -1.59375q0.875 0 1.609375 0.3125q0.734375 0.3125 1.09375 0.828125q0.375 0.5 0.515625 1.203125q0.09375 0.453125 0.09375 1.59375l0 5.953125l-1.640625 0l0 -5.890625q0 -1.0 -0.203125 -1.484375q-0.1875 -0.5 -0.671875 -0.796875q-0.484375 -0.296875 -1.140625 -0.296875q-1.046875 0 -1.8125 0.671875q-0.75 0.65625 -0.75 2.515625l0 5.28125l-1.640625 0zm10.375732 0l0 -13.359375l1.640625 0l0 7.625l3.890625 -3.9375l2.109375 0l-3.6875 3.59375l4.0625 6.078125l-2.015625 0l-3.203125 -4.953125l-1.15625 1.125l0 3.828125l-1.640625 0zm8.671875 -2.890625l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.90625q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.453125 2.4375 0.75q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125zm15.370789 2.890625l0 -13.359375l5.046875 0q1.328125 0 2.03125 0.125q0.96875 0.171875 1.640625 0.640625q0.671875 0.453125 1.078125 1.28125q0.40625 0.828125 0.40625 1.828125q0 1.703125 -1.09375 2.890625q-1.078125 1.171875 -3.921875 1.171875l-3.421875 0l0 5.421875l-1.765625 0zm1.765625 -7.0l3.453125 0q1.71875 0 2.4375 -0.640625q0.71875 -0.640625 0.71875 -1.796875q0 -0.84375 -0.421875 -1.4375q-0.421875 -0.59375 -1.125 -0.78125q-0.4375 -0.125 -1.640625 -0.125l-3.421875 0l0 4.78125zm10.427948 7.0l0 -13.359375l1.640625 0l0 13.359375l-1.640625 0zm10.519836 0l0 -1.421875q-1.125 1.640625 -3.0625 1.640625q-0.859375 0 -1.609375 -0.328125q-0.734375 -0.328125 -1.09375 -0.828125q-0.359375 -0.5 -0.5 -1.21875q-0.109375 -0.46875 -0.109375 -1.53125l0 -5.984375l1.640625 0l0 5.359375q0 1.28125 0.109375 1.734375q0.15625 0.640625 0.65625 1.015625q0.5 0.375 1.234375 0.375q0.734375 0 1.375 -0.375q0.65625 -0.390625 0.921875 -1.03125q0.265625 -0.65625 0.265625 -1.890625l0 -5.1875l1.640625 0l0 9.671875l-1.46875 0zm3.735077 0.796875l1.59375 0.234375q0.109375 0.75 0.5625 1.078125q0.609375 0.453125 1.671875 0.453125q1.140625 0 1.75 -0.453125q0.625 -0.453125 0.84375 -1.265625q0.125 -0.5 0.109375 -2.109375q-1.0625 1.265625 -2.671875 1.265625q-2.0 0 -3.09375 -1.4375q-1.09375 -1.4375 -1.09375 -3.453125q0 -1.390625 0.5 -2.5625q0.515625 -1.171875 1.453125 -1.796875q0.953125 -0.640625 2.25 -0.640625q1.703125 0 2.8125 1.375l0 -1.15625l1.515625 0l0 8.359375q0 2.265625 -0.46875 3.203125q-0.453125 0.9375 -1.453125 1.484375q-0.984375 0.546875 -2.453125 0.546875q-1.71875 0 -2.796875 -0.78125q-1.0625 -0.765625 -1.03125 -2.34375zm1.359375 -5.8125q0 1.90625 0.75 2.78125q0.765625 0.875 1.90625 0.875q1.125 0 1.890625 -0.859375q0.765625 -0.875 0.765625 -2.734375q0 -1.78125 -0.796875 -2.671875q-0.78125 -0.90625 -1.890625 -0.90625q-1.09375 0 -1.859375 0.890625q-0.765625 0.875 -0.765625 2.625zm9.328857 -6.453125l0 -1.890625l1.640625 0l0 1.890625l-1.640625 0zm0 11.46875l0 -9.671875l1.640625 0l0 9.671875l-1.640625 0zm4.144806 0l0 -9.671875l1.46875 0l0 1.375q1.0625 -1.59375 3.078125 -1.59375q0.875 0 1.609375 0.3125q0.734375 0.3125 1.09375 0.828125q0.375 0.5 0.515625 1.203125q0.09375 0.453125 0.09375 1.59375l0 5.953125l-1.640625 0l0 -5.890625q0 -1.0 -0.203125 -1.484375q-0.1875 -0.5 -0.671875 -0.796875q-0.484375 -0.296875 -1.140625 -0.296875q-1.046875 0 -1.8125 0.671875q-0.75 0.65625 -0.75 2.515625l0 5.28125l-1.640625 0zm10.500732 0l0 -13.359375l1.78125 0l0 11.78125l6.5625 0l0 1.578125l-8.34375 0zm10.250702 -11.46875l0 -1.890625l1.640625 0l0 1.890625l-1.640625 0zm0 11.46875l0 -9.671875l1.640625 0l0 9.671875l-1.640625 0zm5.6448364 0l-1.515625 0l0 -13.359375l1.640625 0l0 4.765625q1.046875 -1.296875 2.65625 -1.296875q0.890625 0 1.6875 0.359375q0.796875 0.359375 1.3125 1.015625q0.515625 0.640625 0.796875 1.5625q0.296875 0.921875 0.296875 1.96875q0 2.484375 -1.234375 3.84375q-1.21875 1.359375 -2.953125 1.359375q-1.703125 0 -2.6875 -1.4375l0 1.21875zm-0.015625 -4.90625q0 1.734375 0.484375 2.515625q0.765625 1.265625 2.09375 1.265625q1.078125 0 1.859375 -0.9375q0.78125 -0.9375 0.78125 -2.78125q0 -1.890625 -0.75 -2.796875q-0.75 -0.90625 -1.828125 -0.90625q-1.0625 0 -1.859375 0.9375q-0.78125 0.9375 -0.78125 2.703125z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m409.0 386.50656l145.98425 0l0 77.00787l-145.98425 0z" fill-rule="evenodd"></path><path fill="#000000" d="m418.84375 409.1297l1.65625 -0.140625q0.125 1.0 0.546875 1.640625q0.4375 0.640625 1.34375 1.046875q0.921875 0.390625 2.0625 0.390625q1.0 0 1.78125 -0.296875q0.78125 -0.296875 1.15625 -0.8125q0.375 -0.53125 0.375 -1.15625q0 -0.625 -0.375 -1.09375q-0.359375 -0.46875 -1.1875 -0.796875q-0.546875 -0.203125 -2.390625 -0.640625q-1.828125 -0.453125 -2.5625 -0.84375q-0.96875 -0.5 -1.4375 -1.234375q-0.46875 -0.75 -0.46875 -1.671875q0 -1.0 0.578125 -1.875q0.578125 -0.890625 1.671875 -1.34375q1.109375 -0.453125 2.453125 -0.453125q1.484375 0 2.609375 0.484375q1.140625 0.46875 1.75 1.40625q0.609375 0.921875 0.65625 2.09375l-1.6875 0.125q-0.140625 -1.265625 -0.9375 -1.90625q-0.78125 -0.65625 -2.3125 -0.65625q-1.609375 0 -2.34375 0.59375q-0.734375 0.59375 -0.734375 1.421875q0 0.71875 0.53125 1.171875q0.5 0.46875 2.65625 0.96875q2.15625 0.484375 2.953125 0.84375q1.171875 0.53125 1.71875 1.359375q0.5625 0.828125 0.5625 1.90625q0 1.0625 -0.609375 2.015625q-0.609375 0.9375 -1.75 1.46875q-1.140625 0.515625 -2.578125 0.515625q-1.8125 0 -3.046875 -0.53125q-1.21875 -0.53125 -1.921875 -1.59375q-0.6875 -1.0625 -0.71875 -2.40625zm12.756073 8.015625l-0.1875 -1.53125q0.546875 0.140625 0.9375 0.140625q0.546875 0 0.875 -0.1875q0.328125 -0.171875 0.546875 -0.5q0.15625 -0.25 0.5 -1.21875q0.046875 -0.140625 0.140625 -0.40625l-3.671875 -9.6875l1.765625 0l2.015625 5.59375q0.390625 1.078125 0.703125 2.25q0.28125 -1.125 0.671875 -2.203125l2.078125 -5.640625l1.640625 0l-3.6875 9.828125q-0.59375 1.609375 -0.921875 2.203125q-0.4375 0.8125 -1.0 1.1875q-0.5625 0.375 -1.34375 0.375q-0.484375 0 -1.0625 -0.203125zm8.75 -6.609375l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.90625q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.453125 2.4375 0.75q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125zm18.953125 -10.46875l1.765625 0l0 7.71875q0 2.015625 -0.453125 3.203125q-0.453125 1.1875 -1.640625 1.9375q-1.1875 0.734375 -3.125 0.734375q-1.875 0 -3.078125 -0.640625q-1.1875 -0.65625 -1.703125 -1.875q-0.5 -1.234375 -0.5 -3.359375l0 -7.71875l1.765625 0l0 7.71875q0 1.734375 0.3125 2.5625q0.328125 0.8125 1.109375 1.265625q0.796875 0.453125 1.9375 0.453125q1.953125 0 2.78125 -0.890625q0.828125 -0.890625 0.828125 -3.390625l0 -7.71875zm5.004181 13.359375l0 -13.359375l1.765625 0l0 13.359375l-1.765625 0zm16.491638 -3.109375l1.6875 0.203125q-0.40625 1.484375 -1.484375 2.3125q-1.078125 0.8125 -2.765625 0.8125q-2.125 0 -3.375 -1.296875q-1.234375 -1.3125 -1.234375 -3.671875q0 -2.453125 1.25 -3.796875q1.265625 -1.34375 3.265625 -1.34375q1.9375 0 3.15625 1.328125q1.234375 1.3125 1.234375 3.703125q0 0.15625 0 0.4375l-7.21875 0q0.09375 1.59375 0.90625 2.453125q0.8125 0.84375 2.015625 0.84375q0.90625 0 1.546875 -0.46875q0.640625 -0.484375 1.015625 -1.515625zm-5.390625 -2.65625l5.40625 0q-0.109375 -1.21875 -0.625 -1.828125q-0.78125 -0.953125 -2.03125 -0.953125q-1.125 0 -1.90625 0.765625q-0.765625 0.75 -0.84375 2.015625zm8.047577 5.765625l3.53125 -5.03125l-3.265625 -4.640625l2.046875 0l1.484375 2.265625q0.421875 0.640625 0.671875 1.078125q0.40625 -0.59375 0.734375 -1.0625l1.640625 -2.28125l1.953125 0l-3.34375 4.546875l3.59375 5.125l-2.015625 0l-1.984375 -3.0l-0.515625 -0.8125l-2.546875 3.8125l-1.984375 0zm10.421875 3.703125l0 -13.375l1.484375 0l0 1.25q0.53125 -0.734375 1.1875 -1.09375q0.671875 -0.375 1.625 -0.375q1.234375 0 2.171875 0.640625q0.953125 0.625 1.4375 1.796875q0.484375 1.15625 0.484375 2.546875q0 1.484375 -0.53125 2.671875q-0.53125 1.1875 -1.546875 1.828125q-1.015625 0.625 -2.140625 0.625q-0.8125 0 -1.46875 -0.34375q-0.65625 -0.34375 -1.0625 -0.875l0 4.703125l-1.640625 0zm1.484375 -8.484375q0 1.859375 0.75 2.765625q0.765625 0.890625 1.828125 0.890625q1.09375 0 1.875 -0.921875q0.78125 -0.9375 0.78125 -2.875q0 -1.84375 -0.765625 -2.765625q-0.75 -0.921875 -1.8125 -0.921875q-1.046875 0 -1.859375 0.984375q-0.796875 0.96875 -0.796875 2.84375zm15.516327 1.671875l1.6875 0.203125q-0.40625 1.484375 -1.484375 2.3125q-1.078125 0.8125 -2.765625 0.8125q-2.125 0 -3.375 -1.296875q-1.234375 -1.3125 -1.234375 -3.671875q0 -2.453125 1.25 -3.796875q1.265625 -1.34375 3.265625 -1.34375q1.9375 0 3.15625 1.328125q1.234375 1.3125 1.234375 3.703125q0 0.15625 0 0.4375l-7.21875 0q0.09375 1.59375 0.90625 2.453125q0.8125 0.84375 2.015625 0.84375q0.90625 0 1.546875 -0.46875q0.640625 -0.484375 1.015625 -1.515625zm-5.390625 -2.65625l5.40625 0q-0.109375 -1.21875 -0.625 -1.828125q-0.78125 -0.953125 -2.03125 -0.953125q-1.125 0 -1.90625 0.765625q-0.765625 0.75 -0.84375 2.015625zm15.453857 2.21875l1.609375 0.21875q-0.265625 1.65625 -1.359375 2.609375q-1.078125 0.9375 -2.671875 0.9375q-1.984375 0 -3.1875 -1.296875q-1.203125 -1.296875 -1.203125 -3.71875q0 -1.578125 0.515625 -2.75q0.515625 -1.171875 1.578125 -1.75q1.0625 -0.59375 2.3125 -0.59375q1.578125 0 2.578125 0.796875q1.0 0.796875 1.28125 2.265625l-1.59375 0.234375q-0.234375 -0.96875 -0.8125 -1.453125q-0.578125 -0.5 -1.390625 -0.5q-1.234375 0 -2.015625 0.890625q-0.78125 0.890625 -0.78125 2.8125q0 1.953125 0.75 2.84375q0.75 0.875 1.953125 0.875q0.96875 0 1.609375 -0.59375q0.65625 -0.59375 0.828125 -1.828125zm6.59375 2.078125l0.234375 1.453125q-0.6875 0.140625 -1.234375 0.140625q-0.890625 0 -1.390625 -0.28125q-0.484375 -0.28125 -0.6875 -0.734375q-0.203125 -0.46875 -0.203125 -1.9375l0 -5.578125l-1.203125 0l0 -1.265625l1.203125 0l0 -2.390625l1.625 -0.984375l0 3.375l1.65625 0l0 1.265625l-1.65625 0l0 5.671875q0 0.6875 0.078125 0.890625q0.09375 0.203125 0.28125 0.328125q0.203125 0.109375 0.578125 0.109375q0.265625 0 0.71875 -0.0625zm0.9489136 -1.421875l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.90625q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.453125 2.4375 0.75q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125z" fill-rule="nonzero"></path><path fill="#000000" d="m419.23438 423.95782l0 -1.890625l1.640625 0l0 1.890625l-1.640625 0zm0 11.46875l0 -9.671875l1.640625 0l0 9.671875l-1.640625 0zm4.1448364 0l0 -9.671875l1.46875 0l0 1.375q1.0625 -1.59375 3.078125 -1.59375q0.875 0 1.609375 0.3125q0.734375 0.3125 1.09375 0.828125q0.375 0.5 0.515625 1.203125q0.09375 0.453125 0.09375 1.59375l0 5.953125l-1.640625 0l0 -5.890625q0 -1.0 -0.203125 -1.484375q-0.1875 -0.5 -0.671875 -0.796875q-0.484375 -0.296875 -1.140625 -0.296875q-1.046875 0 -1.8125 0.671875q-0.75 0.65625 -0.75 2.515625l0 5.28125l-1.640625 0zm13.953827 -1.46875l0.234375 1.453125q-0.6875 0.140625 -1.234375 0.140625q-0.890625 0 -1.390625 -0.28125q-0.484375 -0.28125 -0.6875 -0.734375q-0.203125 -0.46875 -0.203125 -1.9375l0 -5.578125l-1.203125 0l0 -1.265625l1.203125 0l0 -2.390625l1.625 -0.984375l0 3.375l1.65625 0l0 1.265625l-1.65625 0l0 5.671875q0 0.6875 0.078125 0.890625q0.09375 0.203125 0.28125 0.328125q0.203125 0.109375 0.578125 0.109375q0.265625 0 0.71875 -0.0625zm8.230194 -1.640625l1.6875 0.203125q-0.40625 1.484375 -1.484375 2.3125q-1.078125 0.8125 -2.765625 0.8125q-2.125 0 -3.375 -1.296875q-1.234375 -1.3125 -1.234375 -3.671875q0 -2.453125 1.25 -3.796875q1.265625 -1.34375 3.265625 -1.34375q1.9375 0 3.15625 1.328125q1.234375 1.3125 1.234375 3.703125q0 0.15625 0 0.4375l-7.21875 0q0.09375 1.59375 0.90625 2.453125q0.8125 0.84375 2.015625 0.84375q0.90625 0 1.546875 -0.46875q0.640625 -0.484375 1.015625 -1.515625zm-5.390625 -2.65625l5.40625 0q-0.109375 -1.21875 -0.625 -1.828125q-0.78125 -0.953125 -2.03125 -0.953125q-1.125 0 -1.90625 0.765625q-0.765625 0.75 -0.84375 2.015625zm9.125702 5.765625l0 -9.671875l1.46875 0l0 1.46875q0.5625 -1.03125 1.03125 -1.359375q0.484375 -0.328125 1.0625 -0.328125q0.828125 0 1.6875 0.53125l-0.5625 1.515625q-0.609375 -0.359375 -1.203125 -0.359375q-0.546875 0 -0.96875 0.328125q-0.421875 0.328125 -0.609375 0.890625q-0.28125 0.875 -0.28125 1.921875l0 5.0625l-1.625 0zm6.618927 0l0 -8.40625l-1.453125 0l0 -1.265625l1.453125 0l0 -1.03125q0 -0.96875 0.171875 -1.453125q0.234375 -0.640625 0.828125 -1.03125q0.59375 -0.390625 1.671875 -0.390625q0.6875 0 1.53125 0.15625l-0.25 1.4375q-0.5 -0.09375 -0.953125 -0.09375q-0.75 0 -1.0625 0.328125q-0.3125 0.3125 -0.3125 1.1875l0 0.890625l1.890625 0l0 1.265625l-1.890625 0l0 8.40625l-1.625 0zm11.105164 -1.1875q-0.921875 0.765625 -1.765625 1.09375q-0.828125 0.3125 -1.796875 0.3125q-1.59375 0 -2.453125 -0.78125q-0.859375 -0.78125 -0.859375 -1.984375q0 -0.71875 0.328125 -1.296875q0.328125 -0.59375 0.84375 -0.9375q0.53125 -0.359375 1.1875 -0.546875q0.46875 -0.125 1.453125 -0.25q1.984375 -0.234375 2.921875 -0.5625q0.015625 -0.34375 0.015625 -0.421875q0 -1.0 -0.46875 -1.421875q-0.625 -0.546875 -1.875 -0.546875q-1.15625 0 -1.703125 0.40625q-0.546875 0.40625 -0.8125 1.421875l-1.609375 -0.21875q0.21875 -1.015625 0.71875 -1.640625q0.5 -0.640625 1.453125 -0.984375q0.953125 -0.34375 2.1875 -0.34375q1.25 0 2.015625 0.296875q0.78125 0.28125 1.140625 0.734375q0.375 0.4375 0.515625 1.109375q0.078125 0.421875 0.078125 1.515625l0 2.1875q0 2.28125 0.109375 2.890625q0.109375 0.59375 0.40625 1.15625l-1.703125 0q-0.265625 -0.515625 -0.328125 -1.1875zm-0.140625 -3.671875q-0.890625 0.375 -2.671875 0.625q-1.015625 0.140625 -1.4375 0.328125q-0.421875 0.1875 -0.65625 0.53125q-0.21875 0.34375 -0.21875 0.78125q0 0.65625 0.5 1.09375q0.5 0.4375 1.453125 0.4375q0.9375 0 1.671875 -0.40625q0.75 -0.421875 1.09375 -1.140625q0.265625 -0.5625 0.265625 -1.640625l0 -0.609375zm10.516357 1.3125l1.609375 0.21875q-0.265625 1.65625 -1.359375 2.609375q-1.078125 0.9375 -2.671875 0.9375q-1.984375 0 -3.1875 -1.296875q-1.203125 -1.296875 -1.203125 -3.71875q0 -1.578125 0.515625 -2.75q0.515625 -1.171875 1.578125 -1.75q1.0625 -0.59375 2.3125 -0.59375q1.578125 0 2.578125 0.796875q1.0 0.796875 1.28125 2.265625l-1.59375 0.234375q-0.234375 -0.96875 -0.8125 -1.453125q-0.578125 -0.5 -1.390625 -0.5q-1.234375 0 -2.015625 0.890625q-0.78125 0.890625 -0.78125 2.8125q0 1.953125 0.75 2.84375q0.75 0.875 1.953125 0.875q0.96875 0 1.609375 -0.59375q0.65625 -0.59375 0.828125 -1.828125zm9.640625 0.4375l1.6875 0.203125q-0.40625 1.484375 -1.484375 2.3125q-1.078125 0.8125 -2.765625 0.8125q-2.125 0 -3.375 -1.296875q-1.234375 -1.3125 -1.234375 -3.671875q0 -2.453125 1.25 -3.796875q1.265625 -1.34375 3.265625 -1.34375q1.9375 0 3.15625 1.328125q1.234375 1.3125 1.234375 3.703125q0 0.15625 0 0.4375l-7.21875 0q0.09375 1.59375 0.90625 2.453125q0.8125 0.84375 2.015625 0.84375q0.90625 0 1.546875 -0.46875q0.640625 -0.484375 1.015625 -1.515625zm-5.390625 -2.65625l5.40625 0q-0.109375 -1.21875 -0.625 -1.828125q-0.78125 -0.953125 -2.03125 -0.953125q-1.125 0 -1.90625 0.765625q-0.765625 0.75 -0.84375 2.015625zm14.715271 5.765625l0 -8.40625l-1.453125 0l0 -1.265625l1.453125 0l0 -1.03125q0 -0.96875 0.171875 -1.453125q0.234375 -0.640625 0.828125 -1.03125q0.59375 -0.390625 1.671875 -0.390625q0.6875 0 1.53125 0.15625l-0.25 1.4375q-0.5 -0.09375 -0.953125 -0.09375q-0.75 0 -1.0625 0.328125q-0.3125 0.3125 -0.3125 1.1875l0 0.890625l1.890625 0l0 1.265625l-1.890625 0l0 8.40625l-1.625 0zm4.7770386 0l0 -9.671875l1.46875 0l0 1.46875q0.5625 -1.03125 1.03125 -1.359375q0.484375 -0.328125 1.0625 -0.328125q0.828125 0 1.6875 0.53125l-0.5625 1.515625q-0.609375 -0.359375 -1.203125 -0.359375q-0.546875 0 -0.96875 0.328125q-0.421875 0.328125 -0.609375 0.890625q-0.28125 0.875 -0.28125 1.921875l0 5.0625l-1.625 0zm5.6189575 -4.84375q0 -2.6875 1.484375 -3.96875q1.25 -1.078125 3.046875 -1.078125q2.0 0 3.265625 1.3125q1.265625 1.296875 1.265625 3.609375q0 1.859375 -0.5625 2.9375q-0.5625 1.0625 -1.640625 1.65625q-1.0625 0.59375 -2.328125 0.59375q-2.03125 0 -3.28125 -1.296875q-1.25 -1.3125 -1.25 -3.765625zm1.6875 0q0 1.859375 0.796875 2.796875q0.8125 0.921875 2.046875 0.921875q1.21875 0 2.03125 -0.921875q0.8125 -0.9375 0.8125 -2.84375q0 -1.796875 -0.8125 -2.71875q-0.8125 -0.921875 -2.03125 -0.921875q-1.234375 0 -2.046875 0.921875q-0.796875 0.90625 -0.796875 2.765625zm9.297607 4.84375l0 -9.671875l1.46875 0l0 1.359375q0.453125 -0.71875 1.203125 -1.140625q0.765625 -0.4375 1.71875 -0.4375q1.078125 0 1.765625 0.453125q0.6875 0.4375 0.96875 1.234375q1.15625 -1.6875 2.984375 -1.6875q1.453125 0 2.21875 0.796875q0.78125 0.796875 0.78125 2.453125l0 6.640625l-1.640625 0l0 -6.09375q0 -0.984375 -0.15625 -1.40625q-0.15625 -0.4375 -0.578125 -0.703125q-0.421875 -0.265625 -0.984375 -0.265625q-1.015625 0 -1.6875 0.6875q-0.671875 0.671875 -0.671875 2.15625l0 5.625l-1.640625 0l0 -6.28125q0 -1.09375 -0.40625 -1.640625q-0.40625 -0.546875 -1.3125 -0.546875q-0.6875 0 -1.28125 0.359375q-0.59375 0.359375 -0.859375 1.0625q-0.25 0.703125 -0.25 2.03125l0 5.015625l-1.640625 0z" fill-rule="nonzero"></path><path fill="#000000" d="m419.4375 457.42657l0 -13.359375l5.046875 0q1.328125 0 2.03125 0.125q0.96875 0.171875 1.640625 0.640625q0.671875 0.453125 1.078125 1.28125q0.40625 0.828125 0.40625 1.828125q0 1.703125 -1.09375 2.890625q-1.078125 1.171875 -3.921875 1.171875l-3.421875 0l0 5.421875l-1.765625 0zm1.765625 -7.0l3.453125 0q1.71875 0 2.4375 -0.640625q0.71875 -0.640625 0.71875 -1.796875q0 -0.84375 -0.421875 -1.4375q-0.421875 -0.59375 -1.125 -0.78125q-0.4375 -0.125 -1.640625 -0.125l-3.421875 0l0 4.78125zm10.427948 7.0l0 -13.359375l1.640625 0l0 13.359375l-1.640625 0zm10.519806 0l0 -1.421875q-1.125 1.640625 -3.0625 1.640625q-0.859375 0 -1.609375 -0.328125q-0.734375 -0.328125 -1.09375 -0.828125q-0.359375 -0.5 -0.5 -1.21875q-0.109375 -0.46875 -0.109375 -1.53125l0 -5.984375l1.640625 0l0 5.359375q0 1.28125 0.109375 1.734375q0.15625 0.640625 0.65625 1.015625q0.5 0.375 1.234375 0.375q0.734375 0 1.375 -0.375q0.65625 -0.390625 0.921875 -1.03125q0.265625 -0.65625 0.265625 -1.890625l0 -5.1875l1.640625 0l0 9.671875l-1.46875 0zm3.7351074 0.796875l1.59375 0.234375q0.109375 0.75 0.5625 1.078125q0.609375 0.453125 1.671875 0.453125q1.140625 0 1.75 -0.453125q0.625 -0.453125 0.84375 -1.265625q0.125 -0.5 0.109375 -2.109375q-1.0625 1.265625 -2.671875 1.265625q-2.0 0 -3.09375 -1.4375q-1.09375 -1.4375 -1.09375 -3.453125q0 -1.390625 0.5 -2.5625q0.515625 -1.171875 1.453125 -1.796875q0.953125 -0.640625 2.25 -0.640625q1.703125 0 2.8125 1.375l0 -1.15625l1.515625 0l0 8.359375q0 2.265625 -0.46875 3.203125q-0.453125 0.9375 -1.453125 1.484375q-0.984375 0.546875 -2.453125 0.546875q-1.71875 0 -2.796875 -0.78125q-1.0625 -0.765625 -1.03125 -2.34375zm1.359375 -5.8125q0 1.90625 0.75 2.78125q0.765625 0.875 1.90625 0.875q1.125 0 1.890625 -0.859375q0.765625 -0.875 0.765625 -2.734375q0 -1.78125 -0.796875 -2.671875q-0.78125 -0.90625 -1.890625 -0.90625q-1.09375 0 -1.859375 0.890625q-0.765625 0.875 -0.765625 2.625zm9.328857 -6.453125l0 -1.890625l1.640625 0l0 1.890625l-1.640625 0zm0 11.46875l0 -9.671875l1.640625 0l0 9.671875l-1.640625 0zm4.144806 0l0 -9.671875l1.46875 0l0 1.375q1.0625 -1.59375 3.078125 -1.59375q0.875 0 1.609375 0.3125q0.734375 0.3125 1.09375 0.828125q0.375 0.5 0.515625 1.203125q0.09375 0.453125 0.09375 1.59375l0 5.953125l-1.640625 0l0 -5.890625q0 -1.0 -0.203125 -1.484375q-0.1875 -0.5 -0.671875 -0.796875q-0.484375 -0.296875 -1.140625 -0.296875q-1.046875 0 -1.8125 0.671875q-0.75 0.65625 -0.75 2.515625l0 5.28125l-1.640625 0zm10.500702 0l0 -13.359375l1.78125 0l0 11.78125l6.5625 0l0 1.578125l-8.34375 0zm10.250732 -11.46875l0 -1.890625l1.640625 0l0 1.890625l-1.640625 0zm0 11.46875l0 -9.671875l1.640625 0l0 9.671875l-1.640625 0zm5.6448364 0l-1.515625 0l0 -13.359375l1.640625 0l0 4.765625q1.046875 -1.296875 2.65625 -1.296875q0.890625 0 1.6875 0.359375q0.796875 0.359375 1.3125 1.015625q0.515625 0.640625 0.796875 1.5625q0.296875 0.921875 0.296875 1.96875q0 2.484375 -1.234375 3.84375q-1.21875 1.359375 -2.953125 1.359375q-1.703125 0 -2.6875 -1.4375l0 1.21875zm-0.015625 -4.90625q0 1.734375 0.484375 2.515625q0.765625 1.265625 2.09375 1.265625q1.078125 0 1.859375 -0.9375q0.78125 -0.9375 0.78125 -2.78125q0 -1.890625 -0.75 -2.796875q-0.75 -0.90625 -1.828125 -0.90625q-1.0625 0 -1.859375 0.9375q-0.78125 0.9375 -0.78125 2.703125z" fill-rule="nonzero"></path></g></svg>
+
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java
index 4b3afdc..6c31b2a 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java
@@ -181,6 +181,5 @@
         void onScreenOff();
         void onShowSafetyWarning(int flags);
         void onAccessibilityModeChanged(Boolean showA11yStream);
-        void onConnectedDeviceChanged(String deviceName);
     }
 }
diff --git a/packages/SystemUI/plugin/update_plugin_lib.sh b/packages/SystemUI/plugin/update_plugin_lib.sh
new file mode 100755
index 0000000..a105b45
--- /dev/null
+++ b/packages/SystemUI/plugin/update_plugin_lib.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+cd $ANDROID_BUILD_TOP/frameworks/base/packages/SystemUI/plugin
+# Clear out anything old.
+rm -rf /tmp/plugin_classes/
+mkdir /tmp/plugin_classes
+
+# Compile the jar
+javac -cp $ANDROID_BUILD_TOP/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar:$ANDROID_BUILD_TOP/out/target/common/obj/JAVA_LIBRARIES/core-all_intermediates/classes.jar `find src -name *.java` -d /tmp/plugin_classes/
+echo "" >> /tmp/plugin_classes/manifest.txt
+jar cvfm SystemUIPluginLib.jar /tmp/plugin_classes/manifest.txt -C /tmp/plugin_classes .
+
+# Place the jar and update the latest
+mv SystemUIPluginLib.jar ./SystemUIPluginLib-`date +%m-%d-%Y`.jar
+rm SystemUIPluginLib-latest.jar
+ln -s SystemUIPluginLib-`date +%m-%d-%Y`.jar SystemUIPluginLib-latest.jar
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
index d0389eb..828c9df 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
@@ -34,6 +34,7 @@
               android:layout_marginBottom="7dp"
               android:paddingStart="64dp"
               android:paddingEnd="64dp"
+              android:textColor="?attr/wallpaperTextColor"
               android:theme="@style/TextAppearance.Keyguard"
     />
     <LinearLayout android:id="@+id/row"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
index 31635a5..fa14d1b 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
@@ -62,7 +62,7 @@
                 android:layout_gravity="center_horizontal"
                 android:layout_centerHorizontal="true"
                 android:layout_alignParentTop="true"
-                android:letterSpacing="0.04"
+                android:letterSpacing="0.03"
                 android:textColor="?attr/wallpaperTextColor"
                 android:singleLine="true"
                 style="@style/widget_big_thin"
@@ -76,6 +76,7 @@
                 android:layout_marginTop="22dp"
                 android:layout_below="@id/clock_view"
                 android:background="#f00"
+                android:backgroundTint="?attr/wallpaperTextColor"
                 android:layout_centerHorizontal="true" />
 
             <include layout="@layout/keyguard_status_area"
diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml
index b3ed8f5..8956735 100644
--- a/packages/SystemUI/res-keyguard/values-ar/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"تم ضبط التنبيه التالي على <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Delete"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"‏تعطيل شريحة eSIM"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"‏يتعذّر إيقاف eSIM."</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"‏يتعذّر إيقاف eSIM بسبب خطأ."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"نسيت النقش"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"نقش خاطئ"</string>
@@ -69,7 +71,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"ارسم نقشك"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"‏أدخل رقم التعريف الشخصي لشريحة SIM."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"‏أدخل رقم التعريف الشخصي لشريحة SIM التابعة للمشغّل \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"‏يجب تعطيل شريحة eSIM لاستخدام الجهاز دون خدمة جوال."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"‏<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> يجب إيقاف eSIM لاستخدام الجهاز دون خدمة جوّال."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"أدخل رقم التعريف الشخصي"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"أدخل كلمة المرور"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"‏شريحة SIM معطّلة الآن. أدخل رمز PUK للمتابعة. اتصل بمشغل شبكة الجوّال للاطلاع على التفاصيل."</string>
diff --git a/packages/SystemUI/res-keyguard/values-as/strings.xml b/packages/SystemUI/res-keyguard/values-as/strings.xml
new file mode 100644
index 0000000..06820a6
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/values-as/strings.xml
@@ -0,0 +1,147 @@
+<?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">
+    <string name="app_name" msgid="3171996292755059205">"কীগাৰ্ড"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3420548423949593123">"পিন ক\'ড লিখক"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="670683628782925409">"ছিমৰ PUK আৰু নতুন পিন ক\'ড লিখক"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="3747778500166059332">"ছিমৰ PUK ক\'ড"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8188243197504453830">"নতুন ছিমৰ পিন ক\'ড"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="5790410752696806482"><font size="17">"পাছৱৰ্ড লিখিবলৈ স্পৰ্শ কৰক"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="595980919238127672">"আনলক কৰিবলৈ পাছৱৰ্ড লিখক"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"আনলক কৰিবলৈ পিন লিখক"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"ভুল পিন ক\'ড।"</string>
+    <!-- no translation found for keyguard_sim_error_message_short (592109500618448312) -->
+    <skip />
+    <string name="keyguard_charged" msgid="2222329688813033109">"চ্চার্জ কৰা হ\'ল"</string>
+    <string name="keyguard_plugged_in" msgid="89308975354638682">"চ্চার্জ কৰি থকা হৈছে"</string>
+    <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"দ্ৰুত গতিৰে চ্চাৰ্জ কৰি থকা হৈছে"</string>
+    <string name="keyguard_plugged_in_charging_slowly" msgid="6637043106038550407">"লাহে লাহে চ্চাৰ্জ হৈ আছে"</string>
+    <string name="keyguard_low_battery" msgid="9218432555787624490">"আপোনাৰ চ্চার্জাৰ সংযোগ কৰক।"</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="8566679946700751371">"আনলক কৰিবলৈ মেনু টিপক।"</string>
+    <string name="keyguard_network_locked_message" msgid="6743537524631420759">"নেটৱর্ক লক কৰা অৱস্থাত আছে"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="6327533369959764518">"কোনো ছিম কাৰ্ড নাই"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="4550152848200783542">"টেবলেটত ছিম কার্ড নাই।"</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="6585414237800161146">"ফ\'নত ছিম কার্ড নাই।"</string>
+    <string name="keyguard_missing_sim_instructions" msgid="7350295932015220392">"এখন ছিম কাৰ্ড ভৰাওক।"</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="589889372883904477">"ছিম কাৰ্ডখন নাই বা চিনাক্ত কৰিব নোৱাৰি। এখন ছিম কাৰ্ড ভৰাওক।"</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="654102080186420706">"ব্যৱহাৰৰ অযোগ্য ছিম কাৰ্ড।"</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="4683178224791318347">"আপোনাৰ ছিম কাৰ্ডখন স্থায়ীভাৱে অক্ষম হৈছে।\n অন্য এখন ছিমৰ বাবে আপোনাৰ ৱায়াৰলেছ সেৱা প্ৰদানকাৰীৰ সৈতে যোগাযোগ কৰক।"</string>
+    <string name="keyguard_sim_locked_message" msgid="953766009432168127">"ছিম কাৰ্ড লক কৰা হৈছে।"</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="1772789643694942073">"ছিম কার্ডখন PUKৰ দ্বাৰা লক কৰা হৈছে।"</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="3586601150825821675">"ছিম কার্ড আনলক কৰি থকা হৈছে…"</string>
+    <string name="keyguard_accessibility_pin_area" msgid="703175752097279029">"পিনৰ ক্ষেত্ৰ"</string>
+    <string name="keyguard_accessibility_sim_pin_area" msgid="912702510825058921">"ছিম পিনৰ ক্ষেত্ৰ"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"ছিমৰ PUK ক্ষেত্ৰ"</string>
+    <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"পৰৱৰ্তী এলাৰ্ম <xliff:g id="ALARM">%1$s</xliff:g> বজাত ছেট কৰা হৈছে"</string>
+    <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"মচক"</string>
+    <!-- no translation found for disable_carrier_button_text (6914341927421916114) -->
+    <skip />
+    <!-- no translation found for error_disable_esim_title (4852978431156228006) -->
+    <skip />
+    <!-- no translation found for error_disable_esim_msg (676694908770135639) -->
+    <skip />
+    <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"এণ্টাৰ বুটাম"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"আৰ্হি পাহৰিলে নেকি"</string>
+    <string name="kg_wrong_pattern" msgid="7620081431514773802">"ভুল আৰ্হি"</string>
+    <string name="kg_wrong_password" msgid="4580683060277329277">"ভুল পাছৱৰ্ড"</string>
+    <string name="kg_wrong_pin" msgid="4785660766909463466">"ভুল পিন"</string>
+    <!-- no translation found for kg_too_many_failed_attempts_countdown (4368805541257003755) -->
+    <string name="kg_pattern_instructions" msgid="5547646893001491340">"আপোনাৰ আৰ্হি আঁকক"</string>
+    <!-- no translation found for kg_sim_pin_instructions (6389000973113699187) -->
+    <skip />
+    <!-- no translation found for kg_sim_pin_instructions_multi (1643757228644271861) -->
+    <skip />
+    <!-- no translation found for kg_sim_lock_esim_instructions (4416732549172148542) -->
+    <skip />
+    <string name="kg_pin_instructions" msgid="4069609316644030034">"পিন দিয়ক"</string>
+    <string name="kg_password_instructions" msgid="136952397352976538">"পাছৱৰ্ড দিয়ক"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"ছিমখন বর্তমান অক্ষম অৱস্থাত আছে। অব্যাহত ৰাখিবলৈ PUK ক\'ড লিখক। সবিশেষ জানিবলৈ বাহকৰ সৈতে যোগাযোগ কৰক।"</string>
+    <string name="kg_puk_enter_puk_hint_multi" msgid="1373131883510840794">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" ছিমখন বর্তমান অক্ষম অৱস্থাত আছে। অব্যাহত ৰাখিবলৈ PUK ক\'ড দিয়ক। সবিশেষ জানিবলৈ বাহকৰ সৈতে যোগাযোগ কৰক।"</string>
+    <string name="kg_puk_enter_pin_hint" msgid="3137789674920391087">"আপোনাৰ পছন্দৰ পিন ক\'ড লিখক"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="3089485999116759671">"আপোনাৰ পচন্দৰ পিন ক\'ড নিশ্চিত কৰক"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="4471738151810900114">"ছিম কার্ড আনলক কৰি থকা হৈছে…"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="3057533256729513335">"৪টাৰ পৰা ৮টা সংখ্যাযুক্ত এটা পিন লিখক।"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="6003602401368264144">"PUK ক\'ডটো ৮টা বা তাতকৈ অধিক সংখ্যা থকা হ\'ব লাগিব।"</string>
+    <string name="kg_invalid_puk" msgid="5399287873762592502">"শুদ্ধ PUK ক\'ডটো পুনৰ দিয়ক। বাৰে বাৰে ভুল ক\'ড দিলে ছিমখন স্থায়ীভাৱে অক্ষম হ\'ব।"</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="5672736555427444330">"পিন ক\'ড মিলা নাই"</string>
+    <string name="kg_login_too_many_attempts" msgid="6604574268387867255">"বহুতবাৰ ভুলকৈ আর্হি অঁকা হৈছে"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8637788033282252027">"আপুনি আপোনাৰ পিন <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুলকৈ লিখিছে। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g>ছেকেণ্ডৰ পিছত আকৌ চেষ্টা কৰক।"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7724148763268377734">"আপুনি আপোনাৰ পাছৱৰ্ড <xliff:g id="NUMBER_0">%1$d</xliff:g>বাৰ ভুলকৈ লিখিছে। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ছেকেণ্ডৰ পাছত আকৌ চেষ্টা কৰক।"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4820967667848302092">"আপুনি আপোনাৰ আনলক আৰ্হি <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুলকৈ আঁকিছে। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g>ছেকেণ্ডৰ পিছত আকৌ চেষ্টা কৰক।"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1629351522209932316">"আপুনি টেবলেটটো আনলক কৰিবলৈ <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে আৰু <xliff:g id="NUMBER_1">%2$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিলে টেবলেটটো ৰিছেট কৰা হ\'ব, যি কার্যই টেবলেটটোত থকা সকলো ডেটা মচিব।"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="3921998703529189931">"আপুনি ফ\'নটো আনলক কৰিবলৈ <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে আৰু <xliff:g id="NUMBER_1">%2$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিলে ফ\'নটো ৰিছেট কৰা হ\'ব, যি কার্যই ফ\'নটোত থকা সকলো ডেটা মচিব।"</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="4694232971224663735">"আপুনি টেবলেটটো আনলক কৰিবলৈ <xliff:g id="NUMBER">%d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে। এই টেবলেটটো ৰিছেট কৰা হ\'ব, যি কার্যই ইয়াৰ সকলো ডেটা মচিব।"</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="2365964340830006961">"আপুনি ফ\'নটো আনলক কৰিবলৈ <xliff:g id="NUMBER">%d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে। এই ফ\'নটো ৰিছেট কৰা হ\'ব, যিয়ে ইয়াৰ সকলো ডেটা মচিব।"</string>
+    <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="1365418870560228936">"আপুনি টেবলেটটো আনলক কৰিবলৈ <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে আৰু <xliff:g id="NUMBER_1">%2$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিলে এই ব্যৱহাৰকাৰীক আঁতৰোৱা হ\'ব, যিয়ে ব্যৱহাৰকাৰীৰ সকলো ডেটা মচিব।"</string>
+    <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="2151286957817486128">"আপুনি ফ\'নটো আনলক কৰিবলৈ <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে। আৰু <xliff:g id="NUMBER_1">%2$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিলে এই ব্যৱহাৰকাৰীক আঁতৰোৱা হ\'ব, যিয়ে ব্যৱহাৰকাৰীৰ সকলো ডেটা মচিব।"</string>
+    <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="5464020754932560928">"আপুনি টেবলেটটো আনলক কৰিবলৈ <xliff:g id="NUMBER">%d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে। এই ব্যৱহাৰকাৰীক আঁতৰোৱা হ\'ব, যিয়ে ব্যৱহাৰকাৰীৰ সকলো ডেটা মচিব।"</string>
+    <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="6171564974118059">"আপুনি ফ\'নটো আনলক কৰিবলৈ <xliff:g id="NUMBER">%d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে। এই ব্যৱহাৰকাৰীক আঁতৰোৱা হ\'ব, যি কার্যই ব্যৱহাৰকাৰীৰ সকলো ডেটা মচিব।"</string>
+    <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="9154513795928824239">"আপুনি টেবলেটটো আনলক কৰিবলৈ <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে। আৰু <xliff:g id="NUMBER_1">%2$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিলে কৰ্মস্থানৰ প্ৰ\'ফাইলটো আঁতৰোৱা হ\'ব, যিয়ে প্ৰ\'ফাইলটোৰ সকলো ডেটা মচিব।"</string>
+    <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="2162434417489128282">"আপুনি ফ\'নটো আনলক কৰিবলৈ <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে। আৰু <xliff:g id="NUMBER_1">%2$d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিলে কৰ্মস্থানৰ প্ৰ\'ফাইলটো আঁতৰোৱা হ\'ব, যিয়ে প্ৰ\'ফাইলটোৰ সকলো ডেটা মচিব।"</string>
+    <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="8966727588974691544">"আপুনি টেবলেটটো আনলক কৰিবলৈ <xliff:g id="NUMBER">%d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে। আপোনাৰ কৰ্মস্থানৰ প্ৰ\'ফাইলটো আঁতৰোৱা হ\'ব, যি কার্যই প্ৰ\'ফাইলটোৰ সকলো ডেটা মচিব।"</string>
+    <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="8476407539834855">"আপুনি ফ\'নটো আনলক কৰিবলৈ <xliff:g id="NUMBER">%d</xliff:g> বাৰ ভুল প্ৰয়াস কৰিছে। আপোনাৰ কৰ্মস্থানৰ প্ৰ\'ফাইলটো আঁতৰোৱা হ\'ব, যিয়ে প্ৰ\'ফাইলটোৰ সকলো ডেটা মচিব।"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="956706236554092172">"আপুনি আপোনাৰ আনলক আৰ্হিটো <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুলকৈ আঁকিছে। <xliff:g id="NUMBER_1">%2$d</xliff:g>তকৈ বেছি বাৰ ভুল আৰ্হি আঁকিলে আপোনাৰ টেবলেটটো কোনো একাউণ্টৰ জৰিয়তে আনলক কৰিবলৈ কোৱা হ\'ব।\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> ছেকেণ্ডৰ পিছত আকৌ চেষ্টা কৰক।"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="8364140853305528449">"আপুনি আপোনাৰ আনলক আৰ্হিটো <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুলকৈ আঁকিছে। <xliff:g id="NUMBER_1">%2$d</xliff:g>তকৈ বেছি বাৰ ভুল আৰ্হি আঁকিলে আপোনাৰ ফ\'নটো কোনো একাউণ্টৰ জৰিয়তে আনলক কৰিবলৈ কোৱা হ\'ব।\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> ছেকেণ্ডৰ পিছত আকৌ চেষ্টা কৰক।"</string>
+    <string name="kg_password_wrong_pin_code_pukked" msgid="3389829202093674267">"ছিমৰ ভুল পিন ক\'ড, আপোনাৰ ডিভাইচটো আনলক কৰিবলৈ আপুনি এতিয়া আপোনাৰ বাহকৰ সৈতে যোগাযোগ কৰিবই লাগিব।"</string>
+    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="4314341367727055967">
+      <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="kg_password_wrong_puk_code_dead" msgid="3329017604125179374">"ছিম ব্যৱহাৰযোগ্য নহয়। আপোনাৰ বাহকৰ সৈতে যোগাযোগ কৰক।"</string>
+    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="2287504898931957513">
+      <item quantity="one">ছিমৰ ভুল PUK ক\'ড, আপুনি আৰু <xliff:g id="NUMBER_1">%d</xliff:g> বাৰ ভুল ক’ড দিলে আপোনাৰ ছিম চিৰকালৰ বাবে ব্যৱহাৰৰ অনুপযোগী হ’ব।</item>
+      <item quantity="other">ছিমৰ ভুল PUK ক\'ড, আপুনি আৰু <xliff:g id="NUMBER_1">%d</xliff:g> বাৰ ভুল ক’ড দিলে আপোনাৰ ছিম চিৰকালৰ বাবে ব্যৱহাৰৰ অনুপযোগী হ’ব।</item>
+    </plurals>
+    <string name="kg_password_pin_failed" msgid="8769990811451236223">"ছিম পিনৰ জৰিয়তে আনলক কৰিব পৰা নগ\'ল!"</string>
+    <string name="kg_password_puk_failed" msgid="1331621440873439974">"ছিম PUKৰ জৰিয়তে আনলক কৰিব পৰা নগ\'ল!"</string>
+    <string name="kg_pin_accepted" msgid="7637293533973802143">"ক\'ড গ্ৰহণ কৰা হ\'ল!"</string>
+    <string name="keyguard_carrier_default" msgid="4274828292998453695">"কোনো সেৱা নাই।"</string>
+    <string name="accessibility_ime_switch_button" msgid="2695096475319405612">"ইনপুট পদ্ধতি সলনি কৰক"</string>
+    <string name="airplane_mode" msgid="3807209033737676010">"এয়াৰপ্লেন ম\'ড"</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="7246972020562621506">"ডিভাইচ ৰিষ্টাৰ্ট হোৱাৰ পিছত আৰ্হি দিয়াটো বাধ্যতামূলক"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="6303592361322290145">"ডিভাইচ ৰিষ্টাৰ্ট হোৱাৰ পিছত পিন দিয়াটো বাধ্যতামূলক"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6984641181515902406">"ডিভাইচ ৰিষ্টাৰ্ট হোৱাৰ পিছত পাছৱৰ্ড দিয়াটো বাধ্যতামূলক"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="5304487696073914063">"অতিৰিক্ত সুৰক্ষাৰ বাবে আর্হি দিয়াটো বাধ্যতামূলক"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="8851462864335757813">"অতিৰিক্ত সুৰক্ষাৰ বাবে পিন দিয়াটো বাধ্যতামূলক"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="6563904839641583441">"অতিৰিক্ত সুৰক্ষাৰ বাবে পাছৱর্ড দিয়াটো বাধ্যতামূলক"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="3398054847288438444">"প্ৰ\'ফাইল সলনি কৰোঁতে আৰ্হি দিয়াটো বাধ্যতামূলক"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"ডিভাইচ ৰিষ্টাৰ্ট হোৱাৰ পিছত পিন দিয়াটো বাধ্যতামূলক"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="8383831046318421845">"প্ৰ\'ফাইল সলনি কৰোঁতে পাছৱৰ্ড দিয়াটো বাধ্যতামূলক"</string>
+    <!-- no translation found for kg_prompt_reason_device_admin (3452168247888906179) -->
+    <skip />
+    <string name="kg_prompt_reason_user_request" msgid="8236951765212462286">"ডিভাইচটো মেনুৱেলভাৱে লক কৰা হৈছিল"</string>
+    <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="71299470072448533">
+      <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>
+    <plurals name="kg_prompt_reason_time_pin" formatted="false" msgid="34586942088144385">
+      <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>
+    <plurals name="kg_prompt_reason_time_password" formatted="false" msgid="257297696215346527">
+      <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="fingerprint_not_recognized" msgid="348813995267914625">"চিনাক্ত কৰিব পৰা নগ\'ল"</string>
+    <!-- no translation found for kg_password_default_pin_message (6203676909479972943) -->
+    <!-- no translation found for kg_password_default_puk_message (8744416410184198352) -->
+</resources>
diff --git a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
index 079ba92..a652905 100644
--- a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Sledeći alarm je podešen za <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Izbriši"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Onemogući eSIM"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"Onemogućavanje eSIM-a nije uspelo"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"eSIM ne može da se onemogući zbog greške."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Zaboravio/la sam šablon"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Pogrešan šablon"</string>
@@ -66,7 +68,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Nacrtajte šablon"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Unesite PIN za SIM."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Unesite PIN za SIM „<xliff:g id="CARRIER">%1$s</xliff:g>“."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Onemogućite eSIM da biste uređaj koristili bez mobilne usluge."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Onemogućite eSIM da biste uređaj koristili bez mobilne usluge."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Unesite PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Unesite lozinku"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM kartica je sada onemogućena. Unesite PUK kôd da biste nastavili. Detaljne informacije potražite od mobilnog operatera."</string>
diff --git a/packages/SystemUI/res-keyguard/values-be/strings.xml b/packages/SystemUI/res-keyguard/values-be/strings.xml
index a3a381549..744fde3 100644
--- a/packages/SystemUI/res-keyguard/values-be/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-be/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Наступны будзільнік пастаўлены на <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Выдаліць"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Адключыць eSIM-карту"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"Немагчыма адключыць eSIM-карту"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"Немагчыма адключыць eSIM-карту з-за памылкі."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Увесці"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Забыў(-ла) узор"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Няправільны ўзор"</string>
@@ -67,7 +69,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Намалюйце ўзор"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Увядзіце PIN-код SIM-карты."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Увядзіце PIN-код SIM-карты для \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Адключыце eSIM-карту, каб выкарыстоўваць прыладу без сэрвісу мабільнай перадачы даных."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Каб выкарыстоўваць прыладу без мабільнай сувязі, адключыце eSIM-карту."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Увядзіце PIN-код"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Увядзіце пароль"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-карта зараз адключана. Увядзіце PUK-код, каб працягнуць. Звяжыцеся са сваім аператарам, каб атрымаць дадатковую інфармацыю."</string>
diff --git a/packages/SystemUI/res-keyguard/values-bg/strings.xml b/packages/SystemUI/res-keyguard/values-bg/strings.xml
index 87c7519..3c94610 100644
--- a/packages/SystemUI/res-keyguard/values-bg/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bg/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Следващият будилник е зададен за <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Изтриване"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Деактивиране на ел. SIM карта"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"Електронната SIM карта не може да бъде деактивирана"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"Електронната SIM карта не може да бъде деактивирана поради грешка."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"„Enter“"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Забравена фигура"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Грешна фигура"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Начертайте фигурата си"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Въведете ПИН кода за SIM картата."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Въведете ПИН кода на SIM картата за „<xliff:g id="CARRIER">%1$s</xliff:g>“."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Деактивирайте електронната SIM карта, за да използвате устройството без мобилна услуга."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Деактивирайте електронната SIM карта, за да използвате устройството без мобилна услуга."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Въведете ПИН кода"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Въведете паролата"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM картата вече е деактивирана. Въведете PUK кода, за да продължите. Свържете се с оператора за подробности."</string>
diff --git a/packages/SystemUI/res-keyguard/values-bn/strings.xml b/packages/SystemUI/res-keyguard/values-bn/strings.xml
index 81c56da..215928d 100644
--- a/packages/SystemUI/res-keyguard/values-bn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bn/strings.xml
@@ -53,10 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"পরবর্তী অ্যালার্ম <xliff:g id="ALARM">%1$s</xliff:g> এ সেট করা হয়েছে"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"মুছুন"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"ই-সিমটি অক্ষম করুন"</string>
-    <!-- no translation found for error_disable_esim_title (4852978431156228006) -->
-    <skip />
-    <!-- no translation found for error_disable_esim_msg (676694908770135639) -->
-    <skip />
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"ই-সিম বন্ধ করা যাচ্ছে না"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"একটি সমস্যার কারণে ই-সিমটি বন্ধ করা যাচ্ছে না।"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"এন্টার"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"প্যাটার্ন ভুলে গেছি"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"ভুল প্যাটার্ন"</string>
@@ -69,8 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"আপনার প্যাটার্ন আঁকুন"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"সিমের পিন লিখুন।"</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" এর জন্য সিমের পিন লিখুন।"</string>
-    <!-- no translation found for kg_sim_lock_esim_instructions (4416732549172148542) -->
-    <skip />
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> মোবাইল পরিষেবা ছাড়া ডিভাইস ব্যবহার করার জন্য ই-সিম বন্ধ করুন।"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"পিন লিখুন"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"পাসওয়ার্ড লিখুন"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"সিমটি এখন অক্ষম করা হয়েছে। চালিয়ে যেতে PUK কোডটি লিখুন। বিশদ বিবরণের জন্য পরিষেবা প্রদানকারীর সাথে যোগাযোগ করুন।"</string>
diff --git a/packages/SystemUI/res-keyguard/values-bs/strings.xml b/packages/SystemUI/res-keyguard/values-bs/strings.xml
index 6ff819c..d485108 100644
--- a/packages/SystemUI/res-keyguard/values-bs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bs/strings.xml
@@ -53,10 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Naredni alarm je podešen za <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Izbriši"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Onemogući eSIM karticu"</string>
-    <!-- no translation found for error_disable_esim_title (4852978431156228006) -->
-    <skip />
-    <!-- no translation found for error_disable_esim_msg (676694908770135639) -->
-    <skip />
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"Nije moguće onemogućiti eSIM"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"eSIM nije moguće onemogućiti zbog greške."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Zaboravili ste uzorak?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Pogrešan uzorak"</string>
@@ -70,8 +68,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Nacrtajte uzorak"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Unesite PIN SIM kartice."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Unesite PIN SIM kartice operatera \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
-    <!-- no translation found for kg_sim_lock_esim_instructions (4416732549172148542) -->
-    <skip />
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Onemogućite eSIM za korištenje uređaja bez mobilne usluge."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Unesite PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Unesite lozinku"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM kartica je sada onemogućena. Unesite PUK kôd da nastavite. Za više informacija obratite se operateru."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ca/strings.xml b/packages/SystemUI/res-keyguard/values-ca/strings.xml
index 511516e..283226c 100644
--- a/packages/SystemUI/res-keyguard/values-ca/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ca/strings.xml
@@ -53,10 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"S\'ha definit la pròxima alarma per a l\'hora següent: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Suprimeix"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Desactiva l\'eSIM"</string>
-    <!-- no translation found for error_disable_esim_title (4852978431156228006) -->
-    <skip />
-    <!-- no translation found for error_disable_esim_msg (676694908770135639) -->
-    <skip />
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"No es pot desactivar l\'eSIM"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"S\'ha produït un error i no es pot desactivar l\'eSIM."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Retorn"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"He oblidat el patró"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"El patró no és correcte"</string>
@@ -69,8 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Dibuixa el patró"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Introdueix el PIN de la SIM."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Introdueix el PIN de la SIM de: <xliff:g id="CARRIER">%1$s</xliff:g>."</string>
-    <!-- no translation found for kg_sim_lock_esim_instructions (4416732549172148542) -->
-    <skip />
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Desactiva l\'eSIM per utilitzar el dispositiu sense servei mòbil."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Introdueix el PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Introdueix la contrasenya"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"La SIM està desactivada. Introdueix el codi PUK per continuar. Contacta amb l\'operador de telefonia mòbil per obtenir més informació."</string>
diff --git a/packages/SystemUI/res-keyguard/values-de/strings.xml b/packages/SystemUI/res-keyguard/values-de/strings.xml
index 852a9c1..d742786 100644
--- a/packages/SystemUI/res-keyguard/values-de/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-de/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Nächster Wecker gestellt für <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Löschen"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM deaktivieren"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"Die eSIM kann nicht deaktiviert werden"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"Die eSim kann aufgrund eines Fehlers nicht deaktiviert werden."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Eingabe"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Muster vergessen"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Falsches Muster"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Muster zeichnen"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Gib die SIM-PIN ein"</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Gib die SIM-PIN für \"<xliff:g id="CARRIER">%1$s</xliff:g>\" ein."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Deaktiviere eSIM, um das Gerät ohne Mobilfunkdienst zu verwenden."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Deaktiviere die eSIM, um das Gerät ohne Mobilfunkdienst zu verwenden."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN eingeben"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Passwort eingeben"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Die SIM-Karte ist jetzt deaktiviert. Gib den PUK-Code ein, um fortzufahren. Weitere Informationen erhältst du von deinem Mobilfunkanbieter."</string>
diff --git a/packages/SystemUI/res-keyguard/values-el/strings.xml b/packages/SystemUI/res-keyguard/values-el/strings.xml
index 0127ef1..4c3390b 100644
--- a/packages/SystemUI/res-keyguard/values-el/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-el/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Το επόμενο ξυπνητήρι ορίστηκε στις <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Διαγραφή"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Απενεργοποίηση eSIM"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"Αδυναμία απενεργοποίησης eSIM"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"Δεν είναι δυνατή η απενεργοποίηση της eSIM, εξαιτίας κάποιου σφάλματος."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Ξεχάσατε το μοτίβο"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Λάθος μοτίβο"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Σχεδιάστε το μοτίβο σας"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Εισαγωγή αριθμού PIN κάρτας SIM"</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Εισαγάγετε τον αριθμό PIN της κάρτας SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Απενεργοποιήστε την eSIM, για να χρησιμοποιήσετε τη συσκευή χωρίς υπηρεσία για κινητά."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Απενεργοποιήστε την eSIM, για να χρησιμοποιήσετε τη συσκευή χωρίς υπηρεσία για κινητά."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Εισαγάγετε τον αριθμό PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Εισαγάγετε κωδικό πρόσβασης"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Η κάρτα SIM είναι απενεργοποιημένη αυτή τη στιγμή. Εισαγάγετε τον κωδικό PUK για να συνεχίσετε. Επικοινωνήστε με την εταιρεία κινητής τηλεφωνίας σας για λεπτομέρειες."</string>
diff --git a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
index df0c45b..9fd0ed5 100644
--- a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Próxima alarma establecida: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Borrar"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Inhabilitar eSIM"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"No se puede inhabilitar la eSIM"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"No se puede inhabilitar la eSIM debido a un error."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Intro"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"¿Olvidaste el patrón?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Patrón incorrecto"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Dibuja tu patrón"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Ingresa el PIN de la tarjeta SIM."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Ingresa el PIN de la tarjeta SIM de \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Inhabilita la eSIM para usar el dispositivo sin servicio de datos móviles."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Inhabilita la tarjeta eSIM para usar el dispositivo sin servicio móvil."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Ingresa el PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Escribe la contraseña"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"La tarjeta SIM está inhabilitada. Para continuar, ingresa el código PUK. Si quieres obtener más información, comunícate con el proveedor."</string>
diff --git a/packages/SystemUI/res-keyguard/values-et/strings.xml b/packages/SystemUI/res-keyguard/values-et/strings.xml
index bca98ef..eaf1400 100644
--- a/packages/SystemUI/res-keyguard/values-et/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-et/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Järgmine alarm on määratud ajaks <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Kustuta"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Keela eSIM-kaart"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"eSIM-kaarti ei saa keelata"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"Vea tõttu ei saa eSIM-kaarte keelata."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Sisesta"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Unustasin mustri"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Vale muster"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Joonistage oma muster"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Sisestage SIM-kaardi PIN-kood."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Sisestage operaatori „<xliff:g id="CARRIER">%1$s</xliff:g>” SIM-kaardi PIN-kood."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Keelake eSIM-kaart, et seadet ilma mobiilsideteenuseta kasutada."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Keelake eSIM-kaart, et seadet ilma mobiilsideteenuseta kasutada."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Sisestage PIN-kood"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Sisestage parool"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-kaart on nüüd keelatud. Jätkamiseks sisestage PUK-kood. Lisateabe saamiseks võtke ühendust operaatoriga."</string>
diff --git a/packages/SystemUI/res-keyguard/values-fa/strings.xml b/packages/SystemUI/res-keyguard/values-fa/strings.xml
index ce46e6a..0cb3e0b 100644
--- a/packages/SystemUI/res-keyguard/values-fa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fa/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"زنگ ساعت بعدی برای <xliff:g id="ALARM">%1$s</xliff:g> تنظیم شد"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"حذف"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"‏غیرفعال کردن eSIM"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"سیم‌کارت داخلی غیرفعال نشد"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"به دلیل بروز خطا، سیم‌کارت داخلی غیرفعال نشد."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"الگو را فراموش کرده‌اید"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"الگوی اشتباه"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"الگوی خود را رسم کنید"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"پین سیم‌کارت را وارد کنید."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"پین سیم‌کارت «<xliff:g id="CARRIER">%1$s</xliff:g>» را وارد کنید."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"‏برای استفاده از دستگاه بدون سرویس همراه، eSIM را غیرفعال کنید."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g>برای استفاده از دستگاه بدون سرویس همراه، سیم‌کارت داخلی را غیرفعال کنید."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"کد پین را وارد کنید"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"گذرواژه را وارد کنید"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"اکنون سیم‌کارت غیرفعال است. کد پین را برای ادامه وارد کنید. برای جزئیات با شرکت مخابراتی خود تماس بگیرید."</string>
diff --git a/packages/SystemUI/res-keyguard/values-fr/strings.xml b/packages/SystemUI/res-keyguard/values-fr/strings.xml
index 34b638e..5d5e363 100644
--- a/packages/SystemUI/res-keyguard/values-fr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Date et heure de la prochaine alarme : <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Supprimer"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Désactiver la carte eSIM"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"Impossible de désactiver la carte eSIM"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"Impossible de désactiver la carte eSIM en raison d\'une erreur."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Entrée"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"J\'ai oublié le schéma"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Schéma incorrect"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Dessinez votre schéma"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Saisissez le code PIN de la carte SIM."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Saisissez le code PIN de la carte SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Désactivez la carte eSIM pour utiliser l\'appareil sans service mobile."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Désactivez la carte eSIM pour utiliser l\'appareil sans service mobile."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Saisissez le code"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Saisissez le mot de passe"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"La carte SIM est maintenant désactivée. Pour continuer, saisissez la clé PUK. Contactez votre opérateur pour en savoir plus."</string>
diff --git a/packages/SystemUI/res-keyguard/values-gl/strings.xml b/packages/SystemUI/res-keyguard/values-gl/strings.xml
index e21e844..7075c37 100644
--- a/packages/SystemUI/res-keyguard/values-gl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gl/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Próxima alarma definida para: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Eliminar"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Desactivar eSIM"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"Non se puido desactivar a eSIM"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"A eSIM non se puido desactivar debido a un erro."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Intro"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Esqueciches o padrón"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Padrón incorrecto"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Debuxa o teu padrón"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Introduce o PIN da SIM."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Introduce o PIN da SIM para \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Desactiva a eSIM para usar o dispositivo sen servizo móbil."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Desactiva a eSIM para usar o dispositivo sen o servizo móbil."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Introduce o PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Insire o teu contrasinal"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Agora a tarxeta SIM está desactivada. Introduce o código PUK para continuar. Ponte en contacto co operador para obter máis información."</string>
diff --git a/packages/SystemUI/res-keyguard/values-gu/strings.xml b/packages/SystemUI/res-keyguard/values-gu/strings.xml
index d2e6c02..d7faa2a 100644
--- a/packages/SystemUI/res-keyguard/values-gu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gu/strings.xml
@@ -53,10 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"<xliff:g id="ALARM">%1$s</xliff:g> માટે આગલું એલાર્મ સેટ કર્યું"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"કાઢી નાખો"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIMને અક્ષમ કરો"</string>
-    <!-- no translation found for error_disable_esim_title (4852978431156228006) -->
-    <skip />
-    <!-- no translation found for error_disable_esim_msg (676694908770135639) -->
-    <skip />
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"ઇ-સિમ બંધ કરી શકાતું નથી"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"એક ભૂલને લીધે ઇ-સિમ બંધ કરી શકાતું નથી."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"દાખલ કરો"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"પૅટર્ન ભૂલી ગયાં"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"ખોટી પૅટર્ન"</string>
@@ -69,8 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"તમારી પૅટર્ન દોરો"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"સિમ પિન દાખલ કરો"</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" માટે સિમ પિન દાખલ કરો."</string>
-    <!-- no translation found for kg_sim_lock_esim_instructions (4416732549172148542) -->
-    <skip />
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> મોબાઇલ સેવા વગર ઉપકરણનો ઉપયોગ કરવા માટે ઇ-સિમને બંધ કરો."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"પિન દાખલ કરો"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"પાસવર્ડ દાખલ કરો"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"સિમ હમણાં અક્ષમ કરેલ છે. ચાલુ રાખવા માટે PUK કોડ દાખલ કરો. વિગતો માટે કૅરિઅરનો સંપર્ક કરો."</string>
diff --git a/packages/SystemUI/res-keyguard/values-hi/strings.xml b/packages/SystemUI/res-keyguard/values-hi/strings.xml
index dfd06b2..746e883 100644
--- a/packages/SystemUI/res-keyguard/values-hi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hi/strings.xml
@@ -53,10 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"अगला अलार्म <xliff:g id="ALARM">%1$s</xliff:g> बजे के लिए सेट किया गया है"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"मिटाएं"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM अक्षम करें"</string>
-    <!-- no translation found for error_disable_esim_title (4852978431156228006) -->
-    <skip />
-    <!-- no translation found for error_disable_esim_msg (676694908770135639) -->
-    <skip />
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"ई-सिम बंद नहीं किया जा सकता"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"किसी गड़बड़ी की वजह से ई-सिम बंद नहीं किया जा सकता."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"पैटर्न भूल गए हैं"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"गलत पैटर्न"</string>
@@ -69,8 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"अपना पैटर्न बनाएं"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"सिम पिन डालें."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" के लिए सिम पिन डालें"</string>
-    <!-- no translation found for kg_sim_lock_esim_instructions (4416732549172148542) -->
-    <skip />
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> मोबाइल सेवा के बिना डिवाइस का इस्तेमाल करने के लिए ई-सिम बंद करें."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"पिन डालें"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"पासवर्ड डालें"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"सिम अब काम नहीं करेगा. जारी रखने के लिए PUK कोड डालें. ज़्यादा जानकारी के लिए अपनी मोबाइल और इंटरनेट सेवा देने वाली कंपनी से संपर्क करें."</string>
diff --git a/packages/SystemUI/res-keyguard/values-hr/strings.xml b/packages/SystemUI/res-keyguard/values-hr/strings.xml
index cfdf5cd..f4dca4c 100644
--- a/packages/SystemUI/res-keyguard/values-hr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hr/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Sljedeći alarm postavljen za <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Izbriši"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Onemogući eSIM"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"Nije moguće onemogućiti eSIM"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"Onemogućivanje eSIM-a nije uspjelo zbog pogreške."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Unos"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Zaboravili ste uzorak"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Pogrešan uzorak"</string>
@@ -66,7 +68,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Iscrtajte svoj uzorak"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Unesite PIN za SIM"</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Unesite PIN za SIM mobilnog operatera \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Onemogućite eSIM kako biste uređaj upotrebljavali bez mobilne usluge."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Onemogućite eSIM kako biste uređaj upotrebljavali bez mobilne usluge."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Unesite PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Unesite zaporku"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM je sad onemogućen. Unesite PUK kôd da biste nastavili. Obratite se mobilnom operateru za više pojedinosti."</string>
diff --git a/packages/SystemUI/res-keyguard/values-hu/strings.xml b/packages/SystemUI/res-keyguard/values-hu/strings.xml
index 71f34a9..b9a51bc 100644
--- a/packages/SystemUI/res-keyguard/values-hu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hu/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"A következő ébresztés beállított ideje: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Törlés"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Az e-SIM-kártya letiltása"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"Nem lehet letiltani az eSIM-et"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"Hiba történt, így az eSIM-et nem lehet letiltani."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Elfelejtettem a mintát"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Helytelen minta"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Rajzolja le a mintát"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Adja meg a SIM-kártya PIN-kódját."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Adja meg a(z) „<xliff:g id="CARRIER">%1$s</xliff:g>” SIM-kártya PIN-kódját."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Tiltsa le az e-SIM-kártyát az eszköz mobilszolgáltatás nélküli használatához."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Tiltsa le az e-SIM-et az eszköz mobilszolgáltatás nélküli használatához."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Adja meg a PIN-kódot"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Írja be a jelszót"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"A SIM-kártya le van tiltva. A folytatáshoz adja meg a PUK-kódot. A részletekért vegye fel a kapcsolatot szolgáltatójával."</string>
diff --git a/packages/SystemUI/res-keyguard/values-in/strings.xml b/packages/SystemUI/res-keyguard/values-in/strings.xml
index ee3621c..e5d2c89 100644
--- a/packages/SystemUI/res-keyguard/values-in/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-in/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Alarm berikutnya disetel untuk <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Hapus"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Nonaktifkan eSIM"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"Tidak dapat menonaktifkan eSIM"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"eSIM tidak dapat dinonaktifkan karena terjadi error."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Masukkan"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Lupa Pola?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Pola Salah"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Gambar pola Anda"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Masukkan PIN SIM."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Masukkan PIN SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Nonaktifkan eSIM untuk menggunakan perangkat tanpa layanan seluler."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Nonaktifkan eSIM untuk menggunakan perangkat tanpa layanan seluler."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Masukkan PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Masukkan Sandi"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM telah dinonaktifkan. Masukkan kode PUK untuk melanjutkan. Hubungi operator untuk keterangan selengkapnya."</string>
diff --git a/packages/SystemUI/res-keyguard/values-is/strings.xml b/packages/SystemUI/res-keyguard/values-is/strings.xml
index cead5c4..e0ef1f8 100644
--- a/packages/SystemUI/res-keyguard/values-is/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-is/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Næsti vekjari stilltur á <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Eyða"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Aftengja eSIM"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"Ekki tókst að gera eSIM-kort óvirkt"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"Villa kom í veg fyrir að hægt væri að gera eSIM-kortið óvirkt."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Færa inn"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Man ekki mynstrið"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Rangt mynstur"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Teiknaðu mynstrið þitt"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Sláðu inn PIN-númer SIM-kortsins."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Sláðu inn PIN-númer SIM-korts fyrir „<xliff:g id="CARRIER">%1$s</xliff:g>“."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Aftengdu eSIM til að nota tækið án farsímakerfisþjónustu."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Gerðu eSIM-kortið óvirkt til að nota tækið án tengingar við farsímakerfi."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Sláðu inn PIN-númer"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Sláðu inn aðgangsorð"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-kortið hefur verið gert óvirkt. Sláðu inn PUK-númerið til að halda áfram. Hafðu samband við símafyrirtækið til að fá frekari upplýsingar."</string>
diff --git a/packages/SystemUI/res-keyguard/values-iw/strings.xml b/packages/SystemUI/res-keyguard/values-iw/strings.xml
index 8be3a89..35facff 100644
--- a/packages/SystemUI/res-keyguard/values-iw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-iw/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"ההתראה הבאה נקבעה ל-<xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Delete"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"‏השבתת ה-eSIM"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"‏לא ניתן להשבית את כרטיס ה-eSIM"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"‏לא ניתן להשבית את כרטיס ה-eSIM עקב שגיאה."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"שכחתי את קו ביטול הנעילה"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"קו ביטול הנעילה שגוי"</string>
@@ -67,7 +69,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"שרטט את קו ביטול הנעילה"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"‏הזן את קוד הגישה של כרטיס ה-SIM."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"‏הזן את קוד הגישה של כרטיס ה-SIM של <xliff:g id="CARRIER">%1$s</xliff:g>."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"‏השבת את ה-eSIM כדי להשתמש במכשיר ללא שירות סלולרי."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"‏<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> יש להשבית את כרטיס ה-eSIM כדי להשתמש במכשיר ללא שירות סלולרי."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"הזן קוד גישה"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"הזן את הסיסמה"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"‏כרטיס ה-SIM מושבת כעת. הזן קוד PUK כדי להמשיך. פנה אל הספק לפרטים."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ja/strings.xml b/packages/SystemUI/res-keyguard/values-ja/strings.xml
index 6bdc200..0442849 100644
--- a/packages/SystemUI/res-keyguard/values-ja/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ja/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"次のアラームを <xliff:g id="ALARM">%1$s</xliff:g> に設定しました"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"削除"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM を無効にする"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"eSIM を無効にできません"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"エラーのため、eSIM を無効にできません。"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"入力"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"パターンを忘れた場合"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"パターンが正しくありません"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"パターンを入力してください"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM PIN を入力してください。"</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"「<xliff:g id="CARRIER">%1$s</xliff:g>」の SIM PIN を入力してください。"</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"モバイル サービスなしで端末を使用するには eSIM を無効にしてください。"</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g>モバイル サービスなしで端末を使用するには eSIM を無効にしてください。"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN を入力してください"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"パスワードを入力してください"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM が無効になりました。続行するには PUK コードを入力してください。詳しくは携帯通信会社にお問い合わせください。"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ka/strings.xml b/packages/SystemUI/res-keyguard/values-ka/strings.xml
index 31ccaae..48fecdf2e 100644
--- a/packages/SystemUI/res-keyguard/values-ka/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ka/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"შემდეგი მაღვიძარა დაყენებულია <xliff:g id="ALARM">%1$s</xliff:g>-ზე"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"წაშლა"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM-ის გათიშვა"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"eSIM-ის გათიშვა ვერ ხერხდება"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"eSIM-ის გათიშვა ვერ ხერხდება წარმოქმნილი შეცდომის გამო."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"შეყვანა"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"დაგავიწყდათ ნიმუში"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"ნიმუში არასწორია"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"დახატეთ თქვენი ნიმუში"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"შეიყვანეთ SIM ბარათის PIN-კოდი."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"შეიყვანეთ SIM ბარათის PIN-კოდი „<xliff:g id="CARRIER">%1$s</xliff:g>“-ისთვის."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"გათიშეთ eSIM, მოწყობილობის მობილური სერვისების გარეშე გამოსაყენებლად."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> გათიშეთ eSIM, მოწყობილობის მობილური სერვისების გარეშე გამოსაყენებლად."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"შეიყვანეთ PIN-კოდი"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"შეიყვანეთ პაროლი"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM ბარათი ახლა დეაქტივირებულია. გასაგრძელებლად შეიყვანეთ PUK-კოდი. დეტალური ინფორმაციისთვის დაუკავშირდით თქვენს ოპერატორს."</string>
diff --git a/packages/SystemUI/res-keyguard/values-kk/strings.xml b/packages/SystemUI/res-keyguard/values-kk/strings.xml
index f9e12f1..dd15717 100644
--- a/packages/SystemUI/res-keyguard/values-kk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kk/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Келесі дабыл уақыты: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Жою"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM картасын өшіру"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"eSIM картасы өшірілмеді"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"Қатеге байланысты eSIM картасы өшірілмеді."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Енгізу"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Өрнекті ұмытып қалдыңыз ба?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Өрнек қате"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Өрнекті енгізіңіз"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM PIN кодын енгізіңіз."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" үшін SIM PIN кодын енгізіңіз."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Құрылғыны мобильдік қызметсіз пайдалану үшін eSIM картасын өшіріңіз."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Құрылығыны мобильдік байланыс қызметінсіз пайдалану үшін eSIM картасын өшіріңіз."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN кодын енгізіңіз"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Кілтсөзді енгізіңіз"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM картасы өшірілді. Жалғастыру үшін PUK кодын енгізіңіз. Толығырақ ақпаратты оператордан алыңыз."</string>
diff --git a/packages/SystemUI/res-keyguard/values-km/strings.xml b/packages/SystemUI/res-keyguard/values-km/strings.xml
index 3bf4379..8b516c2 100644
--- a/packages/SystemUI/res-keyguard/values-km/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-km/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"បាន​កំណត់ម៉ោង​រោទិ៍​បន្ទាប់​នៅថ្ងៃ <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"លុប"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"បិទ eSIM"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"មិនអាច​បិទ eSIM បាន​ទេ"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"មិនអាច​បិទ eSIM បានទេ ដោយសារ​មាន​បញ្ហា។"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"ភ្លេច​​លំនាំ"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"លំនាំ​មិន​ត្រឹមត្រូវ​ទេ"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"គូរ​លំនាំ​របស់​អ្នក"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"បញ្ចូល​កូដ PIN របស់​ស៊ីម។"</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"បញ្ចូល​កូដ PIN របស់​ស៊ីម​សម្រាប់ \"<xliff:g id="CARRIER">%1$s</xliff:g>\"។"</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"បិទ eSIM ដើម្បីប្រើប្រាស់ឧបករណ៍​ដោយ​មិនចាំបាច់ប្រើសេវាកម្មទិន្នន័យចល័ត។"</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> បិទ eSIM ដើម្បី​ប្រើ​ឧបករណ៍​ដោយ​គ្មាន​សេវាកម្ម​ទូរសព្ទ​ចល័ត។"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"បញ្ចូល​កូដ PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"បញ្ចូល​ពាក្យ​សម្ងាត់"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"ឥឡូវ​នេះ​ ស៊ីម​ត្រូវ​បាន​បិទ​ដំណើរការ​ហើយ។ បញ្ចូល​កូដ PUK ដើម្បី​បន្ត។ សូម​ទាក់ទង​ទៅក្រុមហ៊ុន​បម្រើ​សេវា​ទូរសព្ទ​របស់​អ្នក ដើម្បី​ទទួល​បាន​ព័ត៌មាន​លម្អិត។"</string>
diff --git a/packages/SystemUI/res-keyguard/values-kn/strings.xml b/packages/SystemUI/res-keyguard/values-kn/strings.xml
index 690ce65..d14c1a2 100644
--- a/packages/SystemUI/res-keyguard/values-kn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kn/strings.xml
@@ -53,10 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"<xliff:g id="ALARM">%1$s</xliff:g> ಗಂಟೆಗೆ ಮುಂದಿನ ಅಲಾರಮ್ ಹೊಂದಿಸಲಾಗಿದೆ"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"ಅಳಿಸಿ"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
-    <!-- no translation found for error_disable_esim_title (4852978431156228006) -->
-    <skip />
-    <!-- no translation found for error_disable_esim_msg (676694908770135639) -->
-    <skip />
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"eSIM ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"ದೋಷದ ಕಾರಣದಿಂದಾಗಿ eSIM ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"ನಮೂದಿಸಿ"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"ಪ್ಯಾಟರ್ನ್ ಮರೆತಿದ್ದೀರಿ"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"ಪ್ಯಾಟರ್ನ್ ತಪ್ಪಾಗಿದೆ"</string>
@@ -69,8 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"ನಿಮ್ಮ ಪ್ಯಾಟರ್ನ್ ಚಿತ್ರಿಸಿ"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"ಸಿಮ್‌ ಪಿನ್‌ ನಮೂದಿಸಿ."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" ಗಾಗಿ ಸಿಮ್ ಪಿನ್ ನಮೂದಿಸಿ."</string>
-    <!-- no translation found for kg_sim_lock_esim_instructions (4416732549172148542) -->
-    <skip />
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> ಮೊಬೈಲ್ ಸೇವೆ ಇಲ್ಲದೆ ಸಾಧನವನ್ನು ಬಳಸಲು eSIM ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"ಪಿನ್‌ ನಮೂದಿಸಿ"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"ಪಾಸ್‌ವರ್ಡ್ ನಮೂದಿಸಿ"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"ಈಗ ಸಿಮ್‌ ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ. ಮುಂದುವರೆಯಲು PUK ಕೋಡ್ ನಮೂದಿಸಿ. ವಿವರಗಳಿಗಾಗಿ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ko/strings.xml b/packages/SystemUI/res-keyguard/values-ko/strings.xml
index 1a34229..cd2f079 100644
--- a/packages/SystemUI/res-keyguard/values-ko/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ko/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"<xliff:g id="ALARM">%1$s</xliff:g>에 다음 알람이 설정됨"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"삭제"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM 사용 중지"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"eSIM을 사용 중지할 수 없음"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"오류로 인해 eSIM을 사용 중지할 수 없습니다."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter 키"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"패턴을 잊음"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"잘못된 패턴"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"패턴 그리기"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM PIN을 입력하세요."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\'<xliff:g id="CARRIER">%1$s</xliff:g>\'의 SIM PIN을 입력하세요."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"모바일 서비스 없이 기기를 사용하려면 eSIM을 사용 중지하세요."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> 모바일 서비스 없이 기기를 사용하려면 eSIM을 사용 중지하세요."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN 입력"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"비밀번호 입력"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM이 사용 중지되었습니다. 계속하려면 PUK 코드를 입력하세요. 자세한 내용은 이동통신사에 문의하시기 바랍니다."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ky/strings.xml b/packages/SystemUI/res-keyguard/values-ky/strings.xml
index a4f5b7d..f1b6baa 100644
--- a/packages/SystemUI/res-keyguard/values-ky/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ky/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Кийинки ойготкуч саат <xliff:g id="ALARM">%1$s</xliff:g> коюлган"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Жок кылуу"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM-картаны өчүрүү"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"eSIM-картаны өчүрүүгө болбойт"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"Катадан улам eSIM-картаны өчүрүүгө болбойт."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Киргизүү"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Графикалык ачкычты унутуп калдым"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Графикалык ачкыч туура эмес"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Графикалык ачкычты тартыңыз"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM-картанын PIN-кодун киргизиңиз."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" SIM-картасынын PIN-кодун киргизиңиз."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Түзмөктү мобилдик кызматсыз колдонуу үчүн eSIM-картаны өчүрүңүз."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Түзмөктү мобилдик кызматсыз колдонуу үчүн eSIM-картаны өчүрүңүз."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN-кодду киргизиңиз"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Сырсөздү киргизиңиз"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-карта азыр жарактан чыкты. Улантуу үчүн PUK-кодду киргизиңиз. Анын чоо-жайын билүү үчүн байланыш операторуна кайрылыңыз."</string>
diff --git a/packages/SystemUI/res-keyguard/values-lo/strings.xml b/packages/SystemUI/res-keyguard/values-lo/strings.xml
index 10a81d0..97a5dcf 100644
--- a/packages/SystemUI/res-keyguard/values-lo/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lo/strings.xml
@@ -53,10 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"ໂມງປຸກຕໍ່ໄປຖືກຕັ້ງໄວ້ເວລາ <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"ລຶບ"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"ປິດການໃຊ້ eSIM ແລ້ວ"</string>
-    <!-- no translation found for error_disable_esim_title (4852978431156228006) -->
-    <skip />
-    <!-- no translation found for error_disable_esim_msg (676694908770135639) -->
-    <skip />
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"ບໍ່ສາມາດປິດການເຮັດວຽກຂອງ eSIM ໄດ້"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"ບໍ່ສາມາດປິດການນຳໃຊ້ eSIM ໄດ້ເນື່ອງຈາກມີຂໍ້ຜິດພາດ."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"ປ້ອນເຂົ້າ"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"ລືມຮູບແບບປົດລັອກ?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"ຮູບແບບຜິດ"</string>
@@ -69,8 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"ແຕ້ມຮູບແບບປົດລັອກຂອງທ່ານ"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"ໃສ່ລະຫັດ PIN ຂອງຊິມ."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"ໃສ່ລະຫັດ PIN ຂອງຊິມສຳລັບ \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
-    <!-- no translation found for kg_sim_lock_esim_instructions (4416732549172148542) -->
-    <skip />
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> ປິດການນຳໃຊ້ eSIM ເພື່ອໃຊ້ອຸປະກອນໂດຍບໍ່ຕ້ອງເຊື່ອມຕໍ່ເຄືອຂ່າຍ."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"ໃສ່ລະຫັດ PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"ໃສ່ລະຫັດຜ່ານ"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"ຊິມຖືກປິດການນຳໃຊ້ແລ້ວ. ປ້ອນລະຫັດ PUK ເພື່ອດຳເນີນການຕໍ່. ຕິດຕໍ່ຜູ່ໃຫ້ບໍລິການສຳລັບລາຍລະອຽດ."</string>
diff --git a/packages/SystemUI/res-keyguard/values-lt/strings.xml b/packages/SystemUI/res-keyguard/values-lt/strings.xml
index bf041a0..7909ee3 100644
--- a/packages/SystemUI/res-keyguard/values-lt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lt/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Kitas nustatytas signalas: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Ištrinti"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Išjungti eSIM kortelę"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"Nepavyko išjungti „eSIM“ kortelės"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"Dėl klaidos nepavyko išjungti „eSIM“ kortelės."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Pamiršau atrakinimo piešinį"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Netinkamas atrakinimo piešinys"</string>
@@ -67,7 +69,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Nupieškite atrakinimo piešinį"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Įveskite SIM kortelės PIN kodą."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Įveskite „<xliff:g id="CARRIER">%1$s</xliff:g>“ SIM kortelės PIN kodą"</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Išjungti eSIM kortelę ir naudoti įrenginį be mobiliojo ryšio paslaugos."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Išjunkite eSIM kortelę ir naudokite įrenginį be mobiliojo ryšio paslaugos."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Įveskite PIN kodą"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Įveskite slaptažodį"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Dabar SIM neleidžiama. Jei norite tęsti, įveskite PUK kodą. Jei reikia išsamios informacijos, susisiekite su operatoriumi."</string>
diff --git a/packages/SystemUI/res-keyguard/values-lv/strings.xml b/packages/SystemUI/res-keyguard/values-lv/strings.xml
index 475e9ce..137f60a 100644
--- a/packages/SystemUI/res-keyguard/values-lv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lv/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Nākamā signāla atskaņošanas laiks: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Dzēšanas taustiņš"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Atspējot eSIM karti"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"Nevar atspējot eSIM karti"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"Kļūdas dēļ nevar atspējot eSIM karti."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Ievadīšanas taustiņš"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Aizmirsu kombināciju"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Nepareiza kombinācija."</string>
@@ -66,7 +68,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Zīmējiet savu kombināciju."</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Ievadiet SIM kartes PIN kodu."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Ievadiet SIM kartes “<xliff:g id="CARRIER">%1$s</xliff:g>” PIN kodu."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Atspējojiet eSIM karti, lai ierīci varētu izmantot bez mobilā pakalpojuma."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Atspējojiet eSIM karti, lai ierīci varētu izmantot bez mobilā pakalpojuma."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Ievadiet PIN."</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Ievadiet paroli"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM karte ir atspējota. Lai turpinātu, ievadiet PUK kodu. Lai iegūtu detalizētu informāciju, sazinieties ar mobilo sakaru operatoru."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ml/strings.xml b/packages/SystemUI/res-keyguard/values-ml/strings.xml
index 7e12a22..5cc635c0 100644
--- a/packages/SystemUI/res-keyguard/values-ml/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ml/strings.xml
@@ -53,10 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"അടുത്ത അലാറം <xliff:g id="ALARM">%1$s</xliff:g>-ന് സജ്ജീകരിച്ചു"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"ഇല്ലാതാക്കുക"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM പ്രവർത്തനരഹിതമാക്കുക"</string>
-    <!-- no translation found for error_disable_esim_title (4852978431156228006) -->
-    <skip />
-    <!-- no translation found for error_disable_esim_msg (676694908770135639) -->
-    <skip />
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"ഇ-സിം പ്രവർത്തനരഹിതമാക്കാനാകുന്നില്ല"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"പിശക് കാരണം ഇ-സിം പ്രവർത്തനരഹിതമാക്കാനാകുന്നില്ല"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"എന്റർ"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"പാറ്റേൺ മറന്നു"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"പാറ്റേൺ തെറ്റാണ്"</string>
@@ -69,8 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"നിങ്ങളുടെ പാറ്റേൺ വരയ്‌ക്കുക"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"സിം പിൻ നൽകുക."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" എന്ന കാരിയർക്കുള്ള സിം പിൻ നൽകുക."</string>
-    <!-- no translation found for kg_sim_lock_esim_instructions (4416732549172148542) -->
-    <skip />
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> മൊ‌ബൈൽ സേവനമില്ലാതെ ഉപകരണം ഉപയോഗിക്കാൻ ഇ-സിം പ്രവർത്തനരഹിതമാക്കുക."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"പിൻ നൽകുക"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"പാസ്‌വേഡ് നൽകുക"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"സിം ഇപ്പോൾ പ്രവർത്തനരഹിതമാക്കി. തുടരുന്നതിന് PUK കോഡ് നൽകുക. വിശദാംശങ്ങൾക്ക് കാരിയറെ ബന്ധപ്പെടുക."</string>
diff --git a/packages/SystemUI/res-keyguard/values-mn/strings.xml b/packages/SystemUI/res-keyguard/values-mn/strings.xml
index 5f9b63d..258f8c4 100644
--- a/packages/SystemUI/res-keyguard/values-mn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mn/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Дараагийн сэрүүлгийг <xliff:g id="ALARM">%1$s</xliff:g>-д тавьсан"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Устгах"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM-г идэвхгүй болгох"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"eSIM-г идэвхгүй болгох боломжгүй"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"Алдаа гарсан тул eSIM-г идэвхгүй болгох боломжгүй байна."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Оруулах"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Загварыг мартсан"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Загвар буруу байна"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Загварыг оруулна уу"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM-н ПИН-г оруулна уу."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\"-н SIM-н ПИН-г оруулна уу."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Төхөөрөмжийг мобайл үйлчилгээгүй ашиглахын тулд eSIM-г идэвхгүй болгоно уу."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Төхөөрөмжийг мобайл үйлчилгээгүйгээр ашиглахын тулд eSIM-г идэвхгүй болгоно уу."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"ПИН оруулна уу"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Нууц үг оруулна уу"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM идэвхгүй байна. Үргэлжлүүлэх бол PUK кодыг оруулна уу. Дэлгэрэнгүй мэдээлэл авах бол оператор компанитайгаа холбогдоно уу."</string>
diff --git a/packages/SystemUI/res-keyguard/values-mr/strings.xml b/packages/SystemUI/res-keyguard/values-mr/strings.xml
index daa40c6..b8d7b4e 100644
--- a/packages/SystemUI/res-keyguard/values-mr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mr/strings.xml
@@ -53,10 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"पुढील अलार्म <xliff:g id="ALARM">%1$s</xliff:g> साठी सेट केला"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"हटवा"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM बंद करा"</string>
-    <!-- no translation found for error_disable_esim_title (4852978431156228006) -->
-    <skip />
-    <!-- no translation found for error_disable_esim_msg (676694908770135639) -->
-    <skip />
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"eSIM बंद करू नका"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"एका एररमुळे eSIM बंद होऊ शकत नाही."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"एंटर करा"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"पॅटर्न विसरलात"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"चुकीचा पॅटर्न"</string>
@@ -69,8 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"तुमचा पॅटर्न काढा"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"सिम पिन एंटर करा"</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" साठी सिम पिन एंटर करा"</string>
-    <!-- no translation found for kg_sim_lock_esim_instructions (4416732549172148542) -->
-    <skip />
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> मोबाइल सेवेशिवाय डिव्हाइस वापरण्यासाठी eSIM बंद करा."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"पिन एंटर करा"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"पासवर्ड एंटर करा"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"सिम आता अक्षम केले आहे. सुरू ठेवण्यासाठी PUK कोड एंटर करा. तपशीलांसाठी वाहकाशी संपर्क साधा."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ms/strings.xml b/packages/SystemUI/res-keyguard/values-ms/strings.xml
index d37e7ee..2ee456b 100644
--- a/packages/SystemUI/res-keyguard/values-ms/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ms/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Penggera seterusnya ditetapkan pada <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Padam"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Lumpuhkan eSIM"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"Tidak dapat melumpuhkan eSIM"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"eSIM tidak dapat dilumpuhkan kerana ralat."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Kekunci Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Terlupa Corak"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Corak salah"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Lukis corak anda"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Masukkan PIN SIM."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Masukkan PIN SIM untuk \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Lumpuhkan eSIM untuk menggunakan peranti tanpa perkhidmatan mudah alih."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Lumpuhkan eSIM untuk menggunakan peranti tanpa perkhidmatan mudah alih."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Masukkan PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Masukkan Kata Laluan"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM kini dilumpuhkan. Masukkan kod PUK untuk meneruskan. Hubungi pembawa untuk mendapatkan butiran."</string>
diff --git a/packages/SystemUI/res-keyguard/values-nb/strings.xml b/packages/SystemUI/res-keyguard/values-nb/strings.xml
index 2c0e3d6..5d504b38 100644
--- a/packages/SystemUI/res-keyguard/values-nb/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nb/strings.xml
@@ -53,10 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Neste alarm er stilt inn for <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Slett"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Deaktiver e-SIM-kortet"</string>
-    <!-- no translation found for error_disable_esim_title (4852978431156228006) -->
-    <skip />
-    <!-- no translation found for error_disable_esim_msg (676694908770135639) -->
-    <skip />
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"Kan ikke deaktivere e-SIM-kortet"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"E-SIM-kortet kan ikke deaktiveres på grunn av en feil."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Har du glemt mønsteret?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Feil mønster"</string>
@@ -69,8 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Tegn mønsteret ditt"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Skriv inn PIN-koden for SIM-kortet."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Skriv inn PIN-koden for SIM-kortet «<xliff:g id="CARRIER">%1$s</xliff:g>»."</string>
-    <!-- no translation found for kg_sim_lock_esim_instructions (4416732549172148542) -->
-    <skip />
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Deaktiver e-SIM-kortet for å bruke enheten uten mobiltjeneste."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Skriv inn PIN-koden"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Skriv inn passordet"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-kortet er nå deaktivert. Skriv inn PUK-koden for å fortsette. Ta kontakt med operatøren for mer informasjon."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml
index dcb309f..8079d70 100644
--- a/packages/SystemUI/res-keyguard/values-ne/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml
@@ -53,10 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"अर्को अलार्म <xliff:g id="ALARM">%1$s</xliff:g> का लागि सेट गरियो"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"मेट्नुहोस्"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM लाई असक्षम पार्नुहोस्"</string>
-    <!-- no translation found for error_disable_esim_title (4852978431156228006) -->
-    <skip />
-    <!-- no translation found for error_disable_esim_msg (676694908770135639) -->
-    <skip />
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"eSIM लाई असक्षम पार्न सकिएन"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"कुनै त्रुटिका कारण यो eSIM लाई असक्षम पार्न सकिएन।"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"प्रविष्टि गर्नुहोस्"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"ढाँचा बिर्सनुभयो"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"गलत ढाँचा"</string>
@@ -69,8 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"आफ्नो ढाँचा कोर्नुहोस्"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM को PIN प्रविष्टि गर्नुहोस्।"</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" को SIM को PIN प्रविष्ट गर्नुहोस्।"</string>
-    <!-- no translation found for kg_sim_lock_esim_instructions (4416732549172148542) -->
-    <skip />
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> मोबाइल सेवा बिना यन्त्रको प्रयोग गर्न eSIM लाई असक्षम पार्नुहोस्।"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN प्रविष्टि गर्नुहोस्"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"पासवर्ड प्रविष्ट गर्नुहोस्"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM कार्ड अहिले असक्षम छ। सुचारु गर्नको लागि PUK कोड प्रविष्ट गर्नुहोस्।  विवरणको लागि सेवा प्रदायकलाई सम्पर्क गर्नुहोस्।"</string>
diff --git a/packages/SystemUI/res-keyguard/values-nl/strings.xml b/packages/SystemUI/res-keyguard/values-nl/strings.xml
index 6aa66dd..c18b721 100644
--- a/packages/SystemUI/res-keyguard/values-nl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nl/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Volgende wekker ingesteld voor <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Delete"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Simkaart uitschakelen"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"E-simkaart kan niet worden uitgeschakeld"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"De e-simkaart kan niet worden uitgeschakeld vanwege een fout."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Patroon vergeten"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Onjuist patroon"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Teken je patroon"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Geef de pincode van de simkaart op."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Geef de pincode voor de simkaart van \'<xliff:g id="CARRIER">%1$s</xliff:g>\' op."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Schakel de e-simkaart uit om het apparaat te gebruiken zonder mobiele service."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Schakel de e-simkaart uit om het apparaat te gebruiken zonder mobiele service."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Geef je pincode op"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Geef je wachtwoord op"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"De simkaart is nu uitgeschakeld. Geef de pukcode op om door te gaan. Neem contact op met de provider voor informatie."</string>
diff --git a/packages/SystemUI/res-keyguard/values-pa/strings.xml b/packages/SystemUI/res-keyguard/values-pa/strings.xml
index ddb83e9..4728211 100644
--- a/packages/SystemUI/res-keyguard/values-pa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pa/strings.xml
@@ -53,10 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"ਅਗਲਾ ਅਲਾਰਮ <xliff:g id="ALARM">%1$s</xliff:g> \'ਤੇ ਸੈੱਟ ਕੀਤਾ ਗਿਆ"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"ਮਿਟਾਓ"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM ਨੂੰ ਅਯੋਗ ਬਣਾਓ"</string>
-    <!-- no translation found for error_disable_esim_title (4852978431156228006) -->
-    <skip />
-    <!-- no translation found for error_disable_esim_msg (676694908770135639) -->
-    <skip />
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"ਈ-ਸਿਮ ਬੰਦ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"ਕੋਈ ਗੜਬੜ ਹੋਣ ਕਰਕੇ ਈ-ਸਿਮ ਬੰਦ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ।"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"ਦਾਖਲ ਕਰੋ"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"ਪੈਟਰਨ ਭੁੱਲ ਗਏ"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"ਗਲਤ ਪੈਟਰਨ"</string>
@@ -69,8 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"ਆਪਣਾ ਪੈਟਰਨ ਉਲੀਕੋ"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"ਸਿਮ ਪਿੰਨ ਦਾਖਲ ਕਰੋ।"</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" ਲਈ ਸਿਮ ਪਿੰਨ ਦਾਖਲ ਕਰੋ।"</string>
-    <!-- no translation found for kg_sim_lock_esim_instructions (4416732549172148542) -->
-    <skip />
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> ਮੋਬਾਈਲ ਸੇਵਾ ਤੋਂ ਬਿਨਾਂ ਡੀਵਾਈਸ ਨੂੰ ਵਰਤਣ ਲਈ ਈ-ਸਿਮ ਬੰਦ ਕਰੋ।"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"ਪਿੰਨ ਦਾਖਲ ਕਰੋ"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"ਪਾਸਵਰਡ ਦਾਖਲ ਕਰੋ"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"ਸਿਮ ਹੁਣ ਬੰਦ ਕੀਤਾ ਗਿਆ ਹੈ। ਜਾਰੀ ਰੱਖਣ ਲਈ PUK ਕੋਡ ਦਾਖਲ ਕਰੋ। ਵੇਰਵਿਆਂ ਲਈ ਕੈਰੀਅਰ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pl/strings.xml b/packages/SystemUI/res-keyguard/values-pl/strings.xml
index ee6ad62..471289a 100644
--- a/packages/SystemUI/res-keyguard/values-pl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pl/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Następny alarm ustawiony na: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Usuwanie"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Wyłącz eSIM"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"Nie można wyłączyć karty eSIM"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"Nie można wyłączyć karty eSIM z powodu błędu."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Nie pamiętam wzoru"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Nieprawidłowy wzór"</string>
@@ -67,7 +69,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Narysuj wzór"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Wpisz kod PIN karty SIM."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Wpisz kod PIN karty SIM „<xliff:g id="CARRIER">%1$s</xliff:g>”."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Wyłącz eSIM, by używać urządzenia bez usługi sieci komórkowej."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Wyłącz kartę eSIM, by używać urządzenia bez usługi sieci komórkowej."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Wpisz kod PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Wpisz hasło"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Karta SIM została wyłączona. Wpisz kod PUK, by przejść dalej. Skontaktuj się z operatorem, by uzyskać więcej informacji."</string>
@@ -91,10 +93,10 @@
     <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="2151286957817486128">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> próbowałeś nieprawidłowo odblokować telefon. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach użytkownik zostanie usunięty, co spowoduje skasowanie wszystkich danych użytkownika."</string>
     <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="5464020754932560928">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Użytkownik zostanie usunięty, co spowoduje skasowanie wszystkich danych użytkownika."</string>
     <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="6171564974118059">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowałeś nieprawidłowo odblokować telefon. Użytkownik zostanie usunięty, co spowoduje skasowanie wszystkich danych użytkownika."</string>
-    <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="9154513795928824239">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach profil do pracy zostanie usunięty, co spowoduje skasowanie wszystkich danych tego profilu."</string>
-    <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="2162434417489128282">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> próbowałeś nieprawidłowo odblokować telefon. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach profil do pracy zostanie usunięty, co spowoduje skasowanie wszystkich danych tego profilu."</string>
-    <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="8966727588974691544">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Profil do pracy zostanie usunięty, co spowoduje skasowanie wszystkich danych tego profilu."</string>
-    <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="8476407539834855">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowałeś nieprawidłowo odblokować telefon. Profil do pracy zostanie usunięty, co spowoduje skasowanie wszystkich danych tego profilu."</string>
+    <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="9154513795928824239">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach profil służbowy zostanie usunięty, co spowoduje skasowanie wszystkich danych tego profilu."</string>
+    <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="2162434417489128282">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> próbowałeś nieprawidłowo odblokować telefon. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach profil służbowy zostanie usunięty, co spowoduje skasowanie wszystkich danych tego profilu."</string>
+    <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="8966727588974691544">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Profil służbowy zostanie usunięty, co spowoduje skasowanie wszystkich danych tego profilu."</string>
+    <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="8476407539834855">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowałeś nieprawidłowo odblokować telefon. Profil służbowy zostanie usunięty, co spowoduje skasowanie wszystkich danych tego profilu."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="956706236554092172">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach konieczne będzie odblokowanie tabletu przy użyciu konta e-mail.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="8364140853305528449">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach konieczne będzie odblokowanie telefonu przy użyciu konta e-mail.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="3389829202093674267">"Nieprawidłowy kod PIN karty SIM. Musisz teraz skontaktować się z operatorem, by odblokował Twoje urządzenie."</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
index 73f2b7f..3369d45 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
@@ -82,7 +82,7 @@
     <string name="kg_login_too_many_attempts" msgid="6604574268387867255">"Demasiadas tentativas para desenhar o padrão"</string>
     <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8637788033282252027">"Introduziu o PIN incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7724148763268377734">"Introduziu a palavra-passe incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4820967667848302092">"Desenhou a sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4820967667848302092">"Desenhou a sua padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1629351522209932316">"Tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, este tablet será reposto, o que eliminará todos os dados do mesmo."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="3921998703529189931">"Tentou desbloquear incorretamente o telemóvel <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, este telemóvel será reposto, o que eliminará todos os dados do mesmo."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="4694232971224663735">"Tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER">%d</xliff:g> vezes. Este tablet será reposto, o que eliminará todos os dados do mesmo."</string>
@@ -95,8 +95,8 @@
     <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="2162434417489128282">"Tentou desbloquear incorretamente o telemóvel <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, o perfil de trabalho será removido, o que eliminará todos os dados do mesmo."</string>
     <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="8966727588974691544">"Tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER">%d</xliff:g> vezes. O perfil de trabalho será removido, o que eliminará todos os dados do mesmo."</string>
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="8476407539834855">"Tentou desbloquear incorretamente o telemóvel <xliff:g id="NUMBER">%d</xliff:g> vezes. O perfil de trabalho será removido, o que eliminará todos os dados do mesmo."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="956706236554092172">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, ser-lhe-á pedido para desbloquear o tablet através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="8364140853305528449">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, ser-lhe-á pedido para desbloquear o telemóvel através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="956706236554092172">"Desenhou o padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, ser-lhe-á pedido para desbloquear o tablet através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="8364140853305528449">"Desenhou o padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, ser-lhe-á pedido para desbloquear o telemóvel através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="3389829202093674267">"Código PIN do cartão SIM incorreto. Tem de contactar o seu operador para desbloquear o dispositivo."</string>
     <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="4314341367727055967">
       <item quantity="other">Código PIN do cartão SIM incorreto. Tem mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas.</item>
diff --git a/packages/SystemUI/res-keyguard/values-sk/strings.xml b/packages/SystemUI/res-keyguard/values-sk/strings.xml
index b69f502..bb74cd3 100644
--- a/packages/SystemUI/res-keyguard/values-sk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sk/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Nasledujúci budík je nastavený na <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Odstrániť"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Zakázať eSIM kartu"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"eSIM karta sa nedá deaktivovať"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"eSIM karta sa nedá deaktivovať, pretože sa vyskytla chyba."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Nepamätám si vzor"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Nesprávny vzor"</string>
@@ -67,7 +69,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Nakreslite svoj vzor"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Zadajte PIN pre SIM kartu"</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Zadajte kód PIN pre SIM kartu operátora <xliff:g id="CARRIER">%1$s</xliff:g>."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Zakážte eSIM kartu a používajte zariadenie bez mobilnej služby."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Zakážte eSIM kartu a používajte zariadenie bez mobilnej služby."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Zadajte kód PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Zadajte heslo"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM karta je teraz zakázaná. Ak chcete pokračovať, zadajte kód PUK. Podrobné informácie získate od operátora."</string>
diff --git a/packages/SystemUI/res-keyguard/values-sl/strings.xml b/packages/SystemUI/res-keyguard/values-sl/strings.xml
index cd53c6c..3443d66 100644
--- a/packages/SystemUI/res-keyguard/values-sl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sl/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Naslednji alarm je nastavljen za <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Izbris"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Onemogoči kartico e-SIM"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"Digitalne kartice e-SIM ni mogoče onemogočiti"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"Digitalne kartice e-SIM zaradi napake ni mogoče onemogočiti."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Tipka Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Pozabljen vzorec"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Napačen vzorec"</string>
@@ -67,7 +69,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Narišite vzorec"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Vnesite kodo PIN kartice SIM."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Vnesite kodo PIN kartice SIM operaterja »<xliff:g id="CARRIER">%1$s</xliff:g>«."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Onemogočite kartico e-SIM, če želite napravo uporabljati brez mobilne storitve."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Onemogočite digitalno kartico e-SIM, če želite napravo uporabljati brez mobilne storitve."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Vnesite kodo PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Vnesite geslo"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Kartica SIM je onemogočena. Če želite nadaljevati, vnesite kodo PUK. Za dodatne informacije se obrnite na operaterja."</string>
diff --git a/packages/SystemUI/res-keyguard/values-sq/strings.xml b/packages/SystemUI/res-keyguard/values-sq/strings.xml
index 0a55795..10b5430 100644
--- a/packages/SystemUI/res-keyguard/values-sq/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sq/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Alarmi tjetër i caktuar: <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Fshi"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Çaktivizo kartën eSIM"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"Karta eSIM nuk mund të çaktivizohet"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"Karta eSIM nuk mund të çaktivizohet për shkak të një gabimi."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Dërgo"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Harrova motivin"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Motivi është i gabuar"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Vizato motivin tënd"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Fut kodin PIN të kartës SIM"</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Fut kodin PIN të kartës SIM për \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Çaktivizo kartën eSIM për ta përdorur pajisjen pa shërbimin celular."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Çaktivizo kartën eSIM për ta përdorur pajisjen pa shërbimin celular."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Fut kodin PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Fut fjalëkalimin"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Karta SIM tani është e çaktivizuar. Fut kodin PUK për të vazhduar. Kontakto me operatorin për detaje."</string>
diff --git a/packages/SystemUI/res-keyguard/values-sr/strings.xml b/packages/SystemUI/res-keyguard/values-sr/strings.xml
index 08db0bd1..f9d5b77 100644
--- a/packages/SystemUI/res-keyguard/values-sr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sr/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Следећи аларм је подешен за <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Избриши"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Онемогући eSIM"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"Онемогућавање eSIM-а није успело"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"eSIM не може да се онемогући због грешке."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Заборавио/ла сам шаблон"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Погрешан шаблон"</string>
@@ -66,7 +68,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Нацртајте шаблон"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Унесите PIN за SIM."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Унесите PIN за SIM „<xliff:g id="CARRIER">%1$s</xliff:g>“."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Онемогућите eSIM да бисте уређај користили без мобилне услуге."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Онемогућите eSIM да бисте уређај користили без мобилне услуге."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Унесите PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Унесите лозинку"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM картица је сада онемогућена. Унесите PUK кôд да бисте наставили. Детаљне информације потражите од мобилног оператера."</string>
diff --git a/packages/SystemUI/res-keyguard/values-sv/strings.xml b/packages/SystemUI/res-keyguard/values-sv/strings.xml
index 54a1d0d..04c22a6 100644
--- a/packages/SystemUI/res-keyguard/values-sv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sv/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Nästa alarm är inställt på <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Radera"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Inaktivera eSIM"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"Det gick inte att inaktivera eSIM-kortet"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"Det gick inte att inaktivera eSIM-kortet på grund av ett fel."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Retur"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Har du glömt ditt grafiska lösenord?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Fel grafiskt lösenord"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Rita ditt grafiska lösenord"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Ange pinkod för SIM-kortet."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Ange pinkod för SIM-kortet för <xliff:g id="CARRIER">%1$s</xliff:g>."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Inaktivera eSIM om du vill använda enheten utan mobiltjänst."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Inaktivera eSIM om du vill använda enheten utan mobiltjänst."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Ange pinkod"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Ange lösenord"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-kortet har inaktiverats. Du måste ange en PUK-kod innan du kan fortsätta. Kontakta operatören för mer information."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ta/strings.xml b/packages/SystemUI/res-keyguard/values-ta/strings.xml
index 376c74f..5ba5692 100644
--- a/packages/SystemUI/res-keyguard/values-ta/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ta/strings.xml
@@ -53,10 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"அடுத்த அலாரம் <xliff:g id="ALARM">%1$s</xliff:g>க்கு அமைக்கப்பட்டுள்ளது"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"நீக்கும் பொத்தான்"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"இ-சிம்மை முடக்கும்"</string>
-    <!-- no translation found for error_disable_esim_title (4852978431156228006) -->
-    <skip />
-    <!-- no translation found for error_disable_esim_msg (676694908770135639) -->
-    <skip />
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"eSIMஐ முடக்க முடியவில்லை"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"பிழை ஏற்பட்டதால் eSIMஐ முடக்க முடியவில்லை."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"என்டர் பொத்தான்"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"பேட்டர்ன் நினைவில்லையா"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"தவறான பேட்டர்ன்"</string>
@@ -69,8 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"பேட்டர்னை வரையவும்"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"சிம் பின்னை உள்ளிடவும்."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\"க்கான சிம் பின்னை உள்ளிடவும்."</string>
-    <!-- no translation found for kg_sim_lock_esim_instructions (4416732549172148542) -->
-    <skip />
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> மொபைல் சேவை இல்லாமல் சாதனத்தைப் பயன்படுத்த, eSIMஐ முடக்கவும்."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"பின்னை உள்ளிடவும்"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"கடவுச்சொல்லை உள்ளிடவும்"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"சிம் தற்போது முடக்கப்பட்டுள்ளது. தொடர, PUK குறியீட்டை உள்ளிடவும். விவரங்களுக்கு, தொலைத்தொடர்பு நிறுவனத்தைத் தொடர்புகொள்ளவும்."</string>
diff --git a/packages/SystemUI/res-keyguard/values-te/strings.xml b/packages/SystemUI/res-keyguard/values-te/strings.xml
index 934d6a2..dce2739 100644
--- a/packages/SystemUI/res-keyguard/values-te/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-te/strings.xml
@@ -53,10 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"తర్వాత అలారం <xliff:g id="ALARM">%1$s</xliff:g>కి సెట్ చేయబడింది"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"తొలగించు"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIMని నిలిపివేయండి"</string>
-    <!-- no translation found for error_disable_esim_title (4852978431156228006) -->
-    <skip />
-    <!-- no translation found for error_disable_esim_msg (676694908770135639) -->
-    <skip />
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"eSIMని నిలపడం సాధ్యపడదు"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"ఎర్రర్ కారణంగా eSIMని నిలపడం సాధ్యపడదు."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"నమూనాను మర్చిపోయాను"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"ఆకృతి తప్పు"</string>
@@ -69,8 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"మీ నమూనాను గీయండి"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM పిన్‌ని నమోదు చేయండి."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" కోసం SIM పిన్‌ని నమోదు చేయండి."</string>
-    <!-- no translation found for kg_sim_lock_esim_instructions (4416732549172148542) -->
-    <skip />
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> మొబైల్ సేవ లేకుండా పరికరాన్ని ఉపయోగించడం కోసం eSIMని నిలిపివేయండి."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"పిన్‌ను నమోదు చేయండి"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"పాస్‌వర్డ్‌ని నమోదు చేయండి"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"ఇప్పుడు SIM నిలిపివేయబడింది. కొనసాగించాలంటే, PUK కోడ్‌ను నమోదు చేయండి. వివరాల కోసం క్యారియర్‌ను సంప్రదించండి."</string>
diff --git a/packages/SystemUI/res-keyguard/values-th/strings.xml b/packages/SystemUI/res-keyguard/values-th/strings.xml
index aa33421..ec50fe0 100644
--- a/packages/SystemUI/res-keyguard/values-th/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-th/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"ตั้งเวลาปลุกครั้งถัดไปไว้ที่ <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"ลบ"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"ปิดใช้ซิมอิเล็กทรอนิกส์"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"ปิดใช้ eSIM ไม่ได้"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"ปิดใช้ eSIM ไม่ได้เนื่องจากมีข้อผิดพลาด"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"ลืมรูปแบบ"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"รูปแบบไม่ถูกต้อง"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"วาดรูปแบบของคุณ"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"ป้อน PIN ของซิม"</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"ป้อน PIN ของซิมสำหรับ \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"ปิดใช้ซิมอิเล็กทรอนิกส์เพื่อใช้อุปกรณ์โดยไม่มีบริการมือถือ"</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> ปิดใช้ eSIM เพื่อใช้อุปกรณ์โดยไม่มีบริการมือถือ"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"ป้อน PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"ป้อนรหัสผ่าน"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"ซิมการ์ดถูกปิดใช้แล้ว ป้อนรหัส PUK เพื่อดำเนินการต่อ โปรดสอบถามรายละเอียดจากผู้ให้บริการ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-tl/strings.xml b/packages/SystemUI/res-keyguard/values-tl/strings.xml
index 30657d4..e6204db 100644
--- a/packages/SystemUI/res-keyguard/values-tl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tl/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Nakatakda ang susunod na alarm sa <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"I-delete"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"I-disable ang eSIM"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"Hindi ma-disable ang eSIM"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"Hindi ma-disable ang eSIM dahil sa isang error."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Nakalimutan ang Pattern"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Mali ang Pattern"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Iguhit ang iyong pattern"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Ilagay ang PIN ng SIM."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Ilagay ang PIN ng SIM para sa \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"I-disable ang eSIM upang magamit ang device nang walang serbisyo sa mobile."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> I-disable ang eSIM upang magamit ang device nang walang serbisyo sa mobile."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Ilagay ang PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Ilagay ang Password"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"Naka-disable na ngayon ang SIM. Ilagay ang PUK code upang magpatuloy. Makipag-ugnayan sa carrier para sa mga detalye."</string>
diff --git a/packages/SystemUI/res-keyguard/values-tr/strings.xml b/packages/SystemUI/res-keyguard/values-tr/strings.xml
index e716ee4..d2ba3c9 100644
--- a/packages/SystemUI/res-keyguard/values-tr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tr/strings.xml
@@ -53,10 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Sonraki alarm <xliff:g id="ALARM">%1$s</xliff:g> olarak ayarlandı"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Delete"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM\'i devre dışı bırak"</string>
-    <!-- no translation found for error_disable_esim_title (4852978431156228006) -->
-    <skip />
-    <!-- no translation found for error_disable_esim_msg (676694908770135639) -->
-    <skip />
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"eSIM devre dışı bırakılamıyor"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"Bir hata nedeniyle eSIM devre dışı bırakılamıyor."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Deseni unuttunuz mu?"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Yanlış Desen"</string>
@@ -69,8 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Deseninizi çizin"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"SIM PIN kodunu girin."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" için SIM PIN kodunu girin."</string>
-    <!-- no translation found for kg_sim_lock_esim_instructions (4416732549172148542) -->
-    <skip />
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Cihazı mobil hizmet olmadan kullanmak için eSIM\'i devre dışı bırakın."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"PIN\'i girin"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Şifreyi Girin"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM kart artık devre dışı bırakıldı. Devam etmek için PUK kodunu girin. Ayrıntılı bilgi için operatörle bağlantı kurun."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ur/strings.xml b/packages/SystemUI/res-keyguard/values-ur/strings.xml
index 28a52c0..877e566 100644
--- a/packages/SystemUI/res-keyguard/values-ur/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ur/strings.xml
@@ -53,10 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"اگلا الارم <xliff:g id="ALARM">%1$s</xliff:g> کیلئے سیٹ ہے"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"حذف کریں"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"‏eSIM غیر فعال کریں"</string>
-    <!-- no translation found for error_disable_esim_title (4852978431156228006) -->
-    <skip />
-    <!-- no translation found for error_disable_esim_msg (676694908770135639) -->
-    <skip />
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"‏eSIM کو غیر فعال نہیں کیا جا سکتا"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"‏ایک خرابی کی وجہ سے eSIM کو غیر فعال نہیں کیا جا سکتا۔"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"درج کریں"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"پیٹرن بھول گئے"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"غلط پیٹرن"</string>
@@ -69,8 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"اپنا پیٹرن ڈرا کریں"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"‏SIM PIN درج کریں۔"</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"‏\"<xliff:g id="CARRIER">%1$s</xliff:g>\" کیلئے SIM PIN درج کریں۔"</string>
-    <!-- no translation found for kg_sim_lock_esim_instructions (4416732549172148542) -->
-    <skip />
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"‏<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> موبائل سروس کے بغیر آلہ کا استعمال کرنے کیلئے eSIM غیر فعال کریں۔"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"‏PIN درج کریں"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"پاسورڈ درج کریں"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"‏SIM اب غیر فعال ہوگیا ہے۔ جاری رکھنے کیلئے PUK کوڈ درج کریں۔ تفصیلات کیلئے کیریئر سے رابطہ کریں۔"</string>
diff --git a/packages/SystemUI/res-keyguard/values-vi/strings.xml b/packages/SystemUI/res-keyguard/values-vi/strings.xml
index d20b87e..eb2607d 100644
--- a/packages/SystemUI/res-keyguard/values-vi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-vi/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Báo thức tiếp theo được đặt cho <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Xóa"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Vô hiệu hóa eSIM"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"Không thể tắt eSIM"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"Không thể tắt eSIM do lỗi."</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Nhập"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"Đã quên hình mở khóa"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"Hình mở khóa sai"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"Vẽ hình mở khóa của bạn"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"Nhập mã PIN của SIM."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Nhập mã PIN của SIM dành cho \"<xliff:g id="CARRIER">%1$s</xliff:g>\"."</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"Vô hiệu hóa eSIM để sử dụng thiết bị khi không có dịch vụ di động."</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Tắt eSIM để sử dụng thiết bị khi không có dịch vụ di động."</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"Nhập mã PIN"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"Nhập mật khẩu"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM hiện bị vô hiệu hóa. Hãy nhập mã PUK để tiếp tục. Liên hệ với nhà cung cấp dịch vụ để biết chi tiết."</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
index 8ee5812..c55f2d5 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"下一个闹钟时间已设置为<xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"删除"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"停用 eSIM 卡"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"无法停用 eSIM 卡"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"出现错误,无法停用 eSIM 卡。"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"输入"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"忘记了图案"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"图案错误"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"绘制您的图案"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"请输入 SIM 卡 PIN 码。"</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"请输入“<xliff:g id="CARRIER">%1$s</xliff:g>”的 SIM 卡 PIN 码。"</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"停用 eSIM 卡即可在没有移动服务的情况下使用设备。"</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g>停用 eSIM 卡即可在没有移动服务的情况下使用设备。"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"请输入 PIN 码"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"请输入密码"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM 卡现已停用,需要输入 PUK 码才能继续使用。要了解详情,请联系您的运营商。"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
index 5b0754e..07a4f43 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
@@ -53,6 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"已經將下一個鬧鐘時間設做<xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Delete 鍵 (刪除)"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"停用 eSIM"</string>
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"無法停用 eSIM 卡"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"發生錯誤,因此無法停用此 eSIM 卡。"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter 鍵 (輸入)"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"忘記上鎖圖案"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"上鎖圖案錯誤"</string>
@@ -65,7 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"畫出上鎖圖案"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"輸入 SIM 卡的 PIN 碼。"</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"輸入「<xliff:g id="CARRIER">%1$s</xliff:g>」SIM 卡的 PIN 碼。"</string>
-    <string name="kg_sim_lock_instructions_esim" msgid="4957650659201013804">"停用 eSIM,即可在沒有流動服務的情況下使用裝置。"</string>
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> 停用 eSIM 卡,即可在沒有流動服務的情況下使用裝置。"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"輸入 PIN 碼"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"輸入密碼"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM 卡現已停用,請輸入 PUK 碼以繼續。詳情請與流動網絡供應商聯絡。"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
index ee234cc..de2f73a 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
@@ -53,10 +53,8 @@
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"已設定下一個鬧鐘時間:<xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"刪除"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"停用 eSIM 卡"</string>
-    <!-- no translation found for error_disable_esim_title (4852978431156228006) -->
-    <skip />
-    <!-- no translation found for error_disable_esim_msg (676694908770135639) -->
-    <skip />
+    <string name="error_disable_esim_title" msgid="4852978431156228006">"無法停用 eSIM 卡"</string>
+    <string name="error_disable_esim_msg" msgid="676694908770135639">"發生錯誤,因此無法停用 eSIM 卡。"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter 鍵"</string>
     <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"忘記解鎖圖案"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"解鎖圖案錯誤"</string>
@@ -69,8 +67,7 @@
     <string name="kg_pattern_instructions" msgid="5547646893001491340">"畫出解鎖圖案"</string>
     <string name="kg_sim_pin_instructions" msgid="6389000973113699187">"輸入 SIM 卡的 PIN 碼。"</string>
     <string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"輸入「<xliff:g id="CARRIER">%1$s</xliff:g>」SIM 卡的 PIN 碼。"</string>
-    <!-- no translation found for kg_sim_lock_esim_instructions (4416732549172148542) -->
-    <skip />
+    <string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g>停用 eSIM 卡即可在沒有行動服務的情況下使用裝置。"</string>
     <string name="kg_pin_instructions" msgid="4069609316644030034">"輸入 PIN 碼"</string>
     <string name="kg_password_instructions" msgid="136952397352976538">"輸入密碼"</string>
     <string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM 卡已遭停用,輸入 PUK 碼即可繼續使用。如需瞭解詳情,請與電信業者聯絡。"</string>
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index 4934e14..1c1c757 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -60,8 +60,8 @@
     <dimen name="widget_horizontal_padding">8dp</dimen>
     <dimen name="widget_icon_size">16dp</dimen>
     <dimen name="widget_icon_padding">8dp</dimen>
-    <!-- Dash between notification shelf and date/alarm -->
-    <dimen name="widget_bottom_separator_padding">29dp</dimen>
+    <!-- Space between notification shelf and dash above it -->
+    <dimen name="widget_bottom_separator_padding">28dp</dimen>
 
     <!-- The y translation to apply at the start in appear animations. -->
     <dimen name="appear_y_translation_start">32dp</dimen>
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index 8a48e7b..02d0d70 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -57,15 +57,15 @@
 
     <!-- When the lock screen is showing and the phone plugged in, and the battery
          is not fully charged, say that it's charging.  -->
-    <string name="keyguard_plugged_in">Charging</string>
+    <string name="keyguard_plugged_in"><xliff:g id="percentage">%s</xliff:g> • Charging</string>
 
     <!-- When the lock screen is showing and the phone plugged in, and the battery
          is not fully charged, and it's plugged into a fast charger, say that it's charging fast.  -->
-    <string name="keyguard_plugged_in_charging_fast">Charging rapidly</string>
+    <string name="keyguard_plugged_in_charging_fast"><xliff:g id="percentage">%s</xliff:g> • Charging rapidly</string>
 
     <!-- When the lock screen is showing and the phone plugged in, and the battery
          is not fully charged, and it's plugged into a slow charger, say that it's charging slowly.  -->
-    <string name="keyguard_plugged_in_charging_slowly">Charging slowly</string>
+    <string name="keyguard_plugged_in_charging_slowly"><xliff:g id="percentage">%s</xliff:g> • Charging slowly</string>
 
     <!-- When the lock screen is showing and the battery is low, warn user to plug
          in the phone soon. -->
diff --git a/packages/SystemUI/res/color/white_disabled.xml b/packages/SystemUI/res/color/white_disabled.xml
new file mode 100644
index 0000000..617e232
--- /dev/null
+++ b/packages/SystemUI/res/color/white_disabled.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="@android:color/white"
+          android:alpha="?android:attr/disabledAlpha" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/brightness_mirror_background.xml b/packages/SystemUI/res/drawable/brightness_mirror_background.xml
index b3a0484..43c9b73 100644
--- a/packages/SystemUI/res/drawable/brightness_mirror_background.xml
+++ b/packages/SystemUI/res/drawable/brightness_mirror_background.xml
@@ -16,4 +16,5 @@
   -->
 <shape xmlns:android="http://schemas.android.com/apk/res/android">
     <solid android:color="@color/qs_background_dark" />
+    <corners android:radius="8dp" />
 </shape>
diff --git a/packages/SystemUI/res/drawable/brightness_progress_drawable.xml b/packages/SystemUI/res/drawable/brightness_progress_drawable.xml
new file mode 100644
index 0000000..45d8dc1
--- /dev/null
+++ b/packages/SystemUI/res/drawable/brightness_progress_drawable.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@android:id/background"
+          android:gravity="center_vertical|fill_horizontal">
+        <shape android:shape="rectangle"
+               android:tint="?android:attr/colorControlActivated">
+            <size android:height="@dimen/seek_bar_height" />
+            <solid android:color="@color/white_disabled" />
+            <corners android:radius="@dimen/seek_bar_corner_radius" />
+        </shape>
+    </item>
+    <item android:id="@android:id/progress"
+          android:gravity="center_vertical|fill_horizontal">
+        <scale android:scaleWidth="100%">
+            <shape android:shape="rectangle"
+                   android:tint="?android:attr/colorControlActivated">
+                <size android:height="@dimen/seek_bar_height" />
+                <solid android:color="@android:color/white" />
+                <corners android:radius="@dimen/seek_bar_corner_radius" />
+            </shape>
+        </scale>
+    </item>
+</layer-list>
diff --git a/packages/SystemUI/res/drawable/ic_brightness_thumb.xml b/packages/SystemUI/res/drawable/ic_brightness_thumb.xml
index beedcbb..8281836 100644
--- a/packages/SystemUI/res/drawable/ic_brightness_thumb.xml
+++ b/packages/SystemUI/res/drawable/ic_brightness_thumb.xml
@@ -14,14 +14,14 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="28.0dp"
-        android:height="28.0dp"
+        android:width="24dp"
+        android:height="24dp"
         android:viewportWidth="24.0"
         android:viewportHeight="24.0">
     <path
         android:pathData="m18.250000,12.000000a6.250000,6.250000 0.000000,1.000000 1.000000,-12.500000 0.000000,6.250000 6.250000,0.000000 1.000000,1.000000 12.500000,0.000000z"
-        android:fillColor="?android:attr/colorPrimary" />
+        android:fillColor="@android:color/transparent" />
     <path
         android:pathData="M20,8.69L20,5c0,-0.55 -0.45,-1 -1,-1h-3.69l-2.6,-2.6a0.996,0.996 0,0 0,-1.41 0L8.69,4L5,4c-0.55,0 -1,0.45 -1,1v3.69l-2.6,2.6a0.996,0.996 0,0 0,0 1.41L4,15.3L4,19c0,0.55 0.45,1 1,1h3.69l2.6,2.6c0.39,0.39 1.02,0.39 1.41,0l2.6,-2.6L19,20c0.55,0 1,-0.45 1,-1v-3.69l2.6,-2.6a0.996,0.996 0,0 0,0 -1.41L20,8.69zM12,18.08c-3.36,0 -6.08,-2.73 -6.08,-6.08S8.64,5.92 12,5.92s6.08,2.73 6.08,6.08 -2.72,6.08 -6.08,6.08zM12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4z"
-        android:fillColor="?android:attr/colorControlNormal" />
+        android:fillColor="?android:attr/colorControlActivated" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml b/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml
index 255e377..93df340 100644
--- a/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml
+++ b/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml
@@ -14,104 +14,110 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-                 xmlns:aapt="http://schemas.android.com/aapt">
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
     <aapt:attr name="android:drawable">
-        <vector android:height="24dp"
+        <vector android:name="root"
                 android:width="24dp"
-                android:viewportHeight="102"
-                android:viewportWidth="102"
-                android:tint="?attr/singleToneColor">
-            <group android:name="_R_G">
-                <group android:name="_R_G_L_0_G" android:translateX="53.086" android:translateY="48.907000000000004" android:pivotX="-2.083" android:pivotY="2.083" android:rotation="90">
-                    <group android:name="_R_G_L_0_G_D_0_P_0_G_0_T_0" android:rotation="100.1" android:scaleX="0.7979999999999999" android:scaleY="0.7979999999999999">
-                        <path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M17.15 -37.84 C30.19,-31.91 39.52,-19.62 41.9,-4.86 C42.15,-3.39 43.45,-2.31 44.95,-2.31 C46.88,-2.31 48.34,-4.06 48.05,-5.94 C44.37,-27.64 27.64,-45.91 0.84,-48.09 C-1.08,-48.25 -2.17,-45.91 -0.83,-44.53 C-0.83,-44.53 9.87,-33.83 9.87,-33.83 C10.67,-33.04 11.92,-33.04 12.76,-33.79 C12.76,-33.79 17.15,-37.84 17.15,-37.84c "/>
-                    </group>
-                    <group android:name="_R_G_L_0_G_D_1_P_0_G_0_T_0" android:rotation="87.2" android:scaleX="0.77" android:scaleY="0.77">
-                        <path android:name="_R_G_L_0_G_D_1_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-21.32 42.01 C-34.36,36.07 -43.68,23.78 -46.07,9.02 C-46.33,7.55 -47.62,6.47 -49.12,6.47 C-51.04,6.47 -52.51,8.23 -52.21,10.11 C-48.53,31.81 -31.81,50.08 -5.01,52.25 C-3.09,52.42 -2,50.08 -3.34,48.7 C-3.34,48.7 -14.04,38 -14.04,38 C-14.84,37.21 -16.11,37.19 -16.93,37.96 C-16.93,37.96 -21.32,42.01 -21.32,42.01c "/>
-                    </group>
-                    <path android:name="_R_G_L_0_G_D_2_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M40.77 9.4 C40.77,9.4 -9.4,-40.77 -9.4,-40.77 C-11.91,-43.28 -15.67,-43.28 -18.18,-40.77 C-18.18,-40.77 -44.94,-14.01 -44.94,-14.01 C-47.45,-11.5 -47.45,-7.74 -44.94,-5.23 C-44.94,-5.23 5.23,44.94 5.23,44.94 C7.74,47.45 11.51,47.45 14.01,44.94 C14.01,44.94 40.77,18.18 40.77,18.18 C43.28,15.67 43.28,11.91 40.77,9.4c  M3.85 34.82 C3.85,34.82 -34.4,-3.44 -34.4,-3.44 C-34.4,-3.44 -7.64,-30.19 -7.64,-30.19 C-7.64,-30.19 30.61,8.06 30.61,8.06 C30.61,8.06 3.85,34.82 3.85,34.82c "/>
-                </group>
+                android:height="24dp"
+                android:viewportWidth="24.0"
+                android:viewportHeight="24.0">
+            <group android:name="icon" android:pivotX="12" android:pivotY="12">
+                <!-- Tint color to be set directly -->
+                <path android:fillColor="#FFFFFFFF"
+                      android:pathData="M17,1.01L7,1c-1.1,0 -2,0.9 -2,2v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3c0,-1.1 -0.9,-1.99 -2,-1.99zM17,19H7V5h10v14z"/>
             </group>
-            <group android:name="time_group"/>
         </vector>
     </aapt:attr>
 
-    <target android:name="_R_G_L_0_G_D_0_P_0_G_0_T_0">
+    <!-- Repeat all animations 3 times but don't fade out at the end -->
+    <target android:name="root">
         <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="rotation" android:duration="333" android:startOffset="0" android:valueFrom="100.1" android:valueTo="0" android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
+            <set android:ordering="sequentially">
+                <!-- Linear fade in-->
+                <objectAnimator android:propertyName="alpha"
+                                android:duration="100"
+                                android:valueFrom="0"
+                                android:valueTo="1"
+                                android:interpolator="@android:anim/linear_interpolator" />
+                <!-- Linear fade out -->
+                <objectAnimator android:propertyName="alpha"
+                                android:duration="100"
+                                android:startOffset="1700"
+                                android:valueFrom="1"
+                                android:valueTo="0"
+                                android:interpolator="@android:anim/linear_interpolator"/>
+                <!-- Linear fade in-->
+                <objectAnimator android:propertyName="alpha"
+                                android:duration="100"
+                                android:startOffset="100"
+                                android:valueFrom="0"
+                                android:valueTo="1"
+                                android:interpolator="@android:anim/linear_interpolator" />
+                <!-- Linear fade out -->
+                <objectAnimator android:propertyName="alpha"
+                                android:duration="100"
+                                android:startOffset="1700"
+                                android:valueFrom="1"
+                                android:valueTo="0"
+                                android:interpolator="@android:anim/linear_interpolator"/>
+                <!-- Linear fade in-->
+                <objectAnimator android:propertyName="alpha"
+                                android:duration="100"
+                                android:startOffset="100"
+                                android:valueFrom="0"
+                                android:valueTo="1"
+                                android:interpolator="@android:anim/linear_interpolator" />
             </set>
         </aapt:attr>
     </target>
-
-    <target android:name="_R_G_L_0_G_D_0_P_0_G_0_T_0">
+    <target android:name="icon">
         <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="scaleX" android:duration="333" android:startOffset="0" android:valueFrom="0.798" android:valueTo="1" android:valueType="floatType">
+            <set android:ordering="sequentially">
+                <!-- Icon rotation with start timing offset after fade in -->
+                <objectAnimator android:propertyName="rotation"
+                                android:startOffset="100"
+                                android:duration="600"
+                                android:valueFrom="?attr/rotateButtonStartAngle"
+                                android:valueTo="?attr/rotateButtonEndAngle">
                     <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.667,1 1.0,1.0"/>
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator android:propertyName="scaleY" android:duration="333" android:startOffset="0" android:valueFrom="0.798" android:valueTo="1" android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.667,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
 
-    <target android:name="_R_G_L_0_G_D_1_P_0_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="rotation" android:duration="333" android:startOffset="0" android:valueFrom="87.2" android:valueTo="0" android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
+                <!-- Reset rotation position for fade in -->
+                <objectAnimator android:propertyName="rotation"
+                                android:startOffset="1300"
+                                android:duration="100"
+                                android:valueFrom="?attr/rotateButtonStartAngle"
+                                android:valueTo="?attr/rotateButtonStartAngle"/>
 
-    <target android:name="_R_G_L_0_G_D_1_P_0_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="scaleX" android:duration="333" android:startOffset="0" android:valueFrom="0.77" android:valueTo="1" android:valueType="floatType">
+                <!-- Icon rotation with start timing offset after fade in -->
+                <objectAnimator android:propertyName="rotation"
+                                android:duration="600"
+                                android:valueFrom="?attr/rotateButtonStartAngle"
+                                android:valueTo="?attr/rotateButtonEndAngle">
                     <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.667,1 1.0,1.0"/>
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator android:propertyName="scaleY" android:duration="333" android:startOffset="0" android:valueFrom="0.77" android:valueTo="1" android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.667,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
 
-    <target android:name="_R_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="rotation" android:duration="333" android:startOffset="0" android:valueFrom="90" android:valueTo="0" android:valueType="floatType">
+                <!-- Reset rotation position for fade in -->
+                <objectAnimator android:propertyName="rotation"
+                                android:startOffset="1300"
+                                android:duration="100"
+                                android:valueFrom="?attr/rotateButtonStartAngle"
+                                android:valueTo="?attr/rotateButtonStartAngle"/>
+
+                <!-- Icon rotation with start timing offset after fade in -->
+                <objectAnimator android:propertyName="rotation"
+                                android:duration="600"
+                                android:valueFrom="?attr/rotateButtonStartAngle"
+                                android:valueTo="?attr/rotateButtonEndAngle">
                     <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
             </set>
         </aapt:attr>
     </target>
-
-    <target android:name="time_group">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="translateX" android:duration="517" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
-            </set>
-        </aapt:attr>
-    </target>
 </animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/rounded_bg_bottom_background.xml b/packages/SystemUI/res/drawable/rounded_bg_bottom_background.xml
new file mode 100644
index 0000000..8d03ce7
--- /dev/null
+++ b/packages/SystemUI/res/drawable/rounded_bg_bottom_background.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <solid android:color="@*android:color/material_grey_200" />
+    <corners
+        android:bottomLeftRadius="@dimen/corner_size"
+        android:topLeftRadius="0dp"
+        android:bottomRightRadius="@dimen/corner_size"
+        android:topRightRadius="0dp"
+        />
+</shape>
diff --git a/packages/SystemUI/res/layout/brightness_mirror.xml b/packages/SystemUI/res/layout/brightness_mirror.xml
index d6e7507..e3440b5 100644
--- a/packages/SystemUI/res/layout/brightness_mirror.xml
+++ b/packages/SystemUI/res/layout/brightness_mirror.xml
@@ -14,19 +14,19 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
   -->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/brightness_mirror"
     android:layout_width="@dimen/qs_panel_width"
-    android:layout_height="wrap_content"
+    android:layout_height="@dimen/brightness_mirror_height"
     android:layout_gravity="@integer/notification_panel_layout_gravity"
     android:visibility="invisible">
     <FrameLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:background="@drawable/brightness_mirror_background"
-        android:elevation="2dp">
-        <include layout="@layout/quick_settings_brightness_dialog"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"/>
+        android:layout_marginLeft="@dimen/notification_side_paddings"
+        android:layout_marginRight="@dimen/notification_side_paddings"
+        android:background="@drawable/brightness_mirror_background">
+        <include layout="@layout/quick_settings_brightness_dialog" />
     </FrameLayout>
 </FrameLayout>
diff --git a/packages/SystemUI/res/layout/car_left_navigation_bar.xml b/packages/SystemUI/res/layout/car_left_navigation_bar.xml
index 866b5a5..18301a8 100644
--- a/packages/SystemUI/res/layout/car_left_navigation_bar.xml
+++ b/packages/SystemUI/res/layout/car_left_navigation_bar.xml
@@ -51,7 +51,7 @@
             android:id="@+id/hvac"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
-            systemui:intent="intent:#Intent;action=android.car.intent.action.SHOW_HVAC_CONTROLS;end"
+            systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
             systemui:broadcast="true"
             android:src="@drawable/car_ic_hvac"
             android:background="?android:attr/selectableItemBackground"
diff --git a/packages/SystemUI/res/layout/car_navigation_bar.xml b/packages/SystemUI/res/layout/car_navigation_bar.xml
index 4666c60..9ff16a2 100644
--- a/packages/SystemUI/res/layout/car_navigation_bar.xml
+++ b/packages/SystemUI/res/layout/car_navigation_bar.xml
@@ -49,7 +49,7 @@
             android:id="@+id/hvac"
             android:layout_height="match_parent"
             android:layout_width="wrap_content"
-            systemui:intent="intent:#Intent;action=android.car.intent.action.SHOW_HVAC_CONTROLS;end"
+            systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
             systemui:broadcast="true"
             android:src="@drawable/car_ic_hvac"
             android:background="?android:attr/selectableItemBackground"
diff --git a/packages/SystemUI/res/layout/car_right_navigation_bar.xml b/packages/SystemUI/res/layout/car_right_navigation_bar.xml
index 99ab802..99bd23c 100644
--- a/packages/SystemUI/res/layout/car_right_navigation_bar.xml
+++ b/packages/SystemUI/res/layout/car_right_navigation_bar.xml
@@ -51,7 +51,7 @@
             android:id="@+id/hvac"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
-            systemui:intent="intent:#Intent;action=android.car.intent.action.SHOW_HVAC_CONTROLS;end"
+            systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
             systemui:broadcast="true"
             android:src="@drawable/car_ic_hvac"
             android:background="?android:attr/selectableItemBackground"
diff --git a/packages/SystemUI/res/layout/output_chooser.xml b/packages/SystemUI/res/layout/output_chooser.xml
deleted file mode 100644
index b9f7b15..0000000
--- a/packages/SystemUI/res/layout/output_chooser.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT 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 LinearLayout -->
-<com.android.systemui.HardwareUiLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_marginBottom="0dp"
-    android:clipToPadding="false"
-    android:theme="@style/qs_theme"
-    android:clipChildren="false">
-    <com.android.systemui.volume.OutputChooserLayout
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        xmlns:sysui="http://schemas.android.com/apk/res-auto"
-        android:id="@+id/output_chooser"
-        android:layout_width="@dimen/output_chooser_panel_width"
-        android:layout_height="@dimen/output_chooser_panel_width"
-        android:layout_gravity="center_vertical|end"
-        android:orientation="vertical"
-        android:translationZ="8dp"
-        android:padding="20dp" >
-
-        <TextView
-            android:id="@+id/title"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:textDirection="locale"
-            android:textAppearance="@style/TextAppearance.QS.DetailHeader"
-            android:layout_marginBottom="20dp" />
-
-        <com.android.systemui.qs.AutoSizingList
-            android:id="@android:id/list"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:orientation="vertical"
-            sysui:itemHeight="@dimen/qs_detail_item_height"
-            style="@style/AutoSizingList"/>
-
-        <LinearLayout
-            android:id="@android:id/empty"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_gravity="center"
-            android:gravity="center"
-            android:orientation="vertical">
-
-            <TextView
-                android:id="@+id/empty_text"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:textDirection="locale"
-                android:layout_marginTop="20dp"
-                android:textAppearance="@style/TextAppearance.QS.DetailEmpty"/>
-        </LinearLayout>
-    </com.android.systemui.volume.OutputChooserLayout>
-</com.android.systemui.HardwareUiLayout>
diff --git a/packages/SystemUI/res/layout/output_chooser_item.xml b/packages/SystemUI/res/layout/output_chooser_item.xml
deleted file mode 100644
index c3ddbbe..0000000
--- a/packages/SystemUI/res/layout/output_chooser_item.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT 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:minHeight="@dimen/qs_detail_item_height"
-              android:background="@drawable/btn_borderless_rect"
-              android:clickable="true"
-              android:focusable="true"
-              android:gravity="center_vertical"
-              android:orientation="horizontal" >
-
-    <ImageView
-        android:id="@android:id/icon"
-        android:layout_width="@dimen/qs_detail_item_icon_width"
-        android:layout_height="@dimen/qs_detail_item_icon_size"
-        android:layout_marginStart="@dimen/qs_detail_item_icon_marginStart"
-        android:layout_marginEnd="@dimen/qs_detail_item_icon_marginEnd"
-        android:background="?android:selectableItemBackgroundBorderless"
-        android:tint="?android:attr/textColorPrimary"/>
-
-    <LinearLayout
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="12dp"
-        android:layout_weight="1"
-        android:orientation="vertical" >
-
-        <TextView
-            android:id="@android:id/title"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:textDirection="locale"
-            android:ellipsize="end"
-            android:textAppearance="@style/TextAppearance.QS.DetailItemPrimary" />
-
-        <TextView
-            android:id="@android:id/summary"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:textDirection="locale"
-            android:layout_marginTop="2dp"
-            android:textAppearance="@style/TextAppearance.QS.DetailItemSecondary" />
-    </LinearLayout>
-
-    <ImageView
-        android:id="@android:id/icon2"
-        style="@style/QSBorderlessButton"
-        android:layout_width="48dp"
-        android:layout_height="48dp"
-        android:layout_marginStart="30dp"
-        android:clickable="true"
-        android:focusable="true"
-        android:scaleType="center"
-        android:contentDescription="@*android:string/media_route_controller_disconnect"
-        android:tint="?android:attr/textColorPrimary" />
-
-</LinearLayout>
diff --git a/packages/SystemUI/res/layout/qs_footer_impl.xml b/packages/SystemUI/res/layout/qs_footer_impl.xml
index f635b18..3c24845 100644
--- a/packages/SystemUI/res/layout/qs_footer_impl.xml
+++ b/packages/SystemUI/res/layout/qs_footer_impl.xml
@@ -43,40 +43,24 @@
         android:layout_gravity="center_vertical"
         android:gravity="end" >
 
-        <LinearLayout
-            android:layout_width="0dp"
-            android:layout_height="match_parent"
-            android:layout_weight="1" >
-            <!-- Add an extra 8dp margin before carrier text without shifting it right -->
-            <android.widget.Space
-                android:layout_width="8dp"
-                android:layout_height="match_parent" />
-
-            <com.android.keyguard.CarrierText
-                android:id="@+id/qs_carrier_text"
-                android:layout_width="0dp"
-                android:layout_height="match_parent"
-                android:layout_weight="1"
-                android:gravity="center_vertical|start"
-                android:ellipsize="marquee"
-                android:textAppearance="?android:attr/textAppearanceSmall"
-                android:textColor="?android:attr/textColorPrimary"
-                android:textDirection="locale"
-                android:singleLine="true" />
-        </LinearLayout>
-
-        <View
-            android:id="@+id/qs_drag_handle_view"
-            android:layout_width="24dp"
-            android:layout_height="4dp"
-            android:layout_gravity="center"
-            android:background="@drawable/qs_footer_drag_handle" />
-
-        <com.android.keyguard.AlphaOptimizedLinearLayout
-            android:id="@+id/qs_footer_actions_container"
+        <com.android.keyguard.CarrierText
+            android:id="@+id/qs_carrier_text"
             android:layout_width="0dp"
             android:layout_height="match_parent"
             android:layout_weight="1"
+            android:layout_marginStart="8dp"
+            android:layout_marginEnd="32dp"
+            android:gravity="center_vertical|start"
+            android:ellipsize="marquee"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textColor="?android:attr/textColorPrimary"
+            android:textDirection="locale"
+            android:singleLine="true" />
+
+        <com.android.keyguard.AlphaOptimizedLinearLayout
+            android:id="@+id/qs_footer_actions_container"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
             android:gravity="center_vertical|end" >
             <com.android.systemui.statusbar.phone.MultiUserSwitch
                 android:id="@+id/multi_user_switch"
@@ -139,4 +123,11 @@
         </com.android.keyguard.AlphaOptimizedLinearLayout>
     </LinearLayout>
 
+    <View
+        android:id="@+id/qs_drag_handle_view"
+        android:layout_width="24dp"
+        android:layout_height="4dp"
+        android:layout_gravity="center"
+        android:background="@drawable/qs_footer_drag_handle" />
+
 </com.android.systemui.qs.QSFooterImpl>
diff --git a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
index 080f553..2efae71 100644
--- a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
+++ b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
@@ -15,8 +15,9 @@
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
-    android:layout_height="48dp"
+    android:layout_height="wrap_content"
     android:layout_width="match_parent"
+    android:layout_gravity="center_vertical"
     android:paddingLeft="16dp"
     android:paddingRight="16dp"
     style="@style/BrightnessDialogContainer">
@@ -34,7 +35,7 @@
     <com.android.systemui.settings.ToggleSliderView
         android:id="@+id/brightness_slider"
         android:layout_width="0dp"
-        android:layout_height="wrap_content"
+        android:layout_height="48dp"
         android:layout_gravity="center_vertical"
         android:layout_weight="1"
         android:contentDescription="@string/accessibility_brightness"
diff --git a/packages/SystemUI/res/layout/quick_settings_header_info.xml b/packages/SystemUI/res/layout/quick_settings_header_info.xml
new file mode 100644
index 0000000..89d6e99
--- /dev/null
+++ b/packages/SystemUI/res/layout/quick_settings_header_info.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2018 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/header_text_container"
+    android:layout_width="match_parent"
+    android:layout_height="@dimen/qs_header_tooltip_height"
+    android:layout_below="@id/quick_status_bar_system_icons"
+    android:layout_marginTop="12dp">
+
+    <TextView
+        android:id="@+id/long_press_tooltip"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_horizontal|bottom"
+        android:alpha="0"
+        android:text="@string/quick_settings_header_onboarding_text"
+        android:textAppearance="@style/TextAppearance.QS.TileLabel"
+        android:textColor="?android:attr/colorAccent"
+        android:visibility="invisible" />
+
+    <LinearLayout
+        android:id="@+id/next_alarm"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_horizontal|bottom"
+        android:gravity="center_vertical"
+        android:visibility="invisible">
+
+        <ImageView
+            android:layout_width="@dimen/qs_header_alarm_icon_size"
+            android:layout_height="@dimen/qs_header_alarm_icon_size"
+            android:src="@drawable/stat_sys_alarm"
+            android:tint="?android:attr/textColorPrimary" />
+
+        <TextView
+            android:id="@+id/next_alarm_text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="@dimen/qs_header_alarm_text_margin_start"
+            android:textAppearance="@style/TextAppearance.QS.TileLabel" />
+
+    </LinearLayout>
+
+</FrameLayout>
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 cc79d0d..ca8fcba 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
@@ -32,13 +32,20 @@
     android:elevation="4dp" >
 
     <include layout="@layout/quick_status_bar_header_system_icons" />
+
+    <!-- Status icons within the panel itself (and not in the top-most status bar) -->
     <include layout="@layout/quick_qs_status_icons" />
 
+    <!-- Layout containing tooltips, alarm text, etc. -->
+    <include layout="@layout/quick_settings_header_info" />
+
     <com.android.systemui.qs.QuickQSPanel
         android:id="@+id/quick_qs_panel"
         android:layout_width="match_parent"
         android:layout_height="48dp"
         android:layout_below="@id/quick_qs_status_icons"
+        android:layout_marginStart="@dimen/qs_header_tile_margin_horizontal"
+        android:layout_marginEnd="@dimen/qs_header_tile_margin_horizontal"
         android:accessibilityTraversalAfter="@+id/date_time_group"
         android:accessibilityTraversalBefore="@id/expand_indicator"
         android:clipChildren="false"
diff --git a/packages/SystemUI/res/layout/rotate_suggestion.xml b/packages/SystemUI/res/layout/rotate_suggestion.xml
deleted file mode 100644
index 5074682..0000000
--- a/packages/SystemUI/res/layout/rotate_suggestion.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<com.android.systemui.statusbar.policy.KeyButtonView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/rotate_suggestion"
-    android:layout_width="@dimen/navigation_extra_key_width"
-    android:layout_height="match_parent"
-    android:layout_marginEnd="2dp"
-    android:visibility="invisible"
-    android:scaleType="centerInside"
-    android:contentDescription="@string/accessibility_rotate_button"
-/>
diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml
index 4614999..2e7ab7f 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml
@@ -15,6 +15,7 @@
     limitations under the License.
 -->
 
+<!-- extends FrameLayout -->
 <com.android.systemui.statusbar.ExpandableNotificationRow
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
@@ -54,6 +55,7 @@
         android:paddingStart="8dp"
         />
 
+    <!-- TODO: remove -->
     <ImageButton
         android:id="@+id/helper"
         android:layout_width="48dp"
@@ -64,7 +66,7 @@
         android:tint="#FF0000"
         android:background="@drawable/ripple_drawable"
         android:visibility="visible"
-        />
+    />
 
     <ViewStub
         android:layout="@layout/notification_children_container"
diff --git a/packages/SystemUI/res/layout/status_bar_toggle_slider.xml b/packages/SystemUI/res/layout/status_bar_toggle_slider.xml
index 062e6cb..942f3dd 100644
--- a/packages/SystemUI/res/layout/status_bar_toggle_slider.xml
+++ b/packages/SystemUI/res/layout/status_bar_toggle_slider.xml
@@ -16,10 +16,7 @@
 -->
 
 <!--    android:background="@drawable/status_bar_closed_default_background" -->
-<merge
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
-    >
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
     <CheckBox
         android:id="@+id/toggle"
         android:layout_width="48dp"
@@ -44,6 +41,7 @@
         android:paddingTop="16dp"
         android:paddingBottom="16dp"
         android:thumb="@drawable/ic_brightness_thumb"
+        android:progressDrawable="@drawable/brightness_progress_drawable"
         android:splitTrack="false"
         />
     <TextView
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 803659f..b6d241b 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -23,79 +23,70 @@
     <!-- right-aligned to be physically near volume button -->
     <LinearLayout
         android:id="@+id/volume_dialog"
+        android:minWidth="@dimen/volume_dialog_panel_width"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical|right"
-        android:minWidth="@dimen/volume_dialog_panel_width"
         android:background="@android:color/transparent"
         android:layout_margin="@dimen/volume_dialog_base_margin"
         android:orientation="vertical"
         android:clipChildren="false" >
 
-        <LinearLayout
-            android:id="@+id/volume_dialog_rows"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:clipChildren="false"
-            android:clipToPadding="false"
-            android:background="@drawable/rounded_bg_full"
-            android:translationZ="@dimen/volume_panel_elevation"
-            android:orientation="horizontal" >
-                <!-- volume rows added and removed here! :-) -->
-        </LinearLayout>
-
         <FrameLayout
-            android:id="@+id/footer"
-            android:layout_width="@dimen/volume_dialog_panel_width"
-            android:layout_height="@dimen/volume_dialog_panel_width"
-            android:layout_marginTop="6dp"
-            android:layout_marginBottom="6dp"
-            android:layout_below="@id/volume_dialog_rows"
+            android:id="@+id/ringer"
+            android:layout_width="@dimen/volume_dialog_ringer_size"
+            android:layout_height="@dimen/volume_dialog_ringer_size"
+            android:layout_marginBottom="@dimen/volume_dialog_spacer"
+            android:elevation="@dimen/volume_panel_elevation"
+            android:layout_gravity="right"
             android:background="@drawable/rounded_bg_full">
-
-            <LinearLayout
-                android:id="@+id/footer_linear_layout"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:clipChildren="false"
-                android:clipToPadding="false"
-                android:gravity="center"
-                android:layout_gravity="end"
-                android:translationZ="@dimen/volume_panel_elevation"
-                android:clickable="true"
-                android:orientation="vertical" >
-
-                <TextView
-                    android:id="@+id/ringer_title"
-                    android:text="@string/ring_toggle_title"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:ellipsize="end"
-                    android:maxLines="1"
-                    android:layout_centerVertical="true"
-                    android:textColor="?android:attr/colorControlNormal"
-                    android:textAppearance="@style/TextAppearance.Volume.Header" />
-
-                <com.android.keyguard.AlphaOptimizedImageButton
-                    android:id="@+id/ringer_icon"
-                    style="@style/VolumeButtons"
-                    android:background="?android:selectableItemBackgroundBorderless"
-                    android:layout_width="@dimen/volume_dialog_panel_width"
-                    android:layout_height="@dimen/volume_button_size"
-                    android:tint="@color/accent_tint_color_selector"
-                    android:soundEffectsEnabled="false" />
-
-                <TextView
-                    android:id="@+id/ringer_status"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:ellipsize="end"
-                    android:maxLines="1"
-                    android:textColor="?android:attr/colorControlNormal"
-                    android:textAppearance="@style/TextAppearance.Volume.Header.Secondary" />
-            </LinearLayout>
+            <com.android.keyguard.AlphaOptimizedImageButton
+                android:id="@+id/ringer_icon"
+                style="@style/VolumeButtons"
+                android:background="?android:selectableItemBackgroundBorderless"
+                android:layout_width="@dimen/volume_dialog_tap_target_size"
+                android:layout_height="@dimen/volume_dialog_tap_target_size"
+                android:tint="@color/accent_tint_color_selector"
+                android:layout_gravity="center"
+                android:soundEffectsEnabled="false" />
 
             <include layout="@layout/volume_dnd_icon"/>
         </FrameLayout>
+
+        <LinearLayout
+            android:id="@+id/main"
+            android:layout_width="wrap_content"
+            android:minWidth="@dimen/volume_dialog_panel_width"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            android:clipChildren="false"
+            android:clipToPadding="false"
+            android:background="@drawable/rounded_bg_full"
+            android:elevation="@dimen/volume_panel_elevation" >
+            <LinearLayout
+                android:id="@+id/volume_dialog_rows"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:minWidth="@dimen/volume_dialog_panel_width"
+                android:gravity="center"
+                android:orientation="horizontal" >
+                    <!-- volume rows added and removed here! :-) -->
+            </LinearLayout>
+            <FrameLayout
+                android:layout_height="wrap_content"
+                android:layout_width="match_parent"
+                android:background="@drawable/rounded_bg_bottom_background">
+                <com.android.keyguard.AlphaOptimizedImageButton
+                    android:id="@+id/settings"
+                    android:src="@drawable/ic_settings"
+                    android:layout_width="@dimen/volume_dialog_tap_target_size"
+                    android:layout_height="@dimen/volume_dialog_tap_target_size"
+                    android:layout_gravity="center"
+                    android:background="?android:selectableItemBackgroundBorderless"
+                    android:tint="#8A000000"
+                    android:soundEffectsEnabled="false" />
+            </FrameLayout>
+        </LinearLayout>
+
     </LinearLayout>
 </com.android.systemui.volume.VolumeUiLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/volume_dialog_row.xml b/packages/SystemUI/res/layout/volume_dialog_row.xml
index fb9355a..def6f6b 100644
--- a/packages/SystemUI/res/layout/volume_dialog_row.xml
+++ b/packages/SystemUI/res/layout/volume_dialog_row.xml
@@ -18,78 +18,37 @@
     android:tag="row"
     android:layout_height="wrap_content"
     android:layout_width="@dimen/volume_dialog_panel_width"
-    android:clipChildren="true"
-    android:clipToPadding="true"
+    android:clipChildren="false"
+    android:clipToPadding="false"
     android:theme="@style/qs_theme">
 
     <LinearLayout
-        android:layout_height="match_parent"
+        android:layout_height="wrap_content"
         android:layout_width="match_parent"
-        android:layout_marginTop="10dp"
-        android:layout_marginBottom="10dp"
+        android:layout_marginTop="@dimen/volume_dialog_slider_margin_top"
         android:gravity="center"
+        android:layout_gravity="center"
         android:orientation="vertical" >
-
-        <LinearLayout
-            android:orientation="vertical"
+        <TextView
+            android:id="@+id/volume_row_header"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:gravity="center"
-            android:padding="5dp">
-            <TextView
-                android:id="@+id/volume_row_header"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:ellipsize="end"
-                android:maxLength="10"
-                android:maxLines="1"
-                android:textColor="?android:attr/colorControlNormal"
-                android:textAppearance="@style/TextAppearance.Volume.Header" />
-            <LinearLayout
-                android:id="@+id/output_chooser"
-                android:orientation="vertical"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:minWidth="48dp"
-                android:minHeight="48dp"
-                android:paddingTop="10dp"
-                android:background="?android:selectableItemBackgroundBorderless"
-                android:gravity="center">
-                <TextView
-                    android:id="@+id/volume_row_connected_device"
-                    android:visibility="gone"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:maxLength="10"
-                    android:ellipsize="end"
-                    android:maxLines="1"
-                    android:textAppearance="@style/TextAppearance.Volume.Header.Secondary" />
-                <com.android.keyguard.AlphaOptimizedImageButton
-                    android:id="@+id/output_chooser_button"
-                    android:layout_width="24dp"
-                    android:layout_height="24dp"
-                    android:background="?android:selectableItemBackgroundBorderless"
-                    android:contentDescription="@string/accessibility_output_chooser"
-                    style="@style/VolumeButtons"
-                    android:clickable="false"
-                    android:layout_centerVertical="true"
-                    android:src="@drawable/ic_swap"
-                    android:soundEffectsEnabled="false"/>
-            </LinearLayout>
-        </LinearLayout>
+            android:ellipsize="end"
+            android:maxLength="10"
+            android:maxLines="1"
+            android:visibility="gone"
+            android:textColor="?android:attr/colorControlNormal"
+            android:textAppearance="@style/TextAppearance.Volume.Header" />
         <FrameLayout
             android:id="@+id/volume_row_slider_frame"
-            android:padding="0dp"
-            android:layout_width="@dimen/volume_dialog_panel_width"
+            android:layout_width="match_parent"
             android:layoutDirection="rtl"
-            android:layout_height="@dimen/volume_dialog_panel_width">
+            android:layout_height="@dimen/volume_dialog_slider_height">
             <SeekBar
                 android:id="@+id/volume_row_slider"
                 android:clickable="true"
-                android:padding="0dp"
-                android:layout_margin="0dp"
-                android:layout_width="@dimen/volume_dialog_panel_width"
-                android:layout_height="@dimen/volume_dialog_panel_width"
+                android:layout_width="@dimen/volume_dialog_slider_height"
+                android:layout_height="match_parent"
                 android:layoutDirection="rtl"
                 android:layout_gravity="center"
                 android:rotation="90" />
@@ -98,10 +57,10 @@
         <com.android.keyguard.AlphaOptimizedImageButton
             android:id="@+id/volume_row_icon"
             style="@style/VolumeButtons"
-            android:padding="10dp"
-            android:layout_width="@dimen/volume_button_size"
-            android:layout_height="@dimen/volume_button_size"
+            android:layout_width="@dimen/volume_dialog_tap_target_size"
+            android:layout_height="@dimen/volume_dialog_tap_target_size"
             android:background="?android:selectableItemBackgroundBorderless"
+            android:tint="@color/accent_tint_color_selector"
             android:soundEffectsEnabled="false" />
     </LinearLayout>
 
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 9d090ba7..f37cf3e 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"maak kamera oop"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Kies nuwe taakuitleg"</string>
     <string name="cancel" msgid="6442560571259935130">"Kanselleer"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Vingerafdrukikoon"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Programikoon"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Hulpboodskapgebied"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Nageregkas"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Sluimerskerm"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Moenie Steur Nie"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Net prioriteit"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Net wekkers"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi af"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi is aan"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Geen Wi-Fi-netwerke beskikbaar nie"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Wekker"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Saai uit"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Saai tans uit"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Onbenoemde toestel"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is in veiligmodus gedeaktiveer."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Vee alles uit"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Trek hier om verdeelde skerm te gebruik"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Swiep op om programme te wissel"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Verdeel horisontaal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Verdeel vertikaal"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Verdeel gepasmaak"</string>
@@ -503,21 +505,15 @@
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"Wissel uitvoertoestel"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Skerm is vasgespeld"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Dit hou dit in sig totdat jy dit ontspeld. Raak en hou Terug en Oorsig om dit te ontspeld."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Dit hou dit in sig totdat jy dit ontspeld. Raak en hou Terug en Tuis om dit te ontspeld."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Dit hou dit in sig totdat jy dit ontspeld. Raak en hou Oorsig om dit te ontspeld."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Dit hou dit in sig totdat jy dit ontspeld. Raak en hou Tuis om dit te ontspeld."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Raak en hou die Terug- en Oorsig-knoppie om hierdie skerm te ontspeld"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Raak en hou die Terug- en Tuis-knoppie om hierdie skerm te ontspeld"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Het dit"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nee, dankie"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Skerm is vasgespeld"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Skerm is ontspeld"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Versteek <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Dit sal verskyn die volgende keer wanneer jy dit in instellings aanskakel."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Versteek"</string>
@@ -540,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Tik om te demp. Toeganklikheidsdienste kan dalk gedemp wees."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Tik om op vibreer te stel."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Tik om te demp."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s volumekontroles word gewys. Swiep na bo om toe te maak."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Volumekontroles is versteek"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s volumekontroles"</string>
     <string name="output_title" msgid="5355078100792942802">"Media-uitvoer"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Foonoproep-uitvoer"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Geen toestelle gekry nie"</string>
@@ -691,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Knipbord"</item>
     <item msgid="5742013440802239414">"Sleutelkode"</item>
-    <item msgid="8802889973626281575">"Sleutelbordwisselaar"</item>
-    <item msgid="7095517796293767867">"Rotasievoorstel"</item>
-    <item msgid="8494159969042135235">"Geen"</item>
+    <item msgid="1951959982985094069">"Draaibevestiging, sleutelbordwisselaar"</item>
+    <item msgid="8175437057325747277">"Geen"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normaal"</item>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index cf1adf2..4898e78 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"ካሜራ ክፈት"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"የአዲስ ተግባር አቀማመጥን ይምረጡ"</string>
     <string name="cancel" msgid="6442560571259935130">"ይቅር"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"የጣት አሻራ አዶ"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"የመተግበሪያ አዶ"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"የእገዛ መልዕክት አካባቢ"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"የማወራረጃ ምግቦች መያዣ"</string>
     <string name="start_dreams" msgid="5640361424498338327">"የማያ ገጽ ማቆያ"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"ኤተርኔት"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"አትረብሽ"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"ቅድሚያ የሚሰጠው ብቻ"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"ማንቂያዎች ብቻ"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi ጠፍቷል"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi በርቷል"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"ምንም የWi-Fi  አውታረ መረቦች የሉም"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"ማንቂያ"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"በመውሰድ ላይ"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"ያልተሰየመ መሳሪያ"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> በጥንቃቄ ሁነታ ውስጥ ታግዷል።"</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"ሁሉንም አጽዳ"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"የተከፈለ ማያ ገጽን ለመጠቀም እዚህ ላይ ይጎትቱ"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"መተግበሪያዎችን ለመቀየር ወደ ላይ ያንሸራትቱ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"አግድም ክፈል"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"ቁልቁል ክፈል"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"በብጁ ክፈል"</string>
@@ -503,21 +505,15 @@
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"የውጽዓት መሣሪያን ይቀይሩ"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"ማያ ገጽ ተሰክቷል"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"ይሄ እስኪነቅሉት ድረስ በእይታ ውስጥ ያስቀምጠዋል። ለመንቀል ተመለስ እና አጠቃላይ ዕይታ የሚለውን ይጫኑ እና ይያዙ።"</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"ይሄ እስኪነቅሉት ድረስ በእይታ ውስጥ ያስቀምጠዋል። ለመንቀል ተመለስ እና መነሻ የሚለውን ይንኩ እና ይያዙ።"</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"ይሄ እስኪነቅሉት ድረስ በእይታ ውስጥ ያስቀምጠዋል። ለመንቀል አጠቃላይ ዕይታ ተጭነው ይያዙ።"</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"ይሄ እስኪነቅሉት ድረስ በእይታ ውስጥ ያስቀምጠዋል። ለመንቀል መነሻ የሚለውን ይንኩ እና ይያዙ።"</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"ይህን ማያ ገጽ ለመንቀል ተመለስ እና አጠቃላይ ዕይታ አዝራሮችን ይንኩ እና ይያዙ"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ይህን ማያ ገጽ ለመንቀል ተመለስ እና መነሻ የሚለውን ይንኩ እና ይያዙ"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"ገባኝ"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"አይ፣ አመሰግናለሁ"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"ማያ ገጽ ተሰክቷል"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"ማያ ገጽ ተነቅሏል"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> ይደበቅ?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"በቅንብሮች ውስጥ በሚቀጥለው ጊዜ እንዲበራ በሚያደርጉበት ጊዜ ዳግመኛ ብቅ ይላል።"</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"ደብቅ"</string>
@@ -540,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s። ድምጸ-ከል ለማድረግ መታ ያድርጉ። የተደራሽነት አገልግሎቶች ድምጸ-ከል ሊደረግባቸው ይችላል።"</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s። ወደ ንዝረት ለማቀናበር መታ ያድርጉ።"</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s። ድምጸ-ከል ለማድረግ መታ ያድርጉ።"</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"የ%s ድምጽ መቆጣጠሪያዎች ይታያሉ። ለማሰናበት ወደ ላይ ያንሸራትቱ።"</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"የድምጽ መቆጣጠሪያዎች ተደብቀዋል"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s የድምፅ መቆጣጠሪያዎች"</string>
     <string name="output_title" msgid="5355078100792942802">"የሚዲያ ውጽዓት"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"የስልክ ጥሪ ውፅዓት"</string>
     <string name="output_none_found" msgid="5544982839808921091">"ምንም መሣሪያዎች አልተገኙም"</string>
@@ -691,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"የቅንጥብ ሰሌዳ"</item>
     <item msgid="5742013440802239414">"የቁልፍ ኮድ"</item>
-    <item msgid="8802889973626281575">"የቁልፍ ሰሌዳ መቀየሪያ"</item>
-    <item msgid="7095517796293767867">"የማዞር አስተያየት ጥቆማ"</item>
-    <item msgid="8494159969042135235">"ምንም"</item>
+    <item msgid="1951959982985094069">"ማሽከርከር ያረጋግጡ፣ ቁልፍ ሰሌዳ መቀየሪያ"</item>
+    <item msgid="8175437057325747277">"ምንም የለም"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"መደበኛ"</item>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 1087b99..93ea258 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -107,12 +107,11 @@
     <string name="camera_label" msgid="7261107956054836961">"فتح الكاميرا"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"تحديد تنسيق جديد للمهمة"</string>
     <string name="cancel" msgid="6442560571259935130">"إلغاء"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"رمز بصمة الإصبع"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"رمز التطبيق"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"منطقة رسالة المساعدة"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"زر تكبير/تصغير للتوافق."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"استخدام التكبير/التصغير لتحويل شاشة صغيرة إلى شاشة أكبر"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"تم توصيل البلوتوث."</string>
@@ -283,6 +282,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"حالة الحلويات"</string>
     <string name="start_dreams" msgid="5640361424498338327">"شاشة التوقف"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"عدم الإزعاج"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"الأولوية فقط"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"التنبيهات فقط"</string>
@@ -319,6 +320,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"‏إيقاف Wi-Fi"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"‏تم تشغيل Wi-Fi"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"‏لا تتوفر أي شبكة Wi-Fi"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"تنبيه"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"إرسال"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"جارٍ الإرسال"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"جهاز لا يحمل اسمًا"</string>
@@ -335,9 +337,15 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"جارٍ الاتصال..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"النطاق"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"نقطة اتصال"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"جارٍ تفعيل نقطة الاتصال…"</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="zero">‏%d جهاز</item>
+      <item quantity="two">‏جهازان (%d)</item>
+      <item quantity="few">‏%d أجهزة</item>
+      <item quantity="many">‏%d جهازًا</item>
+      <item quantity="other">‏%d جهاز</item>
+      <item quantity="one">‏جهاز واحد (%d)</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"الإشعارات"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"الفلاش"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"بيانات الجوّال"</string>
@@ -347,10 +355,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> مستخدَمة"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"قيد <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"تحذير <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"الملف الشخصي للعمل"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"الإشعارات والتطبيقات غير مفعّلة"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"إضاءة ليلية"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"تفعيل عند غروب الشمس"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"حتى شروق الشمس"</string>
@@ -368,8 +374,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"تم تعطيل <xliff:g id="APP">%s</xliff:g> في الوضع الآمن."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"مسح الكل"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"اسحب هنا لاستخدام وضع تقسيم الشاشة"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"تقسيم أفقي"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"تقسيم رأسي"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"تقسيم مخصص"</string>
@@ -510,11 +514,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"إيقاف التشغيل الآن"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"توسيع"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"تصغير"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"تبديل جهاز الاستماع"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"تم تثبيت الشاشة"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"يؤدي هذا إلى استمرار عرض الشاشة المُختارة إلى أن تتم إزالة تثبيتها. المس مع الاستمرار الزرين \"رجوع\" و\"نظرة عامة\" لإزالة التثبيت."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"يؤدي هذا إلى استمرار عرض الشاشة المُختارة إلى أن تتم إزالة تثبيتها. المس مع الاستمرار الزرين \"رجوع\" و\"الشاشة الرئيسية\" لإزالة التثبيت."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"يؤدي هذا إلى استمرار عرض الشاشة المُختارة إلى أن تتم إزالة تثبيتها. المس مع الاستمرار زر \"نظرة عامة\" لإزالة التثبيت."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"يؤدي هذا إلى استمرار عرض الشاشة المُختارة إلى أن تتم إزالة تثبيتها. المس مع الاستمرار زر \"الشاشة الرئيسية\" لإزالة التثبيت."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"لإزالة تثبيت هذه الشاشة، يمكنك أن تلمس مع الاستمرار زرّي \"رجوع\" و\"نظرة عامة\"."</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"لإزالة تثبيت هذه الشاشة، يمكنك أن تلمس مع الاستمرار زرّي \"رجوع\" و\"الشاشة الرئيسية\"."</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"حسنًا"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"لا، شكرًا"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"تمّ تثبيت الشاشة."</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"تمَت إزالة تثبيت الشاشة."</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"هل تريد إخفاء <xliff:g id="TILE_LABEL">%1$s</xliff:g>؟"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"سيظهر مرة أخرى عند تمكينه في الإعدادات المرة التالية."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"إخفاء"</string>
@@ -537,8 +548,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"‏%1$s. انقر للتجاهل. قد يتم تجاهل خدمات إمكانية الوصول."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"‏%1$s. انقر للتعيين على الاهتزاز."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"‏%1$s. انقر لكتم الصوت."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"‏تم عرض %s عنصر تحكم في مستوى الصوت. يمكنك التمرير سريعًا لأعلى للتجاهل."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"تم إخفاء عناصر التحكم في مستوى الصوت"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"‏%s عنصر للتحكم في مستوى الصوت"</string>
     <string name="output_title" msgid="5355078100792942802">"إخراج الوسائط"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"إخراج المكالمة الهاتفية"</string>
     <string name="output_none_found" msgid="5544982839808921091">"لم يتم العثور على أي أجهزة."</string>
@@ -594,8 +604,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"باستخدام عناصر التحكم في إشعار التشغيل، يمكنك تعيين مستوى الأهمية من 0 إلى 5 لإشعارات التطبيق. \n\n"<b>"المستوى 5"</b>" \n- العرض أعلى قائمة الإشعارات \n- يسمح بمقاطعة ملء الشاشة \n- الظهور الخاطف دائمًا \n\n"<b>"المستوى 4"</b>" \n- منع مقاطعة ملء الشاشة \n- الظهور الخاطف دائمًا \n\n"<b>"المستوى 3"</b>" \n- منع مقاطعة ملء الشاشة \n- عدم الظهور الخاطف أبدًا \n\n"<b>"المستوى 2"</b>" \n- منع مقاطعة ملء الشاشة \n- عدم الظهور الخاطف أبدًا \n- عدم إصدار أصوات واهتزاز \n\n"<b>"المستوى 1"</b>" \n- منع مقاطعة ملء الشاشة \n- عدم الظهور الخاطف أبدًا \n- عدم إصدار أصوات أو اهتزاز أبدًا \n- الإخفاء من شاشة التأمين وشريط الحالة \n- العرض أسفل قائمة الإشعارات \n\n"<b>"المستوى 0"</b>" \n- حظر جميع الإشعارات من التطبيق"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"الإشعارات"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"لن تتلقى هذه الإشعارات بعد الآن."</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"أنت تتجاهل عادةً هذه الإشعارات. \nهل تريد الاستمرار في عرضها؟"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"هل تريد الاستمرار في تلقي هذه الإشعارات؟"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"إيقاف الإشعارات"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"الاستمرار في تلقّي الإشعارات"</string>
@@ -697,9 +706,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"الحافظة"</item>
     <item msgid="5742013440802239414">"رمز المفتاح"</item>
-    <item msgid="8802889973626281575">"مفتاح تبديل لوحة المفاتيح"</item>
-    <item msgid="7095517796293767867">"اقتراح حول أزرار التنقل"</item>
-    <item msgid="8494159969042135235">"بدون"</item>
+    <item msgid="1951959982985094069">"تأكيد التدوير، مفتاح تبديل لوحة المفاتيح"</item>
+    <item msgid="8175437057325747277">"بدون"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"عادي"</item>
diff --git a/packages/SystemUI/res/values-as-land/strings.xml b/packages/SystemUI/res/values-as-land/strings.xml
new file mode 100644
index 0000000..70b0e1d
--- /dev/null
+++ b/packages/SystemUI/res/values-as-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT 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="toast_rotation_locked" msgid="7609673011431556092">"স্ক্ৰীণখন এতিয়া লেণ্ডস্কেপ স্ক্ৰীণৰ দিশত লক কৰা অৱস্থাত আছে"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-as/config.xml b/packages/SystemUI/res/values-as/config.xml
new file mode 100644
index 0000000..5309563
--- /dev/null
+++ b/packages/SystemUI/res/values-as/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
+</resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
new file mode 100644
index 0000000..e2ac574
--- /dev/null
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -0,0 +1,1202 @@
+<?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">
+    <string name="app_label" msgid="7164937344850004466">"ছিষ্টেম ইউআই"</string>
+    <string name="status_bar_clear_all_button" msgid="7774721344716731603">"মচক"</string>
+    <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"সূচীৰ পৰা আঁতৰাওক"</string>
+    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"এপ্ সম্পৰ্কীয় তথ্য"</string>
+    <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"আপোনাৰ শেহতীয়া স্ক্ৰীণ ইয়াত প্ৰকট হ\'ব"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"শেহতীয়া এপসমূহক আঁতৰাওক"</string>
+    <plurals name="status_bar_accessibility_recent_apps" formatted="false" msgid="9138535907802238759">
+      <item quantity="one">%d খন স্ক্ৰীণ অৱলোকনত আছে</item>
+      <item quantity="other">%d খন স্ক্ৰীণ অৱলোকনত আছে</item>
+    </plurals>
+    <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"কোনো জাননী নাই"</string>
+    <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"চলিত"</string>
+    <string name="status_bar_latest_events_title" msgid="6594767438577593172">"জাননীসমূহ"</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"বেটাৰি কম আছে"</string>
+    <!-- no translation found for battery_low_title_hybrid (6268991275887381595) -->
+    <skip />
+    <string name="battery_low_percent_format" msgid="2900940511201380775">"<xliff:g id="PERCENTAGE">%s</xliff:g> বাকী আছে"</string>
+    <!-- no translation found for battery_low_percent_format_hybrid (6838677459286775617) -->
+    <skip />
+    <!-- no translation found for battery_low_percent_format_hybrid_short (9025795469949145586) -->
+    <skip />
+    <!-- no translation found for battery_low_percent_format_saver_started (7879389868952879166) -->
+    <skip />
+    <string name="invalid_charger" msgid="4549105996740522523">"ইউএছবি চ্চার্জিং কৰিব পৰা নাযাব।\nআপোনাৰ ফ\'নৰ লগত দিয়া চ্চার্জাৰ ব্যৱহাৰ কৰক।"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"ইউএছবি চ্চার্জিং সমৰ্থিত নহয়।"</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"কেৱল যোগান ধৰা চ্চার্জাৰ ব্যৱহাৰ কৰক।"</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"ছেটিংসমূহ"</string>
+    <!-- no translation found for battery_saver_confirmation_title (2052100465684817154) -->
+    <skip />
+    <string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"অন কৰক"</string>
+    <!-- no translation found for battery_saver_start_action (8187820911065797519) -->
+    <skip />
+    <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"ছেটিংসমূহ"</string>
+    <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"ৱাই-ফাই"</string>
+    <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"স্বয়ং-ঘূৰ্ণন স্ক্ৰীণ"</string>
+    <string name="status_bar_settings_mute_label" msgid="554682549917429396">"মিউট"</string>
+    <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"স্বয়ং"</string>
+    <string name="status_bar_settings_notifications" msgid="397146176280905137">"জাননীসমূহ"</string>
+    <string name="bluetooth_tethered" msgid="7094101612161133267">"ব্লুটুথ টেডাৰিং কৰা হ\'ল"</string>
+    <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ইনপুট পদ্ধতি ছেট আপ কৰক"</string>
+    <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"বাস্তৱিক কীব\'ৰ্ড"</string>
+    <!-- no translation found for usb_device_permission_prompt (1825685909587559679) -->
+    <skip />
+    <!-- no translation found for usb_accessory_permission_prompt (2465531696941369047) -->
+    <skip />
+    <!-- no translation found for usb_device_confirm_prompt (7440562274256843905) -->
+    <skip />
+    <!-- no translation found for usb_accessory_confirm_prompt (4333670517539993561) -->
+    <skip />
+    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"ইনষ্টল হৈ থকা কোনো এপে ইউএছবি সহায়ক সামগ্ৰীটো চলাব নোৱাৰে। এই সহায়ক সামগ্ৰীৰ বিষয়ে <xliff:g id="URL">%1$s</xliff:g>ৰ জৰিয়তে অধিক জানক৷"</string>
+    <string name="title_usb_accessory" msgid="4966265263465181372">"ইউএছবিৰ সহায়ক সামগ্ৰী"</string>
+    <string name="label_view" msgid="6304565553218192990">"চাওক"</string>
+    <!-- no translation found for always_use_device (4015357883336738417) -->
+    <skip />
+    <!-- no translation found for always_use_accessory (3257892669444535154) -->
+    <skip />
+    <string name="usb_debugging_title" msgid="4513918393387141949">"ইউএছবি ডিবাগিংৰ অনুমতি দিবনে?"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"এয়া হৈছে কম্পিউটাৰটোৰ RSA কী ফিংগাৰপ্ৰিণ্ট:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_always" msgid="303335496705863070">"এই কম্পিউটাৰটোৰ পৰা সদায় অনুমতি দিয়ক"</string>
+    <!-- no translation found for usb_debugging_secondary_user_title (6353808721761220421) -->
+    <skip />
+    <!-- no translation found for usb_debugging_secondary_user_message (6067122453571699801) -->
+    <skip />
+    <string name="compat_mode_on" msgid="6623839244840638213">"স্ক্ৰীণ পূর্ণ কৰিবলৈ জুম কৰক"</string>
+    <string name="compat_mode_off" msgid="4434467572461327898">"স্ক্ৰীণ পূর্ণ কৰিবলৈ প্ৰসাৰিত কৰক"</string>
+    <!-- no translation found for global_action_screenshot (8329831278085426283) -->
+    <skip />
+    <string name="screenshot_saving_ticker" msgid="7403652894056693515">"স্ক্ৰীণশ্বট ছেভ কৰি থকা হৈছে…"</string>
+    <string name="screenshot_saving_title" msgid="8242282144535555697">"স্ক্ৰীণশ্বট ছেভ কৰি থকা হৈছে…"</string>
+    <!-- no translation found for screenshot_saving_text (2545047868936087248) -->
+    <skip />
+    <!-- no translation found for screenshot_saved_title (5637073968117370753) -->
+    <skip />
+    <!-- no translation found for screenshot_saved_text (7574667448002050363) -->
+    <skip />
+    <!-- no translation found for screenshot_failed_title (9096484883063264803) -->
+    <skip />
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (8844781948876286488) -->
+    <skip />
+    <!-- no translation found for screenshot_failed_to_save_text (3041612585107107310) -->
+    <skip />
+    <!-- no translation found for screenshot_failed_to_capture_text (173674476457581486) -->
+    <skip />
+    <string name="usb_preference_title" msgid="6551050377388882787">"ইউএছবিৰে ফাইল স্থানান্তৰণৰ বিকল্পসমূহ"</string>
+    <string name="use_mtp_button_title" msgid="4333504413563023626">"মিডিয়া প্লেয়াৰ (এমটিপি) হিচাপে সংলগ্ন কৰক"</string>
+    <string name="use_ptp_button_title" msgid="7517127540301625751">"কেমেৰা (পিটিপি) হিচাপে সংলগ্ন কৰক"</string>
+    <string name="installer_cd_button_title" msgid="2312667578562201583">"Macৰ বাবে Android ফাইল স্থানান্তৰ এপ্ ইনষ্টল কৰক"</string>
+    <string name="accessibility_back" msgid="567011538994429120">"উভতি যাওক"</string>
+    <string name="accessibility_home" msgid="8217216074895377641">"গৃহ পৃষ্ঠাৰ বুটাম"</string>
+    <string name="accessibility_menu" msgid="316839303324695949">"মেনু"</string>
+    <string name="accessibility_accessibility_button" msgid="7601252764577607915">"দিব্যাংগসকলৰ বাবে থকা সুবিধাসমূহ"</string>
+    <!-- no translation found for accessibility_rotate_button (7402949513740253006) -->
+    <skip />
+    <string name="accessibility_recent" msgid="5208608566793607626">"অৱলোকন"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"সন্ধান কৰক"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"কেমেৰা"</string>
+    <string name="accessibility_phone_button" msgid="6738112589538563574">"ফ\'ন"</string>
+    <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
+    <skip />
+    <string name="accessibility_unlock_button" msgid="128158454631118828">"আনলক কৰক"</string>
+    <!-- no translation found for accessibility_waiting_for_fingerprint (4808860050517462885) -->
+    <skip />
+    <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+    <skip />
+    <string name="unlock_label" msgid="8779712358041029439">"আনলক কৰক"</string>
+    <string name="phone_label" msgid="2320074140205331708">"ফ\'ন খোলক"</string>
+    <!-- no translation found for voice_assist_label (3956854378310019854) -->
+    <skip />
+    <string name="camera_label" msgid="7261107956054836961">"কেমেৰা খোলক"</string>
+    <!-- no translation found for recents_caption_resize (3517056471774958200) -->
+    <skip />
+    <string name="cancel" msgid="6442560571259935130">"বাতিল কৰক"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
+    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <skip />
+    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
+    <skip />
+    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
+    <skip />
+    <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"উপযোগিতা অনুসৰি জুম কৰা বুটাম।"</string>
+    <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"স্ক্ৰীণৰ আকাৰ ডাঙৰ কৰিবলৈ জুম কৰক।"</string>
+    <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"ব্লুটুথ সংযোগ হ\'ল।"</string>
+    <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"ব্লুটুথ সংযোগ বিচ্ছিন্ন কৰা হ\'ল।"</string>
+    <string name="accessibility_no_battery" msgid="358343022352820946">"বেটাৰি শেষ"</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"বেটাৰিৰ এডাল দণ্ড।"</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"বেটাৰিৰ দুডাল দণ্ড।"</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"বেটাৰিৰ তিনিডাল দণ্ড।"</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"বেটাৰি পূৰাকৈ চ্চাৰ্জ হৈছে।"</string>
+    <string name="accessibility_no_phone" msgid="4894708937052611281">"ফ\'নত ছিগনেল নাই৷"</string>
+    <string name="accessibility_phone_one_bar" msgid="687699278132664115">"ফ\'ন ছিগনেলৰ এডাল দণ্ড।"</string>
+    <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"ফ\'ন ছিগনেলৰ দুডাল দণ্ড।"</string>
+    <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"ফ\'নৰ ছিগনেলৰ তিনিডাল দণ্ড আছে।"</string>
+    <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"ফ\'নৰ ছিগনেল পূৰা আছে৷"</string>
+    <string name="accessibility_no_data" msgid="4791966295096867555">"কোনো ডেটা নাই।"</string>
+    <string name="accessibility_data_one_bar" msgid="1415625833238273628">"ডেটা ছিগনেলৰ এডাল দণ্ড।"</string>
+    <string name="accessibility_data_two_bars" msgid="6166018492360432091">"ডেটা ছংনেলৰ তিনিডাল দণ্ড।"</string>
+    <string name="accessibility_data_three_bars" msgid="9167670452395038520">"ডেটা ছিংগনেলত তিনিডাল দণ্ড আছে।"</string>
+    <string name="accessibility_data_signal_full" msgid="2708384608124519369">"ডেটা ছিগনেল পূৰা আছে।"</string>
+    <string name="accessibility_wifi_name" msgid="7202151365171148501">"<xliff:g id="WIFI">%s</xliff:g>ৰ লগত সংযোগ কৰা হ\'ল।"</string>
+    <string name="accessibility_bluetooth_name" msgid="8441517146585531676">"<xliff:g id="BLUETOOTH">%s</xliff:g>ৰ লগত সংযোগ কৰা হ\'ল।"</string>
+    <!-- no translation found for accessibility_cast_name (4026393061247081201) -->
+    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"কোনো WiMAX নাই।"</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAXৰ এডাল দণ্ড৷"</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAXৰ দুডাল দণ্ড আছে।"</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAXৰ তিনিডাল দণ্ড আছে।"</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAXৰ ছিগনেল পূৰা আছে৷"</string>
+    <!-- no translation found for accessibility_ethernet_disconnected (5896059303377589469) -->
+    <skip />
+    <!-- no translation found for accessibility_ethernet_connected (2692130313069182636) -->
+    <skip />
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"কোনো ছিগনেল নাই।"</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"সংযোগ হৈ থকা নাই।"</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"এডালো দণ্ড নাই।"</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"এডাল দণ্ড।"</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"দুডাল দণ্ড।"</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"তিনিডাল দণ্ড।"</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"সম্পূৰ্ণ ছিগনেল।"</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"অন।"</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"অফ।"</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"সংযোগ কৰা হ’ল।"</string>
+    <string name="accessibility_desc_connecting" msgid="3812924520316280149">"সংযোগ কৰি থকা হৈছে।"</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"জিপিআৰএছ"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"১ X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <!-- no translation found for accessibility_data_connection_4g_plus (3032226872470658661) -->
+    <skip />
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"এলটিই"</string>
+    <!-- no translation found for accessibility_data_connection_lte_plus (361876866906946007) -->
+    <skip />
+    <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+    <string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"ৰ\'মিং"</string>
+    <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
+    <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"ৱাই-ফাই"</string>
+    <string name="accessibility_no_sim" msgid="8274017118472455155">"ছিম নাই।"</string>
+    <!-- no translation found for accessibility_cell_data (5326139158682385073) -->
+    <skip />
+    <!-- no translation found for accessibility_cell_data_on (5927098403452994422) -->
+    <skip />
+    <!-- no translation found for accessibility_cell_data_off (443267573897409704) -->
+    <skip />
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ব্লুটুথ টেডাৰিং।"</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"এয়াৰপ্লেইন ম\'ড।"</string>
+    <!-- no translation found for accessibility_vpn_on (5993385083262856059) -->
+    <skip />
+    <!-- no translation found for accessibility_no_sims (3957997018324995781) -->
+    <skip />
+    <!-- no translation found for accessibility_carrier_network_change_mode (4017301580441304305) -->
+    <skip />
+    <!-- no translation found for accessibility_battery_details (7645516654955025422) -->
+    <skip />
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> শতাংশ বেটাৰি।"</string>
+    <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
+    <skip />
+    <string name="accessibility_settings_button" msgid="799583911231893380">"ছিষ্টেমৰ ছেটিংসমূহ৷"</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"জাননীসমূহ।"</string>
+    <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
+    <skip />
+    <string name="accessibility_remove_notification" msgid="3603099514902182350">"জাননী মচক৷"</string>
+    <string name="accessibility_gps_enabled" msgid="3511469499240123019">"জিপিএছ সক্ষম হ\'ল৷"</string>
+    <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"জিপিএছ বিচাৰি থকা হৈছে।"</string>
+    <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter সক্ষম কৰা হ\'ল৷"</string>
+    <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"ৰিংগাৰ কম্পন অৱস্থাত আছে৷"</string>
+    <string name="accessibility_ringer_silent" msgid="9061243307939135383">"ৰিংগাৰ নীৰৱ কৰা হৈছে৷"</string>
+    <!-- no translation found for accessibility_casting (6887382141726543668) -->
+    <skip />
+    <!-- no translation found for accessibility_work_mode (702887484664647430) -->
+    <skip />
+    <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g>ক আঁতৰাব।"</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> আঁতৰোৱা হৈছে৷"</string>
+    <!-- no translation found for accessibility_recents_all_items_dismissed (4464697366179168836) -->
+    <skip />
+    <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
+    <skip />
+    <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> আৰম্ভ কৰা হৈছে।"</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"জাননী অগ্ৰাহ্য কৰা হৈছে।"</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"জাননী পেনেল।"</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"ক্ষিপ্ৰ ছেটিংসমূহ।"</string>
+    <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"বন্ধ স্ক্ৰীণ।"</string>
+    <string name="accessibility_desc_settings" msgid="3417884241751434521">"ছেটিংসমূহ"</string>
+    <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"অৱলোকন।"</string>
+    <string name="accessibility_desc_work_lock" msgid="4288774420752813383">"কৰ্মস্থানৰ প্ৰ\'ফাইলৰ লক স্ক্ৰীণ"</string>
+    <!-- no translation found for accessibility_desc_close (7479755364962766729) -->
+    <skip />
+    <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"ৱাই-ফাই অফ কৰা হ\'ল।"</string>
+    <string name="accessibility_quick_settings_wifi_changed_on" msgid="6440117170789528622">"ৱাই-ফাই অন কৰা হ\'ল।"</string>
+    <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"ম\'বাইল <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"বেটাৰি <xliff:g id="STATE">%s</xliff:g>।"</string>
+    <string name="accessibility_quick_settings_airplane_off" msgid="7786329360056634412">"এয়াৰপ্লেইন ম\'ড অফ হৈ আছে৷"</string>
+    <string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"এয়াৰপ্লেইন ম\'ড অন হৈ আছে৷"</string>
+    <string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"এয়াৰপ্লেইন ম\'ড অফ কৰা হ\'ল।"</string>
+    <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"এয়াৰপ্লেইন ম\'ড অন কৰা হ\'ল।"</string>
+    <!-- no translation found for accessibility_quick_settings_dnd_priority_on (1448402297221249355) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_dnd_none_on (6882582132662613537) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_dnd_alarms_on (9152834845587554157) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_dnd (6607873236717185815) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_dnd_off (2371832603753738581) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_dnd_changed_off (898107593453022935) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_dnd_changed_on (4483780856613561039) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_bluetooth (6341675755803320038) -->
+    <skip />
+    <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"ব্লুটুথ অফ হৈ আছে।"</string>
+    <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"ব্লুটুথ অন হৈ আছে।"</string>
+    <string name="accessibility_quick_settings_bluetooth_connecting" msgid="6953242966685343855">"ব্লুটুথ সংযোগ কৰি থকা হৈছে।"</string>
+    <string name="accessibility_quick_settings_bluetooth_connected" msgid="4306637793614573659">"ব্লুটুথ সংযোগ কৰা হ\'ল।"</string>
+    <string name="accessibility_quick_settings_bluetooth_changed_off" msgid="2730003763480934529">"ব্লুটুথ অফ কৰা হ\'ল।"</string>
+    <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="8722351798763206577">"ব্লুটুথ অন কৰা হ\'ল।"</string>
+    <string name="accessibility_quick_settings_location_off" msgid="5119080556976115520">"অৱস্থান সবিশেষ অফ হৈ আছে।"</string>
+    <string name="accessibility_quick_settings_location_on" msgid="5809937096590102036">"অৱস্থান সবিশেষ অন হৈ আছে।"</string>
+    <string name="accessibility_quick_settings_location_changed_off" msgid="8526845571503387376">"অৱস্থান সবিশেষ অফ কৰা হ\'ল।"</string>
+    <string name="accessibility_quick_settings_location_changed_on" msgid="339403053079338468">"অৱস্থান সবিশেষ অন কৰা হ\'ল।"</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"<xliff:g id="TIME">%s</xliff:g>ৰ বাবে এলাৰ্ম ছেট কৰা হৈছে।"</string>
+    <string name="accessibility_quick_settings_close" msgid="3115847794692516306">"পেনেল বন্ধ কৰক।"</string>
+    <string name="accessibility_quick_settings_more_time" msgid="3659274935356197708">"অধিক সময়।"</string>
+    <string name="accessibility_quick_settings_less_time" msgid="2404728746293515623">"কম সময়।"</string>
+    <string name="accessibility_quick_settings_flashlight_off" msgid="4936432000069786988">"ফ্লাশ্বলাইট অফ হৈ আছে।"</string>
+    <!-- no translation found for accessibility_quick_settings_flashlight_unavailable (8012811023312280810) -->
+    <skip />
+    <string name="accessibility_quick_settings_flashlight_on" msgid="2003479320007841077">"ফ্লাশ্বলাইট অন হৈ আছে৷"</string>
+    <string name="accessibility_quick_settings_flashlight_changed_off" msgid="3303701786768224304">"ফ্লাশ্বলাইট অফ কৰা হ\'ল।"</string>
+    <string name="accessibility_quick_settings_flashlight_changed_on" msgid="6531793301533894686">"ফ্লাশ্বলাইট অন কৰা হ\'ল।"</string>
+    <string name="accessibility_quick_settings_color_inversion_changed_off" msgid="4406577213290173911">"ৰং বিপৰীতকৰণ অফ কৰা হ\'ল।"</string>
+    <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="6897462320184911126">"ৰং বিপৰীতকৰণ অন কৰা হ\'ল।"</string>
+    <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"ম\'বাইল হটস্পট অফ কৰা হ\'ল।"</string>
+    <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"ম\'বাইল হটস্পট অন কৰা হ\'ল।"</string>
+    <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"স্ক্ৰীণ কাষ্টিং বন্ধ কৰা হ\'ল।"</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_data_saver_changed_off (650231949881093289) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_data_saver_changed_on (4218725402373934151) -->
+    <skip />
+    <string name="accessibility_brightness" msgid="8003681285547803095">"ডিছপ্লেৰ উজ্জ্বলতা"</string>
+    <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"চ্চার্জ কৰি থকা হৈছে"</string>
+    <!-- no translation found for data_usage_disabled_dialog_3g_title (5281770593459841889) -->
+    <skip />
+    <!-- no translation found for data_usage_disabled_dialog_4g_title (1601769736881078016) -->
+    <skip />
+    <!-- no translation found for data_usage_disabled_dialog_mobile_title (6801382439018099779) -->
+    <skip />
+    <!-- no translation found for data_usage_disabled_dialog_title (3932437232199671967) -->
+    <skip />
+    <!-- no translation found for data_usage_disabled_dialog (4919541636934603816) -->
+    <skip />
+    <!-- no translation found for data_usage_disabled_dialog_enable (1412395410306390593) -->
+    <skip />
+    <string name="gps_notification_searching_text" msgid="8574247005642736060">"জিপিএছ সন্ধান কৰি থকা হৈছে"</string>
+    <string name="gps_notification_found_text" msgid="4619274244146446464">"জিপিএছএ অৱস্থান ছেট কৰিছে"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"অৱস্থানৰ অনুৰোধ সক্ৰিয় হৈ আছে"</string>
+    <string name="accessibility_clear_all" msgid="5235938559247164925">"সকলো জাননী মচক৷"</string>
+    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
+    <skip />
+    <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
+    <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"জাননীৰ ছেটিংসমূহ"</string>
+    <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ছেটিংসমূহ"</string>
+    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"আপোনাৰ ফ\'নৰ স্ক্ৰীণ স্বয়ংক্ৰিয়ভাৱে ঘূৰিব৷"</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"স্ক্ৰীণ লেণ্ডস্কেপ দিশত লক কৰা হ\'ল।"</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"স্ক্ৰীণ প\'ৰ্ট্ৰেইট দিশত লক কৰা হ\'ল।"</string>
+    <string name="accessibility_rotation_lock_off_changed" msgid="8134601071026305153">"আপোনাৰ ফ\'নৰ স্ক্ৰীণ এতিয়া স্বয়ংক্ৰিয়ভাৱে ঘূৰিব৷"</string>
+    <string name="accessibility_rotation_lock_on_landscape_changed" msgid="3135965553707519743">"স্ক্ৰীণখন এতিয়া লেণ্ডস্কেইপ দিশত লক কৰা অৱস্থাত আছে।"</string>
+    <string name="accessibility_rotation_lock_on_portrait_changed" msgid="8922481981834012126">"স্ক্ৰীণখন এতিয়া প\'ৰ্ট্ৰেইট দিশত লক কৰা অৱস্থাত আছে।"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"মিষ্টান্ন ভাণ্ডাৰ"</string>
+    <!-- no translation found for start_dreams (5640361424498338327) -->
+    <skip />
+    <string name="ethernet_label" msgid="7967563676324087464">"ইথাৰনেট"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
+    <!-- no translation found for quick_settings_dnd_label (8735855737575028208) -->
+    <skip />
+    <!-- no translation found for quick_settings_dnd_priority_label (483232950670692036) -->
+    <skip />
+    <!-- no translation found for quick_settings_dnd_alarms_label (2559229444312445858) -->
+    <skip />
+    <!-- no translation found for quick_settings_dnd_none_label (5025477807123029478) -->
+    <skip />
+    <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"ব্লুটুথ"</string>
+    <string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"ব্লুটুথ (<xliff:g id="NUMBER">%d</xliff:g>টা ডিভাইচ)"</string>
+    <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"ব্লুটুথ বন্ধ অৱস্থাত আছে"</string>
+    <string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"কোনো যোৰা লগোৱা ডিভাইচ উপলব্ধ নহয়।"</string>
+    <!-- no translation found for quick_settings_bluetooth_secondary_label_battery_level (7106697106764717416) -->
+    <skip />
+    <!-- no translation found for quick_settings_bluetooth_secondary_label_audio (5673845963301132071) -->
+    <skip />
+    <!-- no translation found for quick_settings_bluetooth_secondary_label_headset (1880572731276240588) -->
+    <skip />
+    <!-- no translation found for quick_settings_bluetooth_secondary_label_input (2173322305072945905) -->
+    <skip />
+    <string name="quick_settings_brightness_label" msgid="6968372297018755815">"উজ্জ্বলতা"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"স্বয়ং-ঘূৰ্ণন"</string>
+    <!-- no translation found for accessibility_quick_settings_rotation (4231661040698488779) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_rotation_value (8187398200140760213) -->
+    <skip />
+    <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"ঘূৰ্ণন লক কৰা হ\'ল"</string>
+    <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"প\'ৰ্ট্ৰেইট"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"লেণ্ডস্কেইপ"</string>
+    <string name="quick_settings_ime_label" msgid="7073463064369468429">"ইনপুট পদ্ধতি"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"অৱস্থান"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"অৱস্থান অফ"</string>
+    <string name="quick_settings_media_device_label" msgid="1302906836372603762">"মিডিয়া ডিভাইচ"</string>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"জৰুৰীকালীন কল মাত্ৰ"</string>
+    <string name="quick_settings_settings_label" msgid="5326556592578065401">"ছেটিংসমূহ"</string>
+    <string name="quick_settings_time_label" msgid="4635969182239736408">"সময়"</string>
+    <string name="quick_settings_user_label" msgid="5238995632130897840">"মোক"</string>
+    <string name="quick_settings_user_title" msgid="4467690427642392403">"ব্যৱহাৰকাৰী"</string>
+    <string name="quick_settings_user_new_user" msgid="9030521362023479778">"নতুন ব্যৱহাৰকাৰী"</string>
+    <string name="quick_settings_wifi_label" msgid="9135344704899546041">"ৱাই-ফাই"</string>
+    <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"সংযোগ হৈ থকা নাই"</string>
+    <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"নেটৱৰ্ক নাই"</string>
+    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"ৱাই-ফাই অফ"</string>
+    <!-- no translation found for quick_settings_wifi_on_label (7607810331387031235) -->
+    <skip />
+    <!-- no translation found for quick_settings_wifi_detail_empty_text (269990350383909226) -->
+    <skip />
+    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
+    <skip />
+    <!-- no translation found for quick_settings_cast_title (7709016546426454729) -->
+    <skip />
+    <string name="quick_settings_casting" msgid="6601710681033353316">"কাষ্টিং"</string>
+    <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"নাম নথকা ডিভাইচ"</string>
+    <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"কাষ্টৰ বাবে সাজু"</string>
+    <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"কোনো ডিভাইচ নাই"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"উজ্জ্বলতা"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"স্বয়ং"</string>
+    <string name="quick_settings_inversion_label" msgid="8790919884718619648">"ৰং ওলোটা কৰক"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"ৰং শুধৰণী কৰা ম\'ড"</string>
+    <string name="quick_settings_more_settings" msgid="326112621462813682">"অধিক ছেটিং"</string>
+    <string name="quick_settings_done" msgid="3402999958839153376">"সম্পন্ন কৰা হ\'ল"</string>
+    <string name="quick_settings_connected" msgid="1722253542984847487">"সংযোগ কৰা হ’ল"</string>
+    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
+    <skip />
+    <string name="quick_settings_connecting" msgid="47623027419264404">"সংযোগ কৰি থকা হৈছে..."</string>
+    <string name="quick_settings_tethering_label" msgid="7153452060448575549">"টেডাৰ কৰি থকা হৈছে"</string>
+    <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"হটস্পট"</string>
+    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
+    <skip />
+    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_notifications_label" msgid="4818156442169154523">"জাননীসমূহ"</string>
+    <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"ফ্লাশ্বলাইট"</string>
+    <!-- no translation found for quick_settings_cellular_detail_title (3661194685666477347) -->
+    <skip />
+    <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"ডেটা ব্যৱহাৰ"</string>
+    <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"বাকী থকা ডেটা"</string>
+    <string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"সর্ব্বোচ সীমা"</string>
+    <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> ব্যৱহৃত"</string>
+    <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> সীমা"</string>
+    <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> সকীয়নি"</string>
+    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
+    <skip />
+    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
+    <skip />
+    <!-- no translation found for quick_settings_night_display_label (3577098011487644395) -->
+    <skip />
+    <!-- no translation found for quick_settings_night_secondary_label_on_at_sunset (8483259341596943314) -->
+    <skip />
+    <!-- no translation found for quick_settings_night_secondary_label_until_sunrise (4453017157391574402) -->
+    <skip />
+    <!-- no translation found for quick_settings_night_secondary_label_on_at (6256314040368487637) -->
+    <skip />
+    <!-- no translation found for quick_settings_night_secondary_label_until (8664820079774824618) -->
+    <skip />
+    <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
+    <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC নিষ্ক্ৰিয় হৈ আছে"</string>
+    <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC সক্ষম হৈ আছে"</string>
+    <!-- no translation found for recents_empty_message (808480104164008572) -->
+    <skip />
+    <!-- no translation found for recents_empty_message_dismissed_all (2791312568666558651) -->
+    <skip />
+    <string name="recents_app_info_button_label" msgid="2890317189376000030">"এপ্লিকেশ্বনৰ তথ্য"</string>
+    <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"স্ক্ৰীণ পিনিং"</string>
+    <string name="recents_search_bar_label" msgid="8074997400187836677">"সন্ধান কৰক"</string>
+    <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> আৰম্ভ কৰিব পৰা নগ\'ল৷"</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
+    <!-- no translation found for recents_stack_action_button_label (6593727103310426253) -->
+    <skip />
+    <!-- no translation found for recents_drag_hint_message (2649739267073203985) -->
+    <skip />
+    <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
+    <skip />
+    <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
+    <skip />
+    <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
+    <skip />
+    <string name="recents_accessibility_split_screen_top" msgid="9056056469282256287">"স্ক্ৰীণখনক ওপৰফাললৈ ভাগ কৰক"</string>
+    <string name="recents_accessibility_split_screen_left" msgid="8987144699630620019">"স্ক্ৰীণখনক বাওঁফাললৈ ভাগ কৰক"</string>
+    <string name="recents_accessibility_split_screen_right" msgid="275069779299592867">"স্ক্ৰীণখনক সোঁফাললৈ ভাগ কৰক"</string>
+    <string name="expanded_header_battery_charged" msgid="5945855970267657951">"চ্চার্জ হ\'ল"</string>
+    <string name="expanded_header_battery_charging" msgid="205623198487189724">"চ্চার্জ হৈ আছে"</string>
+    <string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"বেটাৰিৰ চ্চাৰ্জ সম্পূর্ণ হ\'বলৈ <xliff:g id="CHARGING_TIME">%s</xliff:g> বাকী"</string>
+    <string name="expanded_header_battery_not_charging" msgid="4798147152367049732">"চ্চার্জ কৰি থকা নাই"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"নেটৱৰ্ক \nনিৰীক্ষণ কৰা হ\'ব পাৰে"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"অনুসন্ধান কৰক"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>ৰ বাবে ওপৰলৈ শ্লাইড কৰক।"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>ৰ বাবে বাওঁফাললৈ শ্লাইড কৰক।"</string>
+    <!-- no translation found for zen_priority_introduction (1149025108714420281) -->
+    <skip />
+    <!-- no translation found for zen_alarms_introduction (4934328096749380201) -->
+    <skip />
+    <!-- no translation found for zen_priority_customize_button (7948043278226955063) -->
+    <skip />
+    <!-- no translation found for zen_silence_introduction_voice (3948778066295728085) -->
+    <skip />
+    <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+    <skip />
+    <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
+    <string name="speed_bump_explanation" msgid="1288875699658819755">"কম জৰুৰী জাননীসমূহ তলত"</string>
+    <string name="notification_tap_again" msgid="7590196980943943842">"খুলিবলৈ পুনৰাই টিপক"</string>
+    <string name="keyguard_unlock" msgid="8043466894212841998">"আনলক কৰিবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string>
+    <string name="do_disclosure_generic" msgid="5615898451805157556">"আপোনাৰ প্ৰতিষ্ঠানে এই ডিভাইচটো পৰিচালনা কৰে"</string>
+    <!-- no translation found for do_disclosure_with_name (5640615509915445501) -->
+    <skip />
+    <!-- no translation found for phone_hint (4872890986869209950) -->
+    <skip />
+    <!-- no translation found for voice_hint (8939888732119726665) -->
+    <skip />
+    <!-- no translation found for camera_hint (7939688436797157483) -->
+    <skip />
+    <!-- no translation found for interruption_level_none_with_warning (5114872171614161084) -->
+    <skip />
+    <!-- no translation found for interruption_level_none (6000083681244492992) -->
+    <skip />
+    <!-- no translation found for interruption_level_priority (6426766465363855505) -->
+    <skip />
+    <!-- no translation found for interruption_level_alarms (5226306993448328896) -->
+    <skip />
+    <!-- no translation found for interruption_level_none_twoline (3957581548190765889) -->
+    <skip />
+    <!-- no translation found for interruption_level_priority_twoline (1564715335217164124) -->
+    <skip />
+    <!-- no translation found for interruption_level_alarms_twoline (3266909566410106146) -->
+    <skip />
+    <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"চ্চার্জ হৈ আছে (সম্পূর্ণ হ\'বলৈ <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>সময় বাকী)"</string>
+    <!-- no translation found for keyguard_indication_charging_time_fast (9018981952053914986) -->
+    <skip />
+    <!-- no translation found for keyguard_indication_charging_time_slowly (955252797961724952) -->
+    <skip />
+    <string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"ব্যৱহাৰকাৰী সলনি কৰক"</string>
+    <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"ব্যৱহাৰকাৰী সলনি কৰক, বৰ্তমানৰ ব্যৱহাৰকাৰী <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
+    <!-- no translation found for accessibility_multi_user_switch_inactive (1424081831468083402) -->
+    <skip />
+    <string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"প্ৰ\'ফাইল দেখুৱাওক"</string>
+    <string name="user_add_user" msgid="5110251524486079492">"ব্যৱহাৰকাৰী যোগ কৰক"</string>
+    <string name="user_new_user_name" msgid="426540612051178753">"নতুন ব্যৱহাৰকাৰী"</string>
+    <string name="guest_nickname" msgid="8059989128963789678">"অতিথি"</string>
+    <string name="guest_new_guest" msgid="600537543078847803">"অতিথি যোগ কৰক"</string>
+    <string name="guest_exit_guest" msgid="7187359342030096885">"অতিথি আঁতৰাওক"</string>
+    <string name="guest_exit_guest_dialog_title" msgid="8480693520521766688">"অতিথি আঁতৰাবনে?"</string>
+    <string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"এই ছেশ্বনৰ সকলো এপ্ আৰু ডেটা মচা হ\'ব।"</string>
+    <string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"আঁতৰাওক"</string>
+    <string name="guest_wipe_session_title" msgid="6419439912885956132">"আপোনাক পুনৰাই স্বাগতম জনাইছোঁ!"</string>
+    <string name="guest_wipe_session_message" msgid="8476238178270112811">"আপুনি আপোনাৰ ছেশ্বন অব্যাহত ৰাখিব বিচাৰেনে?"</string>
+    <string name="guest_wipe_session_wipe" msgid="5065558566939858884">"আকৌ আৰম্ভ কৰক"</string>
+    <string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"হয়, অব্যাহত ৰাখক"</string>
+    <!-- no translation found for guest_notification_title (1585278533840603063) -->
+    <skip />
+    <!-- no translation found for guest_notification_text (335747957734796689) -->
+    <skip />
+    <!-- no translation found for guest_notification_remove_action (8820670703892101990) -->
+    <skip />
+    <!-- no translation found for user_logout_notification_title (1453960926437240727) -->
+    <skip />
+    <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
+    <skip />
+    <!-- no translation found for user_logout_notification_action (1195428991423425062) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4553596395824132638">"নতুন ব্যৱহাৰকাৰী যোগ কৰিবনে?"</string>
+    <string name="user_add_user_message_short" msgid="2161624834066214559">"আপুনি যেতিয়া এজন নতুন ব্যৱহাৰকাৰী যোগ কৰে, তেওঁ নিজৰ স্থান ছেট আপ কৰা প্ৰয়োজন।\n\nযিকোনো ব্যৱহাৰকাৰীয়ে নিজৰ লগতে আন ব্যৱহাৰকাৰীৰো এপ্ আপডেট কৰিব পাৰে।"</string>
+    <!-- no translation found for user_remove_user_title (4681256956076895559) -->
+    <skip />
+    <!-- no translation found for user_remove_user_message (1453218013959498039) -->
+    <skip />
+    <!-- no translation found for user_remove_user_remove (7479275741742178297) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_title (8614079794522291840) -->
+    <skip />
+    <string name="battery_saver_notification_text" msgid="820318788126672692">"কাৰ্যদক্ষতা আৰু নেপথ্য ডেটা হ্ৰাস কৰে"</string>
+    <!-- no translation found for battery_saver_notification_action_text (132118784269455533) -->
+    <skip />
+    <string name="media_projection_dialog_text" msgid="3071431025448218928">"আপোনাৰ স্ক্ৰীণত প্ৰদৰ্শন হোৱা সকলো <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> কেপশ্বাৰ কৰা আৰম্ভ কৰিব।"</string>
+    <string name="media_projection_remember_text" msgid="3103510882172746752">"পুনৰাই নেদেখুৱাব"</string>
+    <string name="clear_all_notifications_text" msgid="814192889771462828">"সকলো মচক"</string>
+    <string name="media_projection_action_text" msgid="8470872969457985954">"এতিয়াই আৰম্ভ কৰক"</string>
+    <string name="empty_shade_text" msgid="708135716272867002">"কোনো জাননী নাই"</string>
+    <string name="profile_owned_footer" msgid="8021888108553696069">"প্ৰ\'ফাইল নিৰীক্ষণ কৰা হ\'ব পাৰে"</string>
+    <string name="vpn_footer" msgid="2388611096129106812">"নেটৱৰ্ক নিৰীক্ষণ কৰা হ\'ব পাৰে"</string>
+    <!-- no translation found for branded_vpn_footer (2168111859226496230) -->
+    <skip />
+    <string name="quick_settings_disclosure_management_monitoring" msgid="6645176135063957394">"আপোনাৰ প্ৰতিষ্ঠানটোৱে এই ডিভাইচটো পৰিচালনা কৰে আৰু ই নেটৱৰ্কৰ ট্ৰেফিক পৰ্যবেক্ষণ কৰিব পাৰে।"</string>
+    <!-- no translation found for quick_settings_disclosure_named_management_monitoring (370622174777570853) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_management_named_vpn (1085137869053332307) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (6290456493852584017) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_management (3294967280853150271) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_named_management (1059403025094542908) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_management_vpns (3698767349925266482) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_named_management_vpns (7777821385318891527) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_managed_profile_monitoring (5125463987558278215) -->
+    <skip />
+    <string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8973606847896650284">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>এ আপোনাৰ কৰ্মস্থানৰ প্ৰ\'ফাইলৰ নেটৱৰ্ক ট্ৰেফিক পৰ্যবেক্ষণ কৰিব পাৰে"</string>
+    <!-- no translation found for quick_settings_disclosure_monitoring (679658227269205728) -->
+    <skip />
+    <string name="quick_settings_disclosure_vpns" msgid="8170318392053156330">"ডিভাইচটো ভিপিএনবোৰৰ সৈতে সংযুক্ত হৈ আছে"</string>
+    <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (3494535754792751741) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (4467456202486569906) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_named_vpn (6943724064780847080) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (1652495295941959815) -->
+    <skip />
+    <string name="monitoring_title_profile_owned" msgid="6790109874733501487">"প্ৰ\'ফাইল নিৰীক্ষণ"</string>
+    <string name="monitoring_title" msgid="169206259253048106">"নেটৱৰ্ক নিৰীক্ষণ"</string>
+    <string name="monitoring_subtitle_vpn" msgid="876537538087857300">"ভিপিএন"</string>
+    <!-- no translation found for monitoring_subtitle_network_logging (3341264304793193386) -->
+    <skip />
+    <!-- no translation found for monitoring_subtitle_ca_certificate (3874151893894355988) -->
+    <skip />
+    <string name="disable_vpn" msgid="4435534311510272506">"ভিপিএন অক্ষম কৰক"</string>
+    <string name="disconnect_vpn" msgid="1324915059568548655">"ভিপিএন সংযোগ বিচ্ছিন্ন কৰক"</string>
+    <string name="monitoring_button_view_policies" msgid="100913612638514424">"নীতিসমূহ চাওক"</string>
+    <!-- no translation found for monitoring_description_named_management (5281789135578986303) -->
+    <skip />
+    <!-- no translation found for monitoring_description_management (4573721970278370790) -->
+    <skip />
+    <string name="monitoring_description_management_ca_certificate" msgid="5202023784131001751">"আপোনাৰ প্ৰতিষ্ঠানে এই ডিভাইচটোত এটা প্ৰমাণপত্ৰ সম্পৰ্কীয় কৰ্তৃপক্ষ ইনষ্টল কৰিছে। আপোনাৰ সুৰক্ষিত নেটৱৰ্ক ট্ৰেফিক পৰ্যবেক্ষণ বা সংশোধন কৰা হ\'ব পাৰে।"</string>
+    <!-- no translation found for monitoring_description_managed_profile_ca_certificate (4683248196789897964) -->
+    <skip />
+    <string name="monitoring_description_ca_certificate" msgid="7886985418413598352">"এই ডিভাইচটোত এটা প্ৰমাণপত্ৰ সম্পৰ্কীয় কৰ্তৃপক্ষ ইনষ্টল কৰা হৈছে। আপোনাৰ সুৰক্ষিত নেটৱৰ্কৰ ট্ৰেফিক পৰ্যবেক্ষণ বা সংশোধন কৰা হ\'ব পাৰে।"</string>
+    <string name="monitoring_description_management_network_logging" msgid="7184005419733060736">"আপোনাৰ প্ৰশাসকে নেটৱৰ্ক লগিং অন কৰিছে, যিয়ে আপোনাৰ ডিভাইচটোত নেটৱৰ্ক ট্ৰেফিক পৰ্যবেক্ষণ কৰে।"</string>
+    <!-- no translation found for monitoring_description_named_vpn (7403457334088909254) -->
+    <skip />
+    <!-- no translation found for monitoring_description_two_named_vpns (4198511413729213802) -->
+    <skip />
+    <string name="monitoring_description_managed_profile_named_vpn" msgid="1427905889862420559">"আপুনি <xliff:g id="VPN_APP">%1$s</xliff:g>ৰে সংযুক্ত হৈ আছে যিয়ে আপোনাৰ ইমেইল, এপ্ আৰু ৱেবছাইটকে ধৰি নেটৱর্কৰ কাৰ্যকলাপ পৰ্যবেক্ষণ কৰিব পাৰে।"</string>
+    <!-- no translation found for monitoring_description_personal_profile_named_vpn (3133980926929069283) -->
+    <skip />
+    <!-- no translation found for monitoring_description_do_header_generic (96588491028288691) -->
+    <skip />
+    <!-- no translation found for monitoring_description_do_header_with_name (5511133708978206460) -->
+    <skip />
+    <string name="monitoring_description_do_body" msgid="3639594537660975895">"আপোনাৰ প্ৰশাসকে আপোনাৰ ডিভাইচৰ লগত জড়িত ছেটিংসমূহ, কৰ্প\'ৰেইট অনুমতি, এপসমূহ, ডেটা আৰু ডিভাইচৰ অৱস্থান সম্পৰ্কীয় তথ্য পৰ্যবেক্ষণ কৰাৰ লগতে পৰিচালনা কৰিব পাৰিব।"</string>
+    <!-- no translation found for monitoring_description_do_learn_more_separator (3785251953067436862) -->
+    <skip />
+    <!-- no translation found for monitoring_description_do_learn_more (1849514470437907421) -->
+    <skip />
+    <!-- no translation found for monitoring_description_do_body_vpn (8255218762488901796) -->
+    <skip />
+    <string name="monitoring_description_vpn_settings_separator" msgid="1933186756733474388">" "</string>
+    <!-- no translation found for monitoring_description_vpn_settings (6434859242636063861) -->
+    <skip />
+    <!-- no translation found for monitoring_description_ca_cert_settings_separator (4987350385906393626) -->
+    <skip />
+    <!-- no translation found for monitoring_description_ca_cert_settings (5489969458872997092) -->
+    <skip />
+    <string name="monitoring_description_network_logging" msgid="7223505523384076027">"আপোনাৰ প্ৰশাসকে নেটৱৰ্ক লগিং অন কৰিছে, যিয়ে আপোনাৰ ডিভাইচটোত নেটৱৰ্ক ট্ৰেফিক পৰ্যবেক্ষণ কৰে।\n\nএই সম্পৰ্কে অধিক জানিবলৈ আপোনাৰ প্ৰশাসকৰ সৈতে যোগাযোগ কৰক।"</string>
+    <!-- no translation found for monitoring_description_vpn (4445150119515393526) -->
+    <skip />
+    <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"<xliff:g id="ORGANIZATION">%1$s</xliff:g>য়ে আপোনাৰ কৰ্মস্থানৰ প্ৰ\'ফাইল পৰিচালনা কৰে।\n\nআপোনাৰ প্ৰশাসকে ইমেইল, এপসমূহ আৰু আপুনি চোৱা ৱেবছাইটকে ধৰি আপোনাৰ নেটৱৰ্কৰ সকলো কাৰ্যকলাপ পৰ্যবেক্ষণ কৰিব পাৰে। \n\nঅধিক তথ্যৰ বাবে আপোনাৰ প্ৰশাসকৰ সৈতে যোগাযোগ কৰক।\n\nইয়াৰ উপৰি, আপুনি এটা ভিপিএনৰ সৈতে সংযুক্ত হৈ আছে, যিয়ে আপোনাৰ নেটৱৰ্কৰ কাৰ্যকলাপ পৰ্যবেক্ষণ কৰিব পাৰে।"</string>
+    <!-- no translation found for legacy_vpn_name (6604123105765737830) -->
+    <skip />
+    <string name="monitoring_description_app" msgid="1828472472674709532">"আপুনি <xliff:g id="APPLICATION">%1$s</xliff:g>ৰে সংযুক্ত হৈ আছে যিয়ে আপোনাৰ ইমেইল, এপ্ আৰু ৱেবছাইটকে ধৰি নেটৱর্কৰ কাৰ্যকলাপ পৰ্যবেক্ষণ কৰিব পাৰে।"</string>
+    <!-- no translation found for monitoring_description_app_personal (484599052118316268) -->
+    <skip />
+    <!-- no translation found for branded_monitoring_description_app_personal (2669518213949202599) -->
+    <skip />
+    <!-- no translation found for monitoring_description_app_work (4612997849787922906) -->
+    <skip />
+    <!-- no translation found for monitoring_description_app_personal_work (5664165460056859391) -->
+    <skip />
+    <!-- no translation found for keyguard_indication_trust_granted (4985003749105182372) -->
+    <skip />
+    <!-- no translation found for keyguard_indication_trust_managed (8319646760022357585) -->
+    <skip />
+    <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"আপুনি নিজে আনলক নকৰালৈকে ডিভাইচ লক হৈ থাকিব"</string>
+    <string name="hidden_notifications_title" msgid="7139628534207443290">"জাননী ক্ষিপ্ৰতাৰে লাভ কৰক"</string>
+    <string name="hidden_notifications_text" msgid="2326409389088668981">"আপুনি আনলক কৰাৰ পূৰ্বে তেওঁলোকক চাওক"</string>
+    <string name="hidden_notifications_cancel" msgid="3690709735122344913">"নালাগে, ধন্যবাদ"</string>
+    <string name="hidden_notifications_setup" msgid="41079514801976810">"ছেট আপ কৰক"</string>
+    <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
+    <!-- no translation found for volume_zen_end_now (6930243045593601084) -->
+    <skip />
+    <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
+    <skip />
+    <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
+    <skip />
+    <!-- no translation found for accessibility_output_chooser (8185317493017988680) -->
+    <skip />
+    <string name="screen_pinning_title" msgid="3273740381976175811">"স্ক্ৰীণ পিন কৰা হ\'ল"</string>
+    <string name="screen_pinning_description" msgid="8909878447196419623">"এই কাৰ্যই আপুনি আনপিন নকৰালৈকে ইয়াক দেখা পোৱা অৱস্থাত ৰাখে। আনপিন কৰিবলৈ \'পিছলৈ যাওক\' আৰু \'অৱলোকন\'-ত স্পৰ্শ কৰি থাকক।"</string>
+    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
+    <skip />
+    <string name="screen_pinning_description_accessible" msgid="426190689254018656">"এই কাৰ্যই আপুনি আনপিন নকৰালৈকে ইয়াক দেখা পোৱা অৱস্থাত ৰাখে। আনপিন কৰিবলৈ \'অৱলোকন\'-ত স্পৰ্শ কৰি থাকক।"</string>
+    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
+    <skip />
+    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
+    <skip />
+    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
+    <skip />
+    <string name="screen_pinning_positive" msgid="3783985798366751226">"বুজি পালোঁ"</string>
+    <string name="screen_pinning_negative" msgid="3741602308343880268">"নালাগে, ধন্যবাদ"</string>
+    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
+    <skip />
+    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
+    <skip />
+    <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> লুকুৱাবনে?"</string>
+    <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"আপুনি ইয়াক পৰৱৰ্তী সময়ত ছেটিংসমূহত অন কৰিলে ই পুনৰ প্ৰকট হ\'ব।"</string>
+    <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"লুকুৱাওক"</string>
+    <!-- no translation found for managed_profile_foreground_toast (5421487114739245972) -->
+    <skip />
+    <!-- no translation found for stream_voice_call (4410002696470423714) -->
+    <skip />
+    <!-- no translation found for stream_system (7493299064422163147) -->
+    <skip />
+    <string name="stream_ring" msgid="8213049469184048338">"ৰিং"</string>
+    <string name="stream_music" msgid="9086982948697544342">"মিডিয়া"</string>
+    <!-- no translation found for stream_alarm (5209444229227197703) -->
+    <skip />
+    <string name="stream_notification" msgid="2563720670905665031">"জাননী"</string>
+    <string name="stream_bluetooth_sco" msgid="2055645746402746292">"ব্লুটুথ"</string>
+    <string name="stream_dtmf" msgid="2447177903892477915">"ডুৱেল মাল্টি ট\'ন ফ্ৰিকুৱেন্সী"</string>
+    <string name="stream_accessibility" msgid="301136219144385106">"দিব্যাংগসকলৰ বাবে থকা সুবিধাসমূহ"</string>
+    <!-- no translation found for ring_toggle_title (3281244519428819576) -->
+    <skip />
+    <!-- no translation found for volume_ringer_status_normal (4273142424125855384) -->
+    <skip />
+    <!-- no translation found for volume_ringer_status_vibrate (1825615171021346557) -->
+    <skip />
+    <!-- no translation found for volume_ringer_status_silent (6896394161022916369) -->
+    <skip />
+    <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+    <skip />
+    <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+    <skip />
+    <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+    <skip />
+    <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s। কম্পন অৱস্থাত ছেট কৰিবলৈ টিপক।"</string>
+    <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s। মিউট কৰিবলৈ টিপক।"</string>
+    <!-- no translation found for volume_dialog_title (7272969888820035876) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_vibrate (8902050240801159042) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_silent (2128975224280276122) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_ring (6144469689490528338) -->
+    <skip />
+    <!-- no translation found for output_title (5355078100792942802) -->
+    <skip />
+    <!-- no translation found for output_calls_title (8717692905017206161) -->
+    <skip />
+    <!-- no translation found for output_none_found (5544982839808921091) -->
+    <skip />
+    <!-- no translation found for output_none_found_service_off (8631969668659757069) -->
+    <skip />
+    <!-- no translation found for output_service_bt (6224213415445509542) -->
+    <skip />
+    <!-- no translation found for output_service_wifi (3749735218931825054) -->
+    <skip />
+    <!-- no translation found for output_service_bt_wifi (4486837869988770896) -->
+    <skip />
+    <!-- no translation found for system_ui_tuner (708224127392452018) -->
+    <skip />
+    <!-- no translation found for show_battery_percentage (5444136600512968798) -->
+    <skip />
+    <!-- no translation found for show_battery_percentage_summary (3215025775576786037) -->
+    <skip />
+    <!-- no translation found for quick_settings (10042998191725428) -->
+    <skip />
+    <!-- no translation found for status_bar (4877645476959324760) -->
+    <skip />
+    <!-- no translation found for overview (4018602013895926956) -->
+    <skip />
+    <string name="demo_mode" msgid="2532177350215638026">"ছিষ্টেমৰ UI প্ৰদৰ্শন ম\'ড"</string>
+    <!-- no translation found for enable_demo_mode (4844205668718636518) -->
+    <skip />
+    <!-- no translation found for show_demo_mode (2018336697782464029) -->
+    <skip />
+    <!-- no translation found for status_bar_ethernet (5044290963549500128) -->
+    <skip />
+    <!-- no translation found for status_bar_alarm (8536256753575881818) -->
+    <skip />
+    <!-- no translation found for status_bar_work (6022553324802866373) -->
+    <skip />
+    <!-- no translation found for status_bar_airplane (7057575501472249002) -->
+    <skip />
+    <!-- no translation found for add_tile (2995389510240786221) -->
+    <skip />
+    <!-- no translation found for broadcast_tile (3894036511763289383) -->
+    <skip />
+    <!-- no translation found for zen_alarm_warning_indef (3482966345578319605) -->
+    <skip />
+    <!-- no translation found for zen_alarm_warning (444533119582244293) -->
+    <skip />
+    <!-- no translation found for alarm_template (3980063409350522735) -->
+    <skip />
+    <!-- no translation found for alarm_template_far (4242179982586714810) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_detail (2579369091672902101) -->
+    <skip />
+    <!-- no translation found for accessibility_status_bar_hotspot (4099381329956402865) -->
+    <skip />
+    <!-- no translation found for accessibility_managed_profile (6613641363112584120) -->
+    <skip />
+    <!-- no translation found for tuner_warning_title (7094689930793031682) -->
+    <skip />
+    <!-- no translation found for tuner_warning (8730648121973575701) -->
+    <skip />
+    <!-- no translation found for tuner_persistent_warning (8597333795565621795) -->
+    <skip />
+    <!-- no translation found for got_it (2239653834387972602) -->
+    <skip />
+    <!-- no translation found for tuner_toast (603429811084428439) -->
+    <skip />
+    <!-- no translation found for remove_from_settings (8389591916603406378) -->
+    <skip />
+    <!-- no translation found for remove_from_settings_prompt (6069085993355887748) -->
+    <skip />
+    <!-- no translation found for activity_not_found (348423244327799974) -->
+    <skip />
+    <!-- no translation found for clock_seconds (7689554147579179507) -->
+    <skip />
+    <!-- no translation found for clock_seconds_desc (6282693067130470675) -->
+    <skip />
+    <!-- no translation found for qs_rearrange (8060918697551068765) -->
+    <skip />
+    <!-- no translation found for show_brightness (6613930842805942519) -->
+    <skip />
+    <!-- no translation found for experimental (6198182315536726162) -->
+    <skip />
+    <!-- no translation found for enable_bluetooth_title (5027037706500635269) -->
+    <skip />
+    <!-- no translation found for enable_bluetooth_message (9106595990708985385) -->
+    <skip />
+    <!-- no translation found for enable_bluetooth_confirmation_ok (6258074250948309715) -->
+    <skip />
+    <!-- no translation found for show_silently (6841966539811264192) -->
+    <skip />
+    <!-- no translation found for block (2734508760962682611) -->
+    <skip />
+    <!-- no translation found for do_not_silence (6878060322594892441) -->
+    <skip />
+    <!-- no translation found for do_not_silence_block (4070647971382232311) -->
+    <skip />
+    <!-- no translation found for tuner_full_importance_settings (3207312268609236827) -->
+    <skip />
+    <!-- no translation found for tuner_full_importance_settings_on (7545060756610299966) -->
+    <skip />
+    <!-- no translation found for tuner_full_importance_settings_off (8208165412614935229) -->
+    <skip />
+    <!-- no translation found for power_notification_controls_description (4372459941671353358) -->
+    <skip />
+    <string name="notification_header_default_channel" msgid="7506845022070889909">"জাননীসমূহ"</string>
+    <!-- no translation found for notification_channel_disabled (344536703863700565) -->
+    <skip />
+    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
+    <skip />
+    <!-- no translation found for inline_keep_showing (8945102997083836858) -->
+    <skip />
+    <!-- no translation found for inline_stop_button (4172980096860941033) -->
+    <skip />
+    <!-- no translation found for inline_keep_button (6665940297019018232) -->
+    <skip />
+    <!-- no translation found for inline_keep_showing_app (1723113469580031041) -->
+    <skip />
+    <!-- no translation found for notification_unblockable_desc (1037434112919403708) -->
+    <skip />
+    <!-- no translation found for notification_channel_controls_opened_accessibility (6553950422055908113) -->
+    <skip />
+    <!-- no translation found for notification_channel_controls_closed_accessibility (7521619812603693144) -->
+    <skip />
+    <!-- no translation found for notification_channel_switch_accessibility (3420796005601900717) -->
+    <skip />
+    <!-- no translation found for notification_more_settings (816306283396553571) -->
+    <skip />
+    <!-- no translation found for notification_app_settings (420348114670768449) -->
+    <skip />
+    <!-- no translation found for notification_done (5279426047273930175) -->
+    <skip />
+    <!-- no translation found for inline_undo (558916737624706010) -->
+    <skip />
+    <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
+    <string name="notification_menu_gear_description" msgid="2204480013726775108">"জাননীৰ নিয়ন্ত্ৰণসমূহ"</string>
+    <string name="notification_menu_snooze_description" msgid="3653669438131034525">"জাননীক স্নুজ কৰাৰ বিকল্পসমূহ"</string>
+    <string name="snooze_undo" msgid="6074877317002985129">"আনডু কৰক"</string>
+    <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>ৰ বাবে স্নুজ কৰক"</string>
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
+    <!-- no translation found for battery_detail_charging_summary (1279095653533044008) -->
+    <skip />
+    <!-- no translation found for battery_detail_switch_title (6285872470260795421) -->
+    <skip />
+    <!-- no translation found for battery_detail_switch_summary (9049111149407626804) -->
+    <skip />
+    <!-- no translation found for keyboard_key_button_template (6230056639734377300) -->
+    <skip />
+    <!-- no translation found for keyboard_key_home (2243500072071305073) -->
+    <skip />
+    <!-- no translation found for keyboard_key_back (2337450286042721351) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_up (5584144111755734686) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (7331518671788337815) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (1346446024676962251) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (3317323247127515341) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_center (2566737770049304658) -->
+    <skip />
+    <!-- no translation found for keyboard_key_tab (3871485650463164476) -->
+    <skip />
+    <!-- no translation found for keyboard_key_space (2499861316311153293) -->
+    <skip />
+    <!-- no translation found for keyboard_key_enter (5739632123216118137) -->
+    <skip />
+    <!-- no translation found for keyboard_key_backspace (1559580097512385854) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_play_pause (3861975717393887428) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_stop (2859963958595908962) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_next (1894394911630345607) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_previous (4256072387192967261) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_rewind (2654808213360820186) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_fast_forward (3849417047738200605) -->
+    <skip />
+    <!-- no translation found for keyboard_key_page_up (5654098530106845603) -->
+    <skip />
+    <!-- no translation found for keyboard_key_page_down (8720502083731906136) -->
+    <skip />
+    <!-- no translation found for keyboard_key_forward_del (1391451334716490176) -->
+    <skip />
+    <!-- no translation found for keyboard_key_move_home (2765693292069487486) -->
+    <skip />
+    <!-- no translation found for keyboard_key_move_end (5901174332047975247) -->
+    <skip />
+    <!-- no translation found for keyboard_key_insert (8530501581636082614) -->
+    <skip />
+    <!-- no translation found for keyboard_key_num_lock (5052537581246772117) -->
+    <skip />
+    <!-- no translation found for keyboard_key_numpad_template (8729216555174634026) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_system (6472647649616541064) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_system_home (3054369431319891965) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_system_recents (3154851905021926744) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_system_back (2207004531216446378) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_system_notifications (8366964080041773224) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_system_shortcuts_helper (4892255911160332762) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_system_switch_input (2334164096341310324) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_applications (9129465955073449206) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_applications_assist (9095441910537146013) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_applications_browser (6465985474000766533) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_applications_contacts (2064197111278436375) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_applications_email (6257036897441939004) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_applications_music (4775559515850922780) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_applications_youtube (6555453761294723317) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_applications_calendar (9043614299194991263) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_title (4540823317772234308) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3373784330208603030) -->
+    <skip />
+    <!-- no translation found for volume_dnd_silent (4363882330723050727) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
+    <!-- no translation found for battery (7498329822413202973) -->
+    <skip />
+    <!-- no translation found for clock (7416090374234785905) -->
+    <skip />
+    <!-- no translation found for headset (4534219457597457353) -->
+    <skip />
+    <!-- no translation found for accessibility_status_bar_headphones (9156307120060559989) -->
+    <skip />
+    <!-- no translation found for accessibility_status_bar_headset (8666419213072449202) -->
+    <skip />
+    <!-- no translation found for data_saver (5037565123367048522) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
+    <skip />
+    <!-- no translation found for switch_bar_on (1142437840752794229) -->
+    <skip />
+    <!-- no translation found for switch_bar_off (8803270596930432874) -->
+    <skip />
+    <!-- no translation found for nav_bar (1993221402773877607) -->
+    <skip />
+    <string name="nav_bar_layout" msgid="3664072994198772020">"লেআউট"</string>
+    <string name="left_nav_bar_button_type" msgid="8555981238887546528">"বাওঁ বুটামৰ অতিৰিক্ত প্ৰকাৰ"</string>
+    <string name="right_nav_bar_button_type" msgid="2481056627065649656">"সোঁ বুটামৰ অতিৰিক্ত প্ৰকাৰ"</string>
+    <string name="nav_bar_default" msgid="8587114043070993007">"ডিফ\'ল্ট"</string>
+    <!-- no translation found for nav_bar_buttons:2 (1951959982985094069) -->
+  <string-array name="nav_bar_layouts">
+    <item msgid="8077901629964902399">"সাধাৰণ"</item>
+    <item msgid="8256205964297588988">"ঘন"</item>
+    <item msgid="8719936228094005878">"বাওঁফালে হালি যোৱা"</item>
+    <item msgid="586019486955594690">"সোঁফালে হালি যোৱা"</item>
+  </string-array>
+    <string name="menu_ime" msgid="4998010205321292416">"কীব\'ৰ্ড সলনি কৰাৰ সুবিধা"</string>
+    <!-- no translation found for save (2311877285724540644) -->
+    <skip />
+    <string name="reset" msgid="2448168080964209908">"ৰিছেট কৰক"</string>
+    <!-- no translation found for adjust_button_width (6138616087197632947) -->
+    <skip />
+    <!-- no translation found for clipboard (1313879395099896312) -->
+    <skip />
+    <!-- no translation found for accessibility_key (5701989859305675896) -->
+    <skip />
+    <string name="left_keycode" msgid="2010948862498918135">"বাওঁ কীক\'ড"</string>
+    <string name="right_keycode" msgid="708447961000848163">"সোঁ কীক\'ড"</string>
+    <string name="left_icon" msgid="3096287125959387541">"বাওঁ আইকন"</string>
+    <string name="right_icon" msgid="3952104823293824311">"সোঁ আইকন"</string>
+    <!-- no translation found for drag_to_add_tiles (7058945779098711293) -->
+    <skip />
+    <!-- no translation found for drag_to_remove_tiles (3361212377437088062) -->
+    <skip />
+    <!-- no translation found for qs_edit (2232596095725105230) -->
+    <skip />
+    <!-- no translation found for tuner_time (6572217313285536011) -->
+    <skip />
+    <!-- no translation found for clock_options:0 (5965318737560463480) -->
+    <!-- no translation found for clock_options:1 (1427801730816895300) -->
+    <!-- no translation found for clock_options:2 (3830170141562534721) -->
+    <!-- no translation found for battery_options:0 (3160236755818672034) -->
+    <!-- no translation found for battery_options:1 (2139628951880142927) -->
+    <!-- no translation found for battery_options:2 (3327323682209964956) -->
+    <!-- no translation found for other (4060683095962566764) -->
+    <skip />
+    <!-- no translation found for accessibility_divider (5903423481953635044) -->
+    <skip />
+    <!-- no translation found for accessibility_action_divider_left_full (2801570521881574972) -->
+    <skip />
+    <!-- no translation found for accessibility_action_divider_left_70 (3612060638991687254) -->
+    <skip />
+    <!-- no translation found for accessibility_action_divider_left_50 (1248083470322193075) -->
+    <skip />
+    <!-- no translation found for accessibility_action_divider_left_30 (543324403127069386) -->
+    <skip />
+    <!-- no translation found for accessibility_action_divider_right_full (4639381073802030463) -->
+    <skip />
+    <!-- no translation found for accessibility_action_divider_top_full (5357010904067731654) -->
+    <skip />
+    <!-- no translation found for accessibility_action_divider_top_70 (5090779195650364522) -->
+    <skip />
+    <!-- no translation found for accessibility_action_divider_top_50 (6385859741925078668) -->
+    <skip />
+    <!-- no translation found for accessibility_action_divider_top_30 (6201455163864841205) -->
+    <skip />
+    <!-- no translation found for accessibility_action_divider_bottom_full (301433196679548001) -->
+    <skip />
+    <!-- no translation found for accessibility_qs_edit_tile_label (8374924053307764245) -->
+    <skip />
+    <!-- no translation found for accessibility_qs_edit_add_tile_label (8133209638023882667) -->
+    <skip />
+    <!-- no translation found for accessibility_qs_edit_position_label (5055306305919289819) -->
+    <skip />
+    <!-- no translation found for accessibility_qs_edit_move_tile (2461819993780159542) -->
+    <skip />
+    <!-- no translation found for accessibility_qs_edit_remove_tile (7484493384665907197) -->
+    <skip />
+    <!-- no translation found for accessibility_qs_edit_tile_added (8050200862063548309) -->
+    <skip />
+    <!-- no translation found for accessibility_qs_edit_tile_removed (8584304916627913440) -->
+    <skip />
+    <!-- no translation found for accessibility_qs_edit_tile_moved (4343693412689365038) -->
+    <skip />
+    <!-- no translation found for accessibility_desc_quick_settings_edit (8073587401747016103) -->
+    <skip />
+    <!-- no translation found for accessibility_desc_notification_icon (8352414185263916335) -->
+    <skip />
+    <!-- no translation found for dock_forced_resizable (5914261505436217520) -->
+    <skip />
+    <!-- no translation found for dock_non_resizeble_failed_to_dock_text (3871617304250207291) -->
+    <skip />
+    <!-- no translation found for forced_resizable_secondary_display (4230857851756391925) -->
+    <skip />
+    <!-- no translation found for activity_launch_on_secondary_display_failed_text (7793821742158306742) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_settings (6132460890024942157) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_expand (2375165227880477530) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_collapse (1792625797142648105) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_alarm_set (1863000242431528676) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_user (1567445362870421770) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_no_internet (31890692343084075) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_open_details (4230931801728005194) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_open_settings (7806613775728380737) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_edit (7839992848995240393) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_page (5032979051755200721) -->
+    <skip />
+    <string name="tuner_lock_screen" msgid="5755818559638850294">"লক স্ক্ৰীণ"</string>
+    <!-- no translation found for pip_phone_expand (5889780005575693909) -->
+    <skip />
+    <string name="pip_phone_minimize" msgid="1079119422589131792">"সৰু কৰক"</string>
+    <string name="pip_phone_close" msgid="8416647892889710330">"বন্ধ কৰক"</string>
+    <!-- no translation found for pip_phone_settings (8080777499521528521) -->
+    <skip />
+    <!-- no translation found for pip_phone_dismiss_hint (6351678169095923899) -->
+    <skip />
+    <!-- no translation found for pip_menu_title (4707292089961887657) -->
+    <skip />
+    <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> চিত্ৰৰ ভিতৰৰ চিত্ৰত আছে"</string>
+    <!-- no translation found for pip_notification_message (5619512781514343311) -->
+    <skip />
+    <!-- no translation found for pip_play (1417176722760265888) -->
+    <skip />
+    <!-- no translation found for pip_pause (8881063404466476571) -->
+    <skip />
+    <!-- no translation found for pip_skip_to_next (1948440006726306284) -->
+    <skip />
+    <!-- no translation found for pip_skip_to_prev (1955311326688637914) -->
+    <skip />
+    <!-- no translation found for thermal_shutdown_title (4458304833443861111) -->
+    <skip />
+    <!-- no translation found for thermal_shutdown_message (9006456746902370523) -->
+    <skip />
+    <!-- no translation found for thermal_shutdown_dialog_message (566347880005304139) -->
+    <skip />
+    <string name="high_temp_title" msgid="4589508026407318374">"ফ\'নটো গৰম হ\'বলৈ ধৰিছে"</string>
+    <string name="high_temp_notif_message" msgid="5642466103153429279">"ফ\'নটো ঠাণ্ডা হৈ থকা সময়ত কিছুমান সুবিধা উপলব্ধ নহ\'ব"</string>
+    <string name="high_temp_dialog_message" msgid="6840700639374113553">"আপোনাৰ ফ\'নটোৱে নিজে নিজে ঠাণ্ডা হ\'বলৈ স্বয়ংক্ৰিয়ভাৱে চেষ্টা কৰিব। আপুনি ফ\'নটো ব্যৱহাৰ কৰি থাকিব পাৰে কিন্তু ই লাহে লাহে চলিব পাৰে।\n\nফ\'নটো সম্পূৰ্ণভাৱে ঠাণ্ডা হোৱাৰ পিছত ই আগৰ নিচিনাকৈয়েই চলিব।"</string>
+    <string name="lockscreen_shortcut_left" msgid="2182769107618938629">"বাওঁ শ্বৰ্টকাট"</string>
+    <string name="lockscreen_shortcut_right" msgid="3328683699505226536">"সোঁ শ্বৰ্টকাট"</string>
+    <string name="lockscreen_unlock_left" msgid="2043092136246951985">"বাওঁ শ্বৰ্টকাটটোৱেও আনলক কৰিব"</string>
+    <string name="lockscreen_unlock_right" msgid="1529992940510318775">"সোঁ শ্বৰ্টকাটটোৱেও আনলক কৰিব"</string>
+    <string name="lockscreen_none" msgid="4783896034844841821">"একো বাছনি কৰা হোৱা নাই"</string>
+    <string name="tuner_launch_app" msgid="1527264114781925348">"<xliff:g id="APP">%1$s</xliff:g>ক লঞ্চ কৰক"</string>
+    <string name="tuner_other_apps" msgid="4726596850501162493">"অন্যান্য এপসমূহ"</string>
+    <string name="tuner_circle" msgid="2340998864056901350">"পৰিচিত মানুহৰ গোট"</string>
+    <string name="tuner_plus" msgid="6792960658533229675">"যোগ চিহ্ন"</string>
+    <string name="tuner_minus" msgid="4806116839519226809">"বিয়োগ চিহ্ন"</string>
+    <string name="tuner_left" msgid="8404287986475034806">"বাওঁ"</string>
+    <string name="tuner_right" msgid="6222734772467850156">"সোঁ"</string>
+    <string name="tuner_menu" msgid="191640047241552081">"মেনু"</string>
+    <string name="tuner_app" msgid="3507057938640108777">"<xliff:g id="APP">%1$s</xliff:g> এপ্"</string>
+    <string name="notification_channel_alerts" msgid="4496839309318519037">"সতৰ্কবাণীসমূহ"</string>
+    <!-- no translation found for notification_channel_battery (5786118169182888462) -->
+    <skip />
+    <string name="notification_channel_screenshot" msgid="6314080179230000938">"স্ক্ৰীণশ্বটসমূহ"</string>
+    <string name="notification_channel_general" msgid="4525309436693914482">"সাধাৰণ বার্তাসমূহ"</string>
+    <string name="notification_channel_storage" msgid="3077205683020695313">"সঞ্চয়াগাৰ"</string>
+    <string name="instant_apps" msgid="6647570248119804907">"তাৎক্ষণিক এপসমূহ"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"তাৎক্ষণিক এপসমূহক ইনষ্টল কৰাৰ প্ৰয়োজন নাই।"</string>
+    <!-- no translation found for app_info (6856026610594615344) -->
+    <skip />
+    <!-- no translation found for go_to_web (2650669128861626071) -->
+    <skip />
+    <string name="mobile_data" msgid="7094582042819250762">"ম\'বাইল ডেটা"</string>
+    <!-- no translation found for wifi_is_off (1838559392210456893) -->
+    <skip />
+    <!-- no translation found for bt_is_off (2640685272289706392) -->
+    <skip />
+    <!-- no translation found for dnd_is_off (6167780215212497572) -->
+    <skip />
+    <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+    <skip />
+    <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+    <skip />
+    <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+    <skip />
+    <!-- no translation found for qs_dnd_until (3469471136280079874) -->
+    <skip />
+    <!-- no translation found for qs_dnd_keep (1825009164681928736) -->
+    <skip />
+    <!-- no translation found for qs_dnd_replace (8019520786644276623) -->
+    <skip />
+    <!-- no translation found for running_foreground_services_title (381024150898615683) -->
+    <skip />
+    <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
+    <skip />
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"ম’বাইল ডেটা অফ কৰিবনে?"</string>
+    <!-- no translation found for touch_filtered_warning (8671693809204767551) -->
+    <skip />
+    <!-- no translation found for slice_permission_title (7465009437851044444) -->
+    <skip />
+    <!-- no translation found for slice_permission_text_1 (3514586565609596523) -->
+    <skip />
+    <!-- no translation found for slice_permission_text_2 (3146758297471143723) -->
+    <skip />
+    <!-- no translation found for slice_permission_checkbox (7986504458640562900) -->
+    <skip />
+    <!-- no translation found for slice_permission_allow (2340244901366722709) -->
+    <skip />
+    <!-- no translation found for slice_permission_deny (7683681514008048807) -->
+    <skip />
+</resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index e00a2dd..6d086ae 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"kemaranı açın"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Yeni tapşırıq sxemi seçin"</string>
     <string name="cancel" msgid="6442560571259935130">"Ləğv et"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Barmaq izi ikonası"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Tətbiq ikonası"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Yardım mesajı bölməsi"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Desert Qabı"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Ekran qoruyucu"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Narahat etməyin"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Yalnız prioritet"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Yalnız alarmlar"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi sönülüdür"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi Aktiv"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Heç bir Wi-Fi şəbəkəsi əlçatan deyil"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Siqnal"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Yayım"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Yayım"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Adsız cihaz"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> güvənli rejimdə deaktiv edildi."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Hamısını silin"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Ekranı bölmək üçün bura sürüşdürün"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Tətbiqi dəyişmək üçün yuxarı sürüşdürün"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Üfüqi Böl"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Şaquli Böl"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Fərdi Böl"</string>
@@ -503,21 +505,15 @@
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"Çıxış cihazına keçin"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Ekrana sancaq taxıldı"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Sancaq götürülənə qədər bu görünəcək. Sancağı götürmək üçün Geri və İcmal düymələrinə basıb saxlayın."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Sancaq götürülənə qədər bu görünəcək. Sancağı götürmək üçün Geri və Əsas səhifə düymələrinə basıb saxlayın."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Sancaq götürülənə qədər bu görünəcək. Sancağı götürmək üçün Geri düyməsinə basıb saxlayın."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Sancaq götürülənə qədər bu görünəcək. Sancağı götürmək üçün Əsas səhifə düyməsinə basıb saxlayın."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Bu ekrandan sancağı götürmək üçün Geri və İcmal düymələrinə basıb saxlayın"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Bu ekrandan sancağı götürmək üçün Geri və Əsas səhifə düymələrinə basıb saxlayın"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Anladım!"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Yox, çox sağ olun"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Ekran sancılıb"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Sancaq ekrandan götürülüb"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> gizlədilsin?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Ayarlarda onu aktivləşdirəcəyiniz vaxta qədər o, yenidən görünəcək."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Gizlədin"</string>
@@ -540,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Səssiz etmək üçün tıklayın. Əlçatımlılıq xidmətləri səssiz edilmiş ola bilər."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Vibrasiyanı ayarlamaq üçün klikləyin."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Səssiz etmək üçün klikləyin."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s həcm nəzarəti göstərilir. Bitirmək üçün yuxarı çəkin."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Həcm nəzarət gizlədilib"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s səs nəzarətləri"</string>
     <string name="output_title" msgid="5355078100792942802">"Media çıxışı"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Zəng girişi"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Heç bir cihaz tapılmadı"</string>
@@ -691,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Mübadilə buferi"</item>
     <item msgid="5742013440802239414">"Açar kodu"</item>
-    <item msgid="8802889973626281575">"Klaviatura dəyişdirici"</item>
-    <item msgid="7095517796293767867">"Naviqasiya təklifləri"</item>
-    <item msgid="8494159969042135235">"Yoxdur"</item>
+    <item msgid="1951959982985094069">"Çevirin, klaviatura dəyişdirici"</item>
+    <item msgid="8175437057325747277">"Heç bir"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normal"</item>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 9c188ff..6e6fcaf 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -104,12 +104,11 @@
     <string name="camera_label" msgid="7261107956054836961">"otvori kameru"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Izaberi novi raspored zadataka"</string>
     <string name="cancel" msgid="6442560571259935130">"Otkaži"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona otiska prsta"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ikona aplikacije"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Oblast poruke za pomoć"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Dugme Zum kompatibilnosti."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zumiranje sa manjeg na veći ekran."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth je priključen."</string>
@@ -277,6 +276,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Vitrina sa poslasticama"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Čuvar ekrana"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Eternet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Ne uznemiravaj"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Samo prioritetni prekidi"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Samo alarmi"</string>
@@ -313,6 +314,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi je isključen"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi je uključen"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Nije dostupna nijedna Wi-Fi mreža"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarm"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Prebacivanje"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Prebacivanje"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Neimenovani uređaj"</string>
@@ -329,9 +331,12 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Povezuje se..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Povezivanje"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Uključuje se..."</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="one">%d uređaj</item>
+      <item quantity="few">%d uređaja</item>
+      <item quantity="other">%d uređaja</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Obaveštenja"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Lampa"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobilni podaci"</string>
@@ -341,10 +346,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Iskoristili ste <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Ograničenje od <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Upozorenje za <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Profil za Work"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Obaveštenja i aplikacije su isključeni"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Noćno svetlo"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Uključuje se po zalasku sunca"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Do izlaska sunca"</string>
@@ -362,8 +365,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplikacija <xliff:g id="APP">%s</xliff:g> je onemogućena u bezbednom režimu."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Obriši sve"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Prevucite ovde da biste koristili razdeljeni ekran"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Podeli horizontalno"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Podeli vertikalno"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Prilagođeno deljenje"</string>
@@ -504,11 +505,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Isključi odmah"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Proširi"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Skupi"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Promenite izlazni uređaj"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Ekran je zakačen"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Na ovaj način se ovo stalno prikazuje dok ga ne otkačite. Dodirnite i zadržite Nazad i Pregled da biste ga otkačili."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Na ovaj način se ovo stalno prikazuje dok ga ne otkačite. Dodirnite i zadržite Nazad i Početna da biste ga otkačili."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Na ovaj način se ovo stalno prikazuje dok ga ne otkačite. Dodirnite i zadržite Pregled da biste ga otkačili."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Na ovaj način se ovo stalno prikazuje dok ga ne otkačite. Dodirnite i zadržite Početna da biste ga otkačili."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Da biste otkačili ovaj ekran, dodirnite i zadržite dugmad Nazad i Pregled"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Da biste otkačili ovaj ekran, dodirnite i zadržite dugmad Nazad i Početna"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Važi"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Ne, hvala"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Ekran je zakačen"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Ekran je otkačen"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Želite li da sakrijete <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Ovo će se ponovo pojaviti kada ga sledeći put budete uključili u podešavanjima."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Sakrij"</string>
@@ -531,8 +539,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Dodirnite da biste isključili zvuk. Zvuk usluga pristupačnosti će možda biti isključen."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Dodirnite da biste podesili na vibraciju."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Dodirnite da biste isključili zvuk."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Kontrole za jačinu zvuka (%s) su prikazane. Prevucite nagore da biste ih odbacili."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Kontrole za jačinu zvuka su sakrivene"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Kontrole za jačinu zvuka za %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Izlaz medija"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Izlaz za telefonski poziv"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Nije pronađen nijedan uređaj"</string>
@@ -588,8 +595,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Pomoću naprednih kontrola za obaveštenja možete da podesite nivo važnosti od 0. do 5. za obaveštenja aplikacije. \n\n"<b>"5. nivo"</b>" \n– Prikazuju se u vrhu liste obaveštenja \n- Dozvoli prekid režima celog ekrana \n– Uvek zaviruj \n\n"<b>"4. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Uvek zaviruj \n\n"<b>"3. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Nikada ne zaviruj \n\n"<b>"2. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Nikada ne zaviruj \n– Nikada ne proizvodi zvuk ili vibraciju \n\n"<b>"1. nivo"</b>" \n– Spreči prekid režima celog ekrana \n– Nikada ne zaviruj \n– Nikada ne proizvodi zvuk ili vibraciju \n– Sakrij na zaključanom ekranu i statusnoj traci \n– Prikazuju se u dnu liste obaveštenja \n\n"<b>"0. nivo"</b>" \n– Blokiraj sva obaveštenja iz aplikacije"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Obaveštenja"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Više nećete videti ova obaveštenja"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Obično odbacujete ova obaveštenja. \nŽelite li da se i dalje prikazuju?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Želite li da se ova obaveštenja i dalje prikazuju?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Prestani da prikazuješ obaveštenja"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Nastavi da prikazuješ"</string>
@@ -685,9 +691,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Memorija"</item>
     <item msgid="5742013440802239414">"Kôd tastera"</item>
-    <item msgid="8802889973626281575">"Prebacivač za tastaturu"</item>
-    <item msgid="7095517796293767867">"Predlog za rotaciju"</item>
-    <item msgid="8494159969042135235">"Ništa"</item>
+    <item msgid="1951959982985094069">"Potvrda rotiranja, prebacivač za tastaturu"</item>
+    <item msgid="8175437057325747277">"Ništa"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normalni"</item>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 6115de3..248cd09 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -105,12 +105,11 @@
     <string name="camera_label" msgid="7261107956054836961">"адкрыць камеру"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Выберыце новы макет заданняў"</string>
     <string name="cancel" msgid="6442560571259935130">"Скасаваць"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Значок адбіткаў пальцаў"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Значок праграмы"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Вобласць даведачнага паведамлення"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Кнопка сумяшчальнасці маштаба."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Маштабаванне малых элементаў для большага экрана."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth-сувязь."</string>
@@ -281,6 +280,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Вітрына з дэсертамі"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Экранная застаўка"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Не турбаваць"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Толькі прыярытэтныя"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Толькі будзільнікі"</string>
@@ -317,6 +318,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi адключаны"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi уключаны"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Няма даступнай сеткі Wi-Fi"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Будзільнік"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Трансляцыя"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Ідзе перадача"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Прылада без назвы"</string>
@@ -333,9 +335,13 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Падлучэнне..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Мадэм"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Кропка доступу"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Уключэнне…"</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="one">%d прылада</item>
+      <item quantity="few">%d прылады</item>
+      <item quantity="many">%d прылад</item>
+      <item quantity="other">%d прылады</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Апавяшчэнні"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Ліхтарык"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Мабільная перадача даных"</string>
@@ -345,10 +351,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Выкарыстана <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Ліміт <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Папярэджанне: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Працоўны профіль"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Апавяшчэнні і праграмы выключаныя"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Начная падсветка"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Уключаць увечары"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Да ўсходу сонца"</string>
@@ -366,8 +370,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> адключана ў бяспечным рэжыме."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Ачысціць усё"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Перацягніце сюды, каб перайсці ў рэжым падзеленага экрана"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Падзяліць гарызантальна"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Падзяліць вертыкальна"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Падзяліць іншым чынам"</string>
@@ -508,11 +510,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Адключыць"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Разгарнуць"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Згарнуць"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Змяніць прыладу аўдыявыхаду"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Экран замацаваны"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Будзе паказвацца, пакуль не адмацуеце. Каб адмацаваць, краніце і ўтрымлівайце кнопкі \"Назад\" і \"Агляд\"."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Будзе паказвацца, пакуль не адмацуеце. Каб адмацаваць, націсніце і ўтрымлівайце кнопкі \"Назад\" і \"Галоўны экран\"."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Будзе паказвацца, пакуль не адмацуеце. Каб адмацаваць, краніце і ўтрымлівайце кнопку \"Агляд\"."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Будзе паказвацца, пакуль не адмацуеце. Каб адмацаваць, націсніце і ўтрымлівайце кнопку \"Галоўны экран\"."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Каб адмацаваць гэты экран, націсніце і ўтрымлівайце кнопкі \"Назад\" і \"Агляд\""</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Каб адмацаваць гэты экран, націсніце і ўтрымлівайце кнопкі \"Назад\" і \"Галоўны экран\""</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Зразумела"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Не, дзякуй"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Экран замацаваны"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Экран адмацаваны"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Схаваць <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Гэта паведамленне з\'явіцца зноў у наступны раз, калі вы ўключыце яго ў наладах."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Схаваць"</string>
@@ -535,8 +544,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Дакраніцеся, каб адключыць гук. Можа быць адключаны гук службаў спецыяльных магчымасцей."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Дакраніцеся, каб уключыць вібрацыю."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Дакраніцеся, каб адключыць гук"</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Паказваецца наступная колькасць рэгулятараў гучнасці: %s. Правядзіце пальцам уверх, каб закрыць іх."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Рэгулятары гучнасці схаваны"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Рэгулятар гучнасці %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Вывад мультымедыя"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Прылада вываду тэлефонных выклікаў"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Прылады не знойдзены"</string>
@@ -592,8 +600,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"З дапамогай пашыранага кіравання апавяшчэннямі вы можаце задаваць узровень важнасці апавяшчэнняў праграмы ад 0 да 5. \n\n"<b>"Узровень 5"</b>" \n- Паказваць уверсе спіса апавяшчэнняў \n- Дазваляць перапыняць рэжым поўнага экрана \n- Заўсёды дазваляць кароткі паказ \n\n"<b>"Узровень 4"</b>" \n- Забараняць перапыняць рэжым поўнага экрана \n- Заўсёды дазваляць кароткі паказ \n\n"<b>"Узровень 3"</b>" \n- Забараняць перапыняць рэжым поўнага экрана \n- Ніколі не дазваляць кароткі паказ \n\n"<b>"Узровень 2"</b>" \n- Забараняць перапыняць рэжым поўнага экрана \n- Ніколі не дазваляць кароткі паказ \n- Ніколі не прайграваць гук і не вібрыраваць \n\n"<b>"Узровень 1"</b>" \n- Забараняць перапыняць рэжым поўнага экрана \n- Ніколі не дазваляць кароткі паказ \n- Ніколі не прайграваць гук і не вібрыраваць \n- Хаваць з экрана блакіроўкі і панэлі стану \n- Паказваць унізе спіса апавяшчэнняў \n\n"<b>"Узровень 0"</b>" \n- Блакіраваць усе апавяшчэнні ад праграмы"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Апавяшчэнні"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Вы больш не будзеце бачыць гэтыя апавяшчэнні"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Звычайна вы адхіляеце гэтыя апавяшчэнні. \nПаказваць іх?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Працягваць паказваць гэтыя апавяшчэнні?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Спыніць апавяшчэнні"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Працягваць паказваць"</string>
@@ -691,9 +698,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Буфер абмену"</item>
     <item msgid="5742013440802239414">"Код клавішы"</item>
-    <item msgid="8802889973626281575">"Пераключальнік клавіятуры"</item>
-    <item msgid="7095517796293767867">"Паварот"</item>
-    <item msgid="8494159969042135235">"Няма"</item>
+    <item msgid="1951959982985094069">"Пацвердзіць паварот, пераключыць раскладку"</item>
+    <item msgid="8175437057325747277">"Няма"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Звычайная"</item>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 2a5ee20..5468afa 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"отваряне на камерата"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Избиране на ново оформление за задачите"</string>
     <string name="cancel" msgid="6442560571259935130">"Отказ"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Икона за отпечатък"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Икона на приложението"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Област за помощно съобщение"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Бутон за промяна на мащаба с цел съвместимост."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Промяна на мащаба на екрана от по-малък до по-голям."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth е включен."</string>
@@ -275,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Витрина с десерти"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Скрийнсейвър"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Не безпокойте"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Само с приоритет"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Само будилници"</string>
@@ -311,6 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi е изключен"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Функцията за Wi-Fi е включена"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Няма налични Wi-Fi мрежи"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Будилник"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Предаване"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Предава се"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Устройство без име"</string>
@@ -327,9 +329,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Установява се връзка..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Тетъринг"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Точка за достъп"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Включва се..."</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="other">%d устройства</item>
+      <item quantity="one">%d устройство</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Известия"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Фенерче"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Мобилни данни"</string>
@@ -339,10 +343,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Използвано: <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Ограничение от <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Предупреждение: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Служебен потребителски профил"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Известията и приложенията са изключени"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Нощно осветление"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Ще се вкл. по залез"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"До изгрев"</string>
@@ -360,8 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Приложението <xliff:g id="APP">%s</xliff:g> е деактивирано в безопасния режим."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Изчистване на всичко"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Преместете тук с плъзгане, за да използвате режим за разделен екран"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Хоризонтално разделяне"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Вертикално разделяне"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Персонализирано разделяне"</string>
@@ -502,11 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Изключване сега"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Разгъване"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Свиване"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Превключване на устройството за възпроизвеждане на звук"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Екранът е фиксиран"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Екранът ще се показва, докато не го освободите с докосване и задържане на бутона за връщане назад и този за общ преглед."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Екранът ще се показва, докато не го освободите с докосване и задържане на бутона за връщане назад и „Начало“."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Екранът ще се показва, докато не го освободите с докосване и задържане на бутона за общ преглед."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Екранът ще се показва, докато не го освободите с докосване и задържане на бутона „Начало“."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"За да освободите този екран, докоснете и задръжте бутона за връщане назад и този за общ преглед"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"За да освободите този екран, докоснете и задръжте бутона за връщане назад и „Начало“"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Разбрах"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Не, благодаря"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Екранът е фиксиран"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Екранът е освободен"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Да се скрие ли „<xliff:g id="TILE_LABEL">%1$s</xliff:g>“?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Бързите настройки ще се покажат отново следващия път, когато ги включите от „Настройки“."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Скриване"</string>
@@ -529,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Докоснете, за да заглушите звука. Възможно е звукът на услугите за достъпност да бъде заглушен."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Докоснете, за да зададете вибриране."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Докоснете, за да заглушите звука."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Показани са контролите за силата на звука на %s. Прекарайте пръст нагоре, за да ги скриете."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Контролите за силата на звука са скрити"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Контроли за силата на звука – %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Изходяща мултимедия"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Изходящи телефонни обаждания"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Няма намерени устройства"</string>
@@ -586,8 +592,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"С помощта на контролите за известията можете да зададете ниво на важност от 0 до 5 за известията от дадено приложение. \n\n"<b>"Ниво 5"</b>" \n– Показване най-горе в списъка с известия. \n– Разрешаване на прекъсването на цял екран. \n– Известията винаги се показват мимолетно. \n\n"<b>"Ниво 4"</b>" \n– Предотвратяване на прекъсването на цял екран. \n– Известията винаги се показват мимолетно. \n\n"<b>"Ниво 3"</b>" \n– Предотвратяване на прекъсването на цял екран. \n– Известията никога не се показват мимолетно. \n\n"<b>"Ниво 2"</b>" \n– Предотвратяване на прекъсването на цял екран. \n– Известията никога не се показват мимолетно. \n– Без издаване на звуков сигнал и вибриране. \n\n"<b>"Ниво 1"</b>" \n– Предотвратяване на прекъсването на цял екран. \n– Известията никога не се показват мимолетно. \n– Без издаване на звуков сигнал и вибриране. \n– Скриване от заключения екран и лентата на състоянието. \n– Показване най-долу в списъка с известия. \n\n"<b>"Ниво 0"</b>" \n– Блокиране на всички известия от приложението."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Известия"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Вече няма да виждате тези известия"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Обикновено отхвърляте тези известия. \nИскате ли да продължат да се показват?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Тези известия да продължат ли да се показват?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Спиране на известията"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Да продължат да се показват"</string>
@@ -681,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Буферна памет"</item>
     <item msgid="5742013440802239414">"Клавишен код"</item>
-    <item msgid="8802889973626281575">"Превключвател на клавиатурата"</item>
-    <item msgid="7095517796293767867">"Предложение за завъртане"</item>
-    <item msgid="8494159969042135235">"Без"</item>
+    <item msgid="1951959982985094069">"Потвърждаване на завъртането, превключвател за клавиатурата"</item>
+    <item msgid="8175437057325747277">"Няма"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Нормално"</item>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index eb08f50..76b0c3f 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"ক্যামেরা খুলুন"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"নতুন কার্য লেআউট বেছে নিন"</string>
     <string name="cancel" msgid="6442560571259935130">"বাতিল করুন"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"আঙ্গুলের ছাপের আইকন"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"অ্যাপ্লিকেশনের আইকন"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"সহায়তার মেসেজ দেখানোর জায়গা"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"ডেজার্ট কেস"</string>
     <string name="start_dreams" msgid="5640361424498338327">"স্ক্রিন সেভার"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"ইথারনেট"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"বিরক্ত করবেন না"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"শুধুমাত্র অগ্রাধিকার"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"শুধুমাত্র অ্যালার্মগুলি"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"ওয়াই-ফাই বন্ধ"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"ওয়াই-ফাই চালু আছে"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"কোনো ওয়াই-ফাই নেটওয়ার্ক উপলব্ধ নেই"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"অ্যালার্ম"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"কাস্ট করুন"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"কাস্ট করা হচ্ছে"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"নামবিহীন ডিভাইস"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"নিরাপদ মোডে <xliff:g id="APP">%s</xliff:g> অক্ষম করা হয়েছে৷"</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"সবকিছু সাফ করুন"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"বিভক্ত স্ক্রীন ব্যবহার করতে এখানে টেনে আনুন"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"অন্য অ্যাপে যেতে উপরের দিকে সোয়াইপ করুন"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"অনুভূমিক স্প্লিট"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"উল্লম্ব স্প্লিট"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"কাস্টম স্প্লিট করুন"</string>
@@ -500,25 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"এখনই বন্ধ করুন"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"বড় করুন"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"সঙ্কুচিত করুন"</string>
-    <!-- no translation found for accessibility_output_chooser (8185317493017988680) -->
-    <skip />
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"অন্য আউটপুট ডিভাইস বেছে নিন"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"স্ক্রিন পিন করা হয়েছে"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"এটি আপনি আনপিন না করা পর্যন্ত এটিকে প্রদর্শিত করবে৷ আনপিন করতে ফিরুন এবং ওভারভিউ স্পর্শ করে ধরে থাকুন।"</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"এর ফলে আপনি এটি আনপিন না করা পর্যন্ত এটি দেখানো হতে থাকবে। আনপিন করতে \"ফিরে যান\" এবং \"হোম\" বোতামদুটি ট্যাপ করে ধরে রাখুন।"</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"এটি আপনি আনপিন না করা পর্যন্ত এটিকে প্রদর্শিত করবে৷ আনপিন করতে ওভারভিউ স্পর্শ করে ধরে থাকুন৷"</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"এর ফলে আপনি এটি আনপিন না করা পর্যন্ত এটি দেখানো হতে থাকবে। আনপিন করতে \"হোম\" বোতামটি ট্যাপ করে ধরে রাখুন।"</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"এই স্ক্রিনটি আনপিন করতে \"ফিরে যান\" এবং \"এক নজরে\" বোতামদুটি ট্যাপ করে ধরে রাখুন"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"এই স্ক্রিনটি আনপিন করতে \"ফিরে যান\" এবং \"হোম\" বোতামদুটি ট্যাপ করে ধরে রাখুন"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"বুঝেছি"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"না থাক"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"স্ক্রিন পিন করা হয়েছে"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"স্ক্রিন আনপিন করা হয়েছে"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> লুকাবেন?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"আপনি পরের বার সেটিংস-এ এটি চালু করলে এটি উপস্থিত হবে"</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"লুকান"</string>
@@ -541,8 +536,13 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s। নিঃশব্দ করতে আলতো চাপুন। অ্যাক্সেসযোগ্যতার পরিষেবাগুলিকে নিঃশব্দ করা হতে পারে।"</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s। ভাইব্রেট করতে ট্যাপ করুন।"</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s। নিঃশব্দ করতে ট্যাপ করুন।"</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s ভলিউম নিয়ন্ত্রণগুলি দেখানো হয়েছে৷ খারিজ করতে উপরের দিকে সোয়াইপ করুন৷"</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"ভলিউম নিয়ন্ত্রণগুলি লুকানো রয়েছে"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s ভলিউম নিয়ন্ত্রণ"</string>
+    <!-- no translation found for volume_dialog_ringer_guidance_vibrate (8902050240801159042) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_silent (2128975224280276122) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_ring (6144469689490528338) -->
+    <skip />
     <string name="output_title" msgid="5355078100792942802">"মিডিয়া আউটপুট"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"ফোন কল আউটপুট"</string>
     <string name="output_none_found" msgid="5544982839808921091">"কোনও ডিভাইস খুঁজে পাওয়া যায়নি"</string>
@@ -692,9 +692,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"ক্লিপবোর্ড"</item>
     <item msgid="5742013440802239414">"কীকোড"</item>
-    <item msgid="8802889973626281575">"কিবোর্ড স্যুইচার"</item>
-    <item msgid="7095517796293767867">"ঘুরিয়ে দেখার বিষয়ে প্রস্তাবনা"</item>
-    <item msgid="8494159969042135235">"কোনওটিই নয়"</item>
+    <item msgid="1951959982985094069">"ঘোরানো নিশ্চিত করুন, কীবোর্ডের ভাষা বদলানোর সুবিধা"</item>
+    <item msgid="8175437057325747277">"কোনো কিছুই নয়"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"সাধারণ"</item>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 676ecd0..5d63af8 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -104,6 +104,8 @@
     <string name="camera_label" msgid="7261107956054836961">"otvori kameru"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Odaberite novi raspored zadataka"</string>
     <string name="cancel" msgid="6442560571259935130">"Otkaži"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona za otisak prsta"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ikona aplikacije"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Prostor za poruku za pomoć"</string>
@@ -274,6 +276,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Slika sa desertima"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Čuvar ekrana"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Ne ometaj"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Samo prioritetno"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Samo alarmi"</string>
@@ -310,8 +314,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi isključen"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi uključen"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Nema dostupnih Wi-Fi mreža"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarm"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Emitiranje"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Prebacivanje"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Neimenovani uređaj"</string>
@@ -362,7 +365,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> je onemogućena u sigurnom načinu rada."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Obriši sve"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Povucite ovdje za korištenje podijeljenog ekrana"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Prevucite prema gore za promjenu aplikacije"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Podjela po horizontali"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Podjela po vertikali"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Prilagođena podjela"</string>
@@ -503,25 +505,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Isključi sada"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Proširi"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Skupi"</string>
-    <!-- no translation found for accessibility_output_chooser (8185317493017988680) -->
-    <skip />
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Promijenite izlazni uređaj"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Ekran je prikačen"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Ekran ostaje prikazan ovako dok ga ne otkačite. Da ga otkačite, dodirnite i držite dugme Nazad."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Na ovaj način ekran ostaje prikazan dok ga ne otkačite. Da otkačite ekran, dodirnite i držite dugme Nazad i Početna."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Ekran ostaje prikazan ovako dok ga ne otkačite. Da ga otkačite, dodirnite i držite dugme Pregled."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Na ovaj način ekran ostaje prikazan dok ga ne otkačite. Da okačite ekran, dodirnite ili držite dugme Početna."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Dodirnite i držite dugmad Nazad i Pregled da otkačite ekran"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Dodirnite i držite dugmad Nazad i Početna da otkačite ekran."</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Razumijem"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Ne, hvala"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Ekran je zakačen"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Ekran je otkačen"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Želite li sakriti <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Pojavit će se sljedeći put kada opciju uključite u postavkama."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Sakrij"</string>
@@ -546,8 +541,13 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Dodirnite da isključite zvuk. Zvukovi usluga pristupačnosti mogu biti isključeni."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Dodirnite da postavite vibraciju."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Dodirnite da isključite zvuk."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Prikazane kontrole jačine zvuka za: %s. Prevucite prema gore za odbacivanje."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Kontrole jačine zvuka sakrivene"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Kontrole glasnoće za %s"</string>
+    <!-- no translation found for volume_dialog_ringer_guidance_vibrate (8902050240801159042) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_silent (2128975224280276122) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_ring (6144469689490528338) -->
+    <skip />
     <string name="output_title" msgid="5355078100792942802">"Izlaz za medijske fajlove"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Izlaz za telefonske pozive"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Nije pronađen nijedan uređaj"</string>
@@ -699,9 +699,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Međumemorija"</item>
     <item msgid="5742013440802239414">"Kôd tipke"</item>
-    <item msgid="8802889973626281575">"Prebacivač tastatura"</item>
-    <item msgid="7095517796293767867">"Prijedlog rotacije"</item>
-    <item msgid="8494159969042135235">"Nema"</item>
+    <item msgid="1951959982985094069">"Potvrda rotiranjem, prebacivanje tastature"</item>
+    <item msgid="8175437057325747277">"Ništa"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normalna"</item>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 4eff30d..a716a4b 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"obre la càmera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Selecciona el disseny de la tasca nova"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancel·la"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icona d\'empremta digital"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Icona d\'aplicació"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Àrea de missatge d\'ajuda"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Capsa de postres"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Estalvi de pantalla"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"No molestis"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Només amb prioritat"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Només alarmes"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi desconnectada"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"La Wi-Fi està activada"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"No hi ha cap xarxa Wi-Fi disponible"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarma"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Emet"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"En emissió"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Dispositiu sense nom"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"En mode segur, l\'aplicació <xliff:g id="APP">%s</xliff:g> està desactivada."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Esborra-ho tot"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Arrossega-ho aquí per utilitzar la pantalla dividida"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Llisca cap amunt per canviar d\'aplicació"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisió horitzontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Divisió vertical"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Divisió personalitzada"</string>
@@ -500,25 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Desactiva ara"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Amplia"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Replega"</string>
-    <!-- no translation found for accessibility_output_chooser (8185317493017988680) -->
-    <skip />
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Canvia el dispositiu de sortida"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"La pantalla està fixada"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Aquest element es continuarà mostrant fins que deixis de fixar-lo. Per fer-ho, toca i mantén premudes els botons Enrere i Aplicacions recents."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Aquest element es continuarà mostrant fins que deixis de fixar-lo. Per fer-ho, mantén premuts els botons Enrere i Inici."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Aquest element es continuarà mostrant fins que deixis de fixar-lo. Per fer-ho, toca i mantén premut el botó Aplicacions recents."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Aquest element es continuarà mostrant fins que deixis de fixar-lo. Per fer-ho, mantén premut el botó d\'inici."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Per deixar de fixar aquesta pantalla, mantén premuts els botons Enrere i Aplicacions recents"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Per deixar de fixar aquesta pantalla, mantén premuts els botons Enrere i Inici"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"D\'acord"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"No, gràcies"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"S\'ha fitxat la pantalla"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"S\'ha deixat de fixar la pantalla"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Vols amagar <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Tornarà a mostrar-se la propera vegada que l\'activis a la configuració."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Amaga"</string>
@@ -541,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Toca per silenciar el so. Pot ser que els serveis d\'accessibilitat se silenciïn."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Toca per activar la vibració."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Toca per silenciar."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Es mostren %s controls de volum. Llisca cap amunt per ignorar-ho."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Els controls de volum estan amagats"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Controls de volum %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Sortida de contingut multimèdia"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Sortida de trucades"</string>
     <string name="output_none_found" msgid="5544982839808921091">"No s\'ha trobat cap dispositiu"</string>
@@ -692,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Porta-retalls"</item>
     <item msgid="5742013440802239414">"Codi de tecla"</item>
-    <item msgid="8802889973626281575">"Commutador del teclat"</item>
-    <item msgid="7095517796293767867">"Suggeriment de rotació"</item>
-    <item msgid="8494159969042135235">"Cap"</item>
+    <item msgid="1951959982985094069">"Confirma el gir de la pantalla, canvia de teclat"</item>
+    <item msgid="8175437057325747277">"Cap"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normal"</item>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index faa1f1f..75043bc 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -105,6 +105,8 @@
     <string name="camera_label" msgid="7261107956054836961">"spustit fotoaparát"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Vybrat nové rozvržení úkolů"</string>
     <string name="cancel" msgid="6442560571259935130">"Zrušit"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona otisku prstu"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ikona aplikace"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Oblast pro zprávu nápovědy"</string>
@@ -278,6 +280,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Pult se sladkostmi"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Spořič obrazovky"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Nerušit"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Pouze prioritní"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Pouze budíky"</string>
@@ -314,8 +318,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi vypnuta"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi je zapnutá"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Žádné sítě Wi-Fi nejsou k dispozici"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Budík"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Odeslat"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Odesílání"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Nepojmenované zařízení"</string>
@@ -367,7 +370,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplikace <xliff:g id="APP">%s</xliff:g> je v nouzovém režimu zakázána."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Vymazat vše"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Rozdělenou obrazovku můžete použít přetažením zde"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Přejetím nahoru přepnete aplikace"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Vodorovné rozdělení"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Vertikální rozdělení"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Vlastní rozdělení"</string>
@@ -511,21 +513,15 @@
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"Přepnout zařízení pro výstup"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Obrazovka je připnuta"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Obsah bude připnut v zobrazení, dokud jej neuvolníte. Uvolníte jej stisknutím a podržením tlačítek Zpět a Přehled."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Obsah bude připnut v zobrazení, dokud ho neuvolníte. Uvolníte ho podržením tlačítek Zpět a Plocha."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Obsah bude připnut v zobrazení, dokud jej neuvolníte. Uvolníte jej stisknutím a podržením tlačítka Přehled."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Obsah bude připnut v zobrazení, dokud ho neuvolníte. Uvolníte ho podržením tlačítka Plocha."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Chcete-li tuto obrazovku uvolnit, podržte tlačítka Zpět a Přehled"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Chcete-li tuto obrazovku uvolnit, podržte tlačítka Zpět a Plocha"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Rozumím"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Ne, děkuji"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Obrazovka připnuta"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Obrazovka uvolněna"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Skrýt <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Tato položka se znovu zobrazí, až ji v nastavení znovu zapnete."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Skrýt"</string>
@@ -548,8 +544,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Klepnutím vypnete zvuk. Služby přístupnosti mohou být ztlumeny."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Klepnutím nastavíte vibrace."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Klepnutím vypnete zvuk."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Ovládací prvky hlasitosti aplikace %s jsou zobrazeny. Zavřete je přejetím prstem."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Ovládací prvky hlasitosti jsou skryty"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Ovládací prvky hlasitosti %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Výstup médií"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Výstup telefonního hovoru"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Nebyla nalezena žádná zařízení"</string>
@@ -703,9 +698,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Schránka"</item>
     <item msgid="5742013440802239414">"Klávesa"</item>
-    <item msgid="8802889973626281575">"Přepínač klávesnice"</item>
-    <item msgid="7095517796293767867">"Doporučené otočení"</item>
-    <item msgid="8494159969042135235">"Žádné"</item>
+    <item msgid="1951959982985094069">"Potvrzení otočení, přepínač na klávesnici"</item>
+    <item msgid="8175437057325747277">"Žádné"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normální"</item>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 9ebd492..32ddcd5 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"åbn kamera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Vælg nyt opgavelayout"</string>
     <string name="cancel" msgid="6442560571259935130">"Annuller"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikon for fingeraftryk"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Appens ikon"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Område med hjælpemeddelelse"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Dessertcase"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Pauseskærm"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Forstyr ikke"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Kun prioritet"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Kun alarmer"</string>
@@ -532,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Tryk for at slå lyden fra. Lyden i tilgængelighedstjenester kan blive slået fra."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Tryk for at aktivere vibration."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Tryk for at slå lyden fra."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Lydstyrkeknapperne for %s er synlige. Stryg op for at lukke."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Lydstyrkeknapperne er skjult"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s lydstyrkeknapper"</string>
     <string name="output_title" msgid="5355078100792942802">"Medieafspilning"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Udgang til telefonopkald"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Der blev ikke fundet nogen enheder"</string>
@@ -683,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Udklipsholder"</item>
     <item msgid="5742013440802239414">"Tastekode"</item>
-    <item msgid="8802889973626281575">"Tastaturskifter"</item>
-    <item msgid="7095517796293767867">"Rotationsforslag"</item>
-    <item msgid="8494159969042135235">"Ingen"</item>
+    <item msgid="1951959982985094069">"Rotationsbekræftelse, tastaturskifter"</item>
+    <item msgid="8175437057325747277">"Ingen"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normal"</item>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index dd258e1..882b278 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"Kamera öffnen"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Neues Aufgabenlayout auswählen"</string>
     <string name="cancel" msgid="6442560571259935130">"Abbrechen"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingerabdruck-Symbol"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"App-Symbol"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Bereich für die Hilfemeldung"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Schaltfläche für Kompatibilitätszoom"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom auf einen größeren Bildschirm"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Mit Bluetooth verbunden"</string>
@@ -279,6 +278,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Dessertbehälter"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Bildschirmschoner"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Nicht stören"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Nur wichtige Unterbrechungen"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Nur Wecker"</string>
@@ -315,6 +316,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"WLAN aus"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"WLAN an"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Keine WLANs verfügbar"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Wecker"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Streamen"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Wird übertragen"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Unbenanntes Gerät"</string>
@@ -331,9 +333,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Verbindung wird hergestellt…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Wird aktiviert…"</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="other">%d Geräte</item>
+      <item quantity="one">%d Gerät</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Benachrichtigungen"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Taschenlampe"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobile Daten"</string>
@@ -343,10 +347,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> verwendet"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> Datenlimit"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Warnung für <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Arbeitsprofil"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Benachrichtigungen und Apps deaktiviert"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Nachtlicht"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"An bei Sonnenuntergang"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Bis Sonnenaufgang"</string>
@@ -364,8 +366,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ist im abgesicherten Modus deaktiviert."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Alle schließen"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Hierher ziehen, um den Bildschirm zu teilen"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Geteilte Schaltfläche – horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Geteilte Schaltfläche – vertikal"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Geteilte Schaltfläche – benutzerdefiniert"</string>
@@ -506,11 +506,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Jetzt deaktivieren"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Maximieren"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Minimieren"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Ausgabegerät wechseln"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Bildschirm ist fixiert"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Der Bildschirm bleibt so lange eingeblendet, bis du die Fixierung aufhebst. Berühre und halte dazu \"Zurück\" und \"Übersicht\"."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Der Bildschirm wird so lange angezeigt, bis du die Fixierung aufhebst. Berühre und halte dazu \"Zurück\" und \"Startbildschirm\"."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Der Bildschirm bleibt so lange eingeblendet, bis du die Fixierung aufhebst. Berühre und halte dazu \"Übersicht\"."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Der Bildschirm wird so lange angezeigt, bis du die Fixierung aufhebst. Berühre und halte dazu \"Startbildschirm\"."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Um die Fixierung für diesen Bildschirm aufzuheben, berühre und halte \"Zurück\" und \"Übersicht\""</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Um die Fixierung für diesen Bildschirm aufzuheben, berühre und halte \"Zurück\" und \"Startbildschirm\""</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nein danke"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Bildschirm fixiert"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Fixierung für Bildschirm aufgehoben"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> ausblenden?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Sie wird wieder eingeblendet, wenn du sie in den Einstellungen erneut aktivierst."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Ausblenden"</string>
@@ -533,8 +540,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Zum Stummschalten tippen. Bedienungshilfen werden unter Umständen stummgeschaltet."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Zum Aktivieren der Vibration tippen."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Zum Stummschalten tippen."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Lautstärkeregler von %s werden angezeigt. Zum Schließen nach oben wischen."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Lautstärkeregler ausgeblendet"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Lautstärkeregler von %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Medienausgabe"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Telefonanrufausgabe"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Keine Geräte gefunden"</string>
@@ -590,8 +596,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Mit den erweiterten Benachrichtigungseinstellungen kannst du für App-Benachrichtigungen eine Wichtigkeitsstufe von 0 bis 5 festlegen. \n\n"<b>"Stufe 5"</b>" \n- Auf der Benachrichtigungsleiste ganz oben anzeigen \n- Vollbildunterbrechung zulassen \n- Immer kurz einblenden \n\n"<b>"Stufe 4"</b>" \n- Keine Vollbildunterbrechung \n- Immer kurz einblenden \n\n"<b>"Stufe 3"</b>" \n- Keine Vollbildunterbrechung \n- Nie kurz einblenden \n\n"<b>"Stufe 2"</b>" \n- Keine Vollbildunterbrechung \n- Nie kurz einblenden \n- Weder Ton noch Vibration \n\n"<b>"Stufe 1"</b>" \n- Keine Vollbildunterbrechung \n- Nie kurz einblenden \n- Weder Ton noch Vibration \n- Auf Sperrbildschirm und Statusleiste verbergen \n- Auf der Benachrichtigungsleiste ganz unten anzeigen \n\n"<b>"Stufe 0"</b>" \n- Alle Benachrichtigungen der App sperren"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Benachrichtigungen"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Du erhältst diese Benachrichtigungen nicht mehr"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Normalerweise schließt du diese Benachrichtigungen. \nSollen sie trotzdem weiter angezeigt werden?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Diese Benachrichtigungen weiterhin anzeigen?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Benachrichtigungen nicht mehr anzeigen"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Weiterhin anzeigen"</string>
@@ -685,9 +690,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Zwischenablage"</item>
     <item msgid="5742013440802239414">"Keycode"</item>
-    <item msgid="8802889973626281575">"Tastaturwechsler"</item>
-    <item msgid="7095517796293767867">"Drehvorschlag"</item>
-    <item msgid="8494159969042135235">"Keine"</item>
+    <item msgid="1951959982985094069">"Drehen bestätigen, Tastaturwechsler"</item>
+    <item msgid="8175437057325747277">"Keine"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Mittig"</item>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 8c30521..9c3a013 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"άνοιγμα φωτογραφικής μηχανής"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Επιλέξτε τη νέα διάταξη εργασίας"</string>
     <string name="cancel" msgid="6442560571259935130">"Ακύρωση"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Εικονίδιο δακτυλικών αποτυπωμάτων"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Εικονίδιο εφαρμογής"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Περιοχή μηνυμάτων βοήθειας"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Κουμπί εστίασης συμβατότητας."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Ζουμ από μικρότερη σε μεγαλύτερη οθόνη."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Το Bluetooth είναι συνδεδεμένο."</string>
@@ -275,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Επιδόρπιο"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Προφύλαξη οθόνης"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Μην ενοχλείτε"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Μόνο προτεραιότητας"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Μόνο ειδοποιήσεις"</string>
@@ -311,6 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi ανενεργό"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Ενεργό Wi-Fi"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Δεν υπάρχουν διαθέσιμα δίκτυα Wi-Fi"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Ξυπνητήρι"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Μετάδοση"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Μετάδοση"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Ανώνυμη συσκευή"</string>
@@ -327,9 +329,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Σύνδεση…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Πρόσδεση"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Σημείο πρόσβασης Wi-Fi"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Ενεργοποίηση…"</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="other">%d συσκευές</item>
+      <item quantity="one">%d συσκευή</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Ειδοποιήσεις"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Φακός"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Δεδομένα κινητής τηλεφωνίας"</string>
@@ -339,10 +343,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Χρησιμοποιούνται <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Όριο <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Προειδοποίηση για <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Προφίλ εργασίας"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Οι ειδοποιήσεις και οι εφαρμογές είναι απενεργοποιημένες"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Νυχτερινός φωτισμός"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Κατά τη δύση"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Μέχρι την ανατολή"</string>
@@ -360,8 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Η εφαρμογή <xliff:g id="APP">%s</xliff:g> έχει απενεργοποιηθεί στην ασφαλή λειτουργία."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Διαγραφή όλων"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Σύρετε εδώ για να χρησιμοποιήσετε τον διαχωρισμό οθόνης"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Οριζόντιος διαχωρισμός"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Κάθετος διαχωρισμός"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Προσαρμοσμένος διαχωρισμός"</string>
@@ -502,11 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Απενεργοποίηση τώρα"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Ανάπτυξη"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Σύμπτυξη"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Εναλλαγή συσκευής εξόδου"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Η οθόνη καρφιτσώθηκε"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Με αυτόν τον τρόπο παραμένει σε προβολή μέχρι να το ξεκαρφιτσώσετε. Αγγίξτε παρατεταμένα τα στοιχεία \"Επιστροφή\" και \"Επισκόπηση\" για ξεκαρφίτσωμα."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Με αυτόν τον τρόπο, παραμένει σε προβολή μέχρι να το ξεκαρφιτσώσετε. Αγγίξτε παρατεταμένα τα στοιχεία \"Πίσω\" και \"Αρχική οθόνη\" για ξεκαρφίτσωμα."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Με αυτόν τον τρόπο παραμένει σε προβολή μέχρι να το ξεκαρφιτσώσετε. Αγγίξτε παρατεταμένα την \"Επισκόπηση\" για ξεκαρφίτσωμα."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Με αυτόν τον τρόπο, παραμένει σε προβολή μέχρι να το ξεκαρφιτσώσετε. Αγγίξτε παρατεταμένα το στοιχείο \"Αρχική οθόνη\" για ξεκαρφίτσωμα."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Για να ξεκαρφιτσώσετε αυτήν την οθόνη, αγγίξτε παρατεταμένα τα κουμπιά \"Πίσω\" και \"Επισκόπηση\""</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Για να ξεκαρφιτσώσετε αυτήν την οθόνη, αγγίξτε παρατεταμένα τα κουμπιά \"Πίσω\" και \"Αρχική οθόνη\""</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Το κατάλαβα"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Όχι"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Η οθόνη καρφιτσώθηκε"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Η οθόνη ξεκαρφιτσώθηκε"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Απόκρυψη <xliff:g id="TILE_LABEL">%1$s</xliff:g>;"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Θα εμφανιστεί ξανά την επόμενη φορά που θα το ενεργοποιήσετε στις ρυθμίσεις."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Απόκρυψη"</string>
@@ -529,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Πατήστε για σίγαση. Οι υπηρεσίες προσβασιμότητας ενδέχεται να τεθούν σε σίγαση."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Πατήστε για να ενεργοποιήσετε τη δόνηση."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Πατήστε για σίγαση."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Εμφανίζονται τα στοιχεία ελέγχου έντασης %s. Σύρετε για παράβλεψη."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Έγινε απόκρυψη των στοιχείων ελέγχου έντασης"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s στοιχεία ελέγχου έντασης ήχου"</string>
     <string name="output_title" msgid="5355078100792942802">"Έξοδος μέσων"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Έξοδος τηλεφωνικής κλήσης"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Δεν βρέθηκαν συσκευές"</string>
@@ -586,8 +592,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Με τα στοιχεία ελέγχου ειδοποίησης ισχύος, μπορείτε να ορίσετε ένα επίπεδο βαρύτητας από 0 έως 5 για τις ειδοποιήσεις μιας εφαρμογής. \n\n"<b>"Επίπεδο 5"</b>" \n- Εμφάνιση στην κορυφή της λίστας ειδοποιήσεων \n- Να επιτρέπεται η διακοπή πλήρους οθόνης \n- Να γίνεται πάντα σύντομη προβολή \n\n"<b>"Επίπεδο 4"</b>" \n- Αποτροπή διακοπής πλήρους οθόνης \n- Να γίνεται πάντα σύντομη προβολή \n\n"<b>"Επίπεδο 3"</b>" \n- Αποτροπή διακοπής πλήρους οθόνης \n- Να μην γίνεται ποτέ σύντομη προβολή \n\n"<b>"Επίπεδο 2"</b>" \n- Αποτροπή διακοπής πλήρους οθόνης \n- Να μην γίνεται ποτέ σύντομη προβολή \n- Να μην χρησιμοποιείται ποτέ ήχος και δόνηση \n\n"<b>"Επίπεδο 1"</b>" \n- Αποτροπή διακοπής πλήρους οθόνης \n- Να μην γίνεται ποτέ σύντομη προβολή \n- Να μην χρησιμοποιείται ποτέ ήχος και δόνηση \n- Απόκρυψη από την οθόνη κλειδώματος και τη γραμμή κατάστασης \n- Εμφάνιση στο κάτω μέρος της λίστας ειδοποιήσεων \n\n"<b>"Επίπεδο 0"</b>" \n- Αποκλεισμός όλων των ειδοποιήσεων από την εφαρμογή"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Ειδοποιήσεις"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Δεν θα βλέπετε πλέον αυτές τις ειδοποιήσεις"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Συνήθως απορρίπτετε αυτές τις ειδοποιήσεις. \nΝα εξακολουθήσουν να εμφανίζονται;"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Να συνεχίσουν να εμφανίζονται αυτές οι ειδοποιήσεις;"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Διακοπή ειδοποιήσεων"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Συνέχιση εμφάνισης"</string>
@@ -681,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Πρόχειρο"</item>
     <item msgid="5742013440802239414">"Κωδικός-πλήκτρο"</item>
-    <item msgid="8802889973626281575">"Εναλλαγή πληκτρολογίων"</item>
-    <item msgid="7095517796293767867">"Πρόταση περιστροφής"</item>
-    <item msgid="8494159969042135235">"Κανένα"</item>
+    <item msgid="1951959982985094069">"Επιβεβαίωση περιστροφής, εναλλαγή πληκτρολογίου"</item>
+    <item msgid="8175437057325747277">"Κανένα"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Κανονική"</item>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 3e9e3a2..df2a74e 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -103,6 +103,7 @@
     <string name="camera_label" msgid="7261107956054836961">"open camera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Select new task layout"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancel"</string>
+    <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Touch the fingerprint sensor"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingerprint icon"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Application icon"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Help message area"</string>
@@ -272,6 +273,7 @@
     <string name="dessert_case" msgid="1295161776223959221">"Dessert Case"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Screen saver"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <string name="quick_settings_header_onboarding_text" msgid="7872508260264044734">"Press &amp; hold on the icons for more options"</string>
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Do not disturb"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Priority only"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Alarms only"</string>
@@ -308,8 +310,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi Off"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi On"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"No Wi-Fi networks available"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarm"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Casting"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Unnamed device"</string>
@@ -359,7 +360,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is disabled in safe-mode."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Clear all"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Drag here to use split screen"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Swipe up to switch apps"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Split Horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Split Vertical"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Split Customised"</string>
@@ -503,21 +503,15 @@
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"Switch output device"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Screen is pinned"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"This keeps it in view until you unpin. Touch &amp; hold Back and Overview to unpin."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"This keeps it in view until you unpin. Touch &amp; hold Back and Home to unpin."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"This keeps it in view until you unpin. Touch &amp; hold Overview to unpin."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"This keeps it in view until you unpin. Touch &amp; hold Home to unpin."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"To unpin this screen, touch &amp; hold Back and Overview buttons"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"To unpin this screen, touch &amp; hold Back and Home buttons"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Got it"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"No, thanks"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Screen pinned"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Screen unpinned"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Hide <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"It will reappear the next time you turn it on in settings."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Hide"</string>
@@ -540,8 +534,13 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Tap to mute. Accessibility services may be muted."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Tap to set to vibrate."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Tap to mute."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s volume controls shown. Swipe up to dismiss."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Volume controls hidden"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s volume controls"</string>
+    <!-- no translation found for volume_dialog_ringer_guidance_vibrate (8902050240801159042) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_silent (2128975224280276122) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_ring (6144469689490528338) -->
+    <skip />
     <string name="output_title" msgid="5355078100792942802">"Media output"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Phone call output"</string>
     <string name="output_none_found" msgid="5544982839808921091">"No devices found"</string>
@@ -691,9 +690,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Clipboard"</item>
     <item msgid="5742013440802239414">"Keycode"</item>
-    <item msgid="8802889973626281575">"Keyboard switcher"</item>
-    <item msgid="7095517796293767867">"Rotation suggestion"</item>
-    <item msgid="8494159969042135235">"None"</item>
+    <item msgid="1951959982985094069">"Rotate confirm, keyboard switcher"</item>
+    <item msgid="8175437057325747277">"None"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normal"</item>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index e5f4ece..4c05e96 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -103,6 +103,7 @@
     <string name="camera_label" msgid="7261107956054836961">"open camera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Select new task layout"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancel"</string>
+    <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Touch the fingerprint sensor"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingerprint icon"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Application icon"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Help message area"</string>
@@ -272,6 +273,7 @@
     <string name="dessert_case" msgid="1295161776223959221">"Dessert Case"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Screen saver"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <string name="quick_settings_header_onboarding_text" msgid="7872508260264044734">"Press &amp; hold on the icons for more options"</string>
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Do not disturb"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Priority only"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Alarms only"</string>
@@ -308,8 +310,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi Off"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi On"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"No Wi-Fi networks available"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarm"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Casting"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Unnamed device"</string>
@@ -359,7 +360,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is disabled in safe-mode."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Clear all"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Drag here to use split screen"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Swipe up to switch apps"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Split Horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Split Vertical"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Split Customised"</string>
@@ -503,21 +503,15 @@
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"Switch output device"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Screen is pinned"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"This keeps it in view until you unpin. Touch &amp; hold Back and Overview to unpin."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"This keeps it in view until you unpin. Touch &amp; hold Back and Home to unpin."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"This keeps it in view until you unpin. Touch &amp; hold Overview to unpin."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"This keeps it in view until you unpin. Touch &amp; hold Home to unpin."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"To unpin this screen, touch &amp; hold Back and Overview buttons"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"To unpin this screen, touch &amp; hold Back and Home buttons"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Got it"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"No, thanks"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Screen pinned"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Screen unpinned"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Hide <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"It will reappear the next time you turn it on in settings."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Hide"</string>
@@ -540,8 +534,13 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Tap to mute. Accessibility services may be muted."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Tap to set to vibrate."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Tap to mute."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s volume controls shown. Swipe up to dismiss."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Volume controls hidden"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s volume controls"</string>
+    <!-- no translation found for volume_dialog_ringer_guidance_vibrate (8902050240801159042) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_silent (2128975224280276122) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_ring (6144469689490528338) -->
+    <skip />
     <string name="output_title" msgid="5355078100792942802">"Media output"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Phone call output"</string>
     <string name="output_none_found" msgid="5544982839808921091">"No devices found"</string>
@@ -691,9 +690,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Clipboard"</item>
     <item msgid="5742013440802239414">"Keycode"</item>
-    <item msgid="8802889973626281575">"Keyboard switcher"</item>
-    <item msgid="7095517796293767867">"Rotation suggestion"</item>
-    <item msgid="8494159969042135235">"None"</item>
+    <item msgid="1951959982985094069">"Rotate confirm, keyboard switcher"</item>
+    <item msgid="8175437057325747277">"None"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normal"</item>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 3e9e3a2..df2a74e 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -103,6 +103,7 @@
     <string name="camera_label" msgid="7261107956054836961">"open camera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Select new task layout"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancel"</string>
+    <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Touch the fingerprint sensor"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingerprint icon"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Application icon"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Help message area"</string>
@@ -272,6 +273,7 @@
     <string name="dessert_case" msgid="1295161776223959221">"Dessert Case"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Screen saver"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <string name="quick_settings_header_onboarding_text" msgid="7872508260264044734">"Press &amp; hold on the icons for more options"</string>
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Do not disturb"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Priority only"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Alarms only"</string>
@@ -308,8 +310,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi Off"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi On"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"No Wi-Fi networks available"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarm"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Casting"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Unnamed device"</string>
@@ -359,7 +360,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is disabled in safe-mode."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Clear all"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Drag here to use split screen"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Swipe up to switch apps"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Split Horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Split Vertical"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Split Customised"</string>
@@ -503,21 +503,15 @@
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"Switch output device"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Screen is pinned"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"This keeps it in view until you unpin. Touch &amp; hold Back and Overview to unpin."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"This keeps it in view until you unpin. Touch &amp; hold Back and Home to unpin."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"This keeps it in view until you unpin. Touch &amp; hold Overview to unpin."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"This keeps it in view until you unpin. Touch &amp; hold Home to unpin."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"To unpin this screen, touch &amp; hold Back and Overview buttons"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"To unpin this screen, touch &amp; hold Back and Home buttons"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Got it"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"No, thanks"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Screen pinned"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Screen unpinned"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Hide <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"It will reappear the next time you turn it on in settings."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Hide"</string>
@@ -540,8 +534,13 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Tap to mute. Accessibility services may be muted."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Tap to set to vibrate."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Tap to mute."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s volume controls shown. Swipe up to dismiss."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Volume controls hidden"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s volume controls"</string>
+    <!-- no translation found for volume_dialog_ringer_guidance_vibrate (8902050240801159042) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_silent (2128975224280276122) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_ring (6144469689490528338) -->
+    <skip />
     <string name="output_title" msgid="5355078100792942802">"Media output"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Phone call output"</string>
     <string name="output_none_found" msgid="5544982839808921091">"No devices found"</string>
@@ -691,9 +690,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Clipboard"</item>
     <item msgid="5742013440802239414">"Keycode"</item>
-    <item msgid="8802889973626281575">"Keyboard switcher"</item>
-    <item msgid="7095517796293767867">"Rotation suggestion"</item>
-    <item msgid="8494159969042135235">"None"</item>
+    <item msgid="1951959982985094069">"Rotate confirm, keyboard switcher"</item>
+    <item msgid="8175437057325747277">"None"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normal"</item>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 3e9e3a2..df2a74e 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -103,6 +103,7 @@
     <string name="camera_label" msgid="7261107956054836961">"open camera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Select new task layout"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancel"</string>
+    <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Touch the fingerprint sensor"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingerprint icon"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Application icon"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Help message area"</string>
@@ -272,6 +273,7 @@
     <string name="dessert_case" msgid="1295161776223959221">"Dessert Case"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Screen saver"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <string name="quick_settings_header_onboarding_text" msgid="7872508260264044734">"Press &amp; hold on the icons for more options"</string>
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Do not disturb"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Priority only"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Alarms only"</string>
@@ -308,8 +310,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi Off"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi On"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"No Wi-Fi networks available"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarm"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Casting"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Unnamed device"</string>
@@ -359,7 +360,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is disabled in safe-mode."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Clear all"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Drag here to use split screen"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Swipe up to switch apps"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Split Horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Split Vertical"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Split Customised"</string>
@@ -503,21 +503,15 @@
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"Switch output device"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Screen is pinned"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"This keeps it in view until you unpin. Touch &amp; hold Back and Overview to unpin."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"This keeps it in view until you unpin. Touch &amp; hold Back and Home to unpin."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"This keeps it in view until you unpin. Touch &amp; hold Overview to unpin."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"This keeps it in view until you unpin. Touch &amp; hold Home to unpin."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"To unpin this screen, touch &amp; hold Back and Overview buttons"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"To unpin this screen, touch &amp; hold Back and Home buttons"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Got it"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"No, thanks"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Screen pinned"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Screen unpinned"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Hide <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"It will reappear the next time you turn it on in settings."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Hide"</string>
@@ -540,8 +534,13 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Tap to mute. Accessibility services may be muted."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Tap to set to vibrate."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Tap to mute."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s volume controls shown. Swipe up to dismiss."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Volume controls hidden"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s volume controls"</string>
+    <!-- no translation found for volume_dialog_ringer_guidance_vibrate (8902050240801159042) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_silent (2128975224280276122) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_ring (6144469689490528338) -->
+    <skip />
     <string name="output_title" msgid="5355078100792942802">"Media output"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Phone call output"</string>
     <string name="output_none_found" msgid="5544982839808921091">"No devices found"</string>
@@ -691,9 +690,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Clipboard"</item>
     <item msgid="5742013440802239414">"Keycode"</item>
-    <item msgid="8802889973626281575">"Keyboard switcher"</item>
-    <item msgid="7095517796293767867">"Rotation suggestion"</item>
-    <item msgid="8494159969042135235">"None"</item>
+    <item msgid="1951959982985094069">"Rotate confirm, keyboard switcher"</item>
+    <item msgid="8175437057325747277">"None"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normal"</item>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 35cef20..fc3482f 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -103,6 +103,7 @@
     <string name="camera_label" msgid="7261107956054836961">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‎‏‎‎‏‎‏‎‎‎‏‏‎‎‏‏‎‏‏‏‎‎‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‏‎‎‎‏‏‎‏‏‏‎‎‎‎‏‎open camera‎‏‎‎‏‎"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‏‏‏‏‎‎‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‎‏‎‏‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‎Select new task layout‎‏‎‎‏‎"</string>
     <string name="cancel" msgid="6442560571259935130">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‏‎‎‎‏‎‎‏‎‎‏‎‏‎‏‏‎‏‎‎‏‎‎‏‎‏‎‏‏‏‏‎‎‎‏‎‏‏‎‏‏‎‎‏‏‎‎‏‏‎‏‎‎Cancel‎‏‎‎‏‎"</string>
+    <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‏‎‎‏‏‏‏‏‏‎‎‏‏‏‎‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎‎‏‎Touch the fingerprint sensor‎‏‎‎‏‎"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‎‏‏‏‏‎‏‎‏‎‏‎‏‎‎‏‎‏‏‎‏‎‎‎‎‏‏‎‏‎‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‏‎‎Fingerprint icon‎‏‎‎‏‎"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‏‎‎‏‏‎‎‎‏‎‏‏‎‎‎‏‎‏‎‏‏‏‏‎‏‎‏‎‎‎‏‏‎‎‏‎‏‏‏‎‎‎‎‎‎‎‎‎‏‎‏‎‎‎‏‎Application icon‎‏‎‎‏‎"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‎‎‏‏‎‏‎‏‏‏‎‎‏‏‎‎‎‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‎‎‎‏‏‎‎‎‏‎‎‎‏‏‏‎Help message area‎‏‎‎‏‎"</string>
@@ -272,6 +273,7 @@
     <string name="dessert_case" msgid="1295161776223959221">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‏‏‏‏‎‎‏‎‏‎‏‎‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎‏‏‏‎‎‎‏‎‏‏‎‏‎‏‎Dessert Case‎‏‎‎‏‎"</string>
     <string name="start_dreams" msgid="5640361424498338327">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‏‏‎‏‎‎‏‎‏‏‎‏‏‎‏‎‏‎‎‏‏‏‎‏‎‎‎‎‎‎‎‏‎‏‎‎‎‏‎‏‎‏‎‎‎‎‏‎‏‏‏‎Screen saver‎‏‎‎‏‎"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‏‏‏‏‎‎‏‏‎‎‎‏‏‏‎‎‏‎‎‏‏‎‏‎‎‏‎‎‎‏‏‎‏‎‏‎‏‎‎‎‎Ethernet‎‏‎‎‏‎"</string>
+    <string name="quick_settings_header_onboarding_text" msgid="7872508260264044734">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‎‎‏‏‎‎‎‏‎‎‏‎‎‎‏‏‎‏‎‏‏‎‏‎‎‎‎‏‎‏‏‏‎‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‏‎‎Press &amp; hold on the icons for more options‎‏‎‎‏‎"</string>
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‎‏‏‏‏‏‏‎‎‏‏‎‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‎‎‎‎‎Do not disturb‎‏‎‎‏‎"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‎‏‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‎‎‏‏‏‎‏‏‏‏‎‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‎‎Priority only‎‏‎‎‏‎"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‎‎‏‎‎‎‎‏‏‎‏‎‏‏‎‎‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‏‏‎‏‏‎‏‎‏‏‎‎‏‏‏‎‏‎‎‎‏‎‎Alarms only‎‏‎‎‏‎"</string>
@@ -308,8 +310,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‏‏‎‎‎‏‎‏‏‎‎‏‎‏‎‎‎‏‎‎‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‎‎‏‏‎‏‎‏‎‎‏‎‏‎‎‎‎Wi-Fi Off‎‏‎‎‏‎"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‎‎‎‏‎‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‎‎‎‎‎‎‏‏‎‏‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‎Wi-Fi On‎‏‎‎‏‎"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‏‎‏‏‎‎‏‎‏‏‎‎‎‎‏‏‏‏‎‏‏‎‏‎‏‎‏‎‎‎‏‎‎‏‎‏‏‎‏‎‏‎‎No Wi-Fi networks available‎‏‎‎‏‎"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‎‎‏‎‏‎‎‎‎‎‏‏‎‏‏‎‎‎‎‎‏‏‎‎‏‏‏‏‎‎‎‏‎‏‏‏‎‎‎‏‏‏‎‎‎‏‏‏‎‎‎‏‎‎‎Alarm‎‏‎‎‏‎"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‏‎‎‎‏‏‏‎‎‎‏‎‏‎‏‏‎‏‏‏‎‎‎‎‎‏‎‏‏‎‎‏‎‎‏‎Cast‎‏‎‎‏‎"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‏‏‎‎‎‏‎‏‎‎‏‏‏‎‎‏‎‏‎‎‏‎‏‎‎‎‎‏‏‎‎‏‎‎‎Casting‎‏‎‎‏‎"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‏‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‎‎‎‏‏‎‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‎‏‏‎‎‎‎‏‎Unnamed device‎‏‎‎‏‎"</string>
@@ -359,7 +360,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‏‎‎‏‏‏‏‎‎‏‎‏‎‏‎‎‎‏‎‏‎‏‏‎‏‎‏‎‏‏‎‎‏‎‏‏‏‎‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>‎‏‎‎‏‏‏‎ is disabled in safe-mode.‎‏‎‎‏‎"</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‎‎‎‎‏‏‎‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‎‏‏‏‎‏‏‏‏‎‎‎‎‏‎‎‎‏‏‎‏‎Clear all‎‏‎‎‏‎"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‎‎‏‎‏‎‎‏‏‎‏‎‏‎‏‏‏‏‏‎‎‎‏‎‎‎‏‎Drag here to use split screen‎‏‎‎‏‎"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‏‎‎‏‏‏‎‏‏‏‎‏‏‏‏‏‎‏‏‎‏‎‎‏‎‏‏‎‏‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‎‎‎‎‏‎‎‎‏‎Swipe up to switch apps‎‏‎‎‏‎"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‏‏‎‎‎‎‏‏‏‏‎‏‎‎‎‎‏‎‎‎‎‏‏‏‏‏‎‏‎‎‎‏‎‎‎‎‎‎‏‎‏‏‏‏‎‎‎‎‎‏‎‎‎Split Horizontal‎‏‎‎‏‎"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‎‎‎‎‎‏‏‏‏‎‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‎‎‏‎‎‏‏‎‏‎Split Vertical‎‏‎‎‏‎"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‎‏‎‎‏‎‏‎‎‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‏‎‏‎‏‏‎‏‎‎‎‏‏‎‏‏‏‎Split Custom‎‏‎‎‏‎"</string>
@@ -503,21 +503,15 @@
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‏‎‎‎‎‎‎‏‎‏‏‎‏‏‏‎‎‏‎‎‎‏‏‎‏‎‎‏‎‎‏‎‎‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‎‎‎‎Switch output device‎‏‎‎‏‎"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‏‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎‏‎‎‎‎‏‎‎‏‎‏‎‏‎‎‎‏‎‏‎‏‎‏‎‎‏‎‎‏‏‎‎‎‎‏‏‎Screen is pinned‎‏‎‎‏‎"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‎‎‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‎‏‏‏‏‎‏‎‎‎‎‏‏‎‏‎‎‏‏‎‏‏‎‎‎‏‎‎‏‏‏‎This keeps it in view until you unpin. Touch &amp; hold Back and Overview to unpin.‎‏‎‎‏‎"</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‏‎‎‏‎‎‎‏‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‎‏‏‎‎‎‏‏‎This keeps it in view until you unpin. Touch &amp; hold Back and Home to unpin.‎‏‎‎‏‎"</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‏‏‎‏‎‏‎‎‎‏‎‎‎‏‎‎‎‏‎‏‏‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‎‏‏‏‎‎‏‏‎‎‎‎‎‎This keeps it in view until you unpin. Touch &amp; hold Overview to unpin.‎‏‎‎‏‎"</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‎‎‎‏‏‎‏‎‎‏‏‏‎‏‎‏‏‏‎‏‏‎‎‏‎‏‎‎‎‎‏‎‏‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‏‏‎This keeps it in view until you unpin. Touch &amp; hold Home to unpin.‎‏‎‎‏‎"</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‎‏‏‎‎‎‎‎‎‎‎‎‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‎‎‎‏‏‎‎To unpin this screen, touch &amp; hold Back and Overview buttons‎‏‎‎‏‎"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‏‏‎‎‏‏‎‏‏‎‎‎‎‏‎‏‏‎‏‎‏‏‎‏‎‎‏‎‏‎‎‏‏‏‏‏‎‎‎‏‎‏‎‏‏‎‎‎‎‎‏‎To unpin this screen, touch &amp; hold Back and Home buttons‎‏‎‎‏‎"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‏‎‎‏‎‎‎‎‎‎‏‎‏‏‎‎‎‏‎‏‏‏‏‎‏‎‎‏‏‏‏‏‏‎‏‎‎Got it‎‏‎‎‏‎"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‏‏‎‏‏‏‏‎‎‏‏‎‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎‏‎‎‏‎‎‏‏‎‎‎No thanks‎‏‎‎‏‎"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‏‏‏‎‏‎‎‏‏‏‎‏‎‏‎‏‎‎‏‎‎‎‏‎‎‎‏‏‎‏‎‏‎‏‏‎‏‏‎‏‎‏‏‎‏‏‎‏‏‎‏‎Screen pinned‎‏‎‎‏‎"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‎‎‎‎‎‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‎‏‎‏‏‎‎‎‎‏‎‎‎‏‏‏‏‏‎‎‎Screen unpinned‎‏‎‎‏‎"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‎‏‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‎‏‏‎‎‏‎‎‏‏‎‏‏‎Hide ‎‏‎‎‏‏‎<xliff:g id="TILE_LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‎‎‎‎‏‎‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‏‏‏‏‏‎‎It will reappear the next time you turn it on in settings.‎‏‎‎‏‎"</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‏‎‏‎‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‎‎‏‎‏‏‎‏‏‎‎‏‏‏‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‎‏‏‎‏‏‎Hide‎‏‎‎‏‎"</string>
@@ -540,8 +534,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‏‏‏‎‏‏‎‎‎‎‏‏‏‎‎‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‏‎‏‎‎‎‏‏‏‎‎‏‎‎‎‏‏‎‏‎‎%1$s. Tap to mute. Accessibility services may be muted.‎‏‎‎‏‎"</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‎‎‏‏‏‏‏‎‎‎‎‎‎‎‏‏‎‎‏‏‎‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‎‏‎‏‏‎‏‎‎‎‏‎‏‎%1$s. Tap to set to vibrate.‎‏‎‎‏‎"</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‎‏‎‏‏‎‏‎‎‏‎‏‎‏‏‏‎‏‏‎‎‎‎‎‎‏‎‎‏‏‏‎‎‏‏‎‏‎‎‏‏‎‏‎‎‎‏‏‎‎%1$s. Tap to mute.‎‏‎‎‏‎"</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‎‏‏‏‎‏‎‏‏‏‏‎‏‎‏‏‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‏‏‎‏‏‏‎‎‎‎‏‏‎‎‎‎‎‏‏‏‏‎‎%s volume controls shown. Swipe up to dismiss.‎‏‎‎‏‎"</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‎‎‎‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‎‏‎‏‏‎‏‎‎‎‎‏‎‎‏‎‏‏‎‏‎‎‎‎‏‎‎‏‏‏‎Volume controls hidden‎‏‎‎‏‎"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‏‏‎‎‏‎‏‎‎‎‏‏‏‏‏‎‏‎‎‏‏‏‎‏‏‎‎‎‎‎‎‎‏‎‎‏‎‎‏‎‎‎%s volume controls‎‏‎‎‏‎"</string>
     <string name="output_title" msgid="5355078100792942802">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‏‎‎‎‏‎‎‎‎‏‏‏‏‎‎‏‎‏‎‎‏‎‎‎‎‎‏‏‎‎‎‏‏‏‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‎‏‎‎Media output‎‏‎‎‏‎"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‎‏‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‎‎‏‏‏‏‏‏‎‎‏‏‎‎‏‎‏‏‎‎‏‎‎‎‏‎Phone call output‎‏‎‎‏‎"</string>
     <string name="output_none_found" msgid="5544982839808921091">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‎‏‏‏‎‏‏‏‏‎‎‏‎‎‎‎‎‏‏‏‎‏‎‎‏‎‎‎‏‏‏‎‎‏‎‏‎‎‎‏‏‏‎‎‎‎‎‎‎‏‏‎No devices found‎‏‎‎‏‎"</string>
@@ -691,9 +684,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‏‏‏‎‎‏‏‎‎‏‏‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‎‎‎‎‎‏‏‏‎‏‏‎‎‏‏‎Clipboard‎‏‎‎‏‎"</item>
     <item msgid="5742013440802239414">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‏‎‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‏‏‎‏‎‏‎‎‏‎‏‎‏‎‎‎‏‎‎‏‎‎‏‏‎‎‏‏‏‎‏‏‎‏‏‎‎Keycode‎‏‎‎‏‎"</item>
-    <item msgid="8802889973626281575">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‎‏‎‎‏‎‏‏‏‎‎‏‎‏‎‏‎‎‏‎‎‏‎‏‏‎‏‎‏‏‏‏‎‎‏‏‏‏‎‎‏‏‎‎‏‏‏‎Keyboard switcher‎‏‎‎‏‎"</item>
-    <item msgid="7095517796293767867">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‏‏‎‎‎‎‏‎‏‎‏‏‏‏‏‎‏‎‏‏‏‏‎‎‏‎‎‎‏‏‎‎‎‏‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‏‎‏‏‎Rotation suggestion‎‏‎‎‏‎"</item>
-    <item msgid="8494159969042135235">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‏‎‏‎‏‎‎‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‎‎‏‏‎‎‏‎‏‏‏‏‎‎‎‏‏‎‎‎‎‏‏‎None‎‏‎‎‏‎"</item>
+    <item msgid="1951959982985094069">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‎‏‏‎‏‏‎‎‎‎‎‏‎‏‎‎‎‎‏‏‎‎‏‏‏‎‎‏‏‎‎‏‏‎‏‎‏‎‏‎‎‎‏‏‏‎‏‏‎‏‎‏‎Rotate confirm, keyboard switcher‎‏‎‎‏‎"</item>
+    <item msgid="8175437057325747277">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‎‏‎‎‏‏‏‏‏‏‎‎‏‎‏‏‎‎‎‎‎‎‏‏‎‏‎‏‎‏‏‏‎‏‏‏‎‏‎‎‏‏‎‎‎‏‎‎‏‏‎‏‎None‎‏‎‎‏‎"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‎‏‎‎‏‏‏‏‎‎‎‏‎‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‎‏‏‎‏‏‎‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎Normal‎‏‎‎‏‎"</item>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index d02ce1c..f98ed6b 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"abrir cámara"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Selecciona el nuevo diseño de la tarea."</string>
     <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ícono de huella digital"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ícono de la aplicación"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Área de mensajes de ayuda"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Botón de zoom de compatibilidad"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom de pantalla más pequeña a más grande"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth conectado"</string>
@@ -277,6 +276,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Caja para postres"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Protector pantalla"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"No molestar"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Solo prioridad"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Solo alarmas"</string>
@@ -313,6 +314,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi desactivada"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi activado"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"No hay redes Wi-Fi disponibles"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarma"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Transmitir"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Transmitiendo"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Dispositivo sin nombre"</string>
@@ -329,9 +331,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Conectando…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Anclaje a red"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Zona"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Activando…"</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="other">%d dispositivos</item>
+      <item quantity="one">%d dispositivo</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notificaciones"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Linterna"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Datos móviles"</string>
@@ -341,10 +345,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Utilizados: <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Límite de <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Advertencia de <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Perfil de trabajo"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Las notificaciones y las apps están desactivadas"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Luz nocturna"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Al atardecer"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Hasta el amanecer"</string>
@@ -362,8 +364,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> está inhabilitada en modo seguro."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Borrar todo"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Arrastra hasta aquí para usar la pantalla dividida"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"División horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"División vertical"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"División personalizada"</string>
@@ -504,11 +504,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Desactivar ahora"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Expandir"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Contraer"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Cambiar dispositivo de salida"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Pantalla fija"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Esta función mantiene la pantalla visible hasta que dejes de fijarla. Para ello, mantén presionados los botones Atrás y Recientes."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Esta función mantiene la pantalla visible hasta que dejes de fijarla. Para ello, mantén presionados los botones de inicio y Atrás."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Esta función mantiene la pantalla visible hasta que dejes de fijarla. Para ello, mantén presionado el botón Recientes."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Esta función mantiene la pantalla visible hasta que dejes de fijarla. Para ello, mantén presionado el botón de inicio."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Para dejar de fijar esta pantalla, mantén presionados los botones Atrás y Recientes"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Para dejar de fijar esta pantalla, mantén presionados los botones de inicio y Atrás"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Entendido"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"No, gracias"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Pantalla fija"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Pantalla no fija"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"¿Ocultar <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Volverá a aparecer la próxima vez que se active en la configuración."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Ocultar"</string>
@@ -531,8 +538,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Presiona para silenciar. Es posible que los servicios de accesibilidad estén silenciados."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Presiona para establecer el modo vibración."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Presiona para silenciar."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Se muestran los controles de volumen de %s. Desliza el dedo para descartar."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Controles de volumen ocultos"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Controles de volumen %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Salida multimedia"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Salida de llamada telefónica"</string>
     <string name="output_none_found" msgid="5544982839808921091">"No se encontraron dispositivos"</string>
@@ -588,8 +594,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Con los controles de activación de notificaciones, puedes establecer un nivel de importancia para las notificaciones de una app. \n\n"<b>"Nivel 5"</b>" \n- Mostrar en la parte superior de la lista de notificaciones. \n- Permitir interrupción en la pantalla completa. \n- Mostrar siempre. \n\n"<b>"Nivel 4"</b>" \n- No permitir interrupción en la pantalla completa. \n- Mostrar siempre. \n\n"<b>"Nivel 3"</b>" \n- No permitir interrupción en la pantalla completa. \n- No mostrar. \n\n"<b>"Nivel 2"</b>" \n- No permitir interrupción en la pantalla completa. \n- No mostrar. \n- No sonar ni vibrar. \n\n"<b>"Nivel 1"</b>" \n- No permitir interrupción en la pantalla completa. \n- No mostrar. \n- No sonar ni vibrar. \n- Ocultar de la pantalla bloqueada y la barra de estado. \n- Mostrar al final de la lista de notificaciones. \n\n"<b>"Nivel 0"</b>" \n- Bloquear todas las notificaciones de la app."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificaciones"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Ya no verás estas notificaciones"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Sueles descartar estas notificaciones. \n¿Quieres seguir recibiéndolas?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"¿Quieres seguir viendo estas notificaciones?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Detener notificaciones"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Seguir viendo"</string>
@@ -683,9 +688,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Portapapeles"</item>
     <item msgid="5742013440802239414">"Clave de código"</item>
-    <item msgid="8802889973626281575">"Cambio de teclado"</item>
-    <item msgid="7095517796293767867">"Sugerencia de rotación"</item>
-    <item msgid="8494159969042135235">"Ninguno"</item>
+    <item msgid="1951959982985094069">"Confirmar rotación, cambiar de teclado"</item>
+    <item msgid="8175437057325747277">"Ninguno"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normal"</item>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 2a409a5..3b9a49f 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -32,7 +32,7 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"No tienes notificaciones"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Entrante"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notificaciones"</string>
-    <string name="battery_low_title" msgid="6456385927409742437">"Nivel de batería bajo"</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Batería baja"</string>
     <string name="battery_low_title_hybrid" msgid="6268991275887381595">"Queda poca batería. Activa la función Ahorro de batería"</string>
     <string name="battery_low_percent_format" msgid="2900940511201380775">"Queda un <xliff:g id="PERCENTAGE">%s</xliff:g> de batería"</string>
     <string name="battery_low_percent_format_hybrid" msgid="6838677459286775617">"Queda un <xliff:g id="PERCENTAGE">%s</xliff:g> (tiempo restante aproximado según tu uso: <xliff:g id="TIME">%s</xliff:g>)"</string>
@@ -103,6 +103,7 @@
     <string name="camera_label" msgid="7261107956054836961">"abrir cámara"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Seleccionar diseño de tarea nueva"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
+    <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toca el sensor de huellas digitales"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icono de huella digital"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Icono de aplicación"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Área de mensaje de ayuda"</string>
@@ -274,6 +275,7 @@
     <string name="dessert_case" msgid="1295161776223959221">"Caja para postres"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Salvapantallas"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <string name="quick_settings_header_onboarding_text" msgid="7872508260264044734">"Mantén pulsados los iconos para ver más opciones"</string>
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"No molestar"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Solo prioritarias"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Solo alarmas"</string>
@@ -310,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi desactivado"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi activada"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"No hay ninguna red Wi-Fi disponible"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarma"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Enviar"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Enviando"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Dispositivo sin nombre"</string>
@@ -361,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"La aplicación <xliff:g id="APP">%s</xliff:g> se ha inhabilitado en modo seguro."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Borrar todo"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Arrastra hasta aquí para utilizar la pantalla dividida"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Desliza el dedo hacia arriba para cambiar de aplicación"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"División horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"División vertical"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"División personalizada"</string>
@@ -505,21 +505,15 @@
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"Cambiar dispositivo de salida"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Pantalla fijada"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"La pantalla se mantiene visible hasta que dejas de fijarla. Para ello, mantén pulsados los botones Atrás y Aplicaciones recientes."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"La pantalla se mantiene visible hasta que dejas de fijarla. Para ello, mantén pulsados los botones Atrás e Inicio."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"La pantalla se mantiene visible hasta que dejas de fijarla. Para ello, mantén pulsado el botón Aplicaciones recientes."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"La pantalla se mantiene visible hasta que dejas de fijarla. Para ello, mantén pulsado el botón Inicio."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Mantén pulsado el botón Atrás y el de aplicaciones recientes para dejar de fijar esta pantalla"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Mantén pulsado el botón Atrás y el de Inicio para dejar de fijar esta pantalla"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Entendido"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"No, gracias"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Pantalla fijada"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"La pantalla ya no está fija"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"¿Ocultar <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Volverá a aparecer la próxima vez que actives esta opción en Ajustes."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Ocultar"</string>
@@ -542,8 +536,13 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Toca para silenciar. Los servicios de accesibilidad pueden silenciarse."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Toca para activar la vibración."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Toca para silenciar."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s controles de volumen mostrados. Desliza el dedo hacia arriba para rechazar."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Controles de volumen ocultos"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Controles de volumen %s"</string>
+    <!-- no translation found for volume_dialog_ringer_guidance_vibrate (8902050240801159042) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_silent (2128975224280276122) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_ring (6144469689490528338) -->
+    <skip />
     <string name="output_title" msgid="5355078100792942802">"Salida multimedia"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Salida de llamadas"</string>
     <string name="output_none_found" msgid="5544982839808921091">"No se ha podido encontrar ningún dispositivo"</string>
@@ -693,9 +692,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Portapapeles"</item>
     <item msgid="5742013440802239414">"Código de teclado"</item>
-    <item msgid="8802889973626281575">"Cambio de teclado"</item>
-    <item msgid="7095517796293767867">"Sugerencia de rotación"</item>
-    <item msgid="8494159969042135235">"Ninguna"</item>
+    <item msgid="1951959982985094069">"Confirmar rotación, cambiar de teclado"</item>
+    <item msgid="8175437057325747277">"Ninguno"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normal"</item>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index eac4814..9141046 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"ava kaamera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Uue toimingu paigutuse valimine"</string>
     <string name="cancel" msgid="6442560571259935130">"Tühista"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Sõrmejälje ikoon"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Rakenduse ikoon"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Abisõnumi ala"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Sobivussuumi nupp."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Suumi suuremale ekraanile vähem."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth on ühendatud."</string>
@@ -277,6 +276,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Maiustusekorv"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Ekraanisäästja"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Mitte segada"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Ainult prioriteetsed"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Ainult äratused"</string>
@@ -313,6 +314,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"WiFi-ühendus on väljas"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"WiFi on sees"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"WiFi-võrke pole saadaval"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Hoiatus"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Ülekandmine"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Osatäitjad"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Nimeta seade"</string>
@@ -329,9 +331,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Ühenduse loomine ..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Jagamine"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Kuumkoht"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Sisselülitamine …"</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="other">%d seadet</item>
+      <item quantity="one">%d seade</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Märguanded"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Taskulamp"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobiilne andmeside"</string>
@@ -341,10 +345,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> on kasutatud"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Limiit: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> hoiatus"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Tööprofiil"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Märguanded ja rakendused on välja lülitatud"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Öövalgus"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Sissel. päikeselooj."</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Kuni päikesetõusuni"</string>
@@ -362,8 +364,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Rakendus <xliff:g id="APP">%s</xliff:g> on turvarežiimis keelatud."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Kustuta kõik"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Jagatud ekraani kasutamiseks lohistage siia"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Horisontaalne poolitamine"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Vertikaalne poolitamine"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Kohandatud poolitamine"</string>
@@ -504,11 +504,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Lülita kohe välja"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Laiendamine"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Ahendamine"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Väljundseadme vahetamine"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Ekraan on kinnitatud"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"See hoitakse kuval, kuni selle vabastate. Vabastamiseks puudutage pikalt nuppe Tagasi ja Ülevaade."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"See hoitakse kuval, kuni selle vabastate. Vabastamiseks puudutage pikalt nuppe Tagasi ja Avaekraan."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"See hoitakse kuval, kuni selle vabastate. Vabastamiseks puudutage pikalt nuppu Ülevaade."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"See hoitakse kuval, kuni selle vabastate. Vabastamiseks puudutage pikalt nuppu Avaekraan."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Ekraanikuva vabastamiseks puudutage pikalt nuppe Tagasi ja Ülevaade"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Ekraanikuva vabastamiseks puudutage pikalt nuppe Tagasi ja Avaekraan"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Selge"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Tänan, ei"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Ekraanikuva on kinnitatud"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Ekraanikuva on vabastatud"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Kas peita <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"See kuvatakse uuesti järgmisel korral, kui selle seadetes sisse lülitate."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Peida"</string>
@@ -531,8 +538,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Puudutage vaigistamiseks. Juurdepääsetavuse teenused võidakse vaigistada."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Puudutage vibreerimise määramiseks."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Puudutage vaigistamiseks."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s helitugevuse juhtnuppu on kuvatud. Loobumiseks pühkige üles."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Helitugevuse juhtnupud on peidetud"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Helitugevuse juhtnupud: %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Meediaväljund"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Telefonikõne väljund"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Seadmeid ei leitud"</string>
@@ -588,8 +594,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Toite märguannete juhtnuppudega saate määrata rakenduse märguannete tähtsuse taseme vahemikus 0–5. \n\n"<b>"5. tase"</b>" \n- Kuva märguannete loendi ülaosas\n- Luba täisekraanil häirimine \n- Kuva alati ekraani servas \n\n"<b>"4. tase"</b>" \n- Keela täisekraanil häirimine \n- Kuva alati ekraani servas \n\n"<b>"3. tase"</b>" \n- Keela täisekraanil häirimine \n- Ära kunagi kuva ekraani servas \n\n"<b>"2. tase"</b>" \n- Keela täisekraanil häirimine \n- Ära kunagi kuva ekraani servas \n- Ära kunagi helise ega vibreeri \n\n"<b>"1. tase"</b>" \n- Keela täisekraanil häirimine \n- Ära kunagi kuva ekraani servas \n- Ära kunagi helise ega vibreeri \n- Peida lukustuskuval ja olekuribal \n- Kuva märguannete loendi allosas \n\n"<b>"Tase 0"</b>" \n- Blokeeri kõik rakenduse märguanded"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Märguanded"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Te ei näe enam neid märguandeid"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Tavaliselt loobute nendest märguannetest. \nKas soovite neid jätkuvalt näidata?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Kas soovite nende märguannete kuvamist jätkata?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Peata märguanded"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Jätka kuvamist"</string>
@@ -683,9 +688,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Lõikelaud"</item>
     <item msgid="5742013440802239414">"Võtmekood"</item>
-    <item msgid="8802889973626281575">"Klaviatuuri vahetaja"</item>
-    <item msgid="7095517796293767867">"Pööramise soovitus"</item>
-    <item msgid="8494159969042135235">"Puudub"</item>
+    <item msgid="1951959982985094069">"Pööramise kinnitamine, klaviatuuri vahetaja"</item>
+    <item msgid="8175437057325747277">"Mitte ükski"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Tavaline"</item>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 9b52656..0d4789e 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"ireki kamera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Hautatu zereginen diseinua"</string>
     <string name="cancel" msgid="6442560571259935130">"Utzi"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Hatz-markaren ikonoa"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Aplikazioaren ikonoa"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Laguntza-mezuaren eremua"</string>
@@ -274,6 +276,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Postreen kutxa"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Pantaila-babeslea"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Ez molestatu"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Lehentasunezkoak soilik"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Alarmak soilik"</string>
@@ -534,8 +538,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Sakatu audioa desaktibatzeko. Baliteke erabilerraztasun-eginbideen audioa desaktibatzea."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Sakatu hau dardara ezartzeko."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Sakatu hau audioa desaktibatzeko."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Bolumena kontrolatzeko %s aukera daude ikusgai. Pasatu hatza gora baztertzeko."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Ezkutatuta daude bolumena kontrolatzeko aukerak"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s gailuaren bolumena kontrolatzeko aukerak"</string>
     <string name="output_title" msgid="5355078100792942802">"Multimedia-irteera"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Telefono-deiaren irteera"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Ez da aurkitu gailurik"</string>
@@ -685,9 +688,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Arbela"</item>
     <item msgid="5742013440802239414">"Tekla-kodea"</item>
-    <item msgid="8802889973626281575">"Teklatu-aldatzailea"</item>
-    <item msgid="7095517796293767867">"Biratzeko iradokizuna"</item>
-    <item msgid="8494159969042135235">"Bat ere ez"</item>
+    <item msgid="1951959982985094069">"Biratu berresteko, teklatu-aldatzailea"</item>
+    <item msgid="8175437057325747277">"Bat ere ez"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normala"</item>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index a5543d3..9dcdf68 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"باز کردن دوربین"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"انتخاب طرح‌بندی جدید کار"</string>
     <string name="cancel" msgid="6442560571259935130">"لغو"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"نماد اثر انگشت"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"نماد برنامه"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"بخش پیام راهنما"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"دکمه بزرگ‌نمایی سازگار."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"بزرگ‌نمایی از صفحه‌های کوچک تا بزرگ."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"بلوتوث متصل است."</string>
@@ -275,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"ویترین دسر"</string>
     <string name="start_dreams" msgid="5640361424498338327">"محافظ صفحه"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"اترنت"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"مزاحم نشوید"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"فقط اولویت‌دار"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"فقط هشدارها"</string>
@@ -311,6 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"‏Wi-Fi خاموش است"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"‏Wi-Fi روشن"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"‏هیچ شبکه Wi-Fi موجود نیست"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"هشدار"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"فرستادن"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"در حال فرستادن"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"دستگاه بدون نام"</string>
@@ -327,9 +329,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"در حال اتصال..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"اتصال به اینترنت با تلفن همراه"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"نقطه اتصال"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"درحال روشن کردن…"</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="one">‏%d دستگاه</item>
+      <item quantity="other">‏%d دستگاه</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"اعلان‌ها"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"چراغ قوه"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"داده تلفن همراه"</string>
@@ -339,10 +343,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> استفاده شده"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> محدودیت"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"هشدار <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"نمایه کاری"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"اعلان‌ها و برنامه‌ها خاموش است"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"نور شب"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"غروب روشن می‌شود"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"تا طلوع"</string>
@@ -360,8 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> در حالت ایمن غیرفعال است."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"پاک کردن همه"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"برای استفاده از تقسیم صفحه، به اینجا بکشید"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"تقسیم افقی"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"تقسیم عمودی"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"سفارشی کردن تقسیم"</string>
@@ -502,11 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"اکنون خاموش کنید"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"بزرگ کردن"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"کوچک کردن"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"تغییر دستگاه خروجی"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"صفحه نمایش پین شد"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"تا زمانی که پین را بردارید، در نما نگه‌داشته می‌شود. برای برداشتن پین، «برگشت» و «نمای کلی» را لمس کنید و نگه‌دارید."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"تا برداشتن پین، در نما نگه‌داشته می‌شود. برای برداشتن پین، «برگشت» و «صفحه اصلی» را لمس کنید و نگه‌دارید."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"تا زمانی که پین را بردارید، در نما نگه‌داشته می‌شود. برای برداشتن پین، «نمای کلی» را لمس کنید و نگه‌دارید."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"تا برداشتن پین، در نما نگه‌داشته می‌شود. برای برداشتن پین، «صفحه اصلی» را لمس کنید و نگه‌دارید."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"برای برداشتن پین این صفحه، دکمه‌های «برگشت» و «نمای کلی» را لمس کنید و نگه‌دارید"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"برای برداشتن پین این صفحه، دکمه‌های «برگشت» و «صفحه اصلی» را لمس کنید و نگه‌دارید"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"متوجه شدم"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"نه متشکرم"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"صفحه پین شد"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"پین صفحه برداشته شد"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> مخفی شود؟"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"دفعه بعد که آن را روشن کنید، در تنظیمات نشان داده می‌شود."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"پنهان کردن"</string>
@@ -529,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"‏%1$s. برای بی‌صدا کردن ضربه بزنید. ممکن است سرویس‌های دسترس‌پذیری بی‌صدا شوند."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"‏%1$s. برای تنظیم روی لرزش، ضربه بزنید."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"‏%1$s. برای بی‌صدا کردن ضربه بزنید."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"‏کنترل‌های میزان صدای %s  نشان داده شدند. برای نپذیرفتن انگشتتان را تند بکشید."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"کنترل‌های صدا پنهان هستند"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"‏%s کنترل‌های میزان صدا"</string>
     <string name="output_title" msgid="5355078100792942802">"خروجی رسانه"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"خروجی تماس تلفنی"</string>
     <string name="output_none_found" msgid="5544982839808921091">"دستگاهی پیدا نشد"</string>
@@ -586,8 +592,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"با کنترل‌های قدرتمند اعلان می‌توانید سطح اهمیت اعلان‌های هر برنامه را از ۰ تا ۵ تعیین کنید. \n\n"<b>"سطح ۵"</b>" \n- در صدر فهرست اعلان‌ها نشان داده می‌شود \n- وقفه برای نمایش تمام‌صفحه مجاز است \n- همیشه اجمالی نشان داده می‌شود \n\n"<b>"سطح ۴"</b>" \n- وقفه برای نمایش تمام‌صفحه مجاز نیست \n- همیشه اجمالی نشان داده می‌شود \n\n"<b>"سطح ۳"</b>" \n- وقفه برای نمایش تمام‌صفحه مجاز نیست \n- هیچ‌وقت اجمالی نشان داده نمی‌شود \n\n"<b>"سطح ۲"</b>" \n- وقفه برای نمایش تمام‌صفحه مجاز نیست \n- هیچ‌وقت اجمالی نشان داده نمی‌شود \n- هیچ‌وقت صدا و لرزش ایجاد نمی‌کند \n\n"<b>"سطح ۱"</b>" \n- نمایش تمام صفحه مجاز نیست \n- هیچ‌وقت اجمالی نشان داده نمی‌شود \n- هیچ‌وقت صدا یا لرزش ایجاد نمی‌کند \n- در قفل صفحه و نوار وضعیت پنهان است \n- در پایین فهرست اعلان‌ها نشان داده می‌شود \n\n"<b>"سطح ۰"</b>" \n- همه اعلان‌های این برنامه مسدود است"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"اعلان‌ها"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"دیگر این اعلان‌ها را نخواهید دید"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"معمولاً این اعلان‌ها را رد می‌کنید. \nهمچنان نشان داده شود؟"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"نمایش این اعلان‌ها ادامه یابد؟"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"توقف اعلان‌ها"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"همچنان نشان داده شود"</string>
@@ -681,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"بریده‌دان"</item>
     <item msgid="5742013440802239414">"کد کلید"</item>
-    <item msgid="8802889973626281575">"تغییردهنده صفحه‌کلید"</item>
-    <item msgid="7095517796293767867">"پیشنهاد چرخش"</item>
-    <item msgid="8494159969042135235">"هیچ‌کدام"</item>
+    <item msgid="1951959982985094069">"تأیید چرخش، تغییردهنده صفحه‌کلید"</item>
+    <item msgid="8175437057325747277">"هیچ‌کدام"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"معمولی"</item>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index e7fcb43..7daf74d 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"avaa kamera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Valitse uusi tehtävien asettelu"</string>
     <string name="cancel" msgid="6442560571259935130">"Peruuta"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Sormenjälkikuvake"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Sovelluskuvake"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Ohjeviestialue"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Jälkiruokavitriini"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Näytönsäästäjä"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Älä häiritse"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Vain tärkeät"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Vain herätykset"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi-yhteys pois käytöstä"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi on käytössä"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Ei Wi-Fi-verkkoja käytettävissä"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Hälytys"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Suoratoisto"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Lähetetään"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Nimetön laite"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> on poistettu käytöstä vikasietotilassa."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Tyhjennä kaikki"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Jaa näyttö vetämällä tähän."</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Vaihda sovellusta pyyhkäisemällä ylös"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Vaakasuuntainen jako"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Pystysuuntainen jako"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Muokattu jako"</string>
@@ -503,21 +505,15 @@
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"Vaihda toistolaitetta"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Näyttö on kiinnitetty"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Pysyy näkyvissä, kunnes irrotat sen. Irrota painamalla pitkään Edellinen ja Viimeisimmät."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Pysyy näkyvissä, kunnes irrotat sen. Irrota painamalla pitkään Edellinen ja Aloitusnäyttö."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Pysyy näkyvissä, kunnes irrotat sen. Irrota painamalla pitkään Viimeisimmät."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Pysyy näkyvissä, kunnes irrotat sen. Irrota painamalla pitkään Aloitusnäyttö."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Irrota näyttö koskettamalla pitkään Takaisin- ja Viimeisimmät-painikkeita"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Irrota näyttö koskettamalla pitkään Takaisin- ja Aloitusnäyttö-painikkeita"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Selvä"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Ei kiitos"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Näyttö kiinnitetty"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Näyttö irrotettu"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Piilotetaanko <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Se tulee takaisin näkyviin, kun seuraavan kerran otat sen käyttöön asetuksissa."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Piilota"</string>
@@ -540,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Mykistä koskettamalla. Myös esteettömyyspalvelut saattavat mykistyä."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Siirry värinätilaan napauttamalla."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Mykistä napauttamalla."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Äänenvoimakkuuden säätimiä on näkyvissä (%s). Hylkää pyyhkäisemällä ylös."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Äänenvoimakkuuden säätimet piilotettiin."</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Äänenvoimakkuuden säädin: %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Median äänentoisto"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Puhelun äänentoisto"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Laitteita ei löytynyt"</string>
@@ -691,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Leikepöytä"</item>
     <item msgid="5742013440802239414">"Näppäinkoodi"</item>
-    <item msgid="8802889973626281575">"Näppäimistövalitsin"</item>
-    <item msgid="7095517796293767867">"Kiertoehdotus"</item>
-    <item msgid="8494159969042135235">"Ei mitään"</item>
+    <item msgid="1951959982985094069">"Vahvista kiertäminen, vaihda näppäimistöä"</item>
+    <item msgid="8175437057325747277">"Ei mitään"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normaali"</item>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index fe8f6d5..7ceb7ee 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"Ouvrir l\'appareil photo"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Sélectionner un nouveau format de tâche"</string>
     <string name="cancel" msgid="6442560571259935130">"Annuler"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icône d\'empreinte digitale"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Icône de l\'application"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Zone de message d\'aide"</string>
@@ -274,6 +276,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Vitrine des desserts"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Écran de veille"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Ne pas déranger"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Prioritaires seulement"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Alarmes seulement"</string>
@@ -534,8 +538,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Touchez pour couper le son. Il est possible de couper le son des services d\'accessibilité."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Touchez pour activer les vibrations."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Touchez pour couper le son."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Commandes de volume %s affichées. Faire glisser vers le haut pour ignorer."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Les commandes de volume sont masquées"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Commandes de volume de %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Sortie multimédia"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Sortie d\'appel téléphonique"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Aucun appareil trouvé"</string>
@@ -685,9 +688,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Presse-papiers"</item>
     <item msgid="5742013440802239414">"Code de touche"</item>
-    <item msgid="8802889973626281575">"Sélecteur de clavier"</item>
-    <item msgid="7095517796293767867">"Suggestion de rotation"</item>
-    <item msgid="8494159969042135235">"Aucun"</item>
+    <item msgid="1951959982985094069">"Confirmation de rotation, changeur de clavier"</item>
+    <item msgid="8175437057325747277">"Aucun"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normale"</item>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index cc8bcba..1c0b8c0 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -88,6 +88,7 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Accueil"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
     <string name="accessibility_accessibility_button" msgid="7601252764577607915">"Accessibilité"</string>
+    <string name="accessibility_rotate_button" msgid="7402949513740253006">"Faire pivoter l\'écran"</string>
     <string name="accessibility_recent" msgid="5208608566793607626">"Aperçu"</string>
     <string name="accessibility_search_light" msgid="1103867596330271848">"Rechercher"</string>
     <string name="accessibility_camera_button" msgid="8064671582820358152">"Appareil photo"</string>
@@ -102,6 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"ouvrir l\'appareil photo"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Sélectionner un nouveau plan de tâche"</string>
     <string name="cancel" msgid="6442560571259935130">"Annuler"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icône d\'empreinte digitale"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Icône d\'application"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Zone de message d\'aide"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Bouton \"Zoom de compatibilité\""</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom de compatibilité avec la taille de l\'écran"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth connecté"</string>
@@ -180,7 +186,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Sonnerie en mode silencieux"</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
-    <string name="accessibility_work_mode" msgid="2478631941714607225">"Mode Travail"</string>
+    <!-- no translation found for accessibility_work_mode (702887484664647430) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Supprimer <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Application \"<xliff:g id="APP">%s</xliff:g>\" ignorée."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Toutes les applications récentes ont été supprimées."</string>
@@ -269,6 +276,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Vitrine des desserts"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Économiseur d\'écran"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Ne pas déranger"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Prioritaires uniquement"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Alarmes uniquement"</string>
@@ -277,6 +286,10 @@
     <string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth (<xliff:g id="NUMBER">%d</xliff:g> appareils)"</string>
     <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth désactivé"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"Aucun appareil associé disponible."</string>
+    <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="7106697106764717416">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batterie"</string>
+    <string name="quick_settings_bluetooth_secondary_label_audio" msgid="5673845963301132071">"Audio"</string>
+    <string name="quick_settings_bluetooth_secondary_label_headset" msgid="1880572731276240588">"Casque"</string>
+    <string name="quick_settings_bluetooth_secondary_label_input" msgid="2173322305072945905">"Entrée"</string>
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Luminosité"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"Rotation automatique"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"Rotation automatique de l\'écran"</string>
@@ -301,6 +314,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi désactivé"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi activé"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Aucun réseau Wi-Fi disponible"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarme"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Caster"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Diffusion"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Appareil sans nom"</string>
@@ -317,6 +331,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Connexion en cours..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Partage de connexion"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Point d\'accès"</string>
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Activation..."</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="one">%d appareil</item>
+      <item quantity="other">%d appareils</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notifications"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Lampe de poche"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Données mobiles"</string>
@@ -326,8 +345,13 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> utilisés"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> au maximum"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Avertissement : <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <string name="quick_settings_work_mode_label" msgid="6244915274350490429">"Mode Travail"</string>
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Profil professionnel"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Les notifications et les applications sont désactivées"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Éclairage nocturne"</string>
+    <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Activé au crépuscule"</string>
+    <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Jusqu\'à l\'aube"</string>
+    <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Activé à <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="quick_settings_night_secondary_label_until" msgid="8664820079774824618">"Jusqu\'à <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"La technologie NFC est désactivée"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"La technologie NFC est activée"</string>
@@ -480,11 +504,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Désactiver"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Développer"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Réduire"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Changer de périphérique de sortie"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Écran épinglé"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Cet écran est épinglé jusqu\'à l\'annulation de l\'opération. Pour annuler l\'épinglage, appuyez de manière prolongée sur les boutons Retour et Aperçu."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Cet écran est épinglé jusqu\'à l\'annulation de l\'opération. Pour annuler l\'épinglage, appuyez de manière prolongée sur les boutons \"Retour\" et \"Accueil\"."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Cet écran est épinglé jusqu\'à l\'annulation de l\'opération. Pour annuler l\'épinglage, appuyez de manière prolongée sur le bouton Aperçu."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Cet écran est épinglé jusqu\'à l\'annulation de l\'opération. Pour annuler l\'épinglage, appuyez de manière prolongée sur le bouton \"Accueil\"."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Pour annuler l\'épinglage de l\'écran, appuyez de manière prolongée sur les boutons \"Retour\" et \"Aperçu\""</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Pour annuler l\'épinglage de l\'écran, appuyez de manière prolongée sur les boutons \"Retour\" et \"Accueil\""</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Non, merci"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Écran épinglé"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Épinglage d\'écran annulé"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Masquer <xliff:g id="TILE_LABEL">%1$s</xliff:g> ?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Cet élément réapparaîtra la prochaine fois que vous l\'activerez dans les paramètres."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Masquer"</string>
@@ -507,8 +538,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Appuyez pour ignorer. Vous pouvez ignorer les services d\'accessibilité."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Appuyez pour mettre en mode vibreur."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Appuyez pour ignorer."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Commandes de volume %s affichées. Faire glisser vers le haut pour ignorer."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Commandes de volume masquées"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Commandes de volume %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Sortie multimédia"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Sortie de l\'appel téléphonique"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Aucun appareil détecté"</string>
@@ -564,6 +594,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Grâce aux commandes de gestion des notifications, vous pouvez définir le niveau d\'importance (compris entre 0 et 5) des notifications d\'une application. \n\n"<b>"Niveau 5"</b>" \n- Afficher en haut de la liste des notifications \n- Autoriser l\'interruption en plein écran \n- Toujours en aperçu \n\n"<b>"Niveau 4"</b>" \n- Empêcher l\'interruption en plein écran \n- Toujours en aperçu \n\n"<b>"Niveau 3"</b>" \n- Empêcher l\'interruption en plein écran \n- Jamais en aperçu \n\n"<b>"Niveau 2"</b>" \n- Empêcher l\'interruption en plein écran \n- Jamais en aperçu \n- Ne jamais émettre de signal sonore ni déclencher le vibreur \n\n"<b>"Niveau 1"</b>" \n- Empêcher l\'interruption en plein écran \n- Jamais en aperçu \n- Ne jamais émettre de signal sonore ni déclencher le vibreur \n- Masquer les notifications dans l\'écran de verrouillage et la barre d\'état \n- Afficher au bas de la liste des notifications \n\n"<b>"Niveau 0"</b>" \n- Bloquer toutes les notifications de l\'application"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Vous ne recevrez plus ces notifications"</string>
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Vous ignorez généralement ces notifications. \nSouhaitez-vous continuer de les recevoir ?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Continuer d\'afficher ces notifications ?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Arrêter les notifications"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Continuer d\'afficher les notifications"</string>
@@ -657,7 +688,7 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Presse-papiers"</item>
     <item msgid="5742013440802239414">"Code de touche"</item>
-    <item msgid="8802889973626281575">"Sélecteur clavier"</item>
+    <item msgid="1951959982985094069">"Confirmer la rotation, commutateur de clavier"</item>
     <item msgid="8175437057325747277">"Aucun"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
@@ -782,4 +813,10 @@
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Appuyer pour obtenir des informations sur l\'utilisation de la batterie et des données"</string>
     <string name="data_usage_disable_mobile" msgid="5116269981510015864">"Désactiver les données mobiles ?"</string>
     <string name="touch_filtered_warning" msgid="8671693809204767551">"L\'application Paramètres ne peut pas valider votre réponse, car une application masque la demande d\'autorisation."</string>
+    <string name="slice_permission_title" msgid="7465009437851044444">"Autoriser <xliff:g id="APP_0">%1$s</xliff:g> à afficher des éléments de <xliff:g id="APP_2">%2$s</xliff:g> ?"</string>
+    <string name="slice_permission_text_1" msgid="3514586565609596523">"- Accès aux informations de <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="slice_permission_text_2" msgid="3146758297471143723">"- Capacité d\'action dans <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="slice_permission_checkbox" msgid="7986504458640562900">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à afficher des éléments de n\'importe quelle application"</string>
+    <string name="slice_permission_allow" msgid="2340244901366722709">"Autoriser"</string>
+    <string name="slice_permission_deny" msgid="7683681514008048807">"Refuser"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 8f049cd..6d927ea 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"abrir cámara"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Seleccionar novo deseño de tarefas"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icona de impresión dixital"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Icona de aplicación"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Área de mensaxes de axuda"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Botón de zoom de compatibilidade"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom de compatibilidade co tamaño da pantalla."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth conectado"</string>
@@ -277,6 +276,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Caixa de sobremesa"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Protector pantalla"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Non molestar"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Só prioridade"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Só alarmas"</string>
@@ -313,6 +314,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wifi desactivada"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wifi activada"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Non hai redes wifi dispoñibles"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarma"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Emisión"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Emitindo"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Dispositivo sen nome"</string>
@@ -329,9 +331,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Conectando..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Conexión compartida"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Zona wifi"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Activando…"</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="other">%d dispositivos</item>
+      <item quantity="one">%d dispositivo</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notificacións"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Lanterna"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Datos móbiles"</string>
@@ -341,10 +345,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> usados"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Límite de <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Advertencia <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Perfil de traballo"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"As notificacións e as aplicacións están desactivadas"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Luz nocturna"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Activación ao solpor"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Ata o amencer"</string>
@@ -362,8 +364,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"A aplicación <xliff:g id="APP">%s</xliff:g> está desactivada no modo seguro"</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Borrar todo"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Arrastrar aquí para usar a pantalla dividida"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Dividir en horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Dividir en vertical"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Dividir de xeito personalizado"</string>
@@ -504,11 +504,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Desactivar agora"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Ampliar"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Contraer"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Cambia ao dispositivo de saída"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"A pantalla está fixada"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"A pantalla manterase visible ata que a soltes. Para facelo, mantén premido Atrás e Visión xeral."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"A pantalla manterase visible ata que a soltes. Para facelo, mantén premido Atrás e Inicio."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"A pantalla manterase visible ata que a soltes. Para facelo, mantén premido Visión xeral."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"A pantalla manterase visible ata que a soltes. Para facelo, mantén premido Inicio."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Para soltar a pantalla, mantén premidos os botóns Volver e Visión xeral"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Para soltar a pantalla, mantén premidos os botóns Atrás e Inicio"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"De acordo"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Non, grazas"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Fixouse a pantalla"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Soltouse a pantalla"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Queres ocultar <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Volverá aparecer a próxima vez que se active na configuración."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Ocultar"</string>
@@ -531,8 +538,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Toca para silenciar. Pódense silenciar os servizos de accesibilidade."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Toca para establecer a vibración."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Toca para silenciar."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Estanse mostrando os controis de volume de %s. Pasa o dedo cara a arriba para ignoralos."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Ocultáronse os controis de volume"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Controis de volume de %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Saída multimedia"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Saída de chamadas telefónicas"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Non se atopou ningún dispositivo"</string>
@@ -588,8 +594,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Cos controis de notificacións mellorados, podes asignarlles un nivel de importancia comprendido entre 0 e 5 ás notificacións dunha aplicación determinada. \n\n"<b>"Nivel 5"</b>" \n- Mostrar na parte superior da lista de notificacións. \n- Permitir interrupcións no modo de pantalla completa. \n- Mostrar sempre. \n\n"<b>"Nivel 4"</b>" \n- Impedir interrupcións no modo de pantalla completa. \n- Mostrar sempre. \n\n"<b>"Nivel 3"</b>" \n- Impedir interrupcións no modo de pantalla completa. \n- Non mostrar nunca. \n\n"<b>"Nivel 2"</b>" \n- Impedir interrupcións no modo de pantalla completa. \n- Non mostrar nunca. \n- Non soar nin vibrar nunca. \n\n"<b>"Nivel 1"</b>" \n- Impedir interrupcións no modo de pantalla completa. \n- Non mostrar nunca. \n- Non soar nin vibrar nunca. \n- Ocultar na pantalla de bloqueo e na barra de estado. \n- Mostrar na parte inferior da lista de notificacións. \n\n"<b>"Nivel 0"</b>" \n- Bloquear todas as notificacións da aplicación."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notificacións"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Deixarás de ver estas notificacións"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Ignoras estas notificacións a miúdo. \nQueres seguir recibíndoas?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Queres seguir mostrando estas notificacións?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Deter notificacións"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Continuar mostrando notificacións"</string>
@@ -683,9 +688,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Portapapeis"</item>
     <item msgid="5742013440802239414">"Código de teclas"</item>
-    <item msgid="8802889973626281575">"Conmutador do teclado"</item>
-    <item msgid="7095517796293767867">"Suxestión de rotación"</item>
-    <item msgid="8494159969042135235">"Ningún tipo"</item>
+    <item msgid="1951959982985094069">"Confirmación de xiro, conmutador de teclados"</item>
+    <item msgid="8175437057325747277">"Ningún"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normal"</item>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 7c530cd..8b2ec60 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"કૅમેરો ખોલો"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"નવું કાર્ય લેઆઉટ પસંદ કરો"</string>
     <string name="cancel" msgid="6442560571259935130">"રદ કરો"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ફિંગરપ્રિન્ટનું આઇકન"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"ઍપ્લિકેશનનું આઇકન"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"સહાય સંદેશનું ક્ષેત્ર"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"ડેઝર્ટ કેસ"</string>
     <string name="start_dreams" msgid="5640361424498338327">"સ્ક્રીન સેવર"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"ઇથરનેટ"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"ખલેલ પાડશો નહીં"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"ફક્ત પ્રાધાન્યતા"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"ફક્ત એલાર્મ્સ"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"વાઇ-ફાઇ બંધ"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"વાઇ-ફાઇ ચાલુ"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"કોઈ વાઇ-ફાઇ નેટવર્ક્સ ઉપલબ્ધ નથી"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"અલાર્મ"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"કાસ્ટ કરો"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"કાસ્ટ કરી રહ્યાં છે"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"અનામાંકિત ઉપકરણ"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"સુરક્ષિત મોડમાં <xliff:g id="APP">%s</xliff:g> અક્ષમ કરેલ છે."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"બધું સાફ કરો"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"વિભાજિત સ્ક્રીનનો ઉપયોગ કરવા માટે અહીં ખેંચો"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"ઍપ સ્વિચ કરવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"આડું વિભક્ત કરો"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"ઊભું વિભક્ત કરો"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"કસ્ટમ વિભક્ત કરો"</string>
@@ -500,25 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"હમણાં બંધ કરો"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"વિસ્તૃત કરો"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"સંકુચિત કરો"</string>
-    <!-- no translation found for accessibility_output_chooser (8185317493017988680) -->
-    <skip />
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"આઉટપુટ ઉપકરણ સ્વિચ કરો"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"સ્ક્રીન પિન કરેલ છે"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"તમે જ્યાં સુધી અનપિન કરશો નહીં ત્યાં સુધી આ તેને દૃશ્યક્ષમ રાખે છે. અનપિન કરવા માટે પાછળ અને ઝલકને સ્પર્શ કરી રાખો."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"તમે જ્યાં સુધી અનપિન કરશો નહીં ત્યાં સુધી આ તેને દૃશ્યક્ષમ રાખે છે. અનપિન કરવા માટે પાછળ અને હોમને સ્પર્શ કરી રાખો."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"તમે જ્યાં સુધી અનપિન કરશો નહીં ત્યાં સુધી આ તેને દૃશ્યક્ષમ રાખે છે. અનપિન કરવા માટે ઝલકને સ્પર્શ કરી રાખો."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"તમે જ્યાં સુધી અનપિન કરશો નહીં ત્યાં સુધી આ તેને દૃશ્યક્ષમ રાખે છે. અનપિન કરવા માટે હોમને સ્પર્શ કરી રાખો."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"આ સ્ક્રીનને અનપિન કરવા માટે, પાછળ અને ઝલક બટનને સ્પર્શ કરી રાખો"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"આ સ્ક્રીનને અનપિન કરવા માટે, પાછળ અને હોમ બટનને સ્પર્શ કરી રાખો"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"સમજાઈ ગયું"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"ના, આભાર"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"સ્ક્રીન પિન કરી"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"સ્ક્રીન અનપિન કરી"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> ને છુપાવીએ?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"તે સેટિંગ્સમાં તમે તેને ચાલુ કરશો ત્યારે આગલી વખતે ફરીથી દેખાશે."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"છુપાવો"</string>
@@ -541,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. મ્યૂટ કરવા માટે ટૅપ કરો. ઍક્સેસિબિલિટી સેવાઓ મ્યૂટ કરવામાં આવી શકે છે."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. કંપન પર સેટ કરવા માટે ટૅપ કરો."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. મ્યૂટ કરવા માટે ટૅપ કરો."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s વૉલ્યૂમ નિયંત્રણ બતાવ્યાં. છોડી દેવા માટે સ્વાઇપ કરો."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"વૉલ્યૂમ નિયંત્રણ છુપાવ્યાં"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s વૉલ્યૂમ નિયંત્રણો"</string>
     <string name="output_title" msgid="5355078100792942802">"મીડિયાનું આઉટપુટ"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"ફોન કૉલનો આઉટપુટ"</string>
     <string name="output_none_found" msgid="5544982839808921091">"કોઈ ઉપકરણો મળ્યા નથી"</string>
@@ -692,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"ક્લિપબોર્ડ"</item>
     <item msgid="5742013440802239414">"કીકોડ"</item>
-    <item msgid="8802889973626281575">"કીબોર્ડ સ્વિચર"</item>
-    <item msgid="7095517796293767867">"રોટેશન માટે સૂચન"</item>
-    <item msgid="8494159969042135235">"કોઈ નહીં"</item>
+    <item msgid="1951959982985094069">"ફેરવવાની પુષ્ટિ, કીબોર્ડ સ્વિચર"</item>
+    <item msgid="8175437057325747277">"કોઈ નહીં"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"સામાન્ય"</item>
diff --git a/packages/SystemUI/res/values-h560dp-xhdpi/dimens.xml b/packages/SystemUI/res/values-h560dp-xhdpi/dimens.xml
deleted file mode 100644
index f6dbc3d..0000000
--- a/packages/SystemUI/res/values-h560dp-xhdpi/dimens.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2014 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<resources>
-    <fraction name="keyguard_clock_y_fraction_max">32.5%</fraction>
-    <fraction name="keyguard_clock_y_fraction_min">24%</fraction>
-</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-h560dp-xxhdpi/config.xml b/packages/SystemUI/res/values-h560dp-xxhdpi/config.xml
deleted file mode 100644
index b2231a6..0000000
--- a/packages/SystemUI/res/values-h560dp-xxhdpi/config.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2014 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<resources>
-    <!-- The maximum count of notifications on Keyguard. The rest will be collapsed in an overflow
-     card. -->
-    <integer name="keyguard_max_notification_count">4</integer>
-</resources>
-
diff --git a/packages/SystemUI/res/values-h560dp-xxhdpi/dimens.xml b/packages/SystemUI/res/values-h560dp-xxhdpi/dimens.xml
deleted file mode 100644
index 905e9e3..0000000
--- a/packages/SystemUI/res/values-h560dp-xxhdpi/dimens.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2014 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<resources>
-    <fraction name="keyguard_clock_y_fraction_max">32.5%</fraction>
-    <fraction name="keyguard_clock_y_fraction_min">19.8%</fraction>
-</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-h650dp/config.xml b/packages/SystemUI/res/values-h650dp/config.xml
deleted file mode 100644
index ee641b4..0000000
--- a/packages/SystemUI/res/values-h650dp/config.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-  ~ Copyright (C) 2014 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-
-<resources>
-    <!-- The maximum count of notifications on Keyguard. The rest will be collapsed in an overflow
-     card. -->
-    <integer name="keyguard_max_notification_count">5</integer>
-</resources>
-
diff --git a/packages/SystemUI/res/values-h650dp/dimens.xml b/packages/SystemUI/res/values-h650dp/dimens.xml
index 3811f67..8a00953 100644
--- a/packages/SystemUI/res/values-h650dp/dimens.xml
+++ b/packages/SystemUI/res/values-h650dp/dimens.xml
@@ -16,7 +16,4 @@
 
 <resources>
     <dimen name="keyguard_clock_notifications_margin">32dp</dimen>
-
-    <fraction name="keyguard_clock_y_fraction_max">32.5%</fraction>
-    <fraction name="keyguard_clock_y_fraction_min">18.5%</fraction>
 </resources>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 379d1ab..5a4bfe0 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"कैमरा खोलें"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"नया कार्य लेआउट चुनें"</string>
     <string name="cancel" msgid="6442560571259935130">"रद्द करें"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"फ़िंगरप्रिंट आइकॉन"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"ऐप्लिकेशन आइकॉन"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"सहायता का मैसेज दिखाने की जगह"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"मिठाई का डिब्बा"</string>
     <string name="start_dreams" msgid="5640361424498338327">"स्क्रीन सेवर"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"ईथरनेट"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"परेशान ना करें"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"सिर्फ़ प्राथमिकता"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"सिर्फ़ अलार्म"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"वाई-फ़ाई  बंद"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"वाई-फ़ाई चालू है"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"कोई भी वाई-फ़ाई नेटवर्क उपलब्‍ध नहीं है"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"अलार्म"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"कास्ट करें"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"कास्टिंग"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"अनाम डिवाइस"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> को सुरक्षित-मोड में बंद किया गया."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Clear all"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"स्क्रीन के दो हिस्से में बंट जाने, स्पिल्ट स्क्रीन, का इस्तेमाल करने के लिए यहां खींचें और छोडें"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"ऐप्लिकेशन बदलने के लिए ऊपर स्वाइप करें"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"क्षैतिज रूप से विभाजित करें"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"लम्बवत रूप से विभाजित करें"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"अपने मुताबिक बांटें"</string>
@@ -500,25 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"अभी बंद करें"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"विस्तार करें"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"छोटा करें"</string>
-    <!-- no translation found for accessibility_output_chooser (8185317493017988680) -->
-    <skip />
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"आउटपुट डिवाइस बदलें"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"स्‍क्रीन पिन कर दी गई है"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"इससे वह तब तक दिखता रहता है जब तक कि आप उसे अनपिन नहीं कर देते. अनपिन करने के लिए, \'वापस जाएं\' और \'खास जानकारी\' को दबाकर रखें."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"इससे वह तब तक दिखाई देती है जब तक आप उसे अनपिन नहीं कर देते. अनपिन करने के लिए, होम और वापस जाएं वाले बटन को दबाकर रखें."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"इससे वह तब तक दिखता रहता है जब तक कि आप उसे अनपिन नहीं कर देते. अनपिन करने के लिए, \'खास जानकारी\' को दबाकर रखें."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"इससे वह तब तक दिखाई देती है जब तक आप उसे अनपिन नहीं कर देते. अनपिन करने के लिए, होम बटन को दबाकर रखें."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"इस स्क्रीन को अनपिन करने के लिए, खास जानकारी और वापस जाएं वाले बटन को दबाकर रखें"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"इस स्क्रीन को अनपिन करने के लिए, होम और वापस जाएं वाले बटन को दबाकर रखें"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"ठीक है"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"नहीं, रहने दें"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"स्‍क्रीन पिन की गई"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"स्‍क्रीन अनपिन की गई"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> को छिपाएं?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"जब आप उसे अगली बार सेटिंग में चालू करेंगे तो वह फिर से दिखाई देगी."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"छिपाएं"</string>
@@ -541,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. म्यूट करने के लिए टैप करें. सुलभता सेवाएं म्यूट हो सकती हैं."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. कंपन (वाइब्रेशन) पर सेट करने के लिए छूएं."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. म्यूट करने के लिए टैप करें."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s वॉल्यूम नियंत्रण दिखाए गए हैं. खारिज करने के लिए स्वाइप करें."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"वॉल्यूम नियंत्रण छिपे हुए हैं"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s की आवाज़ कम या ज़्यादा करने की सुविधा"</string>
     <string name="output_title" msgid="5355078100792942802">"मीडिया आउटपुट"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"फ़ोन कॉल का आउटपुट"</string>
     <string name="output_none_found" msgid="5544982839808921091">"कोई डिवाइस नहीं मि‍ला"</string>
@@ -692,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"क्लिपबोर्ड"</item>
     <item msgid="5742013440802239414">"कुंजी कोड"</item>
-    <item msgid="8802889973626281575">"कीबोर्ड स्विचर"</item>
-    <item msgid="7095517796293767867">"घुमाने के सुझाव"</item>
-    <item msgid="8494159969042135235">"कोई नहीं"</item>
+    <item msgid="1951959982985094069">"घुमाए जाने की पुष्टि करें, कीबोर्ड की भाषा बदलने की सुविधा"</item>
+    <item msgid="8175437057325747277">"कोई नहीं"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"सामान्य"</item>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index e8096f5..dda1b40 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -104,12 +104,11 @@
     <string name="camera_label" msgid="7261107956054836961">"otvaranje fotoaparata"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Odaberite novi izgled zadataka"</string>
     <string name="cancel" msgid="6442560571259935130">"Odustani"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona otiska prsta"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ikona aplikacije"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Područje poruke za pomoć"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Gumb za kompatibilnost zumiranja."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zumiranje manjeg zaslona na veći."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth povezan."</string>
@@ -277,6 +276,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Izlog za slastice"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Čuvar zaslona"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Ne ometaj"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Samo prioritetno"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Samo alarmi"</string>
@@ -313,6 +314,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi isključen"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi uključen"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Nije dostupna nijedna Wi-Fi mreža"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarm"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Emitiranje"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Emitiranje"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Uređaj bez naziva"</string>
@@ -329,9 +331,12 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Povezivanje..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Dijeljenje veze"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Žarišna točka"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Uključivanje..."</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="one">%d uređaj</item>
+      <item quantity="few">%d uređaja</item>
+      <item quantity="other">%d uređaja</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Obavijesti"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Svjetiljka"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobilni podaci"</string>
@@ -341,10 +346,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> iskorišteno"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Ograničenje od <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Upozorenje <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Radni profil"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Isključene su obavijesti i aplikacije"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Noćno svjetlo"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Uključuje se u suton"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Do izlaska sunca"</string>
@@ -362,8 +365,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplikacija <xliff:g id="APP">%s</xliff:g> onemogućena je u sigurnom načinu."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Izbriši sve"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Povucite ovdje da biste upotrebljavali podijeljeni zaslon"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Podijeli vodoravno"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Podijeli okomito"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Podijeli prilagođeno"</string>
@@ -504,11 +505,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Odmah isključi"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Proširivanje"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Sažimanje"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Promijenite izlazni uređaj"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Zaslon je prikvačen"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Zaslon će tako ostati u prvom planu dok ga ne otkvačite. Dodirnite i zadržite Natrag i Pregled da biste ga otkvačili."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Zaslon će tako ostati u prvom planu dok ga ne otkvačite. Dodirnite gumbe Natrag i Početna i zadržite pritisak da biste ga otkvačili."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Zaslon će tako ostati u prvom planu dok ga ne otkvačite. Dodirnite i zadržite Pregled da biste ga otkvačili."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Zaslon će tako ostati u prvom planu dok ga ne otkvačite. Dodirnite gumb Početna i zadržite pritisak da biste ga otkvačili."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Da biste otkvačili ovaj zaslon, dodirnite gumbe Natrag i Pregled i zadržite pritisak"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Da biste otkvačili ovaj zaslon, dodirnite gumbe Natrag i Početna i zadržite pritisak"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Shvaćam"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Ne, hvala"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Zaslon je pričvršćen"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Zaslon je otkvačen"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Želite li sakriti pločicu <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Ponovo će se pojaviti kada je sljedeći put uključite u postavkama."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Sakrij"</string>
@@ -531,8 +539,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Dodirnite da biste isključili zvuk. Usluge pristupačnosti možda neće imati zvuk."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Dodirnite da biste postavili na vibraciju."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Dodirnite da biste isključili zvuk."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s kontrole glasnoće prikazane. Kliznite prstom prema gore da biste ih odbacili."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Kontrole glasnoće skrivene"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Kontrole glasnoće – %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Medijski izlaz"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Izlaz telefonskih poziva"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Nije pronađen nijedan uređaj"</string>
@@ -588,8 +595,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Napredne kontrole obavijesti omogućuju vam da postavite razinu važnosti za obavijesti aplikacije od 0 do 5. \n\n"<b>"Razina 5"</b>" \n– prikaži na vrhu popisa obavijesti \n– dopusti prekide prikaza na cijelom zaslonu \n– uvijek dopusti brzi pregled \n\n"<b>"Razina 4"</b>" \n– onemogući prekid prikaza na cijelom zaslonu \n– uvijek dopusti brzi pregled \n\n"<b>"Razina 3"</b>" \n– onemogući prekid prikaza na cijelom zaslonu \n– nikad ne dopusti brzi pregled\n\n"<b>"Razina 2"</b>" \n– onemogući prekid prikaza na cijelom zaslonu \n– nikad ne dopusti brzi pregled \n– nikad ne emitiraj zvuk ni vibraciju \n\n"<b>"Razina 1"</b>" \n– onemogući prekid prikaza na cijelom zaslonu \n– nikad ne dopusti brzi pregled \n– nikad ne emitiraj zvuk ni vibraciju \n– ne prikazuj na zaključanom zaslonu i traci statusa \n– prikaži na dnu popisa obavijesti \n\n"<b>"Razina 0"</b>" \n– blokiraj sve obavijesti aplikacije"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Obavijesti"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Te vam se obavijesti više neće prikazivati"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Obično odbacujete te obavijesti. \nŽelite li da se nastave prikazivati?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Želite li da se obavijesti nastave prikazivati?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Zaustavi obavijesti"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Nastavi prikazivati"</string>
@@ -685,9 +691,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Međuspremnik"</item>
     <item msgid="5742013440802239414">"Kôd tipke"</item>
-    <item msgid="8802889973626281575">"Izmjena tipkovnice"</item>
-    <item msgid="7095517796293767867">"Predložena rotacija"</item>
-    <item msgid="8494159969042135235">"Ništa"</item>
+    <item msgid="1951959982985094069">"Potvrda zakretanja, Izmjena tipkovnice"</item>
+    <item msgid="8175437057325747277">"Ništa"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Uobičajen"</item>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index fa173d6..7c85798 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"kamera megnyitása"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Új feladatelrendezés kiválasztása"</string>
     <string name="cancel" msgid="6442560571259935130">"Mégse"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ujjlenyomat ikonja"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Alkalmazás ikonja"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Súgószöveg területe"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Kompatibilitási zoom gomb."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Kicsinyítsen a nagyobb képernyőhöz."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth csatlakoztatva."</string>
@@ -275,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Dessert Case"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Képernyővédő"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Ne zavarjanak"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Csak prioritásos"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Csak ébresztések"</string>
@@ -311,6 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi kikapcsolva"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi bekapcsolva"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Nincs elérhető Wi-Fi-hálózat"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Ébresztő"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Tartalomátküldés"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Átküldés"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Név nélküli eszköz"</string>
@@ -327,9 +329,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Csatlakozás…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Megosztás"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Bekapcsolás…"</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="other">%d eszköz</item>
+      <item quantity="one">%d eszköz</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Értesítések"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Zseblámpa"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobiladatok"</string>
@@ -339,10 +343,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> felhasználva"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> korlát"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Figyelem! <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Munkaprofil"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Az értesítések és az alkalmazások ki vannak kapcsolva"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Éjszakai fény"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Be: naplemente"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Napfelkeltéig"</string>
@@ -360,8 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"A(z) <xliff:g id="APP">%s</xliff:g> csökkentett módban ki van kapcsolva."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Összes törlése"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Húzza ide az osztott képernyő használatához"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Osztott vízszintes"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Osztott függőleges"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Osztott egyéni"</string>
@@ -502,11 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Kikapcsolás most"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Kibontás"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Összecsukás"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Váltás másik kimeneti eszközre"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"A képernyő rögzítve van"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Megjelenítve tartja addig, amíg Ön fel nem oldja a rögzítést. A feloldáshoz tartsa lenyomva a Vissza és az Áttekintés lehetőséget."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Megjelenítve tartja addig, amíg Ön fel nem oldja a rögzítést. A feloldáshoz tartsa lenyomva a Vissza és a Kezdőképernyő elemet."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Megjelenítve tartja addig, amíg Ön fel nem oldja a rögzítést. A feloldáshoz tartsa lenyomva az Áttekintés lehetőséget."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Megjelenítve tartja addig, amíg Ön fel nem oldja a rögzítést. A feloldáshoz tartsa lenyomva a Kezdőképernyő elemet."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"A képernyő rögzítésének feloldásához tartsa lenyomva a Vissza és az Áttekintés gombot"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"A képernyő rögzítésének feloldásához tartsa lenyomva a Vissza és a Kezdőképernyő gombot"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Értem"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nem, köszönöm"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Képernyő rögzítve"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Képernyő rögzítése feloldva"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Elrejti ezt: <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Újból megjelenik majd, amikor ismét engedélyezi a beállítások között."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Elrejtés"</string>
@@ -529,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Koppintson a némításhoz. Előfordulhat, hogy a kisegítő lehetőségek szolgáltatásai le vannak némítva."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Koppintson a rezgés beállításához."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Koppintson a némításhoz."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"A(z) %s hangvezérlői megjelenítve. Az elvetéshez húzza felfelé az ujját."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Hangvezérlők elrejtve"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s hangerőszabályzók"</string>
     <string name="output_title" msgid="5355078100792942802">"Médiakimenet"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Telefonhívás-kimenet"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Nem találhatók eszközök"</string>
@@ -586,8 +592,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Az értesítési beállítások révén 0-tól 5-ig állíthatja be a fontossági szintet az alkalmazás értesítéseinél. \n\n"<b>"5. szint"</b>" \n– Megjelenítés az értesítési lista tetején \n– Teljes képernyő megszakításának engedélyezése \n– Mindig felugrik \n\n"<b>"4. szint"</b>" \n– Teljes képernyő megszakításának megakadályozása \n– Mindig felugrik \n\n"<b>"3. szint"</b>" \n– Teljes képernyő megszakításának megakadályozása \n– Soha nem ugrik fel \n\n"<b>"2. szint"</b>" \n– Teljes képernyő megszakításának megakadályozása \n– Soha nem ugrik fel \n– Soha nincs hangjelzés és rezgés \n\n"<b>"1. szint"</b>" \n– Teljes képernyő megszakításának megakadályozása \n– Soha nem ugrik fel \n– Soha nincs hangjelzés vagy rezgés \n– Elrejtés a lezárási képernyőről és az állapotsávról \n– Megjelenítés az értesítési lista alján \n\n"<b>"0. szint"</b>" \n– Az alkalmazás összes értesítésének letiltása"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Értesítések"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Többé nem jelennek meg ezek az értesítések"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Általában elveti ezeket az értesítéseket.\nSzeretné, hogy továbbra is megjelenjenek?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Továbbra is megjelenjenek ezek az értesítések?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Értesítések letiltása"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Megjelenítés továbbra is"</string>
@@ -681,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Vágólap"</item>
     <item msgid="5742013440802239414">"Billentyűkód"</item>
-    <item msgid="8802889973626281575">"Billentyűzetváltó"</item>
-    <item msgid="7095517796293767867">"Forgatási javaslat"</item>
-    <item msgid="8494159969042135235">"Nincs"</item>
+    <item msgid="1951959982985094069">"Forgatás megerősítése, billentyűzetváltó"</item>
+    <item msgid="8175437057325747277">"Nincs"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normál"</item>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 5dc1dfa..478749a 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"բացել ֆոտոխցիկը"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Ընտրել առաջադրանքի նոր դասավորություն"</string>
     <string name="cancel" msgid="6442560571259935130">"Չեղարկել"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Մատնահետքի պատկերակ"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Հավելվածի պատկերակ"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Օգնության հաղորդագրության դաշտ"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Dessert Case"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Էկրանապահ"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Չանհանգստացնել"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Միայն կարևոր ծանուցումների դեպքում"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Միայն զարթուցիչ"</string>
@@ -532,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s: Հպեք՝ ձայնն անջատելու համար: Մատչելիության ծառայությունների ձայնը կարող է անջատվել:"</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s։ Հպեք՝ թրթռոցը միացնելու համար։"</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s։ Հպեք՝ ձայնը անջատելու համար։"</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s ձայնի ուժգնության կառավարները ցուցադրված են: Մատը սահեցրեք վերև՝ փակելու համար:"</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Ձայնի ուժգնության կառավարները թաքցված են"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Ձայնի ուժգնության կառավարներ` %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Մեդիա արտածում"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Հեռախոսազանգի հնչեցում"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Սարքեր չեն գտնվել"</string>
@@ -683,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Սեղմատախտակ"</item>
     <item msgid="5742013440802239414">"Ստեղնային կոդ"</item>
-    <item msgid="8802889973626281575">"Ստեղնաշարի փոխարկիչ"</item>
-    <item msgid="7095517796293767867">"Պտույտ"</item>
-    <item msgid="8494159969042135235">"Ոչ մեկը"</item>
+    <item msgid="1951959982985094069">"Հաստատել պտտումը, ստեղնաշարի փոխարկիչ"</item>
+    <item msgid="8175437057325747277">"Չկան"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Սովորական"</item>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 7ed6234..7ea5ce4 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"buka kamera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Pilih tata letak tugas baru"</string>
     <string name="cancel" msgid="6442560571259935130">"Batal"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikon sidik jari"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ikon aplikasi"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Area pesan bantuan"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Tombol perbesar/perkecil kompatibilitas."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Perbesar dari layar kecil ke besar."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth tersambung."</string>
@@ -275,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Etalase Hidangan Penutup"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Screen saver"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Jangan ganggu"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Hanya untuk prioritas"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Hanya alarm"</string>
@@ -311,6 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi Mati"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi Aktif"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Tidak ada jaringan Wi-Fi yang tersedia"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarm"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Melakukan transmisi"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Perangkat tanpa nama"</string>
@@ -327,9 +329,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Menyambung..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Menambatkan"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Mengaktifkan..."</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="other">%d perangkat</item>
+      <item quantity="one">%d perangkat</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notifikasi"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Lampu senter"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Data seluler"</string>
@@ -358,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> dinonaktifkan dalam mode aman."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Hapus semua"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Tarik ke sini untuk menggunakan layar terpisah"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Geser ke atas untuk beralih aplikasi"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Pisahkan Horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Pisahkan Vertikal"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Pisahkan Khusus"</string>
@@ -499,11 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Nonaktifkan sekarang"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Luaskan"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Ciutkan"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Ganti perangkat keluaran"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Layar dipasangi pin"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Ini akan terus ditampilkan sampai Anda melepas pin. Sentuh &amp; tahan tombol Kembali dan Ringkasan untuk melepas pin."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Ini akan terus ditampilkan sampai Anda melepas pin. Sentuh &amp; tahan tombol Kembali dan Beranda untuk melepas pin."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Ini akan terus ditampilkan sampai Anda melepas pin. Sentuh dan tahan tombol Ringkasan untuk melepas pin."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ini akan terus ditampilkan sampai Anda melepas pin. Sentuh dan tahan tombol Beranda untuk melepas pin."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Untuk melepas pin layar ini, sentuh &amp; tahan tombol Kembali dan Ringkasan"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Untuk melepas pin layar ini, sentuh &amp; tahan tombol Kembali dan Beranda"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Mengerti"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Lain kali"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Layar dipasangi pin"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Layar dilepas pinnya"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Sembunyikan <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Ini akan muncul kembali saat Anda mengaktifkannya dalam setelan."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Sembunyikan"</string>
@@ -526,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Ketuk untuk membisukan. Layanan aksesibilitas mungkin dibisukan."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Tap untuk menyetel agar bergetar."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Tap untuk menonaktifkan."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Kontrol volume %s ditampilkan. Geser ke atas untuk menutup."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Kontrol volume disembunyikan"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s kontrol volume"</string>
     <string name="output_title" msgid="5355078100792942802">"Keluaran media"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Keluaran panggilan telepon"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Perangkat tidak ditemukan"</string>
@@ -583,8 +592,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Dengan kontrol notifikasi daya, Anda dapt menyetel level kepentingan notifikasi aplikasi dari 0 sampai 5. \n\n"<b>"Level 5"</b>" \n- Muncul di atas daftar notifikasi \n- Izinkan interupsi layar penuh \n- Selalu intip pesan \n\n"<b>"Level 4"</b>" \n- Jangan interupsi layar penuh \n- Selalu intip pesan \n\n"<b>"Level 3"</b>" \n- Jangan interupsi layar penuh \n- Tak pernah intip pesan \n\n"<b>"Level 2"</b>" \n- Jangan interupsi layar penuh \n- Tak pernah intip pesan \n- Tanpa suara dan getaran \n\n"<b>"Level 1"</b>" \n- Jangan interupsi layar penuh \n- Tak pernah intip pesan \n- Tanpa suara atau getaran \n- Sembunyikan dari layar kunci dan bilah status \n- Muncul di bawah daftar notifikasi \n\n"<b>"Level 0"</b>" \n- Blokir semua notifikasi dari aplikasi"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Notifikasi"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Anda tidak akan melihat notifikasi ini lagi"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Anda biasanya menutup notifikasi ini. \nTerus tampilkan?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Terus tampilkan notifikasi ini?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Hentikan notifikasi"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Terus tampilkan"</string>
@@ -678,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Papan klip"</item>
     <item msgid="5742013440802239414">"Kode tombol"</item>
-    <item msgid="8802889973626281575">"Pengalih keyboard"</item>
-    <item msgid="7095517796293767867">"Saran rotasi"</item>
-    <item msgid="8494159969042135235">"Tak Ada"</item>
+    <item msgid="1951959982985094069">"Pengalih keyboard, konfirmasi putar"</item>
+    <item msgid="8175437057325747277">"Tidak ada"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Biasa"</item>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 1e0cd63..c98c858 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"opna myndavél"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Velja nýtt útlit verkefna"</string>
     <string name="cancel" msgid="6442560571259935130">"Hætta við"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingrafaratákn"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Forritstákn"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Svæði hjálparskilaboða"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Hnappur fyrir samhæfisaðdrátt."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Aðlaga forrit fyrir lítinn skjá að stærri skjá."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth tengt."</string>
@@ -275,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Eftirréttaborð"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Skjávari"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Ónáðið ekki"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Aðeins forgangur"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Aðeins vekjarar"</string>
@@ -311,6 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Slökkt á Wi-Fi"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Kveikt á Wi-Fi"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Engin Wi-Fi net í boði"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Vekjari"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Útsending"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Sendir út"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Ónefnt tæki"</string>
@@ -327,9 +329,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Tengist..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tjóðrun"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Heitur reitur"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Kveikir..."</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="one">%d tæki</item>
+      <item quantity="other">%d tæki</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Tilkynningar"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Vasaljós"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Farsímagögn"</string>
@@ -339,10 +343,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> notuð"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> hámark"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> viðvörun"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Vinnusnið"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Slökkt er á tilkynningum og forritum"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Næturljós"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Kveikt við sólsetur"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Til sólarupprásar"</string>
@@ -360,8 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Slökkt er á <xliff:g id="APP">%s</xliff:g> í öruggri stillingu."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Hreinsa allt"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Dragðu hingað til að skipta skjánum"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Lárétt skipting"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Lóðrétt skipting"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Sérsniðin skipting"</string>
@@ -502,11 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Slökkva núna"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Stækka"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Minnka"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Skipta um úttakstæki"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Skjárinn er festur"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Þetta heldur þessu opnu þangað til þú losar það. Haltu fingri á „Til baka“ og „Yfirlit“ til að losa."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Þetta heldur þessu opnu þangað til það er losað. Haltu inni bakkhnappinum og heimahnappinum til að losa."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Þetta heldur þessu opnu þangað til þú losar það. Haltu fingri á „Yfirlit“ til að losa."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Þetta heldur þessu opnu þangað til það er losað. Haltu heimahnappinum inni til að losa."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Til að losa þessa skjámynd skaltu halda inni bakkhnappinum og yfirlitshnappinum"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Til að losa þessa skjámynd skaltu halda inni bakkhnappinum og heimahnappinum"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Ég skil"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nei, takk"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Skjámynd fest"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Skjámynd losuð"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Fela <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Þetta birtist aftur næst þegar þú kveikir á því í stillingunum."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Fela"</string>
@@ -529,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Ýttu til að þagga. Hugsanlega verður slökkt á hljóði aðgengisþjónustu."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Ýttu til að stilla á titring."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Ýttu til að þagga."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s stýringar fyrir hljóðstyrk sýnilegar. Strjúktu upp til að hunsa."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Stýringar fyrir hljóðstyrk faldar"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s stýringar á hljóstyrk"</string>
     <string name="output_title" msgid="5355078100792942802">"Margmiðlunarúttak"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Úttak símtals"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Engin tæki fundust"</string>
@@ -586,8 +592,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Með orkutilkynningastýringum geturðu stillt mikilvægi frá 0 upp í 5 fyrir tilkynningar forrita. \n\n"<b>"Stig 5"</b>" \n- Sýna efst á tilkynningalista \n- Leyfa truflun þegar birt er á öllum skjánum \n- Kíkja alltaf \n\n"<b>"Stig 4"</b>" \n- Hindra truflun við birtingu á öllum skjánum \n- Kíkja alltaf \n\n"<b>"Stig 3"</b>" \n- Hindra truflun við birtingu á öllum skjánum \n- Kíkja aldrei \n\n"<b>"Stig 2"</b>" \n- Hindra truflun við birtingu á öllum skjánum \n- Kíkja aldrei \n- Slökkva á hljóði og titringi \n\n"<b>"Stig 1"</b>" \n- Hindra truflun við birtingu á öllum skjánum \n- Kíkja aldrei \n- Slökkva á hljóði og titringi \n- Fela á lásskjá og stöðustiku \n- Sýna neðst á tilkynningalista \n\n"<b>"Stig 0"</b>" \n- Setja allar tilkynningar frá forriti á bannlista"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Tilkynningar"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Þú munt ekki sjá þessar tilkynningar aftur"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Þú hunsar yfirleitt þessar tilkynningar. \nViltu halda áfram að fá þær?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Sýna áfram þessar tilkynningar?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Stöðva tilkynningar"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Sýna áfram"</string>
@@ -681,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Klippiborð"</item>
     <item msgid="5742013440802239414">"Lykilkóði"</item>
-    <item msgid="8802889973626281575">"Lyklaborðsval"</item>
-    <item msgid="7095517796293767867">"Tillaga um snúning"</item>
-    <item msgid="8494159969042135235">"Ekkert"</item>
+    <item msgid="1951959982985094069">"Snúa til að staðfesta, lyklaborðsval"</item>
+    <item msgid="8175437057325747277">"Ekkert"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Venjulegt"</item>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 89e9cc1..28f327f 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"apri fotocamera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Seleziona un nuovo layout per le attività"</string>
     <string name="cancel" msgid="6442560571259935130">"Annulla"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icona dell\'impronta digitale"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Icona dell\'applicazione"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Area dei messaggi di assistenza"</string>
@@ -274,6 +276,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Vetrina di dolci"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Screensaver"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Non disturbare"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Solo con priorità"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Solo sveglie"</string>
@@ -310,8 +314,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi disattivato"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi attivo"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Nessuna rete Wi-Fi disponibile"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Sveglia"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Trasmetti"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"In trasmissione"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Dispositivo senza nome"</string>
@@ -361,7 +364,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"L\'app <xliff:g id="APP">%s</xliff:g> è stata disattivata in modalità provvisoria."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Cancella tutto"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Trascina qui per utilizzare la modalità Schermo diviso"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Scorri verso l\'alto per passare ad altre app"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisione in orizzontale"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Divisione in verticale"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Divisione personalizzata"</string>
@@ -505,21 +507,15 @@
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"Cambia dispositivo di uscita"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"La schermata è fissata"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"La schermata rimane visibile finché non viene sganciata. Per sganciarla, tieni premuto Indietro e Panoramica."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"La schermata rimane visibile finché non viene disattivato il blocco su schermo. Per disattivarlo, tocca e tieni premuto Indietro e Home."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"La schermata rimane visibile finché non viene sganciata. Per sganciarla, tieni premuto Panoramica."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"La schermata rimane visibile finché non viene disattivato il blocco su schermo. Per disattivarlo, tocca e tieni premuto Home."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Per disattivare il blocco su schermo, tocca e tieni premuti i pulsanti Indietro e Panoramica"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Per disattivare il blocco su schermo, tocca e tieni premuti i pulsanti Indietro e Home"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"No, grazie"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Blocco su schermo attivato"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Blocco su schermo disattivato"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Nascondere <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Verranno visualizzate di nuovo quando le riattiverai nelle impostazioni."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Nascondi"</string>
@@ -542,8 +538,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Tocca per disattivare l\'audio. L\'audio dei servizi di accessibilità può essere disattivato."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Tocca per attivare la vibrazione."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Tocca per disattivare l\'audio."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s comandi del volume mostrati. Fai scorrere verso l\'alto per ignorare."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Comandi del volume nascosti"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Controlli del volume %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Uscita contenuti multimediali"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Uscita telefonate"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Nessun dispositivo trovato"</string>
@@ -693,9 +688,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Appunti"</item>
     <item msgid="5742013440802239414">"Keycode"</item>
-    <item msgid="8802889973626281575">"Selettore tastiera"</item>
-    <item msgid="7095517796293767867">"Suggerimento per la rotazione"</item>
-    <item msgid="8494159969042135235">"Nessuno"</item>
+    <item msgid="1951959982985094069">"Conferma rotazione, selettore tastiera"</item>
+    <item msgid="8175437057325747277">"Nessuno"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normale"</item>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index b6a153e..9aae67f 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -105,12 +105,10 @@
     <string name="camera_label" msgid="7261107956054836961">"פתח את המצלמה"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"בחר פריסה חדשה להצגת משימות"</string>
     <string name="cancel" msgid="6442560571259935130">"ביטול"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"יש לגעת בחיישן טביעות האצבע"</string>
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"סמל טביעת אצבע"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"סמל אפליקציה"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"אזור הודעת עזרה"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"לחצן מרחק מתצוגה של תאימות."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"שנה מרחק מתצוגה של מסך קטן לגדול יותר."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"‏Bluetooth מחובר."</string>
@@ -279,6 +277,7 @@
     <string name="dessert_case" msgid="1295161776223959221">"מזנון קינוחים"</string>
     <string name="start_dreams" msgid="5640361424498338327">"שומר מסך"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <string name="quick_settings_header_onboarding_text" msgid="7872508260264044734">"יש להקיש על הסמלים ולהחזיק אותם להצגת אפשרויות נוספות"</string>
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"נא לא להפריע"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"עדיפות בלבד"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"התראות בלבד"</string>
@@ -315,6 +314,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"‏Wi-Fi כבוי"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"‏Wi-Fi פועל"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"‏אין רשתות Wi-Fi זמינות"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"התראה"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"מעביר"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"מכשיר ללא שם"</string>
@@ -331,9 +331,13 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"מתחבר..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"שיתוף אינטרנט בין ניידים"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"נקודה לשיתוף אינטרנט"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"מפעיל..."</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="two">‏%d מכשירים</item>
+      <item quantity="many">‏%d מכשירים</item>
+      <item quantity="other">‏%d מכשירים</item>
+      <item quantity="one">מכשיר אחד</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"הודעות"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"פנס"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"חבילת גלישה"</string>
@@ -343,10 +347,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> בשימוש"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"הגבלה של <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"אזהרה - <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"פרופיל עבודה"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"הודעות ואפליקציות מושבתות"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"תאורת לילה"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"מופעל בשקיעה"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"עד הזריחה"</string>
@@ -364,8 +366,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> מושבת במצב בטוח."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"נקה הכל"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"גרור לכאן כדי להשתמש במסך מפוצל"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"פיצול אופקי"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"פיצול אנכי"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"פיצול מותאם אישית"</string>
@@ -506,11 +506,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"כבה עכשיו"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"הרחב"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"כווץ"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"החלפת מכשיר פלט"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"המסך מוצמד"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"נשאר בתצוגה עד לביטול ההצמדה. גע בלחצנים \'הקודם\' ו\'סקירה\' והחזק כדי לבטל את ההצמדה."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"נשאר בתצוגה עד לביטול ההצמדה. יש ללחוץ לחיצה ארוכה על הלחצנים \'הקודם\' ו\'דף הבית\' כדי לבטל את ההצמדה."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"נשאר בתצוגה עד לביטול ההצמדה. גע בלחצן \'סקירה\' והחזק כדי לבטל את ההצמדה."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"נשאר בתצוגה עד לביטול ההצמדה. יש ללחוץ לחיצה ארוכה על הלחצן \'דף הבית\' כדי לבטל את ההצמדה."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"כדי לבטל את ההצמדה של מסך זה, יש ללחוץ לחיצה ארוכה על הלחצנים \'הקודם\' ו\'סקירה\'"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"כדי לבטל את ההצמדה של מסך זה, יש ללחוץ לחיצה ארוכה על הלחצנים \'הקודם\' ו\'דף הבית\'"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"הבנתי"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"לא, תודה"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"המסך מוצמד"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"הצמדת המסך בוטלה"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"להסתיר<xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"יופיע מחדש בפעם הבאה שתפעיל את האפשרות בהגדרות."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"הסתר"</string>
@@ -533,8 +540,13 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"‏%1$s. הקש כדי להשתיק. ייתכן ששירותי הנגישות מושתקים."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"‏%1$s. הקש כדי להעביר למצב רטט."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"‏%1$s. הקש כדי להשתיק."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"‏%s פקדי עוצמת הקול גלויים. החלק כלפי מעלה כדי לסגור."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"פקדי עוצמת הקול מוסתרים"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"‏בקרי עוצמת שמע של %s"</string>
+    <!-- no translation found for volume_dialog_ringer_guidance_vibrate (8902050240801159042) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_silent (2128975224280276122) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_ring (6144469689490528338) -->
+    <skip />
     <string name="output_title" msgid="5355078100792942802">"פלט מדיה"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"פלט שיחת טלפון"</string>
     <string name="output_none_found" msgid="5544982839808921091">"לא נמצאו מכשירים"</string>
@@ -590,8 +602,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"בעזרת פקדים של הודעות הפעלה, תוכל להגדיר רמת חשיבות מ-0 עד 5 להודעות אפליקציה. \n\n"<b>"רמה 5"</b>" \n- הצג בראש רשימת ההודעות \n- אפשר הפרעה במסך מלא \n- תמיד אפשר הצצה \n\n"<b>"רמה 4"</b>" \n- מנע הפרעה במסך מלא \n- תמיד אפשר הצצה \n\n"<b>"רמה 3"</b>" \n- מנע הפרעה במסך מלא \n- אף פעם אל תאפשר הצצה \n\n"<b>"רמה 2"</b>" \n- מנע הפרעה במסך מלא \n- אף פעם אל תאפשר הצצה \n- אף פעם אל תאפשר קול ורטט \n\n"<b>"רמה 1"</b>" \n- מנע הפרעה במסך מלא \n- אף פעם אל תאפשר הצצה \n- אף פעם אל תאפשר קול ורטט \n- הסתר ממסך הנעילה ומשורת הסטטוס \n- הצג בתחתית רשימת ההודעות \n\n"<b>"רמה 0"</b>" \n- חסום את כל ההודעות מהאפליקציה"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"הודעות"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"ההודעות האלה לא יוצגו לך יותר"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"הודעות אלה בדרך כלל נדחות על ידיך. \nלהמשיך להציג אותן?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"שנמשיך להציג לך את ההודעות האלה?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"לא, אל תמשיכו"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"כן, המשיכו"</string>
@@ -689,9 +700,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"לוח"</item>
     <item msgid="5742013440802239414">"קוד מפתח"</item>
-    <item msgid="8802889973626281575">"מחליף מקלדת"</item>
-    <item msgid="7095517796293767867">"הצעת סיבוב"</item>
-    <item msgid="8494159969042135235">"אף אחת"</item>
+    <item msgid="1951959982985094069">"סיבוב לאישור, החלפת מקלדת"</item>
+    <item msgid="8175437057325747277">"ללא"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"רגילה"</item>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 983c014..b422f95 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -88,6 +88,7 @@
     <string name="accessibility_home" msgid="8217216074895377641">"ホーム"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"メニュー"</string>
     <string name="accessibility_accessibility_button" msgid="7601252764577607915">"ユーザー補助機能"</string>
+    <string name="accessibility_rotate_button" msgid="7402949513740253006">"画面を回転します"</string>
     <string name="accessibility_recent" msgid="5208608566793607626">"最近"</string>
     <string name="accessibility_search_light" msgid="1103867596330271848">"検索"</string>
     <string name="accessibility_camera_button" msgid="8064671582820358152">"カメラ"</string>
@@ -102,6 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"カメラを起動"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"新しいタスクレイアウトの選択"</string>
     <string name="cancel" msgid="6442560571259935130">"キャンセル"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"指紋アイコン"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"アプリのアイコン"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"ヘルプ メッセージ領域"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"互換ズームボタン。"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"小さい画面から大きい画面に拡大。"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetoothに接続済み。"</string>
@@ -180,7 +186,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"マナーモード着信。"</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
-    <string name="accessibility_work_mode" msgid="2478631941714607225">"Work モード"</string>
+    <!-- no translation found for accessibility_work_mode (702887484664647430) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g>を削除します。"</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g>は削除されました。"</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"最近のアプリケーションをすべて消去しました。"</string>
@@ -269,6 +276,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"デザートケース"</string>
     <string name="start_dreams" msgid="5640361424498338327">"スクリーン セーバー"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"イーサネット"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"マナーモード"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"優先する通知のみ"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"アラームのみ"</string>
@@ -277,6 +286,10 @@
     <string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth(端末数<xliff:g id="NUMBER">%d</xliff:g>)"</string>
     <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth OFF"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"ペア設定されたデバイスがありません"</string>
+    <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="7106697106764717416">"電池 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
+    <string name="quick_settings_bluetooth_secondary_label_audio" msgid="5673845963301132071">"オーディオ"</string>
+    <string name="quick_settings_bluetooth_secondary_label_headset" msgid="1880572731276240588">"ヘッドセット"</string>
+    <string name="quick_settings_bluetooth_secondary_label_input" msgid="2173322305072945905">"入力"</string>
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"画面の明るさ"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"自動回転"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"画面を自動回転します"</string>
@@ -301,6 +314,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi OFF"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi: ON"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Wi-Fiネットワークを利用できません"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"アラーム"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"キャスト"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"キャストしています"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"名前のないデバイス"</string>
@@ -317,6 +331,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"接続しています..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"テザリング"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"アクセスポイント"</string>
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"ON にしています…"</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="other">%d 台の端末</item>
+      <item quantity="one">%d 台の端末</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"通知"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"ライト"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"モバイルデータ"</string>
@@ -326,8 +345,13 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g>使用中"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"上限: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"警告: 上限は<xliff:g id="DATA_LIMIT">%s</xliff:g>です"</string>
-    <string name="quick_settings_work_mode_label" msgid="6244915274350490429">"Work モード"</string>
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"仕事用プロファイル"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"通知とアプリは OFF です"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"読書灯"</string>
+    <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"日の入りに ON"</string>
+    <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"日の出まで"</string>
+    <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g> に ON"</string>
+    <string name="quick_settings_night_secondary_label_until" msgid="8664820079774824618">"<xliff:g id="TIME">%s</xliff:g> まで"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC は無効です"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC は有効です"</string>
@@ -480,11 +504,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"OFF にする"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"展開"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"折りたたむ"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"出力デバイスを選択"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"画面が固定されました"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"固定を解除するまで画面が常に表示されるようになります。[戻る] と [最近] を同時に押し続けると固定が解除されます。"</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"固定を解除するまで画面が常に表示されるようになります。[戻る] と [ホーム] を同時に押し続けると固定が解除されます。"</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"固定を解除するまで画面が常に表示されるようになります。[最近] を押し続けると固定が解除されます。"</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"固定を解除するまで画面が常に表示されるようになります。[ホーム] を押し続けると固定が解除されます。"</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"この画面の固定を解除するには [戻る] ボタンと [最近] ボタンを押し続けます"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"この画面の固定を解除するには [戻る] ボタンと [ホーム] ボタンを押し続けます"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"はい"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"いいえ"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"画面を固定しました"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"画面の固定を解除しました"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g>を非表示にしますか?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"次回、設定でONにすると再表示されます。"</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"非表示"</string>
@@ -507,8 +538,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s。タップしてミュートします。ユーザー補助機能サービスがミュートされる場合があります。"</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s。タップしてバイブレーションに設定します。"</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s。タップしてミュートします。"</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s の音量調節が表示されています。閉じるには、上にスワイプします。"</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"音量調節を非表示にしました"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s の音量調節"</string>
     <string name="output_title" msgid="5355078100792942802">"メディア出力"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"通話の出力"</string>
     <string name="output_none_found" msgid="5544982839808921091">"デバイスが見つかりません"</string>
@@ -564,6 +594,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"電源通知管理では、アプリの通知の重要度をレベル 0~5 で設定できます。\n\n"<b>"レベル 5"</b>" \n- 通知リストの一番上に表示する \n- 全画面表示を許可する \n- 常にポップアップする \n\n"<b>"レベル 4"</b>" \n- 全画面表示しない \n- 常にポップアップする \n\n"<b>"レベル 3"</b>" \n- 全画面表示しない \n- ポップアップしない \n\n"<b>"レベル 2"</b>" \n- 全画面表示しない \n- ポップアップしない \n- 音やバイブレーションを使用しない \n\n"<b>"レベル 1"</b>" \n- 全画面表示しない \n- ポップアップしない \n- 音やバイブレーションを使用しない \n- ロック画面やステータスバーに表示しない \n- 通知リストの一番下に表示する \n\n"<b>"レベル 0"</b>" \n- アプリからのすべての通知をブロックする"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"通知"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"今後、この通知は表示されません"</string>
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"通常、この通知は非表示にしています。\n引き続き、表示しますか?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"この通知を今後も表示しますか?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"通知を表示しない"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"今後も表示する"</string>
@@ -657,7 +688,7 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"クリップボード"</item>
     <item msgid="5742013440802239414">"キーコード"</item>
-    <item msgid="8802889973626281575">"キーボードを切り替え"</item>
+    <item msgid="1951959982985094069">"回転して確認、キーボードの切り替え"</item>
     <item msgid="8175437057325747277">"なし"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
@@ -782,4 +813,10 @@
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"タップして電池やデータの使用量を確認"</string>
     <string name="data_usage_disable_mobile" msgid="5116269981510015864">"モバイルデータを OFF にしますか?"</string>
     <string name="touch_filtered_warning" msgid="8671693809204767551">"アプリが許可リクエストを隠しているため、設定側でユーザーの応答を確認できません。"</string>
+    <string name="slice_permission_title" msgid="7465009437851044444">"「<xliff:g id="APP_2">%2$s</xliff:g>」のスライスの表示を「<xliff:g id="APP_0">%1$s</xliff:g>」に許可しますか?"</string>
+    <string name="slice_permission_text_1" msgid="3514586565609596523">"- 「<xliff:g id="APP">%1$s</xliff:g>」からの情報の読み取り"</string>
+    <string name="slice_permission_text_2" msgid="3146758297471143723">"- 「<xliff:g id="APP">%1$s</xliff:g>」内部での操作"</string>
+    <string name="slice_permission_checkbox" msgid="7986504458640562900">"すべてのアプリのスライスを表示することを「<xliff:g id="APP">%1$s</xliff:g>」に許可する"</string>
+    <string name="slice_permission_allow" msgid="2340244901366722709">"許可"</string>
+    <string name="slice_permission_deny" msgid="7683681514008048807">"拒否"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 3a7fc50..258f21f 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"კამერის გახსნა"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"ახალი ამოცანის განლაგების არჩევა"</string>
     <string name="cancel" msgid="6442560571259935130">"გაუქმება"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"თითის ანაბეჭდის ხატულა"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"აპლიკაციის ხატულა"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"დახმარების შეტყობინების არეალი"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"თავსებადი მასშტაბირების ღილაკი."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"შეცვალეთ პატარა ეკრანი უფრო დიდით."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth დაკავშირებულია."</string>
@@ -275,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"სადესერტო ყუთი"</string>
     <string name="start_dreams" msgid="5640361424498338327">"ეკრანმზოგი"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"ეთერნეტი"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"არ შემაწუხოთ"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"მხოლოდ პრიორიტეტული"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"მხოლოდ გაფრთხილებები"</string>
@@ -311,6 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi გამორთულია"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi ჩართულია"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Wi-Fi ქსელები მიუწვდომელია"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"მაღვიძარა"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"ტრანსლირება"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"გადაიცემა"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"უსახელო მოწყობილობა"</string>
@@ -327,9 +329,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"დაკავშირება..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"ტეტერინგი"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"წვდომის წერტილი"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"მიმდინარეობს ჩართვა..."</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="other">%d მოწყობილობა</item>
+      <item quantity="one">%d მოწყობილობა</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"შეტყობინებები"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"ფანარი"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"მობილური ინტერნეტი"</string>
@@ -339,10 +343,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"გამოყენებულია: <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"ლიმიტი: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> გაფრთხილება"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"სამსახურის პროფილი"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"შეტყობინებები და აპები გამორთულია"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"ღამის განათება"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"ჩაირთოს მზის ჩასვლისას"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"მზის ამოსვლამდე"</string>
@@ -360,8 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> გათიშულია უსაფრთხო რეჟიმში."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"ყველას გასუფთავება"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"ეკრანის გასაყოფად, ჩავლებით გადმოიტანეთ აქ"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ჰორიზონტალური გაყოფა"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"ვერტიკალური გაყოფა"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"ინდივიდუალური გაყობა"</string>
@@ -502,11 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"ახლავე გამორთვა"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"გავრცობა"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ჩაკეცვა"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"გამოტანის მოწყობილობის გადართვა"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"ეკრანი ჩამაგრებულია"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"ამით ის დარჩება ხედში ჩამაგრების მოხსნამდე. ჩამაგრების მოსახსნელად, ხანგრძლივად შეეხეთ „უკან და მიმოხილვა“-ს."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"ამით ის დარჩება ხედში ჩამაგრების მოხსნამდე. ჩამაგრების მოსახსნელად, ხანგრძლივად შეეხეთ „უკან მთავარ გვერდზე“-ს."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"ამით ის დარჩება ხედში ჩამაგრების მოხსნამდე. ჩამაგრების მოსახსნელად, ხანგრძლივად შეეხეთ „მიმოხილვა“-ს."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"ამით ის დარჩება ხედში ჩამაგრების მოხსნამდე. ჩამაგრების მოსახსნელად, ხანგრძლივად შეეხეთ „მთავარ გვერდს“."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"ამ ეკრანის ჩამაგრების მოსახსნელად, ხანგრძლივად შეეხეთ ღილაკებს „უკან“ და „მიმოხილვა“"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ამ ეკრანის ჩამაგრების მოსახსნელად, ხანგრძლივად შეეხეთ ღილაკებს „უკან“ და „მთავარი გვერდი“"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"გასაგებია"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"არა, გმადლობთ"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"ეკრანი ჩამაგრებულია"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"ეკრანის ჩამაგრება მოხსნილია"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"დაიმალოს <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"ის კვლავ გამოჩნდება, როდესაც პარამეტრებში ჩართავთ"</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"დამალვა"</string>
@@ -529,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. შეეხეთ დასადუმებლად. შეიძლება დადუმდეს მარტივი წვდომის სერვისებიც."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. შეეხეთ ვიბრაციაზე დასაყენებლად."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. შეეხეთ დასადუმებლად."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s-ის ხმის მართვის საშუალებები დამალულია. დასახურად, გადაფურცლეთ ზემოთ."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"ხმის მართვის საშუალებები დამალულია"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s-ის ხმის მართვის საშუალებები"</string>
     <string name="output_title" msgid="5355078100792942802">"მედია გამომავალი"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"სატელეფონო ზარის გამომავალი სიგნალი"</string>
     <string name="output_none_found" msgid="5544982839808921091">"მოწყობილობები ვერ მოიძებნა"</string>
@@ -586,8 +592,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"შეტყობინებების მართვის საშუალებების მეშვეობით, შეგიძლიათ განსაზღვროთ აპის შეტყობინებების მნიშვნელობის დონე 0-დან 5-მდე დიაპაზონში. \n\n"<b>"დონე 5"</b>" \n— შეტყობინებათა სიის თავში ჩვენება \n— სრულეკრანიანი რეჟიმის შეფერხების დაშვება \n— ეკრანზე ყოველთვის გამოჩენა \n\n"<b>"დონე 4"</b>" \n— სრულეკრანიანი რეჟიმის შეფერხების აღკვეთა \n— ეკრანზე ყოველთვის გამოჩენა \n\n"<b>"დონე 3"</b>" \n— სრულეკრანიანი რეჟიმის შეფერხების აღკვეთა \n— ეკრანზე გამოჩენის აღკვეთა \n\n"<b>"დონე 2"</b>" \n— სრულეკრანიანი რეჟიმის შეფერხების აღკვეთა \n— ეკრანზე გამოჩენის აღკვეთა \n— ხმისა და ვიბრაციის აღკვეთა \n\n"<b>"დონე 1"</b>" \n— სრულეკრანიანი რეჟიმის შეფერხების აღკვეთა \n— ეკრანზე გამოჩენის აღკვეთა \n— ხმისა და ვიბრაციის აღკვეთა \n— ჩაკეტილი ეკრანიდან და სტატუსის ზოლიდან დამალვა \n— შეტყობინებათა სიის ბოლოში ჩვენება \n\n"<b>"დონე 0"</b>" \n— აპის ყველა შეტყობინების დაბლოკვა"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"შეტყობინებები"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"ამ შეტყობინებებს აღარ დაინახავთ"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"როგორც წესი, თქვენ ასეთ შეტყობინებებს ხურავთ. \nგსურთ მათი ჩვენების გაგრძელება?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"გაგრძელდეს ამ შეტყობინებათა ჩვენება?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"შეტყობინებების შეწყვეტა"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"ჩვენების გაგრძელება"</string>
@@ -681,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"გაცვლის ბუფერი"</item>
     <item msgid="5742013440802239414">"კლავიშის კოდი"</item>
-    <item msgid="8802889973626281575">"კლავიატურის გადამრთველი"</item>
-    <item msgid="7095517796293767867">"შეტრიალების შეთავაზება"</item>
-    <item msgid="8494159969042135235">"არც ერთი"</item>
+    <item msgid="1951959982985094069">"შეტრიალების დადასტურება, კლავიატურის გადამრთველი"</item>
+    <item msgid="8175437057325747277">"არცერთი"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"ჩვეულებრივი"</item>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 15d109c..718a138 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"камераны ашу"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Жаңа тапсырма пішімін таңдау"</string>
     <string name="cancel" msgid="6442560571259935130">"Бас тарту"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Саусақ ізі белгішесі"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Қолданба белгішесі"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Анықтама хабары аумағы"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Үйлесімділік ұлғайту түймесі."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Үлкендеу экранда кішірейту."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth қосылған."</string>
@@ -275,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Десерт жағдайы"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Экранды сақтау режимі"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Этернет"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Мазаламау"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Маңыздылары ғана"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Тек дабылдар"</string>
@@ -311,6 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi өшірулі"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi қосулы"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Қолжетімді Wi-Fi желілері жоқ"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Дабыл"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Трансляция"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Трансляциялануда"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Атаусыз құрылғы"</string>
@@ -327,9 +329,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Қосылуда…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Тетеринг"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Хот-спот"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Қосылуда…"</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="other">%d құрылғы</item>
+      <item quantity="one">%d құрылғы</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Хабарландырулар"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Қалта шам"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Мобильдік деректер"</string>
@@ -358,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> қауіпсіз режимде өшіріледі."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Барлығын тазалау"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Бөлінген экранды пайдалану үшін осында сүйреңіз"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Қолданбаларға ауысу үшін жоғары сырғытыңыз"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Бөлінген көлденең"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Бөлінген тік"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Бөлінген теңшелетін"</string>
@@ -499,11 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Қазір өшіру"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Жаю"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Жию"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Шығыс құрылғыны ауыстыру"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Экран түйрелді"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Экран босатылғанға дейін көрсетіліп тұрады. Оны босату үшін \"Артқа\" және \"Шолу\" түймелерін басып тұрыңыз."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Экран босатылғанға дейін көрсетіліп тұрады. Оны босату үшін \"Артқа\" және \"Негізгі бет\" түймелерін түртіп, ұстап тұрыңыз"</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Экран босатылғанға дейін көрсетіліп тұрады. Оны босату үшін \"Кері\" түймесін басып тұрыңыз."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Экран босатылғанға дейін көрсетіліп тұрады. Оны босату үшін \"Негізгі бет\" түймесін түртіп, ұстап тұрыңыз."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Бұл экранды босату үшін \"Артқа\" және \"Шолу\" түймелерін түртіп, ұстап тұрыңыз"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Бұл экранды босату үшін \"Артқа\" және \"Негізгі бет\" түймелерін түртіп, ұстап тұрыңыз"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Түсіндім"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Жоқ, рақмет"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Экран бекітілді"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Экран босатылды"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> жасыру керек пе?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Ол сіз оны параметрлерде келесі қосқанда қайта пайда болады."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Жасыру"</string>
@@ -526,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Дыбысын өшіру үшін түртіңіз. Арнайы мүмкіндік қызметтерінің дыбысы өшуі мүмкін."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Діріл режимін орнату үшін түртіңіз."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Дыбысын өшіру үшін түртіңіз."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s дыбысты басқару элементтері көрсетулі. Сырғыту арқылы жабыңыз."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Дыбысты басқару элементтері жасырын"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Дыбысты басқару элементтері: %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Meдиа шығысы"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Телефон қоңырау шығысы"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Ешқандай құрылғы табылмады"</string>
@@ -583,8 +592,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Қуат хабарландыруының басқару элементтерімен қолданбаның хабарландырулары үшін 0-ден бастап 5-ке дейін маңыздылық деңгейін орнатуға болады. \n\n"<b>"5-деңгей"</b>" \n- Хабарландыру тізімінің ең басында көрсету \n- Толық экранға ашылуын рұқсат ету \n- Әрдайым қалқымалы хабарландыру түрінде көрсету \n\n"<b>"4-деңгей"</b>" \n- Толық экранға шығармау \n- Әрдайым қалқымалы хабарландыру түрінде көрсету \n\n"<b>"3-деңгей"</b>" \n- Толық экранға шығармау \n- Ешқашан қалқымалы хабарландыру түрінде көрсетпеу \n\n"<b>"2-деңгей"</b>" \n- Толық экранға шығармау \n- Ешқашан қалқымалы хабарландыру түрінде көрсетпеу \n- Ешқашан дыбыс және діріл шығармау \n\n"<b>"1-деңгей"</b>" \n- Толық экранға шығармау \n- Ешқашан қалқымалы хабарландыру түрінде көрсетпеу \n- Ешқашан дыбыс немесе діріл шығармау \n- Құлыпталған экраннан және күйін көрсету жолағынан жасыру \n- Хабарландыру тізімінің ең астында көрсету \n\n"<b>"0-деңгей"</b>" \n- Қолданбадағы барлық хабарландыруларға тыйым салу"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Хабарландырулар"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Хабарландырулар бұдан былай көрсетілмейді"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Әдетте хабарландыруларды көрмейсіз. \nОлар көрсетілсін бе?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Хабарландырулар көрсетілсін бе?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Хабарландыруларға тыйым салу"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Көрсету"</string>
@@ -678,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Буфер"</item>
     <item msgid="5742013440802239414">"Перне коды"</item>
-    <item msgid="8802889973626281575">"Пернетақта ауыстырғышы"</item>
-    <item msgid="7095517796293767867">"Бұру ұсынысы"</item>
-    <item msgid="8494159969042135235">"Ешқайсысы"</item>
+    <item msgid="1951959982985094069">"Айналдыруды растау, пернетақта ауыстырғыш"</item>
+    <item msgid="8175437057325747277">"Ешқандай"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Орташа"</item>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 77fc137..e2cffc4 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"បើក​ម៉ាស៊ីន​ថត"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"ជ្រើសប្លង់ភារកិច្ចថ្មី"</string>
     <string name="cancel" msgid="6442560571259935130">"បោះ​បង់​"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"រូបតំណាង​ស្នាម​ម្រាមដៃ"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"រូបតំណាង​កម្មវិធី"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"តំបន់សារ​ជំនួយ"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"ប៊ូតុង​ពង្រីក​ត្រូវ​គ្នា។"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"ពង្រីក/បង្រួម​​អេក្រង់​ពី​​ទៅធំ"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"បាន​តភ្ជាប់​ប៊្លូធូស។"</string>
@@ -275,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"ករណី Dessert"</string>
     <string name="start_dreams" msgid="5640361424498338327">"ធាតុរក្សាអេក្រង់"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"អ៊ីសឺរណិត"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"កុំរំខាន"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"អាទិភាពប៉ុណ្ណោះ"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"សំឡេងរោទ៍ប៉ុណ្ណោះ"</string>
@@ -311,6 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"វ៉ាយហ្វាយ​បានបិទ"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi បានបើក"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"គ្មានបណ្តាញ Wi-Fi ទេ"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"ម៉ោងរោទ៍"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"ភ្ជាប់"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"ការ​ចាត់​ថ្នាក់"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"ឧបករណ៍​​ដែល​មិន​មាន​ឈ្មោះ"</string>
@@ -327,9 +329,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"កំពុង​តភ្ជាប់..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"ការ​ភ្ជាប់"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"ហតស្ប៉ត"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"កំពុង​បើក..."</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="other">ឧបករណ៍ %d</item>
+      <item quantity="one">ឧបករណ៍ %d</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"ការ​ជូនដំណឹង"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"ពិល"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"ទិន្នន័យ​ទូរសព្ទចល័ត"</string>
@@ -358,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ត្រូវបានបិទដំណើរការក្នុងរបៀបសុវត្ថិភាព"</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"សម្អាតទាំងអស់"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"អូសនៅទីនេះដើម្បីប្រើអេក្រង់បំបែក"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"អូស​ឡើង​លើ​ដើម្បី​ប្តូរ​កម្មវិធី"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"បំបែកផ្តេក"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"បំបែកបញ្ឈរ"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"បំបែកផ្ទាល់ខ្លួន"</string>
@@ -499,11 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"បិទឥឡូវនេះ"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"ពង្រីក"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"បង្រួម"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"ប្ដូរ​ឧបករណ៍​បញ្ចេញ​សំឡេង"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"អេក្រង់​ត្រូវ​បាន​ភ្ជាប់"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"វា​នឹង​នៅតែ​បង្ហាញ រហូត​ទាល់​តែ​អ្នក​ដក​ការដៅ។ សូម​សង្កត់​ប៊ូតុង​ថយ​ក្រោយ និង​ប៊ូតុង​ទិដ្ឋភាពរួម​ឲ្យ​ជាប់ ដើម្បី​ដក​ការ​ដៅ។"</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"វា​នឹង​នៅតែ​បង្ហាញ រហូត​ទាល់​តែ​អ្នក​ដក​ការដៅ។ សូម​ចុចប៊ូតុង​ថយក្រោយ និងប៊ូតុង​ទំព័រដើម​ឱ្យ​ជាប់ ដើម្បី​ដក​ការ​ដៅ។"</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"វា​នឹង​នៅតែ​បង្ហាញ រហូត​ទាល់​តែ​អ្នក​ដក​ការ​ដៅ។ សូម​សង្កត់​ប៊ូតុង​ទិដ្ឋភាពរួម​​ឲ្យ​ជាប់ ដើម្បី​ដក​ការ​ដៅ។"</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"វា​នឹង​នៅតែ​បង្ហាញ រហូត​ទាល់​តែ​អ្នក​ដក​ការដៅ។ សូម​ចុច​ប៊ូតុង​ទំព័រដើម​ឱ្យ​ជាប់ ដើម្បី​ដក​ការ​ដៅ។"</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"ដើម្បី​ដក​ការ​ដៅ​អេក្រង់​នេះ សូម​ចុច​ប៊ូតុង​ថយ​ក្រោយ និង​ប៊ូតុង​ទិដ្ឋភាពរួម​ឱ្យ​ជាប់"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ដើម្បី​ដក​ការ​ដៅ​អេក្រង់​នេះ សូម​ចុច​ប៊ូតុង​ថយ​ក្រោយ និង​ប៊ូតុងទំព័រដើម​ឱ្យ​ជាប់"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"យល់​ហើយ"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"ទេ អរគុណ"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"បាន​ដៅ​អេក្រង់"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"បាន​ដកការ​ដៅ​អេក្រង់"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"លាក់ <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"វា​នឹង​បង្ហាញ​ពេល​ក្រោយ​ ពេល​ដែល​អ្នក​បើក​ក្នុង​ការ​កំណត់។"</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"លាក់"</string>
@@ -526,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s។ ប៉ះដើម្បីបិទសំឡេង។ សេវាកម្មលទ្ធភាពប្រើប្រាស់អាចនឹងត្រូវបានបិទសំឡេង។"</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s ។ ចុច​ដើម្បី​កំណត់​ឲ្យ​ញ័រ។"</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s ។ ចុច​ដើម្បី​បិទ​សំឡេង។"</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"អង្គគ្រប់គ្រងកម្រិតសំឡេង %s បានបង្ហាញ។ អូសឡើងលើដើម្បីបដិសេធ។"</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"អង្គគ្រប់គ្រងកម្រិតសំឡេងបានលាក់"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s របារ​បញ្ជា​កម្រិត​សំឡេង"</string>
     <string name="output_title" msgid="5355078100792942802">"លទ្ធផល​មេឌៀ"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"លទ្ធផល​នៃ​ការ​ហៅ​ទូរសព្ទ"</string>
     <string name="output_none_found" msgid="5544982839808921091">"រកមិន​ឃើញ​ឧបករណ៍​ទេ"</string>
@@ -583,8 +592,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"ជាមួយអង្គគ្រប់គ្រងការជូនដំណឹងថាមពល អ្នកអាចកំណត់កម្រិតសំខាន់ពី 0 ទៅ 5 សម្រាប់ការជូនដំណឹងរបស់កម្មវិធី។ \n\n"<b>"កម្រិត 5"</b>" \n- បង្ហាញនៅផ្នែកខាងលើបញ្ជីជូនដំណឹង \n- អនុញ្ញាតការរំខានលើអេក្រង់ពេញ \n- លោតឡើងជានិច្ច \n\n"<b>"កម្រិត 4"</b>" \n- រារាំងការរំខានលើអេក្រង់ពេញ \n- លោតឡើងជានិច្ច \n\n"<b>"កម្រិត 3"</b>" \n- រារាំងការរំខានលើអេក្រង់ពេញ \n- លោតឡើងជានិច្ច \n\n"<b>"កម្រិត 2"</b>" \n- រារាំងការរំខានលើអេក្រង់ពេញ \n- លោតឡើងជានិច្ច \n- មិនបន្លឺសំឡេង ឬញ័រ \n\n"<b>"កម្រិត 1"</b>" \n- រារាំងការរំខានលើអេក្រង់ពេញ \n- លោតឡើងជានិច្ច \n- មិនបន្លឺសំឡេង ឬញ័រ \n- លាក់ពីអេក្រង់ចាក់សោ និងរបារស្ថានភាព \n- បង្ហាញនៅផ្នែកខាងក្រោមបញ្ជីជូនដំណឹង \n\n"<b>"កម្រិត 0"</b>" \n- រារាំងការជូនដំណឹងទាំងអស់ពីកម្មវិធី"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"ការ​ជូនដំណឹង"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"អ្នក​នឹង​មិនឃើញ​ការជូនដំណឹង​ទាំងនេះ​ទៀតទេ"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"ជាធម្មតា​អ្នក​ច្រានចោល​ការ​ជូន​ដំណឹង​ទាំង​នេះ។ \nបន្ត​បង្ហាញ​ពួកវា​ទៀត​ដែរ​ទេ?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"បន្ត​បង្ហាញ​ការជូនដំណឹង​ទាំងនេះ?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"បញ្ឈប់​ការជូនដំណឹង"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"បន្ត​បង្ហាញ"</string>
@@ -675,13 +683,7 @@
     <string name="left_nav_bar_button_type" msgid="8555981238887546528">"ប្រភេទ​ប៊ូតុង​ខាង​ឆ្វេង​បន្ថែម"</string>
     <string name="right_nav_bar_button_type" msgid="2481056627065649656">"ប្រភេទ​ប៊ូតុង​ខាង​ស្តាំ​បន្ថែម"</string>
     <string name="nav_bar_default" msgid="8587114043070993007">"(លំនាំដើម)"</string>
-  <string-array name="nav_bar_buttons">
-    <item msgid="1545641631806817203">"អង្គចងចាំ"</item>
-    <item msgid="5742013440802239414">"លេខកូដ​គ្រាប់ចុច"</item>
-    <item msgid="8802889973626281575">"កម្មវិធី​ប្តូរក្តារ​ចុច"</item>
-    <item msgid="7095517796293767867">"ការណែនាំ​​ការបង្វិល"</item>
-    <item msgid="8494159969042135235">"គ្មាន"</item>
-  </string-array>
+    <!-- no translation found for nav_bar_buttons:2 (1951959982985094069) -->
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"ធម្មតា"</item>
     <item msgid="8256205964297588988">"តូច"</item>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 4b638f5..427c07d 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"ಕ್ಯಾಮರಾ ತೆರೆಯಿರಿ"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"ಹೊಸ ಕಾರ್ಯ ವಿನ್ಯಾಸವನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
     <string name="cancel" msgid="6442560571259935130">"ರದ್ದುಮಾಡಿ"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಐಕಾನ್"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"ಅಪ್ಲಿಕೇಶನ್‌ ಐಕಾನ್‌"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"ಸಹಾಯ ಸಂದೇಶ ಪ್ರದೇಶ"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"ಡೆಸರ್ಟ್ ಕೇಸ್"</string>
     <string name="start_dreams" msgid="5640361424498338327">"ಸ್ಕ್ರೀನ್ ಸೇವರ್"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"ಇಥರ್ನೆಟ್"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"ಆದ್ಯತೆ ಮಾತ್ರ"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"ಅಲಾರಮ್‌ಗಳು ಮಾತ್ರ"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"ವೈ-ಫೈ ಆಫ್"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"ವೈ-ಫೈ ಆನ್ ಆಗಿದೆ"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"ಯಾವುದೇ ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗಳು ಲಭ್ಯವಿಲ್ಲ"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"ಅಲಾರಮ್"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"ಬಿತ್ತರಿಸುವಿಕೆ"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"ಬಿತ್ತರಿಸಲಾಗುತ್ತಿದೆ"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"ಹೆಸರಿಸದಿರುವ ಸಾಧನ"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ಅನ್ನು ಸುರಕ್ಷಿತ ಮೋಡ್‌ನಲ್ಲಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"ಎಲ್ಲವನ್ನೂ ತೆರವುಗೊಳಿಸಿ"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"ವಿಭಜಿತ ಪರದೆಯನ್ನು ಬಳಸಲು ಇಲ್ಲಿ ಡ್ರ್ಯಾಗ್‌ ಮಾಡಿ"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಸ್ವೈಪ್ ಮಾಡಿ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ಅಡ್ಡಲಾಗಿ ವಿಭಜಿಸಿದ"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"ಲಂಬವಾಗಿ ವಿಭಜಿಸಿದ"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"ಕಸ್ಟಮ್ ವಿಭಜಿಸಿದ"</string>
@@ -500,25 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"ಈಗ ಆಫ್ ಮಾಡಿ"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"ವಿಸ್ತರಿಸು"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ಸಂಕುಚಿಸು"</string>
-    <!-- no translation found for accessibility_output_chooser (8185317493017988680) -->
-    <skip />
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"ಔಟ್‌ಪುಟ್ ಸಾಧನವನ್ನು ಬದಲಿಸಿ"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"ಪರದೆಯನ್ನು ಪಿನ್ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"ನೀವು ಅನ್‌ಪಿನ್ ಮಾಡುವವರೆಗೆ ಅದನ್ನು ವೀಕ್ಷಣೆಯಲ್ಲಿಡುತ್ತದೆ. ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ ಹಾಗೂ ಅನ್‌ಪಿನ್ ಮಾಡಲು ಅವಲೋಕಿಸಿ."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"ನೀವು ಅನ್‌ಪಿನ್ ಮಾಡುವವರೆಗೆ ಅದನ್ನು ವೀಕ್ಷಣೆಯಲ್ಲಿಡುತ್ತದೆ. ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ ಹಾಗೂ ಅನ್‌ಪಿನ್ ಮಾಡಲು ಮುಖಪುಟಕ್ಕೆ ಹಿಂತಿರುಗಿ."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"ನೀವು ಅನ್‌ಪಿನ್ ಮಾಡುವವರೆಗೆ ಅದನ್ನು ವೀಕ್ಷಣೆಯಲ್ಲಿಡುತ್ತದೆ. ಅನ್‌ಪಿನ್ ಮಾಡಲು ಅವಲೋಕನವನ್ನು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹೋಲ್ಡ್ ಮಾಡಿ."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"ನೀವು ಅನ್‌ಪಿನ್ ಮಾಡುವವರೆಗೆ ಅದನ್ನು ವೀಕ್ಷಣೆಯಲ್ಲಿಡುತ್ತದೆ. ಅನ್‌ಪಿನ್ ಮಾಡಲು ಮುಖಪುಟವನ್ನು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಒತ್ತಿಹಿಡಿಯಿರಿ."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"ಈ ಪರದೆಯನ್ನು ಅನ್‌ಪಿನ್ ಮಾಡಲು, ಹಿಂದಕ್ಕೆ ಮತ್ತು ಸಮಗ್ರ ನೋಟ ಬಟನ್‌ಗಳನ್ನು ಸ್ಪರ್ಶಿಸಿ ಒತ್ತಿಹಿಡಿಯಿರಿ"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ಈ ಪರದೆಯನ್ನು ಅನ್‌ಪಿನ್ ಮಾಡಲು, ಹಿಂದಕ್ಕೆ ಮತ್ತು ಮುಖಪುಟ ಬಟನ್‌ಗಳನ್ನು ಸ್ಪರ್ಶಿಸಿ ಒತ್ತಿಹಿಡಿಯಿರಿ"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"ತಿಳಿಯಿತು"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"ಧನ್ಯವಾದಗಳು"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"ಪರದೆಯನ್ನು ಪಿನ್‌ ಮಾಡಲಾಗಿದೆ"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"ಪರದೆಯನ್ನು ಅನ್‌ಪಿನ್‌ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> ಮರೆಮಾಡುವುದೇ?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"ನೀವು ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಅದನ್ನು ಆನ್ ಮಾಡಿದಾಗ ಅದು ಮರುಕಾಣಿಸಿಕೊಳ್ಳುತ್ತದೆ."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"ಮರೆಮಾಡಿ"</string>
@@ -541,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. ಮ್ಯೂಟ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ. ಪ್ರವೇಶಿಸುವಿಕೆ ಸೇವೆಗಳನ್ನು ಮ್ಯೂಟ್‌ ಮಾಡಬಹುದು."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. ವೈಬ್ರೇಟ್ ಮಾಡಲು ಹೊಂದಿಸುವುದಕ್ಕಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. ಮ್ಯೂಟ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s ವಾಲ್ಯೂಮ್ ನಿಯಂತ್ರಣಗಳನ್ನು ತೋರಿಸಲಾಗಿದೆ. ವಜಾಗೊಳಿಸಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"ವಾಲ್ಯೂಮ್ ನಿಯಂತ್ರಣಗಳನ್ನು ಮರೆಮಾಡಲಾಗಿದೆ"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s ವಾಲ್ಯೂಮ್ ನಿಯಂತ್ರಕಗಳು"</string>
     <string name="output_title" msgid="5355078100792942802">"ಮೀಡಿಯಾ ಔಟ್‌ಪುಟ್"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"ಫೋನ್ ಕರೆ ಔಟ್‌ಪುಟ್"</string>
     <string name="output_none_found" msgid="5544982839808921091">"ಯಾವ ಸಾಧನಗಳೂ ಕಂಡುಬಂದಿಲ್ಲ"</string>
@@ -692,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"ಕ್ಲಿಪ್‌ಬೋರ್ಡ್"</item>
     <item msgid="5742013440802239414">"ಕೀಕೋಡ್"</item>
-    <item msgid="8802889973626281575">"ಕೀಬೋರ್ಡ್ ಬದಲಾಯಿಸುವಿಕೆ"</item>
-    <item msgid="7095517796293767867">"ತಿರುಗಿಸುವಿಕೆ ಸಲಹೆ"</item>
-    <item msgid="8494159969042135235">"ಯಾವುದೂ ಅಲ್ಲ"</item>
+    <item msgid="1951959982985094069">"ತಿರುಗಿಸುವಿಕೆ ದೃಢೀಕರಿಸಿ, ಕೀಬೋರ್ಡ್ ಬದಲಾಯಿಸುವಿಕೆ"</item>
+    <item msgid="8175437057325747277">"ಯಾವುದೂ ಅಲ್ಲ"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"ಸಾಮಾನ್ಯ"</item>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index b42d0b5..65e64f3 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"카메라 열기"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"새 작업 레이아웃 선택"</string>
     <string name="cancel" msgid="6442560571259935130">"취소"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"지문 아이콘"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"애플리케이션 아이콘"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"도움말 메시지 영역"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"호환성 확대/축소 버튼입니다."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"작은 화면을 큰 화면으로 확대합니다."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"블루투스가 연결되었습니다."</string>
@@ -277,6 +276,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"디저트 케이스"</string>
     <string name="start_dreams" msgid="5640361424498338327">"화면 보호기"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"이더넷"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"알림 일시중지"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"중요 알림만"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"알람만"</string>
@@ -313,6 +314,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi 꺼짐"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi 사용"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"사용 가능한 Wi-Fi 네트워크 없음"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"알람"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"전송"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"전송 중"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"이름이 없는 기기"</string>
@@ -329,9 +331,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"연결 중..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"테더링"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"핫스팟"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"사용 설정 중..."</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="other">기기 %d대</item>
+      <item quantity="one">기기 %d대</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"알림"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"손전등"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"모바일 데이터"</string>
@@ -341,10 +345,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> 사용됨"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"한도: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> 경고"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"직장 프로필"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"알림 및 앱 사용 중지됨"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"야간 조명"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"일몰에"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"일출까지"</string>
@@ -362,8 +364,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g>은(는) 안전 모드에서 사용 중지됩니다."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"모두 지우기"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"여기를 드래그하여 분할 화면 사용하기"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"수평 분할"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"수직 분할"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"맞춤 분할"</string>
@@ -504,11 +504,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"지금 사용 중지"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"펼치기"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"접기"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"출력 기기 전환"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"화면 고정됨"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"고정 해제할 때까지 계속 표시됩니다. 고정 해제하려면 뒤로 및 최근 사용을 길게 터치하세요."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"고정 해제할 때까지 계속 표시됩니다. 고정 해제하려면 뒤로 및 홈을 길게 터치하세요."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"고정 해제할 때까지 계속 표시됩니다. 고정 해제하려면 최근 사용을 길게 터치하세요."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"고정 해제할 때까지 계속 표시됩니다. 고정 해제하려면 홈을 길게 터치하세요."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"이 화면을 고정 해제하려면 뒤로 및 최근 사용 버튼을 길게 터치하세요."</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"이 화면을 고정 해제하려면 뒤로 및 홈 버튼을 길게 터치하세요."</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"확인"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"거부"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"화면 고정됨"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"화면 고정 해제됨"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g>을(를) 숨기시겠습니까?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"다음번에 설정에서 사용 설정하면 다시 표시됩니다."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"숨기기"</string>
@@ -531,8 +538,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. 탭하여 음소거로 설정하세요. 접근성 서비스가 음소거될 수 있습니다."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. 탭하여 진동으로 설정하세요."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. 탭하여 음소거로 설정하세요."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s 볼륨 컨트롤이 표시됩니다. 닫으려면 위로 스와이프합니다."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"볼륨 컨트롤 숨김"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s 볼륨 컨트롤"</string>
     <string name="output_title" msgid="5355078100792942802">"미디어 출력"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"전화 통화 출력"</string>
     <string name="output_none_found" msgid="5544982839808921091">"기기를 찾을 수 없음"</string>
@@ -588,8 +594,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"전원 알림 컨트롤을 사용하면 앱 알림 관련 중요도를 0부터 5까지로 설정할 수 있습니다. \n\n"<b>"레벨 5"</b>" \n- 알림 목록 상단에 표시 \n- 전체 화면일 경우 알림 표시 허용 \n- 항상 엿보기 표시 \n\n"<b>"레벨 4"</b>" \n- 전체 화면에 알림 표시 금지 \n- 항상 엿보기 표시 \n\n"<b>"레벨 3"</b>" \n- 전체 화면에 알림 표시 금지 \n- 엿보기 표시 안함 \n\n"<b>"레벨 2"</b>" \n- 전체 화면에 알림 표시 금지 \n- 엿보기 표시 안함 \n- 소리나 진동으로 알리지 않음 \n\n"<b>"레벨 1"</b>" \n- 전체 화면에 알림 표시 금지 \n- 엿보기 표시 안함 \n- 소리나 진동으로 알리지 않음 \n- 잠금 화면 및 상태 표시줄에서 숨김 \n- 알림 목록 하단에 표시 \n\n"<b>"레벨 0"</b>" \n- 앱의 모든 알림 차단"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"알림"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"더 이상 다음의 알림을 받지 않습니다"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"보통 이 알림을 닫았습니다. \n알림을 계속 표시하시겠습니까?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"이 알림을 계속 표시하시겠습니까?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"알림 중지"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"계속 표시하기"</string>
@@ -683,9 +688,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"클립보드"</item>
     <item msgid="5742013440802239414">"키 코드"</item>
-    <item msgid="8802889973626281575">"키보드 전환 도구"</item>
-    <item msgid="7095517796293767867">"추천 항목 회전"</item>
-    <item msgid="8494159969042135235">"없음"</item>
+    <item msgid="1951959982985094069">"회전 확인, 키보드 전환 도구"</item>
+    <item msgid="8175437057325747277">"없음"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"보통"</item>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index a1e1415..6489116 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"камераны ачуу"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Жаңы тапшырманын планын тандаңыз"</string>
     <string name="cancel" msgid="6442560571259935130">"Жокко чыгаруу"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Манжа изинин сүрөтчөсү"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Колдонмонун сүрөтчөсү"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Жардам билдирүүсү"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Масштабды сыйыштыруу баскычы."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Кичинекейди чоң экранга масштабдоо."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth байланышта"</string>
@@ -275,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Десерт себети"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Көшөгө"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Тынчымды алба"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Шашылыш эскертмелер гана"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Ойготкучтар гана"</string>
@@ -311,6 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi өчүк"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi күйүк"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Бир дагы жеткиликтүү Wi-Fi тармагы жок"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Ойготкуч"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Тышкы экранга чыгаруу"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Тышкы экранга чыгарылууда"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Аты жок түзмөк"</string>
@@ -327,9 +329,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Туташууда…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Тетеринг"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Туташуу чекити"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Күйгүзүлүүдө…"</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="other">%d түзмөк</item>
+      <item quantity="one">%d түзмөк</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Эскертмелер"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Кол чырак"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Мобилдик Интернет"</string>
@@ -358,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> коопсуз режиминде өчүрүлдү."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Баарын тазалоо"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Экранды бөлүү үчүн бул жерге сүйрөңүз"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Колдонмолорду которуштуруу үчүн өйдө сүрүңүз"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Туурасынан бөлүү"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Тигинен бөлүү"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Ыңгайлаштырылган бөлүү"</string>
@@ -499,11 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Азыр өчүрүлсүн"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Жайып көрсөтүү"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Жыйнап коюу"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Аудио түзмөктү которуштуруу"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Экран кадалган"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Ал бошотулмайынча көрүнө берет. Бошотуу үчүн, \"Артка\" жана \"Карап чыгуу\" баскычтарын басып, кармап туруңуз."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Ал бошотулмайынча көрүнө берет. Бошотуу үчүн, \"Артка\" жана \"Башкы бет\" баскычтарын басып, кармап туруңуз."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Ал бошотулмайынча көрүнө берет. Бошотуу үчүн, \"Карап чыгуу\" баскычын басып, кармап туруңуз."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ал бошотулмайынча көрүнө берет. Бошотуу үчүн, \"Башкы бет\" баскычын басып, кармап туруңуз."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Бул экранды бошотуу үчүн \"Артка\" жана \"Сереп салуу\" баскычтарын басып, кармап туруңуз"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Бул экранды бошотуу үчүн \"Артка\" жана \"Башкы бет\" баскычтарын басып, кармап туруңуз"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Түшүндүм"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Жок, рахмат"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Экран кадалды"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Экран бошотулду"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> жашырылсынбы?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Бул кийинки жолу жөндөөлөрдөн күйгүзүлгөндө кайра көрүнөт."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Жашыруу"</string>
@@ -526,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Үнүн өчүрүү үчүн таптап коюңуз. Атайын мүмкүнчүлүктөр кызматынын үнүн өчүрүп койсо болот."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Дирилдөөгө коюу үчүн басыңыз."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Үнүн өчүрүү үчүн басыңыз."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s үндү башкаруу элементтери көрсөтүлгөн. Этибарга албоо үчүн өйдө серпип коюңуз."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Үндү башкаруу элементтери жашырылган"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s үндү башкаруу элементтери"</string>
     <string name="output_title" msgid="5355078100792942802">"Медиа түзмөк"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Телефон чалуу"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Түзмөктөр табылган жок"</string>
@@ -583,8 +592,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Бул функциянын жардамы менен ар бир колдонмо үчүн эскертменин маанилүүлүк деңгээлин 0дон 5ке чейин койсоңуз болот. \n\n"<b>"5-деңгээл"</b>" \n- Эскертмелер тизмесинин башында көрсөтүлсүн \n- Эскертмелер толук экранда көрсөтүлсүн \n- Калкып чыгуучу эскертмелерге уруксат берилсин \n\n"<b>"4-деңгээл"</b>" \n- Эскертмелер толук экранда көрсөтүлбөсүн \n- Калкып чыгуучу эскертмелерге уруксат берилсин \n\n"<b>"3-деңгээл"</b>" \n- Эскертмелер толук экранда көрсөтүлбөсүн \n- Калкып чыгуучу эскертмелерге тыюу салынсын \n\n"<b>"2-деңгээл"</b>" \n- Эскертмелер толук экранда көрсөтүлбөсүн \n- Калкып чыгуучу эскертмелерге тыюу салынсын \n- Эч качан добуш чыгып же дирилдебесин \n\n"<b>"1-деңгээл"</b>" \n- Эскертмелер толук экранда көрсөтүлбөсүн \n- Калкып чыгуучу эскертмелерге тыюу салынсын \n- Эч качан добуш чыгып же дирилдебесин \n- Кулпуланган экрандан жана абал тилкесинен жашырылсын \n- Эскертмелер тизмесинин аягында көрсөтүлсүн \n\n"<b>"0-деңгээл"</b>" \n- Колдонмодон алынган бардык эскертмелер бөгөттөлсүн"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Эскертмелер"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Мындан ары бул эскертмелер сизге көрсөтүлбөйт"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Адатта мындай эскертмелерди өткөрүп жибересиз. \nАлар көрсөтүлө берсинби?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Бул эскертмелер көрсөтүлө берсинби?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Эскертмелерди токтотуу"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Көрсөтүлө берсин"</string>
@@ -678,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Алмашуу буфери"</item>
     <item msgid="5742013440802239414">"Баскыч коду"</item>
-    <item msgid="8802889973626281575">"Баскычтоп которуштургуч"</item>
-    <item msgid="7095517796293767867">"Буруу сунушу"</item>
-    <item msgid="8494159969042135235">"Эч бири"</item>
+    <item msgid="1951959982985094069">"Бурууну ырастоо, баскычтопту которуштургуч"</item>
+    <item msgid="8175437057325747277">"Эч бири"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Кадимки"</item>
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index ca05240..e37ca1c 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -22,8 +22,10 @@
     <dimen name="docked_divider_handle_width">2dp</dimen>
     <dimen name="docked_divider_handle_height">16dp</dimen>
 
+    <dimen name="brightness_mirror_height">96dp</dimen>
+
     <dimen name="qs_tile_margin_top">2dp</dimen>
-    <dimen name="qs_brightness_padding_top">0dp</dimen>
+    <dimen name="qs_header_tooltip_height">24dp</dimen>
 
     <dimen name="battery_detail_graph_space_top">9dp</dimen>
     <dimen name="battery_detail_graph_space_bottom">9dp</dimen>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 1b56074..ce1d551 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"ເປີດ​ກ້ອງ"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"ເລືອກ​ແຜນ​ຜັງ​ໜ້າ​ວຽກ​ໃໝ່"</string>
     <string name="cancel" msgid="6442560571259935130">"ຍົກເລີກ"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ໄອຄອນລາຍນິ້ວມື"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"ໄອຄອນແອັບພລິເຄຊັນ"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"ຊ່ວຍພື້ນທີ່ຂໍ້ຄວາມ"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"ກ່ອງຂອງຫວານ"</string>
     <string name="start_dreams" msgid="5640361424498338327">"ພາບພັກໜ້າຈໍ"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"ຫ້າມ​ລົບ​ກວນ"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"ບຸ​ລິ​ມະ​ສິດເທົ່າ​ນັ້ນ"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"ໂມງ​ປຸກ​ເທົ່າ​ນັ້ນ"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi​-Fi ປິດ"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi ເປີດ"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"ບໍ່​ມີ​ເຄືອ​ຂ່າຍ Wi-Fi ຢູ່"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"ໂມງປຸກ"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"ການສົ່ງສັນຍານ"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"​ກຳ​ລັງ​ສົ່ງ​ສັນ​ຍານ"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"​ອຸ​ປະ​ກອນບໍ່​ມີ​ຊື່"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ຖືກປິດໃຊ້ໃນໂໝດຄວາມມປອດໄພ."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"ລຶບລ້າງທັງໝົດ"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"ລາກມາບ່ອນນີ້ເພື່ອໃຊ້ການແບ່ງໜ້າຈໍ"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"ປັດຂື້ນເພື່ອສະຫຼັບແອັບ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ການ​ແຍກ​ລວງ​ຂວາງ"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"ການ​ແຍກ​ລວງ​ຕັ້ງ"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"ການ​ແຍກ​ກຳ​ນົດ​ເອງ"</string>
@@ -500,25 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"ປິດດຽວນີ້"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"ຂະຫຍາຍ"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ຫຍໍ້ລົງ"</string>
-    <!-- no translation found for accessibility_output_chooser (8185317493017988680) -->
-    <skip />
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"ສະຫຼັບອຸປະກອນສົ່ງສຽງອອກ"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"ປັກ​ໝຸດໜ້າ​ຈໍ​ແລ້ວ"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"ນີ້ຈະສະແດງມັນໃນໜ້າຈໍຈົນກວ່າທ່ານຈະເຊົາປັກມຸດ. ໃຫ້ແຕະປຸ່ມກັບຄືນ ແລະ ປຸ່ມພາບຮວມຄ້າງໄວ້ເພື່ອຍົກເລີກການປັກມຸດ."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"ນີ້ຈະສະແດງມັນໃນໜ້າຈໍຈົນກວ່າທ່ານຈະເຊົາປັກໝຸດ. ໃຫ້ແຕະປຸ່ມກັບຄືນ ແລະ ປຸ່ມພາບຮວມຄ້າງໄວ້ເພື່ອຍົກເລີກການປັກໝຸດ."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"ນີ້ຈະສະແດງມັນໃນໜ້າຈໍຈົນກວ່າທ່ານຈະເຊົາປັກມຸດ. ໃຫ້ແຕະປຸ່ມພາບຮວມຄ້າງໄວ້ເພື່ອຍົກເລີກການປັກມຸດ."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"ນີ້ຈະສະແດງມັນໃນໜ້າຈໍຈົນກວ່າທ່ານຈະເຊົາປັກໝຸດ. ໃຫ້ແຕະປຸ່ມພາບຮວມຄ້າງໄວ້ເພື່ອຍົກເລີກການປັກໝຸດ."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"ເພື່ອຍົກເລີກການປັກໝຸດໜ້າຈໍນີ້, ໃຫ້ແຕະປຸ່ມກັບຄືນ ແລະ ປຸ່ມພາບຮວມຄ້າງໄວ້"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ເພື່ອຍົກເລີກການປັກໝຸດໜ້າຈໍນີ້, ໃຫ້ແຕະປຸ່ມກັບຄືນ ແລະ ປຸ່ມພາບຮວມຄ້າງໄວ້"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"ເຂົ້າໃຈແລ້ວ"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"ບໍ່, ຂອບໃຈ"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"ປັກໝຸດໜ້າຈໍແລ້ວ"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"ຍົກເລີກການປັກໝຸດໜ້າຈໍແລ້ວ"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"ເຊື່ອງ <xliff:g id="TILE_LABEL">%1$s</xliff:g> ຫຼື​ບໍ່?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"​ມັນ​ຈະ​ສະ​ແດງ​ຄືນ​ໃໝ່​ເມື່ອ​ທ່ານ​ເປີດ​ນຳ​ໃຊ້​ມັນ​ໃນ​ການ​ຕັ້ງ​ຄ່າ​ຄັ້ງ​ຕໍ່​ໄປ."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"ເຊື່ອງ"</string>
@@ -541,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. ແຕະເພື່ອປິດສຽງ. ບໍລິການຊ່ວຍເຂົ້າເຖິງອາດຖືກປິດສຽງໄວ້."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. ແຕະເພື່ອຕັ້ງເປັນສັ່ນເຕືອນ."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. ແຕະເພື່ອປິດສຽງ."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"ສະແດງສ່ວນຄວບຄຸມສຽງ %s ແລ້ວ. ປັດອອກຂ້າງເພື່ອປິດໄວ້."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"ເຊື່ອງສ່ວນຄວບຄຸມສຽງແລ້ວ"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"ການຄວບຄຸມສຽງ %s"</string>
     <string name="output_title" msgid="5355078100792942802">"ມີເດຍເອົ້າພຸດ"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"ເອົ້າພຸດສາຍໂທອອກ"</string>
     <string name="output_none_found" msgid="5544982839808921091">"ບໍ່ພົບອຸປະກອນ"</string>
@@ -692,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"ຄລິບບອດ"</item>
     <item msgid="5742013440802239414">"ລະຫັດກະແຈ"</item>
-    <item msgid="8802889973626281575">"ຕົວສະຫຼັບແປ້ນພິມ"</item>
-    <item msgid="7095517796293767867">"ການແນະນຳການໝຸນ"</item>
-    <item msgid="8494159969042135235">"ບໍ່ມີ"</item>
+    <item msgid="1951959982985094069">"ຢືນຢັນມຸນ, ຕົວສະຫຼັບແປ້ນພິມ"</item>
+    <item msgid="8175437057325747277">"ບໍ່ໃຊ້"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"ປົກກະຕິ"</item>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index cc0f8ab..a35ccba 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -105,12 +105,10 @@
     <string name="camera_label" msgid="7261107956054836961">"atidaryti fotoaparatą"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Pasirinkti naują užduoties išdėstymą"</string>
     <string name="cancel" msgid="6442560571259935130">"Atšaukti"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Palieskite kontrolinio kodo jutiklį"</string>
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Kontrolinio kodo piktograma"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Programos piktograma"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Pagalbos pranešimo sritis"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Suderinamumo priartinimo mygtukas."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Padidinti ekraną."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"„Bluetooth“ prijungtas."</string>
@@ -279,6 +277,7 @@
     <string name="dessert_case" msgid="1295161776223959221">"Desertų dėklas"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Ekrano užsklanda"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Eternetas"</string>
+    <string name="quick_settings_header_onboarding_text" msgid="7872508260264044734">"Paspauskite ir palaikykite piktogramas, kad būtų parodyta daugiau parinkčių"</string>
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Netrukdyti"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Tik prioritetiniai įvykiai"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Tik signalai"</string>
@@ -315,6 +314,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"„Wi-Fi“ išjungta"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"„Wi-Fi“ įjungtas"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Nėra jokių pasiekiamų „Wi-Fi“ tinklų"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Signalas"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Perdavimas"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Perduodama"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Įrenginys be pavadinimo"</string>
@@ -331,9 +331,13 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Prisijungiama..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Susiejimas"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Viešosios interneto prieigos taškas"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Įjungiama..."</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="one">%d įrenginys</item>
+      <item quantity="few">%d įrenginiai</item>
+      <item quantity="many">%d įrenginio</item>
+      <item quantity="other">%d įrenginių</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Pranešimai"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Žibintuvėlis"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobiliojo ryšio duomenys"</string>
@@ -343,10 +347,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Išnaudota: <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Limitas: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> įspėjimas"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Darbo profilis"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Pranešimai ir programos išjungti"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Nakties šviesa"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Per saulėlydį"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Iki saulėtekio"</string>
@@ -364,8 +366,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Programa „<xliff:g id="APP">%s</xliff:g>“ išjungta saugos režimu."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Išvalyti viską"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Vilkite čia, kad naudotumėte skaidytą ekraną"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Horizontalus skaidymas"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Vertikalus skaidymas"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Tinkintas skaidymas"</string>
@@ -506,11 +506,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Išjungti dabar"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Išskleisti"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Sutraukti"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Perjungti išvesties įrenginį"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Ekranas prisegtas"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Tai bus rodoma, kol atsegsite. Palieskite ir palaikykite „Atgal“ ir „Apžvalga“, kad atsegtumėte."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Tai bus rodoma, kol atsegsite. Palieskite ir palaikykite „Atgal“ ir „Pagrindinis ekranas“, kad atsegtumėte."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Tai bus rodoma, kol atsegsite. Palieskite ir palaikykite „Apžvalga“, kad atsegtumėte."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Tai bus rodoma, kol atsegsite. Palieskite ir palaikykite „Pagrindinis ekranas“, kad atsegtumėte."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Kad atsegtumėte šį ekraną, palieskite ir palaikykite mygtukus „Atgal“ ir „Apžvalga“"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Kad atsegtumėte šį ekraną, palieskite ir palaikykite mygtukus „Atgal“ ir „Pagrindinis ekranas“"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Supratau"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Ne, ačiū"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Ekranas prisegtas"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Ekranas atsegtas"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Slėpti „<xliff:g id="TILE_LABEL">%1$s</xliff:g>“?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Tai bus vėl parodyta, kai kitą kartą įjungsite tai nustatymuose."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Slėpti"</string>
@@ -533,8 +540,13 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Palieskite, kad nutildytumėte. Gali būti nutildytos pritaikymo neįgaliesiems paslaugos."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Palieskite, kad nustatytumėte vibravimą."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Palieskite, kad nutildytumėte."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Rodomi „%s“ garsumo valdikliai. Perbraukite į viršų, kad atsisakytumėte."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Garsumo valdikliai paslėpti"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Garsumo valdikliai: %s"</string>
+    <!-- no translation found for volume_dialog_ringer_guidance_vibrate (8902050240801159042) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_silent (2128975224280276122) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_ring (6144469689490528338) -->
+    <skip />
     <string name="output_title" msgid="5355078100792942802">"Medijos išvestis"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Telefono skambučių išvestis"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Įrenginių nerasta"</string>
@@ -590,8 +602,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Naudodami pranešimų valdiklius galite nustatyti programos pranešimų svarbos lygį nuo 0 iki 5. \n\n"<b>"5 lygis"</b>" \n– Rodyti pranešimų sąrašo viršuje \n– Leisti pertraukti, kai veikia viso ekrano režimas \n– Visada rodyti pranešimus \n\n"<b>"4 lygis"</b>" \n– Neleisti pertraukti viso ekrano režimo \n– Visada rodyti pranešimus \n\n"<b>"3 lygis"</b>" \n– Neleisti pertraukti viso ekrano režimo \n– Niekada nerodyti pranešimų \n\n"<b>"2 lygis"</b>" \n– Neleisti pertraukti viso ekrano režimo \n– Niekada nerodyti pranešimų \n– Niekada neleisti garso ir nevibruoti \n\n"<b>"1 lygis"</b>" \n– Neleisti pertraukti viso ekrano režimo \n– Niekada nerodyti pranešimų \n– Niekada neleisti garso ir nevibruoti \n– Slėpti užrakinimo ekrane ir būsenos juostoje \n– Rodyti pranešimų sąrašo apačioje \n\n"<b>"0 lygis"</b>" \n– Blokuoti visus programos pranešimus"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Pranešimai"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Nebematysite šių pranešimų"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Paprastai šių pranešimų atsisakote. \nToliau juos rodyti?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Toliau rodyti šiuos pranešimus?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Sustabdyti pranešimus"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Toliau rodyti"</string>
@@ -689,9 +700,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Iškarpinė"</item>
     <item msgid="5742013440802239414">"Klavišo kodas"</item>
-    <item msgid="8802889973626281575">"Klaviatūros perjungiklis"</item>
-    <item msgid="7095517796293767867">"Pasukimo pasiūlymas"</item>
-    <item msgid="8494159969042135235">"Nėra"</item>
+    <item msgid="1951959982985094069">"Pasukimo patvirtinimas, klaviatūros perjungiklis"</item>
+    <item msgid="8175437057325747277">"Nėra"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Įprastas"</item>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 1d0d57a..a4b7d2e 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -104,12 +104,11 @@
     <string name="camera_label" msgid="7261107956054836961">"atvērt kameru"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Atlasiet jaunu uzdevumu izkārtojumu"</string>
     <string name="cancel" msgid="6442560571259935130">"Atcelt"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Pirksta nospieduma ikona"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Lietojumprogrammas ikona"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Palīdzības ziņojuma apgabals"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Saderības tālummaiņas poga."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Veikt tālummaiņu no mazāka ekrāna uz lielāku."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth savienojums ir izveidots."</string>
@@ -277,6 +276,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Saldo ēdienu stends"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Ekrānsaudzētājs"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Tīkls Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Netraucēt"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Tikai prioritārie"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Tikai signāli"</string>
@@ -313,6 +314,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi ir izslēgts"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi savienojums ieslēgts"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Nav pieejams neviens Wi-Fi tīkls."</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Signāls"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Apraide"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Notiek apraide…"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Nenosaukta ierīce"</string>
@@ -329,9 +331,12 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Notiek savienojuma izveide…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Piesaiste"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Tīklājs"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Notiek ieslēgšana…"</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="zero">%d ierīču</item>
+      <item quantity="one">%d ierīce</item>
+      <item quantity="other">%d ierīces</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Paziņojumi"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Zibspuldze"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobilie dati"</string>
@@ -341,10 +346,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Tiek izmantots: <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Ierobežojums: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> brīdinājums"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Darba profils"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Paziņojumi un lietotnes ir izslēgtas"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Nakts režīms"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Saulrietā"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Līdz saullēktam"</string>
@@ -362,8 +365,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Lietotne <xliff:g id="APP">%s</xliff:g> ir atspējota drošajā režīmā."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Notīrīt visu"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Velciet šeit, lai izmantotu ekrāna sadalīšanu"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Horizontāls dalījums"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Vertikāls dalījums"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Pielāgots dalījums"</string>
@@ -504,11 +505,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Izslēgt tūlīt"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Izvērst"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Sakļaut"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Pārslēgt izvades ierīci"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Ekrāns ir piesprausts"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Šādi tas būs redzams līdz brīdim, kad to atspraudīsiet. Lai atspraustu, pieskarieties pogām Atpakaļ un Pārskats un turiet tās."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Šādi tas būs redzams līdz brīdim, kad to atspraudīsiet. Lai atspraustu, pieskarieties pogām “Atpakaļ” un “Sākums” un turiet tās."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Šādi tas būs redzams līdz brīdim, kad to atspraudīsiet. Lai atspraustu, pieskarieties pogai Pārskats un turiet to."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Šādi tas būs redzams līdz brīdim, kad to atspraudīsiet. Lai atspraustu, pieskarieties pogai “Sākums” un turiet to."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Lai atspraustu šo ekrānu, pieskarieties pogām “Atpakaļ” un “Pārskats” un turiet tās."</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Lai atspraustu šo ekrānu, pieskarieties pogām “Atpakaļ” un “Sākums” un turiet tās."</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Sapratu!"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nē, paldies"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Ekrāns ir piesprausts"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Ekrāns ir atsprausts"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Vai paslēpt vienumu <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Tas tiks atkārtoti parādīts, kad nākamreiz ieslēgsiet to iestatījumos."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Paslēpt"</string>
@@ -531,8 +539,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Pieskarieties, lai izslēgtu skaņu. Var tikt izslēgti pieejamības pakalpojumu signāli."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Pieskarieties, lai iestatītu vibrozvanu."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Pieskarieties, lai izslēgtu skaņu."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Tiek rādītas %s skaļuma vadīklas. Velciet augšup, lai nerādītu."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Skaļuma vadīklas paslēptas"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s skaļuma vadīklas"</string>
     <string name="output_title" msgid="5355078100792942802">"Multivides izvade"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Tālruņa zvana izvade"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Nav atrasta neviena ierīce"</string>
@@ -588,8 +595,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Izmantojot barošanas paziņojumu vadīklas, varat lietotnes paziņojumiem iestatīt svarīguma līmeni (no 0 līdz 5). \n\n"<b>"5. līmenis"</b>" \n- Tiek rādīts paziņojumu saraksta augšdaļā \n- Tiek atļauta pilnekrāna režīma pārtraukšana \n- Ieskats vienmēr atļauts \n\n"<b>"4. līmenis"</b>" \n- Tiek novērsta pilnekrāna režīma pārtraukšana \n- Ieskats vienmēr atļauts \n\n"<b>"3. līmenis"</b>" \n- Tiek novērsta pilnekrāna režīma pārtraukšana \n- Ieskats nav atļauts \n\n"<b>"2. līmenis"</b>" \n- Tiek novērsta pilnekrāna režīma pārtraukšana \n- Ieskats nav atļauts \n- Nav atļautas skaņas un vibrosignāls \n\n"<b>"1. līmenis"</b>" \n- Tiek novērsta pilnekrāna režīma pārtraukšana \n- Ieskats nav atļauts \n- Nav atļautas skaņas un vibrosignāls \n- Paziņojumi tiek paslēpti bloķēšanas ekrānā un statusa joslā \n- Paziņojumi tiek rādīti paziņojumu saraksta apakšdaļā \n\n"<b>"0. līmenis"</b>" \n- Visi lietotnes paziņojumi tiek bloķēti"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Paziņojumi"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Jūs vairs neredzēsiet šos paziņojumus."</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Parasti jūs noraidāt šādus paziņojumus. \nVai turpināt tos rādīt?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Vai turpināt rādīt šos paziņojumus?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Apturēt paziņojumu rādīšanu"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Turpināt rādīt"</string>
@@ -685,9 +691,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Starpliktuve"</item>
     <item msgid="5742013440802239414">"Taustiņu kods"</item>
-    <item msgid="8802889973626281575">"Tastatūras pārslēdzējs"</item>
-    <item msgid="7095517796293767867">"Rotācijas ieteikums"</item>
-    <item msgid="8494159969042135235">"Nav"</item>
+    <item msgid="1951959982985094069">"Apstiprināt pagriežot, tastatūras pārslēdzējs"</item>
+    <item msgid="8175437057325747277">"Neviens"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normāls"</item>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 07ea7aa..a7f6aae 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"отвори камера"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Изберете нов распоред на задача"</string>
     <string name="cancel" msgid="6442560571259935130">"Откажи"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Икона за отпечатоци"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Икона за апликацијата"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Поле за пораки за помош"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Dessert Case"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Заштитник на екран"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Етернет"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Не вознемирувај"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Само приоритетно"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Само аларми"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi е исклучено"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Вклучено е Wi-Fi"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Нема достапни Wi-Fi мрежи"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Аларм"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Емитувај"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Емитување"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Неименуван уред"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> е оневозможен во безбеден режим."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Исчисти ги сите"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Повлечете тука за да користите поделен екран"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Повлечете нагоре за да се префрлите од една на друга апликација"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Раздели хоризонтално"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Раздели вертикално"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Раздели прилагодено"</string>
@@ -503,21 +505,15 @@
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"Префрлете го излезниот уред"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Екранот е прикачен"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Ќе се гледа сѐ додека не го откачите. Допрете и држете „Назад“ и „Краток преглед“ за откачување."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Ќе се гледа сѐ додека не го откачите. Допрете и задржете „Назад“ и „Почетен екран“ за откачување."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Ќе се гледа сѐ додека не го откачите. Допрете и држете „Краток преглед“ за откачување."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ќе се гледа сѐ додека не го откачите. Допрете и задржете „Почетен екран“ за откачување."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"За откачување на екранов, допрете и задржете ги копчињата „Назад“ и „Краток преглед“"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"За откачување на екранов, допрете и задржете ги копчињата „Назад“ и „Почетен екран“"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Сфатив"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Не, фала"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Екранот е прикачен"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Екранот е откачен"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Сокриј <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Ќе се појави повторно следниот пат кога ќе го вклучите во поставки."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Сокриј"</string>
@@ -540,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Допрете за да исклучите звук. Можеби ќе се исклучи звукот на услугите за достапност."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Допрете за да се постави на вибрации."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Допрете за да се исклучи звукот."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Прикажани се контролите за јачина на звукот на %s. Повлечете нагоре за да отфрлите."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Скриени се контролите за јачина на звукот"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Контроли на јачината на звукот за %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Излез за аудиовизуелни содржини"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Излез за телефонски повик"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Не се најдени уреди"</string>
@@ -691,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Табла со исечоци"</item>
     <item msgid="5742013440802239414">"Код на копче"</item>
-    <item msgid="8802889973626281575">"Менувач на тастатура"</item>
-    <item msgid="7095517796293767867">"Предлог за ротација"</item>
-    <item msgid="8494159969042135235">"Нема"</item>
+    <item msgid="1951959982985094069">"Потврди ротирање, менувач на тастатура"</item>
+    <item msgid="8175437057325747277">"Ништо"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Нормални"</item>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index d4d6297..c59c774 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"ക്യാമറ തുറക്കുക"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"പുതിയ ടാസ്‌ക് ലേഔട്ട് തിരഞ്ഞെടുക്കുക"</string>
     <string name="cancel" msgid="6442560571259935130">"റദ്ദാക്കുക"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"വിരലടയാള ഐക്കൺ"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"ആപ്പ് ഐക്കൺ"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"സഹായ സന്ദേശ ഏരിയ"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"ഡെസേർട്ട് കെയ്സ്"</string>
     <string name="start_dreams" msgid="5640361424498338327">"സ്ക്രീൻ സേവർ"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"ഇതർനെറ്റ്"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"ശല്ല്യപ്പെടുത്തരുത്"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"മുൻഗണന മാത്രം"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"അലാറങ്ങൾ മാത്രം"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"വൈഫൈ ഓഫുചെയ്യുക"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"വൈഫൈ ഓണാണ്"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"വൈഫൈ നെറ്റ്‌വർക്കുകളൊന്നും ലഭ്യമല്ല"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"അലാറം"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"കാസ്‌റ്റുചെയ്യുക"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"കാസ്റ്റുചെയ്യുന്നു"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"പേരിടാത്ത ഉപകരണം"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"സുരക്ഷിത മോഡിൽ <xliff:g id="APP">%s</xliff:g> പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"എല്ലാം മായ്‌ക്കുക"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"സ്പ്ലിറ്റ് സ്ക്രീൻ ഉപയോഗിക്കുന്നതിന് ഇവിടെ വലിച്ചിടുക"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"ആപ്പുകൾ മാറാൻ മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യുക"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"തിരശ്ചീനമായി വേർതിരിക്കുക"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"ലംബമായി വേർതിരിക്കുക"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"ഇഷ്‌ടാനുസൃതമായി വേർതിരിക്കുക"</string>
@@ -500,25 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"ഇപ്പോൾ ഓഫ് ചെയ്യുക"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"വികസിപ്പിക്കുക"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ചുരുക്കുക"</string>
-    <!-- no translation found for accessibility_output_chooser (8185317493017988680) -->
-    <skip />
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"ഔട്ട്‌പുട്ട് ഉപകരണം മാറുക"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"സ്‌ക്രീൻ പിൻ ചെയ്‌തു"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"നിങ്ങൾ അൺപിൻ ചെയ്യുന്നതുവരെ ഇത് കാണുന്ന വിധത്തിൽ നിലനിർത്തും. അൺപിൻ ചെയ്യാൻ \'തിരികെ\', \'ചുരുക്കവിവരണം\' എന്നിവ സ്‌പർശിച്ച് പിടിക്കുക."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"നിങ്ങൾ അൺപിൻ ചെയ്യുന്നതുവരെ ഇത് കാണുന്ന വിധത്തിൽ നിലനിർത്തും. അൺപിൻ ചെയ്യാൻ \'തിരികെ പോവുക\', \'ഹോം\' ബട്ടണുകൾ സ്‌പർശിച്ച് പിടിക്കുക."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"നിങ്ങൾ അൺപിൻ ചെയ്യുന്നതുവരെ ഇത് കാണുന്ന വിധത്തിൽ നിലനിർത്തും. അൺപിൻ ചെയ്യാൻ \'ചുരുക്കവിവരണം\' സ്‌പർശിച്ച് പിടിക്കുക."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"നിങ്ങൾ അൺപിൻ ചെയ്യുന്നതുവരെ ഇത് കാണുന്ന വിധത്തിൽ നിലനിർത്തും. അൺപിൻ ചെയ്യാൻ \'ഹോം\' ബട്ടൺ സ്‌പർശിച്ച് പിടിക്കുക."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"ഈ സ്‌ക്രീൻ അൺപിൻ ചെയ്യാൻ, \'തിരികെ പോവുക\', \'അവലോകനം\' ബട്ടണുകൾ സ്‌പർശിച്ച് പിടിക്കുക"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ഈ സ്‌ക്രീൻ അൺപിൻ ചെയ്യാൻ, \'തിരികെ പോവുക\', \'ഹോം\' ബട്ടണുകൾ സ്‌പർശിച്ച് പിടിക്കുക"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"മനസ്സിലായി"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"വേണ്ട, നന്ദി"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"സ്‌ക്രീൻ പിൻ ചെയ്തു"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"സ്‌ക്രീൻ അൺപിൻ ചെയ്തു"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> എന്നത് മറയ്‌ക്കണോ?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"അടുത്ത തവണ നിങ്ങൾ അത് ക്രമീകരണങ്ങളിൽ ഓണാക്കുമ്പോൾ അത് വീണ്ടും ദൃശ്യമാകും."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"മറയ്‌ക്കുക"</string>
@@ -541,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. മ്യൂട്ടുചെയ്യുന്നതിന് ടാപ്പുചെയ്യുക. ഉപയോഗസഹായി സേവനങ്ങൾ മ്യൂട്ടുചെയ്യപ്പെട്ടേക്കാം."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s വൈബ്രേറ്റിലേക്ക് സജ്ജമാക്കുന്നതിന് ടാപ്പുചെയ്യുക."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s മ്യൂട്ടുചെയ്യുന്നതിന് ടാപ്പുചെയ്യുക."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s വോളിയം നിയന്ത്രണങ്ങൾ കാണിച്ചിരിക്കുന്നു. ഡിസ്മിസ് ചെയ്യുന്നതിന് മുകളിലേക്ക് സ്വൈപ്പുചെയ്യുക."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"വോളിയം നിയന്ത്രണങ്ങൾ മറച്ചിരിക്കുന്നു"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s ശബ്‌ദ നിയന്ത്രണങ്ങൾ"</string>
     <string name="output_title" msgid="5355078100792942802">"മീഡിയ ഔട്ട്പുട്ട്"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"ഫോൺ കോൾ ഔട്ട്പുട്ട്"</string>
     <string name="output_none_found" msgid="5544982839808921091">"ഉപകരണങ്ങളൊന്നും കണ്ടെത്തിയില്ല"</string>
@@ -692,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"ക്ലിപ്പ്ബോർഡ്"</item>
     <item msgid="5742013440802239414">"കീകോഡ്"</item>
-    <item msgid="8802889973626281575">"കീബോർഡ് സ്വിച്ചർ"</item>
-    <item msgid="7095517796293767867">"തിരിക്കൽ നിർദ്ദേശം"</item>
-    <item msgid="8494159969042135235">"ഒന്നുമില്ല"</item>
+    <item msgid="1951959982985094069">"റൊട്ടേറ്റ് ചെയ്യൽ സ്ഥിരീകരിക്കുക, കീബോഡ് മാറൽ"</item>
+    <item msgid="8175437057325747277">"ഒന്നുമില്ല"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"സാധാരണ വേഗത്തിൽ"</item>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index f1d0c18..af98542 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -101,12 +101,11 @@
     <string name="camera_label" msgid="7261107956054836961">"камер нээх"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Шинэ ажиллах талбарыг сонгоно уу"</string>
     <string name="cancel" msgid="6442560571259935130">"Цуцлах"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Хурууны хээний дүрс тэмдэг"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Аппын дүрс тэмдэг"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Туслах зурвасын хэсэг"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Тохиромжтой өсгөх товч."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Жижгээс том дэлгэцрүү өсгөх."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth холбогдсон."</string>
@@ -273,6 +272,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Амттаны хайрцаг"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Дэлгэц амраагч"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Этернет"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Бүү саад бол"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Зөвхөн чухал зүйлс"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Зөвхөн сэрүүлэг"</string>
@@ -309,6 +310,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi унтарсан"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi асаалттай"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Wi-Fi сүлжээ байхгүй байна"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Сэрүүлэг"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Дамжуулах"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Дамжуулж байна"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Нэргүй төхөөрөмж"</string>
@@ -325,9 +327,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Холбогдож байна..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Модем болгох"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Сүлжээний цэг"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Асааж байна…"</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="other">%d төхөөрөмж</item>
+      <item quantity="one">%d төхөөрөмж</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Мэдэгдэл"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Гар чийдэн"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Мобайл дата"</string>
@@ -337,10 +341,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> ашигласан"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> хязгаар"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> анхааруулга"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Ажлын профайл"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Мэдэгдэл болон апп унтраалттай байна"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Шөнийн гэрэл"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Нар жаргах үед"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Нар мандах хүртэл"</string>
@@ -358,8 +360,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g>-г аюулгүй горимд идэвхгүй болгосон."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Бүгдийг арилгах"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Хуваагдсан дэлгэцийг ашиглахын тулд энд чирэх"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Хэвтээ чиглэлд хуваах"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Босоо чиглэлд хуваах"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Хүссэн хэлбэрээр хуваах"</string>
@@ -500,11 +500,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Одоо унтраах"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Дэлгэх"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Хураах"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Гаралтын төхөөрөмжийг солих"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Дэлгэц эхэнд байрлуулагдсан"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Таныг тогтоосныг болиулах хүртэл үүнийг харуулна. Тогтоосныг болиулахын тулд Буцах, Тоймыг дараад хүлээнэ үү."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Таныг тогтоосныг болиулах хүртэл үүнийг харуулсан хэвээр байна. Тогтоосныг болиулахын тулд Буцах, Нүүр хуудас товчлуурыг дараад хүлээнэ үү."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Таныг тогтоосныг болиулах хүртэл харагдах болно. Тогтоосныг болиулахын тулд Буцах товчлуурыг дараад, хүлээнэ үү."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Таныг тогтоосныг болиулах хүртэл үүнийг харуулсан хэвээр байна. Тогтоосныг болиулахын тулд Нүүр хуудас товчлуурыг дараад хүлээнэ үү."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Энэ дэлгэцийг тогтоосныг болиулахын тулд Буцах, Тойм товчлуурыг дараад хүлээнэ үү"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Энэ дэлгэцийг тогтоосныг болиулахын тулд Буцах, Нүүр хуудас товчлуурыг дараад хүлээнэ үү"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Ойлголоо"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Үгүй"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Дэлгэцийг тогтоосон"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Дэлгэцийг тогтоосныг болиулсан"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g>-ийг нуух уу?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Тохируулгын хэсэгт үүнийг асаахад энэ дахин харагдана."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Нуух"</string>
@@ -527,10 +534,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Дууг нь хаахын тулд товшино уу. Хүртээмжийн үйлчилгээний дууг хаасан."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Чичиргээнд тохируулахын тулд товшино уу."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Дууг хаахын тулд товшино уу."</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for volume_dialog_accessibility_shown_message (1834631467074259998) -->
-    <skip />
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Түвшний удирдлагыг нуусан"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s түвшний хяналт"</string>
     <string name="output_title" msgid="5355078100792942802">"Медиа гаралт"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Утасны дуудлагын гаралт"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Төхөөрөмж олдсонгүй"</string>
@@ -586,8 +590,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Тэжээлийн мэдэгдлийн удирдлагын тусламжтайгаар та апп-н мэдэгдэлд 0-5 хүртэлх ач холбогдлын түвшин тогтоох боломжтой. \n\n"<b>"5-р түвшин"</b>" \n- Мэдэгдлийн жагсаалтын хамгийн дээр харуулна \n- Бүтэн дэлгэцэд саад болно \n- Дэлгэцэд тогтмол гарч ирнэ \n\n"<b>"4-р түвшин"</b>" \n- Бүтэн дэлгэцэд саад болохоос сэргийлнэ \n- Дэлгэцэд тогтмол гарч ирнэ \n\n"<b>"3-р түвшин"</b>" \n- Бүтэн дэлгэцэд саад болохоос сэргийлнэ \n- Дэлгэцэд хэзээ ч гарч ирэхгүй \n\n"<b>"2-р түвшин"</b>" \n- Бүтэн дэлгэцэд саад болохоос сэргийлнэ \n- Дэлгэцэд хэзээ ч гарч ирэхгүй \n- Дуу болон чичиргээ хэзээ ч гаргахгүй \n\n"<b>"1-р түвшин"</b>" \n- Бүтэн дэлгэцэд саад болохоос сэргийлнэ \n- Дэлгэцэд хэзээ ч гарч ирэхгүй \n- Дуу болон чичиргээ хэзээ ч гаргахгүй \n- Түгжигдсэн дэлгэц болон статусын самбараас нууна \n- Мэдэгдлийн жагсаалтын доор харуулна \n\n"<b>"0-р түвшин"</b>" \n- Энэ апп-н бүх мэдэгдлийг блоклоно"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Мэдэгдэл"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Та эдгээр мэдэгдлийг цаашид харахгүй"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Та эдгээр мэдэгдлийг ихэвчлэн хаадаг. \nЭдгээрийг харуулсан хэвээр байх уу?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Эдгээр мэдэгдлийг харуулсан хэвээр байх уу?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Мэдэгдлийг зогсоох"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Харуулсан хэвээр байх"</string>
@@ -681,9 +684,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Түр санах ой"</item>
     <item msgid="5742013440802239414">"Түлхүүр код"</item>
-    <item msgid="8802889973626281575">"Гар солигч"</item>
-    <item msgid="7095517796293767867">"Эргүүлэлтийн зөвлөмж"</item>
-    <item msgid="8494159969042135235">"Байхгүй"</item>
+    <item msgid="1951959982985094069">"Эргүүлэхийг баталгаажуулах, гар солигч"</item>
+    <item msgid="8175437057325747277">"Хоосон"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Энгийн"</item>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index c348110..bf2d7ae 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"कॅमेरा उघडा"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"नवीन कार्य लेआउट निवडा"</string>
     <string name="cancel" msgid="6442560571259935130">"रद्द करा"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"फिंगरप्रिंट आयकन"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"अॅप्लिकेशन आयकन"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"मदत संदेश क्षेत्र"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"मिष्ठान्न प्रकरण"</string>
     <string name="start_dreams" msgid="5640361424498338327">"स्क्रीन सेव्हर"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"इथरनेट"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"व्यत्यय आणू नका"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"केवळ प्राधान्य"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"केवळ अलार्म"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"वाय-फाय बंद"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"वाय-फाय चालू"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"वाय-फाय नेटवर्क उपलब्‍ध नाहीत"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"अलार्म"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"कास्‍ट करा"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"कास्ट करत आहे"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"निनावी डिव्हाइस"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> सुरक्षित-मोडमध्ये अक्षम केला आहे."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"सर्व साफ करा"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"विभाजित स्क्रीन वापर करण्यासाठी येथे ड्रॅग करा"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"अ‍ॅप्स स्विच करण्यासाठी वर स्वाइप करा"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"क्षैतिज विभाजित करा"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"अनुलंब विभाजित करा"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"सानुकूल विभाजित करा"</string>
@@ -500,25 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"आता बंद करा"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"विस्तृत करा"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"संकुचित करा"</string>
-    <!-- no translation found for accessibility_output_chooser (8185317493017988680) -->
-    <skip />
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"आउटपुट डिव्‍हाइस स्विच करा"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"स्क्रीन पिन केलेली आहे"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"आपण अनपिन करेर्यंत हे यास दृश्यामध्ये ठेवते. अनपिन करण्‍यासाठी परत आणि विहंगावलोकनास स्पर्श करा आणि धरून ठेवा."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"तुम्ही अनपिन करेर्यंत हे त्याला दृश्यामध्ये ठेवते. अनपिन करण्‍यासाठी मागे आणि होम वर स्पर्श करा आणि धरून ठेवा."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"आपण अनपिन करेर्यंत हे यास दृश्यामध्ये ठेवते. अनपिन करण्‍यासाठी विहंगावलोकनास स्पर्श करा आणि धरून ठेवा."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"तुम्ही अनपिन करेपर्यंत हे त्यास दृश्यामध्ये ठेवते. अनपिन करण्यासाठी होमला स्पर्श करा आणि धरून ठेवा."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"हा स्क्रीन अनपिन करण्यासाठी, मागे आणि अवलोकन बटणांना स्पर्श करून धरून ठेवा"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"हा स्क्रीन अनपिन करण्यासाठी, मागे आणि होम बटणांना स्पर्श करून धरून ठेवा"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"समजले"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"नाही, नको"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"स्क्रीन पिन केला"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"स्क्रीन अनपिन केला"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> लपवायचे?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"आपण सेटिंग्जमध्ये ते पुढील वेळी चालू कराल तेव्हा ते पुन्हा दिसेल."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"लपवा"</string>
@@ -541,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. नि:शब्द करण्यासाठी टॅप करा. प्रवेशक्षमता सेवा नि:शब्द केल्या जाऊ शकतात."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. कंपन सेट करण्यासाठी टॅप करा."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. नि:शब्द करण्यासाठी टॅप करा."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s आवाज नियंत्रणे दर्शविली. डिसमिस करण्यासाठी वर स्वाइप करा."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"आवाज नियंत्रणे लपविली"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s व्हॉल्यूम नियंत्रण"</string>
     <string name="output_title" msgid="5355078100792942802">"मीडिया आउटपुट"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"फोन कॉल आउटपुट"</string>
     <string name="output_none_found" msgid="5544982839808921091">"कोणतीही डिव्हाइस सापडली नाहीत"</string>
@@ -692,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"क्लिपबोर्ड"</item>
     <item msgid="5742013440802239414">"कीकोड"</item>
-    <item msgid="8802889973626281575">"कीबोर्ड स्विचर"</item>
-    <item msgid="7095517796293767867">"रोटेशन सूचना"</item>
-    <item msgid="8494159969042135235">"काहीही नाही"</item>
+    <item msgid="1951959982985094069">"फिरवणे निश्चित, कीबोर्ड स्विचर"</item>
+    <item msgid="8175437057325747277">"काहीही नाही"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"सामान्य"</item>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index d2674ae..97bde1d 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"buka kamera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Pilih reka letak tugas baharu"</string>
     <string name="cancel" msgid="6442560571259935130">"Batal"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikon cap jari"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ikon aplikasi"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Bahagian mesej bantuan"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Butang zum keserasian."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Skrin zum lebih kecil kepada lebih besar."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth disambungkan."</string>
@@ -275,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Bekas Pencuci Mulut"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Penyelamat skrin"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Jangan ganggu"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Keutamaan sahaja"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Penggera sahaja"</string>
@@ -311,6 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi Dimatikan"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi Dihidupkan"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Tiada rangkaian Wi-Fi tersedia"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Penggera"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Hantar"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Menghantar"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Peranti tidak bernama"</string>
@@ -327,9 +329,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Menyambung..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Penambatan"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Tempat liputan"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Menghidupkan…"</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="other">%d peranti</item>
+      <item quantity="one">%d peranti</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Pemberitahuan"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Lampu suluh"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Data mudah alih"</string>
@@ -339,10 +343,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> digunakan"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> had"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Amaran <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Profil kerja"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Pemberitahuan &amp; apl dimatikan"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Cahaya Malam"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Dihidupkan pd senja"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Hingga matahari terbit"</string>
@@ -360,8 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> dilumpuhkan dalam mod selamat."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Kosongkan semua"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Seret ke sini untuk menggunakan skrin pisah"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Mendatar Terpisah"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Menegak Terpisah"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Tersuai Terpisah"</string>
@@ -502,11 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Matikan sekarang"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Kembangkan"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Runtuhkan"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Tukar peranti output"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Skrin telah disemat"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Tindakan ini memastikan skrin kelihatan sehingga anda menyahsemat. Sentuh &amp; tahan Kembali dan Ikhtisar untuk menyahsemat."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Tindakan ini memastikan skrin kelihatan sehingga anda menyahsemat. Sentuh &amp; tahan Kembali dan Skrin Utama untuk menyahsemat."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Tindakan ini memastikan skrin kelihatan sehingga anda menyahsemat. Sentuh &amp; tahan Ikhtisar untuk menyahsemat."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Tindakan ini memastikan skrin kelihatan sehingga anda menyahsemat. Sentuh &amp; tahan Skrin Utama untuk menyahsemat."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Untuk menyahsemat skrin ini, sentuh &amp; tahan butang Kembali dan Ikhtisar"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Untuk menyahsemat skrin ini, sentuh &amp; tahan butang Kembali dan Skrin Utama"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Faham"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Tidak"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Skrin disemat"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Skrin dinyahsemat"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Sembunyikan <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Mesej itu akan terpapar semula pada kali seterusnya anda menghidupkan apl dalam tetapan."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Sembunyikan"</string>
@@ -529,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Ketik untuk meredam. Perkhidmatan kebolehaksesan mungkin diredamkan."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Ketik untuk menetapkan pada getar."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Ketik untuk meredam."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s kawalan kelantangan ditunjukkan. Leret ke atas untuk mengetepikan."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Kawalan kelantangan disembunyikan"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s kawalan kelantangan"</string>
     <string name="output_title" msgid="5355078100792942802">"Output media"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Output panggilan telefon"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Tiada peranti ditemui"</string>
@@ -586,8 +592,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Dengan kawalan pemberitahuan berkuasa, anda boleh menetapkan tahap kepentingan dari 0 hingga 5 untuk pemberitahuan apl. \n\n"<b>"Tahap 5"</b>" \n- Tunjukkan pada bahagian atas senarai pemberitahuan \n- Benarkan gangguan skrin penuh \n- Sentiasa intai \n\n"<b>"Tahap 4"</b>" \n- Halang gangguan skrin penuh \n- Sentiasa intai \n\n"<b>"Tahap 3"</b>" \n- Halang gangguan skrin penuh \n- Jangan intai \n\n"<b>"Tahap 2"</b>" \n- Halang gangguan skrin penuh \n- Jangan intai \n- Jangan berbunyi dan bergetar \n\n"<b>"Tahap 1"</b>" \n- Halang gangguan skrin penuh \n- Jangan intai \n- Jangan berbunyi atau bergetar \n- Sembunyikan daripada skrin kunci dan bar status \n- Tunjukkan di bahagian bawah senarai pemberitahuan \n\n"<b>"Tahap 0"</b>" \n- Sekat semua pemberitahuan daripada apl"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Pemberitahuan"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Anda tidak akan melihat pemberitahuan ini lagi"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Biasanya anda mengetepikan pemberitahuan ini. \nTerus tunjukkan pemberitahuan?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Terus tunjukkan pemberitahuan ini?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Hentikan pemberitahuan"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Terus tunjukkan"</string>
@@ -681,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Papan Keratan"</item>
     <item msgid="5742013440802239414">"Kod Kunci"</item>
-    <item msgid="8802889973626281575">"Penukar papan kekunci"</item>
-    <item msgid="7095517796293767867">"Cadangan putaran"</item>
-    <item msgid="8494159969042135235">"Tiada"</item>
+    <item msgid="1951959982985094069">"Pengesahan putaran, penukar papan kekunci"</item>
+    <item msgid="8175437057325747277">"Tiada"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Biasa"</item>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 41f28e2..0e4d375 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -103,6 +103,7 @@
     <string name="camera_label" msgid="7261107956054836961">"ကင်မရာ ဖွင့်ရန်"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"အလုပ်သစ်စီစဥ်မှုကို ရွေးပါ။"</string>
     <string name="cancel" msgid="6442560571259935130">"မလုပ်တော့"</string>
+    <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"လက်ဗွေအာရုံခံကိရိယာကို တို့ပါ"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"လက်ဗွေ သင်္ကေတ"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"အပလီကေးရှင်း သင်္ကေတ"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"အကူအညီမက်ဆေ့ဂျ် နေရာ"</string>
@@ -272,6 +273,7 @@
     <string name="dessert_case" msgid="1295161776223959221">"မုန့်ထည့်သော ပုံး"</string>
     <string name="start_dreams" msgid="5640361424498338327">"ဖန်သားပြင်အသုံးပြုမှု ချွေတာမှုစနစ်"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"အီသာနက်"</string>
+    <string name="quick_settings_header_onboarding_text" msgid="7872508260264044734">"နောက်ထပ် ရွေးချယ်စရာများအတွက် သင်္ကေတပုံများကို ဖိထားပါ"</string>
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"မနှောင့်ယှက်ရ"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"ဦးစားပေးများသာ"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"နှိုးစက်များသာ"</string>
@@ -308,8 +310,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"ဝိုင်ဖိုင်ပိတ်ရန်"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi ကိုဖွင့်ပါ"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Wi-Fi ကွန်ရက် မရှိပါ"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"နှိုးစက်"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"ကာစ်တင်"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"အမည်မတပ် ကိရိယာ"</string>
@@ -359,7 +360,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ကို ဘေးကင်းလုံခြုံသည့်မုဒ်တွင် ပိတ်ထားပါသည်။"</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"အားလုံး ဖယ်ရှားပါ"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"မျက်နှာပြင် ခွဲခြမ်းပြသခြင်းကို အသုံးပြုရန် ဤနေရာသို့ ပွတ်၍ဆွဲထည့်ပါ"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"အက်ပ်များကို ဖွင့်ရန် အပေါ်သို့ ပွတ်ဆွဲပါ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ရေပြင်ညီ ပိုင်းမည်"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"ဒေါင်လိုက်ပိုင်းမည်"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"စိတ်ကြိုက် ပိုင်းမည်"</string>
@@ -503,21 +503,15 @@
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"အထွက် စက်ပစ္စည်းကို ပြောင်းပါ"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"မျက်နှာပြင် ပင်ထိုးပြီးပါပြီ"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"သင်ပင်မဖြုတ်မခြင်း ၎င်းကို ပြသထားပါမည်။ ပင်ဖြုတ်ရန် Back နှင့် Overview ကို ထိ၍ဖိထားပါ။"</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"သင်က ပင်မဖြုတ်မခြင်း ၎င်းကို ပြသထားပါမည်။ ပင်ဖြုတ်ရန် \'နောက်သို့\' နှင့် \'ပင်မ\' ခလုတ်တို့ကို တို့၍ဖိထားပါ။"</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"သင်ပင်မဖြုတ်မချင်း ၎င်းကိုပြသထားပါမည်။ ပင်ဖြုတ်ရန် Overview ကိုထိပြီး ဖိထားပါ။"</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"သင်က ပင်မဖြုတ်မချင်း ၎င်းကိုပြသထားပါမည်။ ပင်ဖြုတ်ရန် \'ပင်မ\' ခလုတ်ကို တို့၍ဖိထားပါ။"</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"ဤမျက်နှာပြင်ကို ပင်ဖြုတ်ရန်အတွက် \'နောက်သို့\' နှင့် \'အနှစ်ချုပ်\' ခလုတ်တို့ကို တို့၍ဖိထားပါ"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ဤမျက်နှာပြင်ကို ပင်ဖြုတ်ရန်အတွက် \'နောက်သို့\' နှင့် \'ပင်မ\' ခလုတ်တို့ကို တို့၍ဖိထားပါ"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"ရပါပြီ"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"မလိုတော့ပါ"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"မျက်နှာပြင်ကို ပင်ထိုးထားသည်"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"မျက်နှာပြင်ကို ပင်ဖြုတ်လိုက်ပါပြီ"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> ဝှက်မည်လား?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"နောက်တစ်ကြိမ်သင် ချိန်ညှိချက်များဖွင့်လျှင် ၎င်းပေါ်လာပါမည်။"</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"ဖျောက်ထားမည်"</string>
@@ -540,8 +534,13 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s။ အသံပိတ်ရန် တို့ပါ။ အများသုံးစွဲနိုင်မှု ဝန်ဆောင်မှုများကို အသံပိတ်ထားနိုင်ပါသည်။"</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s။ တုန်ခါခြင်းသို့ သတ်မှတ်ရန်တို့ပါ။"</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s။ အသံတိတ်ရန် တို့ပါ။"</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"အသံအတိုးအလျှော့ခလုတ် %s ပြသထားပါသည်။ ပယ်ရန် အပေါ်သို့ပွတ်ဆွဲပါ။"</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"အသံအတိုးအလျှော့ခလုတ်များကို ဝှက်ထားပါသည်"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s အသံအတိုးအလျှော့ ခလုတ်များ"</string>
+    <!-- no translation found for volume_dialog_ringer_guidance_vibrate (8902050240801159042) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_silent (2128975224280276122) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_ring (6144469689490528338) -->
+    <skip />
     <string name="output_title" msgid="5355078100792942802">"မီဒီယာ အထွက်"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"ဖုန်းလိုင်း အထွက်"</string>
     <string name="output_none_found" msgid="5544982839808921091">"မည်သည့် စက်ပစ္စည်းမျှ မတွေ့ပါ"</string>
@@ -691,9 +690,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"ကလစ်ဘုတ်"</item>
     <item msgid="5742013440802239414">"ကီးကုဒ်"</item>
-    <item msgid="8802889973626281575">"ကီးဘုတ် ပြောင်းလဲပေးသည့်စနစ်"</item>
-    <item msgid="7095517796293767867">"လှည့်မှု အကြံပြုချက်"</item>
-    <item msgid="8494159969042135235">"တစ်ခုမျှမရှိ"</item>
+    <item msgid="1951959982985094069">"လှည့်ခြင်းကို အတည်ပြုရန်၊ ကီးဘုတ်ပြောင်း ကိရိယာ"</item>
+    <item msgid="8175437057325747277">"တစ်ခုမျှမရှိ"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"ပုံမှန်"</item>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 5bd4f2e..0d79faa 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"åpne kamera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Velg en ny utforming for oppgaver"</string>
     <string name="cancel" msgid="6442560571259935130">"Avbryt"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikon for fingeravtrykk"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Appikon"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Område for hjelpemelding"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Dessertmonter"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Skjermsparer"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"«Ikke forstyrr»"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Bare prioritet"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Bare alarmer"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi er av"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi er på"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Ingen tilgjengelige Wi-Fi-nettverk"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarm"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Casting"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Enhet uten navn"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> er slått av i sikker modus."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Tøm alt"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Dra hit for å bruke delt skjerm"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Sveip opp for å bytte apper"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Del horisontalt"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Del vertikalt"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Del tilpasset"</string>
@@ -500,25 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Slå av nå"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Utvid"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Skjul"</string>
-    <!-- no translation found for accessibility_output_chooser (8185317493017988680) -->
-    <skip />
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Bytt enhet for lydutgang"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Skjermen er låst"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"På denne måten blir skjermen synlig frem til du løsner den. Trykk og hold inne Tilbake og Oversikt for å løsne den."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"På denne måten blir skjermen synlig frem til du løsner den. Trykk og hold inne Tilbake og Startside for å løsne den."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"På denne måten blir skjermen synlig frem til du løsner den. Trykk og hold inne Oversikt for å løsne den."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"På denne måten blir skjermen synlig frem til du løsner den. Trykk og hold inne Startside for å løsne den."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"For å løsne denne skjermen, trykk på og hold inne Tilbake- og Oversikt-knappene"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"For å løsne denne skjermen, trykk på og hold inne Tilbake- og Startside-knappene"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Skjønner"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nei takk"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Skjermen er festet"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Skjermen er løsnet"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Vil du skjule <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Den vises igjen neste gang du slår den på i innstillingene."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Skjul"</string>
@@ -541,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Trykk for å slå av lyden. Lyden kan bli slått av for tilgjengelighetstjenestene."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Trykk for å angi vibrasjon."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Trykk for å slå av lyden."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Volumkontrollene for %s vises. Sveip opp for å avvise dem."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Volumkontrollene er skjult"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s volumkontroller"</string>
     <string name="output_title" msgid="5355078100792942802">"Medieutdata"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Utgang for telefonsamtaler"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Fant ingen enheter"</string>
@@ -692,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Utklippstavle"</item>
     <item msgid="5742013440802239414">"Tastkode"</item>
-    <item msgid="8802889973626281575">"Bytteknapp for tastatur"</item>
-    <item msgid="7095517796293767867">"Forslag til rotasjon"</item>
-    <item msgid="8494159969042135235">"Ingen"</item>
+    <item msgid="1951959982985094069">"Rotasjonsbekreftelse, bytteknapp for tastatur"</item>
+    <item msgid="8175437057325747277">"Ingen"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normal"</item>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index ca81f44..8365151 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"क्यामेरा खोल्नुहोस्"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"नयाँ कार्य लेआउट चयन गर्नुहोस्"</string>
     <string name="cancel" msgid="6442560571259935130">"रद्द गर्नुहोस्"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"फिंगरप्रिन्ट जनाउने आइकन"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"अनुप्रयोग जनाउने आइकन"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"मद्दतसम्बन्धी सन्देशको क्षेत्र"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Dessert Case"</string>
     <string name="start_dreams" msgid="5640361424498338327">"स्क्रिन सेभर"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"बाधा नपुर्याउँनुहोस्"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"प्राथमिकता मात्र"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"अलार्महरू मात्र"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi बन्द"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi सक्रिय छ"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Wi-Fi नेटवर्क अनुपलब्ध"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"अलार्म"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"प्रसारण गर्दै"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"बेनाम उपकरण"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> लाई सुरक्षित-मोडमा असक्षम गरिएको छ।"</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"सबै हटाउनुहोस्"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"विभाजित स्क्रिनको प्रयोग गर्नका लागि यहाँ तान्नुहोस्"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"अनुप्रयोगहरू बदल्न माथितिर स्वाइप गर्नुहोस्"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"तेर्सो रूपमा विभाजन गर्नुहोस्"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"ठाडो रूपमा विभाजन गर्नुहोस्"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"आफू अनुकूल विभाजन गर्नुहोस्"</string>
@@ -500,25 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"अहिले नै निष्क्रिय पार्नुहोस्"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"विस्तार गर्नुहोस्"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"संक्षिप्त पार्नुहोस्"</string>
-    <!-- no translation found for accessibility_output_chooser (8185317493017988680) -->
-    <skip />
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"आउटपुट यन्त्र बदल्नुहोस्"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"पर्दा राखेका छ"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"तपाईंले अनपिन नगरेसम्म यसले त्यसलाई दृश्यमा कायम राख्छ। अनपिन गर्न पछाडि र परिदृश्य बटनलाई छोइराख्नुहोस्।"</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"तपाईंले अनपिन नगरेसम्म यसले त्यसलाई दृश्यमा कायम राख्छ। अनपिन गर्न पछाडि र गृह नामक बटनहरूलाई छोइराख्नुहोस्।"</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"तपाईंले अनपिन नगरेसम्म यसले त्यसलाई दृश्यमा कायम राख्छ। अनपिन गर्न परिदृश्य बटनलाई छोइराख्नुहोस्।"</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"तपाईंले अनपिन नगरेसम्म यसले त्यसलाई दृश्यमा कायम राख्छ। अनपिन गर्न गृह नामक बटनलाई छोइराख्नुहोस्।"</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"यस स्क्रिनलाई अनपनि गर्न पछाडि र परिदृश्य नामक बटनहरूलाई छोइराख्नुहोस्"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"यस स्क्रिनलाई अनपनि गर्न पछाडि र गृह नामक बटनहरूलाई छोइराख्नुहोस्"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"बुझेँ"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"धन्यवाद पर्दैन"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"स्क्रिन पिन गरियो"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"स्क्रिन अनपिन गरियो"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"लुकाउनुहुन्छ <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"यो तपाईं सेटिङ् मा यो बारी अर्को समय देखापर्नेछ।"</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"लुकाउनुहोस्"</string>
@@ -541,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s। म्यूट गर्नका लागि ट्याप गर्नुहोस्। पहुँच सम्बन्धी सेवाहरू म्यूट हुन सक्छन्।"</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s। कम्पन मोडमा सेट गर्न ट्याप गर्नुहोस्।"</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s। म्यूट गर्न ट्याप गर्नुहोस्।"</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s का भोल्युम सम्बन्धी नियन्त्रणहरूलाई देखाइएको छ। खारेज गर्नका लागि स्वाइप गर्नुहोस्।"</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"भोल्युम सम्बन्धी नियन्त्रणहरूलाई लुकाइयो"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s भोल्युमका नियन्त्रणहरू"</string>
     <string name="output_title" msgid="5355078100792942802">"मिडियाको आउटपुट"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"फोन कलको आउटपुट"</string>
     <string name="output_none_found" msgid="5544982839808921091">"कुनै पनि यन्त्र भेटिएन"</string>
@@ -692,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"क्लिपबोर्ड"</item>
     <item msgid="5742013440802239414">"किकोड"</item>
-    <item msgid="8802889973626281575">"किबोर्ड स्विचर"</item>
-    <item msgid="7095517796293767867">"परिक्रमासम्बन्धी सुझाव"</item>
-    <item msgid="8494159969042135235">"कुनै पनि होइन"</item>
+    <item msgid="1951959982985094069">"घुमाउने कार्यको निश्चितता, किबोर्ड स्विचर"</item>
+    <item msgid="8175437057325747277">"कुनै पनि होइन"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"साधारण"</item>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 896d156..a2c1717 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"camera openen"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Nieuwe taakindeling selecteren"</string>
     <string name="cancel" msgid="6442560571259935130">"Annuleren"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Vingerafdrukpictogram"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"App-pictogram"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Gebied voor Help-berichten"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Knop voor compatibiliteitszoom."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Kleiner scherm uitzoomen naar groter scherm."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth-verbinding ingesteld."</string>
@@ -275,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Dessertshowcase"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Screensaver"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Niet storen"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Alleen prioriteit"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Alleen wekkers"</string>
@@ -311,6 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wifi uit"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wifi aan"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Geen wifi-netwerken beschikbaar"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Wekker"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Casten"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Casten"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Naamloos apparaat"</string>
@@ -327,9 +329,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Verbinding maken…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Inschakelen..."</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="other">%d apparaten</item>
+      <item quantity="one">%d apparaat</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Meldingen"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Zaklamp"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobiele data"</string>
@@ -339,10 +343,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> gebruikt"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Limiet van <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Waarschuwing voor <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Werkprofiel"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Meldingen en apps zijn uitgeschakeld"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Nachtverlichting"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Aan bij zonsondergang"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Tot zonsopgang"</string>
@@ -360,8 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is uitgeschakeld in de veilige modus"</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Alles wissen"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Sleep hier naartoe om het scherm te splitsen"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Horizontaal splitsen"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Verticaal splitsen"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Aangepast splitsen"</string>
@@ -502,11 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Nu uitschakelen"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Uitvouwen"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Samenvouwen"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Naar een ander uitvoerapparaat schakelen"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Scherm is vastgezet"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Het scherm blijft zichtbaar totdat je het losmaakt. Tik op Terug en Overzicht en houd deze vast om het scherm los te maken."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Het scherm blijft zichtbaar totdat je het losmaakt. Tik op Terug en Home en houd deze vast om het scherm los te maken."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Het scherm blijft zichtbaar totdat je het losmaakt. Tik op Overzicht en houd dit vast om het scherm los te maken."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Het scherm blijft zichtbaar totdat je het losmaakt. Tik op Home en houd dit vast om het scherm los te maken."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Tik op Terug en Overzicht en houd deze knoppen vast om dit scherm los te maken"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Tik op Terug en Home en houd deze knoppen vast om dit scherm los te maken"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Ik snap het"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nee, bedankt"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Scherm vastgezet"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Scherm losgemaakt"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> verbergen?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Deze wordt opnieuw weergegeven zodra u de instelling weer inschakelt."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Verbergen"</string>
@@ -529,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Tik om te dempen. Toegankelijkheidsservices kunnen zijn gedempt."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Tik om in te stellen op trillen."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Tik om te dempen."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Volumeknoppen van %s worden weergegeven. Veeg omhoog om te sluiten."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Volumeknoppen verborgen"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s-volumeknoppen"</string>
     <string name="output_title" msgid="5355078100792942802">"Media-uitvoer"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Uitvoer van telefoongesprek"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Geen apparaten gevonden"</string>
@@ -586,8 +592,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Met beheeropties voor meldingen met betrekking tot stroomverbruik kun je een belangrijkheidsniveau van 0 tot 5 instellen voor de meldingen van een app. \n\n"<b>"Niveau 5"</b>" \n- Boven aan de lijst met meldingen weergeven \n- Onderbreking op volledig scherm toestaan \n- Altijd korte weergave \n\n"<b>"Niveau 4"</b>" \n- Geen onderbreking op volledig scherm \n- Altijd korte weergave \n\n"<b>"Niveau 3"</b>" \n- Geen onderbreking op volledig scherm \n- Nooit korte weergave \n\n"<b>"Niveau 2"</b>" \n- Geen onderbreking op volledig scherm \n- Nooit korte weergave \n- Nooit geluid laten horen of trillen \n\n"<b>"Niveau 1"</b>" \n- Geen onderbreking op volledig scherm \n- Nooit korte weergave \n- Nooit geluid laten horen of trillen \n- Verbergen op vergrendelingsscherm en statusbalk \n- Onder aan de lijst met meldingen weergeven \n\n"<b>"Niveau 0"</b>" \n- Alle meldingen van de app blokkeren"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Meldingen"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Deze meldingen worden niet meer weergegeven"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Meestal sluit je deze meldingen. \nWil je ze blijven weergeven?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Deze meldingen blijven weergeven?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Meldingen stoppen"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Blijven weergeven"</string>
@@ -681,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Klembord"</item>
     <item msgid="5742013440802239414">"Toetscode"</item>
-    <item msgid="8802889973626281575">"Toetsenbordschakelaar"</item>
-    <item msgid="7095517796293767867">"Rotatiesuggestie"</item>
-    <item msgid="8494159969042135235">"Geen"</item>
+    <item msgid="1951959982985094069">"Draaien bevestigen, toetsenbordschakelaar"</item>
+    <item msgid="8175437057325747277">"Geen"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normaal"</item>
diff --git a/packages/SystemUI/res/values-or-land/strings.xml b/packages/SystemUI/res/values-or-land/strings.xml
new file mode 100644
index 0000000..484e924
--- /dev/null
+++ b/packages/SystemUI/res/values-or-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT 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="toast_rotation_locked" msgid="7609673011431556092">"ଲ୍ୟାଣ୍ଡସ୍କେପ୍ ଅବସ୍ଥାରେ ବର୍ତ୍ତମାନ ସ୍କ୍ରୀନ୍‌ଟି ଲକ୍ ଅଛି।"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-or/config.xml b/packages/SystemUI/res/values-or/config.xml
new file mode 100644
index 0000000..5309563
--- /dev/null
+++ b/packages/SystemUI/res/values-or/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 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.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
+</resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
new file mode 100644
index 0000000..c35c8a7
--- /dev/null
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -0,0 +1,1219 @@
+<?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">
+    <string name="app_label" msgid="7164937344850004466">"ସିଷ୍ଟମ୍ UI"</string>
+    <string name="status_bar_clear_all_button" msgid="7774721344716731603">"ଖାଲି କରନ୍ତୁ"</string>
+    <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"ତାଲିକାରୁ ବାହାର କରନ୍ତୁ"</string>
+    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"ଆପ୍‍ ସୂଚନା"</string>
+    <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"ଆପଣଙ୍କ ସମ୍ପ୍ରତି ସ୍କ୍ରୀନ୍‍‌ ଏଠାରେ ଦେଖାଯାଉଛି"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"କିଛି ସମୟ ପୂର୍ବରୁ ଇନଷ୍ଟଲ୍‌ ହୋଇଥିବା ଆପ୍‌ଗୁଡ଼ିକୁ ଖାରଜ କରନ୍ତୁ"</string>
+    <plurals name="status_bar_accessibility_recent_apps" formatted="false" msgid="9138535907802238759">
+      <item quantity="other">ଓଭର୍‌ଭ୍ୟୁରେ %d ସ୍କ୍ରୀନ୍‍</item>
+      <item quantity="one">ଓଭର୍‌ଭ୍ୟୁରେ 1 ସ୍କ୍ରୀନ୍‍</item>
+    </plurals>
+    <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"କୌଣସି ବିଜ୍ଞପ୍ତି ନାହିଁ"</string>
+    <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"ଚାଲୁଅଛି"</string>
+    <string name="status_bar_latest_events_title" msgid="6594767438577593172">"ବିଜ୍ଞପ୍ତି"</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"ବ୍ୟାଟେରୀ କମ୍‍ ଅଛି"</string>
+    <!-- no translation found for battery_low_title_hybrid (6268991275887381595) -->
+    <skip />
+    <string name="battery_low_percent_format" msgid="2900940511201380775">"<xliff:g id="PERCENTAGE">%s</xliff:g> ବାକି ଅଛି"</string>
+    <!-- no translation found for battery_low_percent_format_hybrid (6838677459286775617) -->
+    <skip />
+    <!-- no translation found for battery_low_percent_format_hybrid_short (9025795469949145586) -->
+    <skip />
+    <!-- no translation found for battery_low_percent_format_saver_started (7879389868952879166) -->
+    <skip />
+    <string name="invalid_charger" msgid="4549105996740522523">"USB ଚାର୍ଜିଙ୍ଗ ସପୋର୍ଟ କରୁନାହିଁ।\nକେବଳ ଦିଆଯାଇଥିବା ଚାର୍ଜର୍‌ ହିଁ ବ୍ୟବହାର କରନ୍ତୁ।"</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"USB ଚାର୍ଜିଙ୍ଗ ସପୋର୍ଟ କରୁନାହିଁ।"</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"କେବଳ ଦିଆଯାଇଥିବା ଚାର୍ଜର୍‌ ହିଁ ବ୍ୟବହାର କରନ୍ତୁ।"</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"ସେଟିଙ୍ଗ"</string>
+    <!-- no translation found for battery_saver_confirmation_title (2052100465684817154) -->
+    <skip />
+    <string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"ଅନ୍‌ କରନ୍ତୁ"</string>
+    <!-- no translation found for battery_saver_start_action (8187820911065797519) -->
+    <skip />
+    <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"ସେଟିଙ୍ଗ"</string>
+    <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"ୱାଇ-ଫାଇ"</string>
+    <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"ଅଟୋ-ରୋଟେଟ୍‌ ସ୍କ୍ରୀନ୍‍"</string>
+    <string name="status_bar_settings_mute_label" msgid="554682549917429396">"ମ୍ୟୁଟ୍"</string>
+    <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"ସ୍ୱତଃ"</string>
+    <string name="status_bar_settings_notifications" msgid="397146176280905137">"ବିଜ୍ଞପ୍ତି"</string>
+    <string name="bluetooth_tethered" msgid="7094101612161133267">"ବ୍ଲୁ-ଟୁଥ୍‍ ଟିଥରିଙ୍ଗ୍"</string>
+    <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ଇନପୁଟ୍‍ ପଦ୍ଧତି ସେଟ୍‍ କରନ୍ତୁ"</string>
+    <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"ଫିଜିକଲ୍ କୀ’ବୋର୍ଡ୍"</string>
+    <!-- no translation found for usb_device_permission_prompt (1825685909587559679) -->
+    <skip />
+    <!-- no translation found for usb_accessory_permission_prompt (2465531696941369047) -->
+    <skip />
+    <!-- no translation found for usb_device_confirm_prompt (7440562274256843905) -->
+    <skip />
+    <!-- no translation found for usb_accessory_confirm_prompt (4333670517539993561) -->
+    <skip />
+    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"ଇନଷ୍ଟଲ୍‍ ହୋଇଥିବା କୌଣସି ଆପ୍‍ ଏହି USB ଆକ୍ସେସୋରୀରେ କାମ କରେନାହିଁ। ଏହି ଆକ୍ସେସୋରୀ ବିଷୟରେ <xliff:g id="URL">%1$s</xliff:g>ରେ ଅଧିକ ଜାଣନ୍ତୁ"</string>
+    <string name="title_usb_accessory" msgid="4966265263465181372">"USB ଆକ୍ସେସରୀ"</string>
+    <string name="label_view" msgid="6304565553218192990">"ଦେଖନ୍ତୁ"</string>
+    <!-- no translation found for always_use_device (4015357883336738417) -->
+    <skip />
+    <!-- no translation found for always_use_accessory (3257892669444535154) -->
+    <skip />
+    <string name="usb_debugging_title" msgid="4513918393387141949">"USB ଡିବଗିଙ୍ଗ କରିବେ?"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"କମ୍ପ୍ୟୁଟର୍‌ର RSA କୀ\' ଆଙ୍ଗୁଠି ଚିହ୍ନ ହେଉଛି:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_always" msgid="303335496705863070">"ସବୁବେଳେ ଏହି କମ୍ପ୍ୟୁଟର୍‌ରୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
+    <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USBରେ ଡିବଗ୍‍ କରାଯାଇପାରିବ ନାହିଁ"</string>
+    <!-- no translation found for usb_debugging_secondary_user_message (6067122453571699801) -->
+    <skip />
+    <string name="compat_mode_on" msgid="6623839244840638213">"ସ୍କ୍ରୀନ ଭରିବା ପାଇଁ ଜୁମ୍ କରନ୍ତୁ"</string>
+    <string name="compat_mode_off" msgid="4434467572461327898">"ସ୍କ୍ରୀନ୍‌କୁ ଭରିବା ପାଇଁ ଟାଣନ୍ତୁ"</string>
+    <!-- no translation found for global_action_screenshot (8329831278085426283) -->
+    <skip />
+    <string name="screenshot_saving_ticker" msgid="7403652894056693515">"ସ୍କ୍ରୀନଶଟ୍‍ ସେଭ୍‍ କରାଯାଉଛି…"</string>
+    <string name="screenshot_saving_title" msgid="8242282144535555697">"ସ୍କ୍ରୀନଶଟ୍‍ ସେଭ୍‍ କରାଯାଉଛି…"</string>
+    <!-- no translation found for screenshot_saving_text (2545047868936087248) -->
+    <skip />
+    <!-- no translation found for screenshot_saved_title (5637073968117370753) -->
+    <skip />
+    <!-- no translation found for screenshot_saved_text (7574667448002050363) -->
+    <skip />
+    <!-- no translation found for screenshot_failed_title (9096484883063264803) -->
+    <skip />
+    <!-- no translation found for screenshot_failed_to_save_unknown_text (8844781948876286488) -->
+    <skip />
+    <!-- no translation found for screenshot_failed_to_save_text (3041612585107107310) -->
+    <skip />
+    <!-- no translation found for screenshot_failed_to_capture_text (173674476457581486) -->
+    <skip />
+    <string name="usb_preference_title" msgid="6551050377388882787">"USB ଫାଇଲ୍‌ ଟ୍ରାନ୍ସଫର୍‌ର ବିକଳ୍ପ"</string>
+    <string name="use_mtp_button_title" msgid="4333504413563023626">"ଏକ ମିଡିଆ ପ୍ଲେୟାର୍‍ (MTP) ଭାବରେ ଭର୍ତ୍ତି କରନ୍ତୁ"</string>
+    <string name="use_ptp_button_title" msgid="7517127540301625751">"ଏକ କ୍ୟାମେରା (PTP) ଭାବରେ ଭର୍ତ୍ତି କରନ୍ତୁ"</string>
+    <string name="installer_cd_button_title" msgid="2312667578562201583">"Mac ପାଇଁ Android ଫାଇଲ୍‍ ଟ୍ରାନ୍ସଫର୍‍ ଆପ୍‍ ଇନଷ୍ଟଲ୍‍ କରନ୍ତୁ"</string>
+    <string name="accessibility_back" msgid="567011538994429120">"ଫେରନ୍ତୁ"</string>
+    <string name="accessibility_home" msgid="8217216074895377641">"ହୋମ୍"</string>
+    <string name="accessibility_menu" msgid="316839303324695949">"ମେନୁ"</string>
+    <!-- no translation found for accessibility_accessibility_button (7601252764577607915) -->
+    <skip />
+    <!-- no translation found for accessibility_rotate_button (7402949513740253006) -->
+    <skip />
+    <string name="accessibility_recent" msgid="5208608566793607626">"ସଂକ୍ଷିପ୍ତ ବିବରଣୀ"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"କ୍ୟାମେରା"</string>
+    <string name="accessibility_phone_button" msgid="6738112589538563574">"ଫୋନ୍‍"</string>
+    <string name="accessibility_voice_assist_button" msgid="487611083884852965">"ଭଏସ୍‌ ସହାୟକ"</string>
+    <string name="accessibility_unlock_button" msgid="128158454631118828">"ଅନଲକ୍‌ କରନ୍ତୁ"</string>
+    <!-- no translation found for accessibility_waiting_for_fingerprint (4808860050517462885) -->
+    <skip />
+    <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
+    <skip />
+    <string name="unlock_label" msgid="8779712358041029439">"ଅନଲକ୍‌"</string>
+    <string name="phone_label" msgid="2320074140205331708">"ଫୋନ୍‌ ଖୋଲନ୍ତୁ"</string>
+    <string name="voice_assist_label" msgid="3956854378310019854">"ଭଏସ୍‍ ସହାୟକ ଖୋଲନ୍ତୁ"</string>
+    <string name="camera_label" msgid="7261107956054836961">"କ୍ୟାମେରା ଖୋଲନ୍ତୁ"</string>
+    <string name="recents_caption_resize" msgid="3517056471774958200">"ନୂଆ ଟାସ୍କ ଲେଆଉଟ୍‍ ଚୟନ କରନ୍ତୁ"</string>
+    <string name="cancel" msgid="6442560571259935130">"କ୍ୟାନ୍ସଲ୍‍ କରନ୍ତୁ"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
+    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <skip />
+    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
+    <skip />
+    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
+    <skip />
+    <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"କମ୍ପାଟିବିଲିଟୀ ଜୁମ୍ ବଟନ୍।"</string>
+    <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"ଜୁମ୍ କରି ସ୍କ୍ରୀନ୍‌କୁ ଛୋଟରୁ ବଡ଼ କରନ୍ତୁ।"</string>
+    <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"ବ୍ଲୁ-ଟୁଥ୍‌ ସଂଯୋଗ କରାଯାଇଛି।"</string>
+    <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"ବ୍ଲୁ-ଟୁଥ୍‌ ସଂଯୋଗ କରାଯାଇନାହିଁ।"</string>
+    <string name="accessibility_no_battery" msgid="358343022352820946">"ବ୍ୟାଟେରୀ ନାହିଁ।"</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"ବ୍ୟାଟେରୀର ଗୋଟିଏ ବାର୍ ଅଛି।"</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"ବ୍ୟାଟେରୀର ଦୁଇଟି ବାର୍‍ ଅଛି।"</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"ବ୍ୟାଟେରୀର ତିନୋଟି ବାର୍‍ ଅଛି।"</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"ବ୍ୟାଟେରୀ ପୂର୍ଣ୍ଣ‍।"</string>
+    <string name="accessibility_no_phone" msgid="4894708937052611281">"କୌଣସି ଫୋନ୍ ନାହିଁ।"</string>
+    <string name="accessibility_phone_one_bar" msgid="687699278132664115">"ଫୋନର ଗୋଟିଏ ବାର ଅଛି।"</string>
+    <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"ଫୋନର ଦୁଇଟି ବାର୍‌ ଅଛି।"</string>
+    <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"ଫୋନ୍‍ରେ ତିନୋଟି ବାର୍‍ ଅଛି।"</string>
+    <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"ଫୋନ୍ ସିଗ୍ନାଲ୍ ପୂର୍ଣ୍ଣ ଅଛି।"</string>
+    <string name="accessibility_no_data" msgid="4791966295096867555">"କୌଣସି ଡାଟା ନାହିଁ।"</string>
+    <string name="accessibility_data_one_bar" msgid="1415625833238273628">"ଡାଟାର ଗୋଟିଏ ବାର ଅଛି।"</string>
+    <string name="accessibility_data_two_bars" msgid="6166018492360432091">"ଡାଟାର ଦୁଇଟି ବାର୍‌ ଅଛି।"</string>
+    <string name="accessibility_data_three_bars" msgid="9167670452395038520">"ଡାଟାର ତିନୋଟି ବାର୍‍ ଅଛି।"</string>
+    <string name="accessibility_data_signal_full" msgid="2708384608124519369">"ଡାଟା ସିଗ୍ନାଲ୍ ପୂର୍ଣ୍ଣ ଅଛି।"</string>
+    <string name="accessibility_wifi_name" msgid="7202151365171148501">"<xliff:g id="WIFI">%s</xliff:g> ସହିତ ସଂଯୁକ୍ତ।"</string>
+    <string name="accessibility_bluetooth_name" msgid="8441517146585531676">"<xliff:g id="BLUETOOTH">%s</xliff:g> ସହ ସଂଯୁକ୍ତ"</string>
+    <!-- no translation found for accessibility_cast_name (4026393061247081201) -->
+    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"WiMAX ନାହିଁ।"</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAXର ଗୋଟିଏ ବାର୍‌ ଅଛି।"</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAXର ଦୁଇଟି ବାର୍‌ ଅଛି।"</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAXର ତିନୋଟି ବାର୍‌ ଅଛି।"</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAXର ସିଗ୍ନାଲ୍ ସମ୍ପୂର୍ଣ୍ଣ ଅଛି।"</string>
+    <string name="accessibility_ethernet_disconnected" msgid="5896059303377589469">"ଇଥରନେଟ୍‍ ବିଚ୍ଛିନ୍ନ ହୋଇଛି।"</string>
+    <string name="accessibility_ethernet_connected" msgid="2692130313069182636">"ଇଥରନେଟ୍‍ ସଂଯୁକ୍ତ ହୋଇଛି।"</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"କୌଣସି ସିଗ୍ନାଲ୍‍ ନାହିଁ।"</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"ସଂଯୁକ୍ତ ହୋଇନାହିଁ।"</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"କୌଣସି ବାର୍‍ ନାହିଁ।"</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"ଗୋଟିଏ ବାର୍‍ ଅଛି।"</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"ଦୁଇଟି ବାର୍‍ ଅଛି।"</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"ତିନୋଟି ବାର୍‍ ଅଛି।"</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"ସିଗ୍ନାଲ୍ ଫୁଲ୍ ଅଛି।"</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"ଅନ୍।"</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"ଅଫ୍।"</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"ସଂଯୁକ୍ତ।"</string>
+    <string name="accessibility_desc_connecting" msgid="3812924520316280149">"ସଂଯୋଗ କରୁଛି।"</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <!-- no translation found for accessibility_data_connection_4g_plus (3032226872470658661) -->
+    <skip />
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <!-- no translation found for accessibility_data_connection_lte_plus (361876866906946007) -->
+    <skip />
+    <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+    <string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"ରୋମିଙ୍ଗ"</string>
+    <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"ଏଜ୍‌"</string>
+    <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"ୱାଇ-ଫାଇ"</string>
+    <string name="accessibility_no_sim" msgid="8274017118472455155">"କୌଣସି SIM ନାହିଁ।"</string>
+    <!-- no translation found for accessibility_cell_data (5326139158682385073) -->
+    <skip />
+    <!-- no translation found for accessibility_cell_data_on (5927098403452994422) -->
+    <skip />
+    <!-- no translation found for accessibility_cell_data_off (443267573897409704) -->
+    <skip />
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ବ୍ଲୁ-ଟୁଥ୍‍ ଟିଥରିଙ୍ଗ"</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"ଏରୋପ୍ଲେନ୍‍ ମୋଡ୍‌।"</string>
+    <!-- no translation found for accessibility_vpn_on (5993385083262856059) -->
+    <skip />
+    <!-- no translation found for accessibility_no_sims (3957997018324995781) -->
+    <skip />
+    <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"କେରିଅର୍‍ ନେଟ୍‌ୱର୍କ ବଦଳାଯାଉଛି।"</string>
+    <!-- no translation found for accessibility_battery_details (7645516654955025422) -->
+    <skip />
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"ବ୍ୟାଟେରୀ <xliff:g id="NUMBER">%d</xliff:g> ଶତକଡ଼ା ଅଛି।"</string>
+    <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
+    <skip />
+    <string name="accessibility_settings_button" msgid="799583911231893380">"ସିଷ୍ଟମ୍‍ ସେଟିଙ୍ଗ।"</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"ବିଜ୍ଞପ୍ତି"</string>
+    <!-- no translation found for accessibility_overflow_action (5681882033274783311) -->
+    <skip />
+    <string name="accessibility_remove_notification" msgid="3603099514902182350">"ବିଜ୍ଞପ୍ତି ଖାଲି କରନ୍ତୁ।"</string>
+    <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS ସକ୍ଷମ।"</string>
+    <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS ପ୍ରାପ୍ତ କରୁଛି।"</string>
+    <string name="accessibility_tty_enabled" msgid="4613200365379426561">"ଟେଲି-ଟାଇପରାଇଟର୍ ସକ୍ଷମ ଅଛି।"</string>
+    <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"ରିଙ୍ଗର୍‌ କମ୍ପନରେ ଅଛି।"</string>
+    <string name="accessibility_ringer_silent" msgid="9061243307939135383">"ରିଙ୍ଗର୍‌ ସାଇଲେଣ୍ଟରେ ଅଛି।"</string>
+    <!-- no translation found for accessibility_casting (6887382141726543668) -->
+    <skip />
+    <!-- no translation found for accessibility_work_mode (702887484664647430) -->
+    <skip />
+    <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> ଖାରଜ।"</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ଖାରଜ କରିଦିଆଗଲା।"</string>
+    <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"ସମସ୍ତ ସମ୍ପ୍ରତି ଆପ୍ଲିକେଶନଗୁଡ଼ିକ ଖାରଜ କରାଯାଇଛି।"</string>
+    <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) -->
+    <skip />
+    <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> ଆରମ୍ଭ ହେଉଛି।"</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"ବିଜ୍ଞପ୍ତି ଖାରଜ କରାଗଲା।"</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"ବିଜ୍ଞପ୍ତି ଶେଡ୍‍।"</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"ଦ୍ରୁତ ସେଟିଙ୍ଗ।"</string>
+    <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"ଲକ୍‌ ସ୍କ୍ରୀନ୍‌।"</string>
+    <string name="accessibility_desc_settings" msgid="3417884241751434521">"ସେଟିଙ୍ଗ"</string>
+    <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"ସଂକ୍ଷିପ୍ତ ବିବରଣୀ"</string>
+    <!-- no translation found for accessibility_desc_work_lock (4288774420752813383) -->
+    <skip />
+    <string name="accessibility_desc_close" msgid="7479755364962766729">"ବନ୍ଦ କରନ୍ତୁ"</string>
+    <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>।"</string>
+    <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"ୱାଇ-ଫାଇ ବନ୍ଦ ଅଛି।"</string>
+    <string name="accessibility_quick_settings_wifi_changed_on" msgid="6440117170789528622">"ୱାଇ-ଫାଇ ଅନ୍ ଅଛି।"</string>
+    <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"ମୋବାଇଲ୍‍ <xliff:g id="SIGNAL">%1$s</xliff:g>। <xliff:g id="TYPE">%2$s</xliff:g>। <xliff:g id="NETWORK">%3$s</xliff:g>।"</string>
+    <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"<xliff:g id="STATE">%s</xliff:g> ବ୍ୟାଟେରୀ ଅଛି।"</string>
+    <string name="accessibility_quick_settings_airplane_off" msgid="7786329360056634412">"ଏୟାର୍‌ପ୍ଲେନ୍‌ ମୋଡ୍‌ ଅଫ୍ ଅଛି।"</string>
+    <string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"ଏୟାର୍‌ପ୍ଲେନ୍‌ ମୋଡ୍‌ ଅନ୍ ଅଛି।"</string>
+    <string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"ଏୟାର୍‌ପ୍ଲେନ୍‌ ମୋଡ୍‌କୁ ବନ୍ଦ କରାଯାଇଛି।"</string>
+    <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"ଏୟାର୍‌ପ୍ଲେନ୍‌ ମୋଡ୍‌କୁ ଚାଲୁ କରାଯାଇଛି।"</string>
+    <string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅନ୍‍ ଅଛି, କେବଳ ଗୁରୁତ୍ୱର୍ଣ୍ଣ।"</string>
+    <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅନ୍ ଅଛି, ସମ୍ପୂର୍ଣ୍ଣ ନୀରବ।"</string>
+    <string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅନ୍ ଅଛି, କେବଳ ଆଲାର୍ମ।"</string>
+    <!-- no translation found for accessibility_quick_settings_dnd (6607873236717185815) -->
+    <skip />
+    <string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅଫ୍‍ ଅଛି।"</string>
+    <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅଫ୍‍ କରାଯାଇଛି।"</string>
+    <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅନ୍ କରଯାଇଛି।"</string>
+    <!-- no translation found for accessibility_quick_settings_bluetooth (6341675755803320038) -->
+    <skip />
+    <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"ବ୍ଲୁ-ଟୂଥ୍‌ ଅଫ୍ ଅଛି।"</string>
+    <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"ବ୍ଲୁ-ଟୁଥ୍‍ ଅନ୍ ଅଛି।"</string>
+    <string name="accessibility_quick_settings_bluetooth_connecting" msgid="6953242966685343855">"ବ୍ଲୁ-ଟୁଥ୍‌ ସଂଯୋଗ ହେଉଛି।"</string>
+    <string name="accessibility_quick_settings_bluetooth_connected" msgid="4306637793614573659">"ବ୍ଲୁ-ଟୁଥ୍‌କୁ ସଂଯୋଗ କରାଯାଇଛି।"</string>
+    <string name="accessibility_quick_settings_bluetooth_changed_off" msgid="2730003763480934529">"ବ୍ଲୁ-ଟୁଥ୍‍କୁ ବନ୍ଦ କରିଦିଆଯାଇଛି।"</string>
+    <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="8722351798763206577">"ବ୍ଲୁ-ଟୁଥ୍‍କୁ ଚାଲୁ କରାଯାଇଛି।"</string>
+    <string name="accessibility_quick_settings_location_off" msgid="5119080556976115520">"ଲୋକେଶନ୍‌ର ତଥ୍ୟ ବନ୍ଦ ଅଛି।"</string>
+    <string name="accessibility_quick_settings_location_on" msgid="5809937096590102036">"ଲୋକେଶନ୍‌ର ତଥ୍ୟ ଅନ୍ ଅଛି।"</string>
+    <string name="accessibility_quick_settings_location_changed_off" msgid="8526845571503387376">"ଲୋକେଶନ୍‌ର ରିପୋର୍ଟ ବନ୍ଦ କରାଗଲା।"</string>
+    <string name="accessibility_quick_settings_location_changed_on" msgid="339403053079338468">"ଲୋକେଶନ୍‌ର ରିପୋର୍ଟ ଅନ୍ କରାଗଲା।"</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"<xliff:g id="TIME">%s</xliff:g>ରେ ଆଲାର୍ମ ସେଟ୍‍ କରାଯାଇଛି।"</string>
+    <string name="accessibility_quick_settings_close" msgid="3115847794692516306">"ପ୍ୟାନେଲ୍ ବନ୍ଦ କରନ୍ତୁ।"</string>
+    <string name="accessibility_quick_settings_more_time" msgid="3659274935356197708">"ଅଧିକ ସମୟ।"</string>
+    <string name="accessibility_quick_settings_less_time" msgid="2404728746293515623">"କମ୍ ସମୟ।"</string>
+    <string name="accessibility_quick_settings_flashlight_off" msgid="4936432000069786988">"ଫ୍ଲାଶ୍‌ଲାଇଟ୍ ଅଫ୍ ଅଛି।"</string>
+    <!-- no translation found for accessibility_quick_settings_flashlight_unavailable (8012811023312280810) -->
+    <skip />
+    <string name="accessibility_quick_settings_flashlight_on" msgid="2003479320007841077">"ଫ୍ଲାଶ୍‌ଲାଇଟ୍ ଅନ୍ ଅଛି।"</string>
+    <string name="accessibility_quick_settings_flashlight_changed_off" msgid="3303701786768224304">"ଟର୍ଚ୍ଚ ଲାଇଟ୍ ବନ୍ଦ ଅଛି।"</string>
+    <string name="accessibility_quick_settings_flashlight_changed_on" msgid="6531793301533894686">"ଟର୍ଚ୍ଚ ଲାଇଟ୍ ଅନ୍ ଅଛି।"</string>
+    <string name="accessibility_quick_settings_color_inversion_changed_off" msgid="4406577213290173911">"ରଙ୍ଗ ବିପରୀତିକରଣକୁ ବନ୍ଦ କରିଦିଆଗଲା।"</string>
+    <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="6897462320184911126">"ରଙ୍ଗ ବିପରୀତିକରଣକୁ ଚାଲୁ କରିଦିଆଗଲା।"</string>
+    <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"ମୋବାଇଲ୍ ହଟସ୍ପଟ୍‌ ବନ୍ଦ ଅଛି।"</string>
+    <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"ମୋବାଇଲ୍ ହଟସ୍ପଟ୍‌ ଅନ୍ ଅଛି।"</string>
+    <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"ସ୍କ୍ରୀନ୍‌ କାଷ୍ଟ କରିବା ରହିଯାଇଛି।"</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_data_saver_changed_off (650231949881093289) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_data_saver_changed_on (4218725402373934151) -->
+    <skip />
+    <string name="accessibility_brightness" msgid="8003681285547803095">"ଡିସ୍‌ପ୍ଲେ ଉଜ୍ଜ୍ୱଳତା"</string>
+    <!-- no translation found for accessibility_ambient_display_charging (9084521679384069087) -->
+    <skip />
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G ଡାଟା ପଜ୍‍ କରାଯାଇଛି"</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G ଡାଟା ପଜ୍‍ କରାଯାଇଛି"</string>
+    <!-- no translation found for data_usage_disabled_dialog_mobile_title (6801382439018099779) -->
+    <skip />
+    <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"ଡାଟା ପଜ୍‍ କରାଯାଇଛି"</string>
+    <!-- no translation found for data_usage_disabled_dialog (4919541636934603816) -->
+    <skip />
+    <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"ପୁଣି ଚାଲୁ କରନ୍ତୁ"</string>
+    <string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS ଖୋଜାଯାଉଛି"</string>
+    <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS ଦ୍ୱାରା ଲୋକେଶନ୍ ସେଟ୍ କରାଯାଇଛି"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"ଲୋକେଶନ୍‍ ଅନୁରୋଧ ସକ୍ରିୟ ଅଛି"</string>
+    <string name="accessibility_clear_all" msgid="5235938559247164925">"ସମସ୍ତ ବିଜ୍ଞପ୍ତି ଖାଲି କରନ୍ତୁ।"</string>
+    <!-- no translation found for notification_group_overflow_indicator (1863231301642314183) -->
+    <skip />
+    <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
+    <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"ବିଜ୍ଞପ୍ତି ସେଟିଙ୍ଗ"</string>
+    <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ସେଟିଙ୍ଗ"</string>
+    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ସ୍କ୍ରୀନ୍‍ ସ୍ୱଚାଳିତ ଭାବେ ବୁଲିବ।"</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"ଲ୍ୟାଣ୍ଡସ୍କେପ୍‌ ଅବସ୍ଥାରେ ସ୍କ୍ରୀନ୍‍କୁ ଲକ୍‌ କରାଯାଇଛି।"</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"ପୋର୍ଟ୍ରେଟ୍‍ ଅବସ୍ଥାରେ ସ୍କ୍ରୀନ୍‍କୁ ଲକ୍‌ କରାଯାଇଛି।"</string>
+    <string name="accessibility_rotation_lock_off_changed" msgid="8134601071026305153">"ସ୍କ୍ରୀନ୍‍ ବର୍ତ୍ତମାନ ସ୍ୱଚାଳିତ ଭାବେ ବୁଲିବ।"</string>
+    <string name="accessibility_rotation_lock_on_landscape_changed" msgid="3135965553707519743">"ବର୍ତ୍ତମାନ ସ୍କ୍ରୀନ୍‌ଟି ଲ୍ୟାଣ୍ଡସ୍କେପ୍ ଦିଗରେ ଲକ୍ ଅଛି।"</string>
+    <string name="accessibility_rotation_lock_on_portrait_changed" msgid="8922481981834012126">"ବର୍ତ୍ତମାନ ସ୍କ୍ରୀନ୍‌ଟି ପୋର୍ଟେଟ୍ ଦିଗରେ ଲକ୍‌ ଅଛି।"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"ଡେଜର୍ଟ କେସ୍‌"</string>
+    <!-- no translation found for start_dreams (5640361424498338327) -->
+    <skip />
+    <string name="ethernet_label" msgid="7967563676324087464">"ଇଥରନେଟ୍‌"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
+    <string name="quick_settings_dnd_label" msgid="8735855737575028208">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\""</string>
+    <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"କେବଳ ପ୍ରାଥମିକତା"</string>
+    <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"କେବଳ ଆଲାର୍ମ"</string>
+    <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"ସମ୍ପୂର୍ଣ୍ଣ ନୀରବ"</string>
+    <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"ବ୍ଲୁ-ଟୁଥ୍‌"</string>
+    <string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"ବ୍ଲୁ-ଟୁଥ୍‌ (<xliff:g id="NUMBER">%d</xliff:g>ଟି ଡିଭାଇସ୍‌)"</string>
+    <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"ବ୍ଲୁ-ଟୁଥ୍‌ ଅଫ୍"</string>
+    <string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"ପେୟାର୍‍ ହୋଇଥିବା କୌଣସି ଡିଭାଇସ୍ ଉପଲବ୍ଧ ନାହିଁ"</string>
+    <!-- no translation found for quick_settings_bluetooth_secondary_label_battery_level (7106697106764717416) -->
+    <skip />
+    <!-- no translation found for quick_settings_bluetooth_secondary_label_audio (5673845963301132071) -->
+    <skip />
+    <!-- no translation found for quick_settings_bluetooth_secondary_label_headset (1880572731276240588) -->
+    <skip />
+    <!-- no translation found for quick_settings_bluetooth_secondary_label_input (2173322305072945905) -->
+    <skip />
+    <string name="quick_settings_brightness_label" msgid="6968372297018755815">"ଉଜ୍ଜ୍ୱଳତା"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"ସ୍ୱତଃ-ଘୂର୍ଣ୍ଣନ"</string>
+    <!-- no translation found for accessibility_quick_settings_rotation (4231661040698488779) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_rotation_value (8187398200140760213) -->
+    <skip />
+    <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"ଘୂର୍ଣ୍ଣନ ଲକ୍‍ ହୋଇଛି"</string>
+    <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"ପୋର୍ଟ୍ରେଟ୍"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"ଲ୍ୟାଣ୍ଡସ୍କେପ୍"</string>
+    <string name="quick_settings_ime_label" msgid="7073463064369468429">"ଇନପୁଟ୍ ପଦ୍ଧତି"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"ଲୋକେଶନ୍‍"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"ଲୋକେଶନ୍‍ ଅଫ୍‍"</string>
+    <string name="quick_settings_media_device_label" msgid="1302906836372603762">"ମିଡିଆ ଡିଭାଇସ୍‌"</string>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"କେବଳ ଜରୁରୀକାଳୀନ କଲ୍‌"</string>
+    <string name="quick_settings_settings_label" msgid="5326556592578065401">"ସେଟିଙ୍ଗ"</string>
+    <string name="quick_settings_time_label" msgid="4635969182239736408">"ସମୟ"</string>
+    <string name="quick_settings_user_label" msgid="5238995632130897840">"ମୁଁ"</string>
+    <string name="quick_settings_user_title" msgid="4467690427642392403">"ୟୁଜର୍‌"</string>
+    <string name="quick_settings_user_new_user" msgid="9030521362023479778">"ନୂଆ ୟୁଜର୍‌"</string>
+    <string name="quick_settings_wifi_label" msgid="9135344704899546041">"ୱାଇ-ଫାଇ"</string>
+    <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"ସଂଯୁକ୍ତ ହୋଇନାହିଁ"</string>
+    <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"ନେଟ୍‌ୱର୍କ ନାହିଁ"</string>
+    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"ୱାଇ-ଫାଇ ଅଫ୍‍"</string>
+    <!-- no translation found for quick_settings_wifi_on_label (7607810331387031235) -->
+    <skip />
+    <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"କୌଣସି ୱାଇ-ଫାଇ ନେଟ୍‌ୱର୍କ ଉପଲବ୍ଧ ନାହିଁ"</string>
+    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
+    <skip />
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"କାଷ୍ଟ"</string>
+    <string name="quick_settings_casting" msgid="6601710681033353316">"କାଷ୍ଟିଙ୍ଗ"</string>
+    <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"ନାମହୀନ ଡିଭାଇସ୍‍"</string>
+    <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"କାଷ୍ଟ୍ ପାଇଁ ପ୍ରସ୍ତୁତ"</string>
+    <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"କୌଣସି ଡିଭାଇସ୍ ଉପଲବ୍ଧ ନାହିଁ"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ଉଜ୍ଜ୍ୱଳତା"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ସ୍ୱଚାଳିତ"</string>
+    <string name="quick_settings_inversion_label" msgid="8790919884718619648">"ରଙ୍ଗ ପୂର୍ବପରି କରନ୍ତୁ"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"ରଙ୍ଗ ସଂଶୋଧନ ମୋଡ୍‍"</string>
+    <string name="quick_settings_more_settings" msgid="326112621462813682">"ଅଧିକ ସେଟିଙ୍ଗ"</string>
+    <string name="quick_settings_done" msgid="3402999958839153376">"ହୋଇଗଲା"</string>
+    <string name="quick_settings_connected" msgid="1722253542984847487">"ସଂଯୁକ୍ତ"</string>
+    <!-- no translation found for quick_settings_connected_battery_level (4136051440381328892) -->
+    <skip />
+    <string name="quick_settings_connecting" msgid="47623027419264404">"ସଂଯୋଗ କରୁଛି..."</string>
+    <string name="quick_settings_tethering_label" msgid="7153452060448575549">"ଟିଥରିଙ୍ଗ"</string>
+    <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"ହଟସ୍ପଟ୍‌"</string>
+    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
+    <skip />
+    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_notifications_label" msgid="4818156442169154523">"ବିଜ୍ଞପ୍ତି"</string>
+    <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"ଫ୍ଲାଶ୍‍ଲାଇଟ"</string>
+    <!-- no translation found for quick_settings_cellular_detail_title (3661194685666477347) -->
+    <skip />
+    <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"ଡାଟାର ବ୍ୟବହାର"</string>
+    <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"ଅବଶିଷ୍ଟ ଡାଟା"</string>
+    <string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"ସୀମାଠାରୁ ଅଧିକ"</string>
+    <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> ବ୍ୟବହାର କରାଯାଇଛି"</string>
+    <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> ସୀମା"</string>
+    <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> ଚେତାବନୀ"</string>
+    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
+    <skip />
+    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
+    <skip />
+    <!-- no translation found for quick_settings_night_display_label (3577098011487644395) -->
+    <skip />
+    <!-- no translation found for quick_settings_night_secondary_label_on_at_sunset (8483259341596943314) -->
+    <skip />
+    <!-- no translation found for quick_settings_night_secondary_label_until_sunrise (4453017157391574402) -->
+    <skip />
+    <!-- no translation found for quick_settings_night_secondary_label_on_at (6256314040368487637) -->
+    <skip />
+    <!-- no translation found for quick_settings_night_secondary_label_until (8664820079774824618) -->
+    <skip />
+    <!-- no translation found for quick_settings_nfc_label (9012153754816969325) -->
+    <skip />
+    <!-- no translation found for quick_settings_nfc_off (6883274004315134333) -->
+    <skip />
+    <!-- no translation found for quick_settings_nfc_on (6680317193676884311) -->
+    <skip />
+    <!-- no translation found for recents_empty_message (808480104164008572) -->
+    <skip />
+    <!-- no translation found for recents_empty_message_dismissed_all (2791312568666558651) -->
+    <skip />
+    <string name="recents_app_info_button_label" msgid="2890317189376000030">"ଆପ୍ଲିକେଶନ୍‍ ସୂଚନା"</string>
+    <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ସ୍କ୍ରୀନ୍‌ ଲକ୍‌"</string>
+    <string name="recents_search_bar_label" msgid="8074997400187836677">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
+    <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> କୁ ଆରମ୍ଭ କରାଯାଇପାରିଲା ନାହିଁ।"</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
+    <!-- no translation found for recents_stack_action_button_label (6593727103310426253) -->
+    <skip />
+    <!-- no translation found for recents_drag_hint_message (2649739267073203985) -->
+    <skip />
+    <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ଭୂସମାନ୍ତର ଭାବରେ ଭାଗ କରନ୍ତୁ"</string>
+    <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"ଭୂଲମ୍ବ ଭାବରେ ଭାଗ କରନ୍ତୁ"</string>
+    <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"କଷ୍ଟମ୍‍ କରି ଭାଗ କରନ୍ତୁ"</string>
+    <!-- no translation found for recents_accessibility_split_screen_top (9056056469282256287) -->
+    <skip />
+    <!-- no translation found for recents_accessibility_split_screen_left (8987144699630620019) -->
+    <skip />
+    <!-- no translation found for recents_accessibility_split_screen_right (275069779299592867) -->
+    <skip />
+    <string name="expanded_header_battery_charged" msgid="5945855970267657951">"ଚାର୍ଜ ହୋଇଗଲା"</string>
+    <string name="expanded_header_battery_charging" msgid="205623198487189724">"ଚାର୍ଜ କରାଯାଉଛି"</string>
+    <string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"ପୂର୍ଣ୍ଣ ଚାର୍ଜ ହେବାକୁ ଆଉ <xliff:g id="CHARGING_TIME">%s</xliff:g> ଅଛି"</string>
+    <string name="expanded_header_battery_not_charging" msgid="4798147152367049732">"ଚାର୍ଜ ହେଉନାହିଁ"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"ନେଟ୍‍ୱର୍କ\nମନିଟର୍‍ କରାଯାଇପାରେ"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"ସର୍ଚ୍ଚ"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ପାଇଁ ଉପରକୁ ସ୍ଲାଇଡ୍‍ କରନ୍ତୁ।"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ପାଇଁ ବାମକୁ ସ୍ଲାଇଡ୍ କରନ୍ତୁ"</string>
+    <!-- no translation found for zen_priority_introduction (1149025108714420281) -->
+    <skip />
+    <!-- no translation found for zen_alarms_introduction (4934328096749380201) -->
+    <skip />
+    <string name="zen_priority_customize_button" msgid="7948043278226955063">"କଷ୍ଟମାଇଜ୍‌ କରନ୍ତୁ"</string>
+    <!-- no translation found for zen_silence_introduction_voice (3948778066295728085) -->
+    <skip />
+    <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
+    <skip />
+    <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
+    <string name="speed_bump_explanation" msgid="1288875699658819755">"ନିମ୍ନରେ କମ୍‍ ଜରୁରୀ ବିଜ୍ଞପ୍ତି"</string>
+    <string name="notification_tap_again" msgid="7590196980943943842">"ଖୋଲିବା ପାଇଁ ପୁଣି ଟାପ୍‍ କରନ୍ତୁ"</string>
+    <string name="keyguard_unlock" msgid="8043466894212841998">"ଅନଲକ୍‌ କରିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍‌ କରନ୍ତୁ"</string>
+    <!-- no translation found for do_disclosure_generic (5615898451805157556) -->
+    <skip />
+    <!-- no translation found for do_disclosure_with_name (5640615509915445501) -->
+    <skip />
+    <string name="phone_hint" msgid="4872890986869209950">"ଫୋନ୍‍ ପାଇଁ ଆଇକନରୁ ସ୍ୱାଇପ୍‍ କରନ୍ତୁ"</string>
+    <string name="voice_hint" msgid="8939888732119726665">"ଭଏସ୍‍ ସହାୟକ ପାଇଁ ଆଇକନରୁ ସ୍ୱାଇପ୍‍ କରନ୍ତୁ"</string>
+    <string name="camera_hint" msgid="7939688436797157483">"କ୍ୟାମେରା ପାଇଁ ଆଇକନରୁ ସ୍ୱାଇପ୍‍ କରନ୍ତୁ"</string>
+    <!-- no translation found for interruption_level_none_with_warning (5114872171614161084) -->
+    <skip />
+    <string name="interruption_level_none" msgid="6000083681244492992">"ସମ୍ପୂର୍ଣ୍ଣ ନୀରବ"</string>
+    <string name="interruption_level_priority" msgid="6426766465363855505">"କେବଳ ପ୍ରାଥମିକତା"</string>
+    <string name="interruption_level_alarms" msgid="5226306993448328896">"କେବଳ ଆଲାର୍ମ"</string>
+    <string name="interruption_level_none_twoline" msgid="3957581548190765889">"ସମ୍ପୂର୍ଣ୍ଣ\nନୀରବ"</string>
+    <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"କେବଳ\nପ୍ରାଥମିକତା"</string>
+    <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"କେବଳ\nଆଲାର୍ମ"</string>
+    <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ଚାର୍ଜ କରାଯାଉଛି (ପୂର୍ଣ୍ଣ ହେବାକୁ <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ରହିଛି)"</string>
+    <!-- no translation found for keyguard_indication_charging_time_fast (9018981952053914986) -->
+    <skip />
+    <!-- no translation found for keyguard_indication_charging_time_slowly (955252797961724952) -->
+    <skip />
+    <string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"ୟୁଜର୍‍ ବଦଳାନ୍ତୁ"</string>
+    <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"ୟୁଜର୍‍ ବଦଳାନ୍ତୁ, ବର୍ତ୍ତମାନର ୟୁଜର୍‍ ହେଉଛନ୍ତି <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
+    <!-- no translation found for accessibility_multi_user_switch_inactive (1424081831468083402) -->
+    <skip />
+    <string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"ପ୍ରୋଫାଇଲ୍ ଦେଖାନ୍ତୁ"</string>
+    <string name="user_add_user" msgid="5110251524486079492">"ୟୁଜର୍‍ଙ୍କୁ ଯୋଡ଼ନ୍ତୁ"</string>
+    <string name="user_new_user_name" msgid="426540612051178753">"ନୂତନ ୟୁଜର୍‍"</string>
+    <string name="guest_nickname" msgid="8059989128963789678">"ଅତିଥି"</string>
+    <string name="guest_new_guest" msgid="600537543078847803">"ଅତିଥି ଯୋଡ଼ନ୍ତୁ"</string>
+    <string name="guest_exit_guest" msgid="7187359342030096885">"ଅତିଥିଙ୍କୁ କାଢ଼ନ୍ତୁ"</string>
+    <string name="guest_exit_guest_dialog_title" msgid="8480693520521766688">"ଅତିଥିଙ୍କୁ କାଢ଼ିଦେବେ?"</string>
+    <string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"ଏହି ଅବଧିର ସମସ୍ତ ଆପ୍‌ ଓ ଡାଟା ଡିଲିଟ୍‌ ହୋଇଯିବ।"</string>
+    <string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"କାଢ଼ିଦିଅନ୍ତୁ"</string>
+    <string name="guest_wipe_session_title" msgid="6419439912885956132">"ପୁଣି ସ୍ୱାଗତ, ଅତିଥି!"</string>
+    <string name="guest_wipe_session_message" msgid="8476238178270112811">"ଆପଣ ନିଜର ଅବଧି ଜାରି ରଖିବାକୁ ଚାହାନ୍ତି କି?"</string>
+    <string name="guest_wipe_session_wipe" msgid="5065558566939858884">"ଆରମ୍ଭ କରନ୍ତୁ"</string>
+    <string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"ହଁ, ଜାରି ରଖନ୍ତୁ"</string>
+    <string name="guest_notification_title" msgid="1585278533840603063">"ଅତିଥି ୟୁଜର୍‍"</string>
+    <!-- no translation found for guest_notification_text (335747957734796689) -->
+    <skip />
+    <string name="guest_notification_remove_action" msgid="8820670703892101990">"ଅତିଥିଙ୍କୁ ବାହାର କରନ୍ତୁ"</string>
+    <!-- no translation found for user_logout_notification_title (1453960926437240727) -->
+    <skip />
+    <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
+    <skip />
+    <!-- no translation found for user_logout_notification_action (1195428991423425062) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4553596395824132638">"ନୂତନ ୟୁଜର୍‍ ଯୋଡ଼ିବେ?"</string>
+    <string name="user_add_user_message_short" msgid="2161624834066214559">"ଜଣେ ନୂଆ ୟୁଜର୍‍ଙ୍କୁ ଯୋଡ଼ିବାବେଳେ, ସେହି ବ୍ୟକ୍ତିଙ୍କୁ ସ୍ଥାନ ସେଟ୍‍ କରିବାକୁ ପଡ଼ିବ। \n \n ଅନ୍ୟ ସମସ୍ତ ୟୁଜର୍‍ଙ୍କ ପାଇଁ ଯେକୌଣସି ୟୁଜର୍‍ ଆପ୍‌ଗୁଡ଼ିକୁ ଅପଡେଟ୍‌ କରିପାରିବେ।"</string>
+    <!-- no translation found for user_remove_user_title (4681256956076895559) -->
+    <skip />
+    <!-- no translation found for user_remove_user_message (1453218013959498039) -->
+    <skip />
+    <!-- no translation found for user_remove_user_remove (7479275741742178297) -->
+    <skip />
+    <!-- no translation found for battery_saver_notification_title (8614079794522291840) -->
+    <skip />
+    <string name="battery_saver_notification_text" msgid="820318788126672692">"କାର୍ଯ୍ୟ ସମ୍ପାଦନ ଓ ବ୍ୟାକ୍‌ଗ୍ରାଉଣ୍ଡ ଡାଟା କମ୍ କରନ୍ତୁ"</string>
+    <!-- no translation found for battery_saver_notification_action_text (132118784269455533) -->
+    <skip />
+    <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ଆପଣଙ୍କ ସ୍କ୍ରୀନ୍‌ରେ ପ୍ରଦର୍ଶିତ ହେଉଥିବା ସମସ୍ତ ବସ୍ତୁକୁ କ୍ୟାପଚର୍ କରିବା ଆରମ୍ଭ ହୋଇଯିବ।"</string>
+    <string name="media_projection_remember_text" msgid="3103510882172746752">"ପୁଣି ଦେଖାନ୍ତୁ ନାହିଁ"</string>
+    <string name="clear_all_notifications_text" msgid="814192889771462828">"ସମସ୍ତ ଖାଲି କରନ୍ତୁ"</string>
+    <string name="media_projection_action_text" msgid="8470872969457985954">"ବର୍ତ୍ତମାନ ଆରମ୍ଭ କରନ୍ତୁ"</string>
+    <string name="empty_shade_text" msgid="708135716272867002">"କୌଣସି ବିଜ୍ଞପ୍ତି ନାହିଁ"</string>
+    <string name="profile_owned_footer" msgid="8021888108553696069">"ପ୍ରୋଫାଇଲ୍ ନିରୀକ୍ଷଣ କରାଯାଇପାରେ।"</string>
+    <string name="vpn_footer" msgid="2388611096129106812">"ନେଟ୍‌ୱର୍କ ନୀରିକ୍ଷଣ କରାଯାଇପାରେ"</string>
+    <!-- no translation found for branded_vpn_footer (2168111859226496230) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_management_monitoring (6645176135063957394) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_named_management_monitoring (370622174777570853) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_management_named_vpn (1085137869053332307) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_named_management_named_vpn (6290456493852584017) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_management (3294967280853150271) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_named_management (1059403025094542908) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_management_vpns (3698767349925266482) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_named_management_vpns (7777821385318891527) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_managed_profile_monitoring (5125463987558278215) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_named_managed_profile_monitoring (8973606847896650284) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_monitoring (679658227269205728) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_vpns (8170318392053156330) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_managed_profile_named_vpn (3494535754792751741) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_personal_profile_named_vpn (4467456202486569906) -->
+    <skip />
+    <!-- no translation found for quick_settings_disclosure_named_vpn (6943724064780847080) -->
+    <skip />
+    <!-- no translation found for monitoring_title_device_owned (1652495295941959815) -->
+    <skip />
+    <string name="monitoring_title_profile_owned" msgid="6790109874733501487">"ପ୍ରୋଫାଇଲ୍ ନୀରିକ୍ଷଣ"</string>
+    <string name="monitoring_title" msgid="169206259253048106">"ନେଟ୍‌ୱର୍କ ନୀରିକ୍ଷଣ"</string>
+    <!-- no translation found for monitoring_subtitle_vpn (876537538087857300) -->
+    <skip />
+    <!-- no translation found for monitoring_subtitle_network_logging (3341264304793193386) -->
+    <skip />
+    <!-- no translation found for monitoring_subtitle_ca_certificate (3874151893894355988) -->
+    <skip />
+    <string name="disable_vpn" msgid="4435534311510272506">"VPN ଅକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="disconnect_vpn" msgid="1324915059568548655">"VPN ବିଛିନ୍ନ କରନ୍ତୁ"</string>
+    <!-- no translation found for monitoring_button_view_policies (100913612638514424) -->
+    <skip />
+    <!-- no translation found for monitoring_description_named_management (5281789135578986303) -->
+    <skip />
+    <!-- no translation found for monitoring_description_management (4573721970278370790) -->
+    <skip />
+    <!-- no translation found for monitoring_description_management_ca_certificate (5202023784131001751) -->
+    <skip />
+    <!-- no translation found for monitoring_description_managed_profile_ca_certificate (4683248196789897964) -->
+    <skip />
+    <!-- no translation found for monitoring_description_ca_certificate (7886985418413598352) -->
+    <skip />
+    <!-- no translation found for monitoring_description_management_network_logging (7184005419733060736) -->
+    <skip />
+    <!-- no translation found for monitoring_description_named_vpn (7403457334088909254) -->
+    <skip />
+    <!-- no translation found for monitoring_description_two_named_vpns (4198511413729213802) -->
+    <skip />
+    <!-- no translation found for monitoring_description_managed_profile_named_vpn (1427905889862420559) -->
+    <skip />
+    <!-- no translation found for monitoring_description_personal_profile_named_vpn (3133980926929069283) -->
+    <skip />
+    <!-- no translation found for monitoring_description_do_header_generic (96588491028288691) -->
+    <skip />
+    <!-- no translation found for monitoring_description_do_header_with_name (5511133708978206460) -->
+    <skip />
+    <!-- no translation found for monitoring_description_do_body (3639594537660975895) -->
+    <skip />
+    <!-- no translation found for monitoring_description_do_learn_more_separator (3785251953067436862) -->
+    <skip />
+    <!-- no translation found for monitoring_description_do_learn_more (1849514470437907421) -->
+    <skip />
+    <!-- no translation found for monitoring_description_do_body_vpn (8255218762488901796) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_settings_separator (1933186756733474388) -->
+    <skip />
+    <!-- no translation found for monitoring_description_vpn_settings (6434859242636063861) -->
+    <skip />
+    <!-- no translation found for monitoring_description_ca_cert_settings_separator (4987350385906393626) -->
+    <skip />
+    <!-- no translation found for monitoring_description_ca_cert_settings (5489969458872997092) -->
+    <skip />
+    <!-- no translation found for monitoring_description_network_logging (7223505523384076027) -->
+    <skip />
+    <string name="monitoring_description_vpn" msgid="4445150119515393526">"ଏକ VPN ସଂଯୋଗ ସେଟ୍‍ ଅପ୍‍ କରିବା ପାଇଁ ଆପଣ ଗୋଟିଏ ଆପକୁ ଅନୁମତି ଦେଲେ।\n\nଏହି ଆପ୍‍ ଇମେଲ୍‍, ଆପ୍‌ ଓ ୱେବସାଇଟ୍‍ ସମେତ ଆପଣଙ୍କ ଡିଭାଇସ୍‍ ଓ ନେଟ୍‌ୱର୍କ ଗତିବିଧିକୁ ନିରୀକ୍ଷଣ କରିପାରେ।"</string>
+    <!-- no translation found for monitoring_description_vpn_profile_owned (2958019119161161530) -->
+    <skip />
+    <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
+    <!-- no translation found for monitoring_description_app (1828472472674709532) -->
+    <skip />
+    <!-- no translation found for monitoring_description_app_personal (484599052118316268) -->
+    <skip />
+    <!-- no translation found for branded_monitoring_description_app_personal (2669518213949202599) -->
+    <skip />
+    <!-- no translation found for monitoring_description_app_work (4612997849787922906) -->
+    <skip />
+    <!-- no translation found for monitoring_description_app_personal_work (5664165460056859391) -->
+    <skip />
+    <!-- no translation found for keyguard_indication_trust_granted (4985003749105182372) -->
+    <skip />
+    <!-- no translation found for keyguard_indication_trust_managed (8319646760022357585) -->
+    <skip />
+    <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"ଯେତେବେଳ ପର୍ଯ୍ୟନ୍ତ ଆପଣ ମାନୁଆଲୀ ଅନଲକ୍‌ କରିନାହାନ୍ତି, ସେତେବେଳ ପର୍ଯ୍ୟନ୍ତ ଡିଭାଇସ୍‌ ଲକ୍‌ ରହିବ"</string>
+    <string name="hidden_notifications_title" msgid="7139628534207443290">"ବିଜ୍ଞପ୍ତିକୁ ଶୀଘ୍ର ପ୍ରାପ୍ତ କରନ୍ତୁ"</string>
+    <string name="hidden_notifications_text" msgid="2326409389088668981">"ଅନଲକ୍‌ କରିବା ପୁର୍ବରୁ ସେମାନଙ୍କୁ ଦେଖନ୍ତୁ"</string>
+    <string name="hidden_notifications_cancel" msgid="3690709735122344913">"ନାହିଁ, ଥାଉ"</string>
+    <string name="hidden_notifications_setup" msgid="41079514801976810">"ସେଟ୍ ଅପ୍ କରନ୍ତୁ"</string>
+    <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
+    <!-- no translation found for volume_zen_end_now (6930243045593601084) -->
+    <skip />
+    <string name="accessibility_volume_expand" msgid="5946812790999244205">"ବଢ଼ାନ୍ତୁ"</string>
+    <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ଛୋଟ କରନ୍ତୁ"</string>
+    <!-- no translation found for accessibility_output_chooser (8185317493017988680) -->
+    <skip />
+    <string name="screen_pinning_title" msgid="3273740381976175811">"ସ୍କ୍ରିନକୁ ପିନ୍‌ କରାଯାଇଛି"</string>
+    <!-- no translation found for screen_pinning_description (8909878447196419623) -->
+    <skip />
+    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
+    <skip />
+    <!-- no translation found for screen_pinning_description_accessible (426190689254018656) -->
+    <skip />
+    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
+    <skip />
+    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
+    <skip />
+    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
+    <skip />
+    <string name="screen_pinning_positive" msgid="3783985798366751226">"ବୁଝିଲି"</string>
+    <string name="screen_pinning_negative" msgid="3741602308343880268">"ନାହିଁ, ଥାଉ"</string>
+    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
+    <skip />
+    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
+    <skip />
+    <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> ଲୁଚାନ୍ତୁ?"</string>
+    <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"ଆଗକୁ ଆପଣ ଯେତେବେଳେ ଏହି ସେଟିଙ୍ଗକୁ ଚାଲୁ କରିବେ, ଏହା ପୁଣି ଦେଖାଦେବ।"</string>
+    <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"ଲୁଚାନ୍ତୁ"</string>
+    <!-- no translation found for managed_profile_foreground_toast (5421487114739245972) -->
+    <skip />
+    <!-- no translation found for stream_voice_call (4410002696470423714) -->
+    <skip />
+    <!-- no translation found for stream_system (7493299064422163147) -->
+    <skip />
+    <!-- no translation found for stream_ring (8213049469184048338) -->
+    <skip />
+    <!-- no translation found for stream_music (9086982948697544342) -->
+    <skip />
+    <!-- no translation found for stream_alarm (5209444229227197703) -->
+    <skip />
+    <!-- no translation found for stream_notification (2563720670905665031) -->
+    <skip />
+    <!-- no translation found for stream_bluetooth_sco (2055645746402746292) -->
+    <skip />
+    <!-- no translation found for stream_dtmf (2447177903892477915) -->
+    <skip />
+    <!-- no translation found for stream_accessibility (301136219144385106) -->
+    <skip />
+    <!-- no translation found for ring_toggle_title (3281244519428819576) -->
+    <skip />
+    <!-- no translation found for volume_ringer_status_normal (4273142424125855384) -->
+    <skip />
+    <!-- no translation found for volume_ringer_status_vibrate (1825615171021346557) -->
+    <skip />
+    <!-- no translation found for volume_ringer_status_silent (6896394161022916369) -->
+    <skip />
+    <!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
+    <skip />
+    <!-- no translation found for volume_stream_content_description_vibrate (1187944970457807498) -->
+    <skip />
+    <!-- no translation found for volume_stream_content_description_mute (3625049841390467354) -->
+    <skip />
+    <!-- no translation found for volume_stream_content_description_vibrate_a11y (6427727603978431301) -->
+    <skip />
+    <!-- no translation found for volume_stream_content_description_mute_a11y (8995013018414535494) -->
+    <skip />
+    <!-- no translation found for volume_dialog_title (7272969888820035876) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_vibrate (8902050240801159042) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_silent (2128975224280276122) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_ring (6144469689490528338) -->
+    <skip />
+    <!-- no translation found for output_title (5355078100792942802) -->
+    <skip />
+    <!-- no translation found for output_calls_title (8717692905017206161) -->
+    <skip />
+    <!-- no translation found for output_none_found (5544982839808921091) -->
+    <skip />
+    <!-- no translation found for output_none_found_service_off (8631969668659757069) -->
+    <skip />
+    <!-- no translation found for output_service_bt (6224213415445509542) -->
+    <skip />
+    <!-- no translation found for output_service_wifi (3749735218931825054) -->
+    <skip />
+    <!-- no translation found for output_service_bt_wifi (4486837869988770896) -->
+    <skip />
+    <!-- no translation found for system_ui_tuner (708224127392452018) -->
+    <skip />
+    <string name="show_battery_percentage" msgid="5444136600512968798">"ଏମ୍ବେଡ୍‍ ହୋଇଥିବା ବ୍ୟାଟେରୀ ଶତକଡ଼ା ଦେଖାନ୍ତୁ"</string>
+    <string name="show_battery_percentage_summary" msgid="3215025775576786037">"ଚାର୍ଜ ହେଉନଥିବାବେଳେ ଷ୍ଟାଟସ୍‍ ବାର୍‍ ଆଇକନ୍‍ ଭିତରେ ବ୍ୟାଟେରୀ ସ୍ତର ଶତକଡ଼ା ଦେଖାନ୍ତୁ"</string>
+    <string name="quick_settings" msgid="10042998191725428">"ଦ୍ରୁତ ସେଟିଙ୍ଗ"</string>
+    <string name="status_bar" msgid="4877645476959324760">"ଷ୍ଟାଟସ୍‍ ବାର୍‍"</string>
+    <!-- no translation found for overview (4018602013895926956) -->
+    <skip />
+    <!-- no translation found for demo_mode (2532177350215638026) -->
+    <skip />
+    <string name="enable_demo_mode" msgid="4844205668718636518">"ଡେମୋ ମୋଡ୍ ସକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="show_demo_mode" msgid="2018336697782464029">"ଡେମୋ ମୋଡ୍‍ ଦେଖାନ୍ତୁ"</string>
+    <string name="status_bar_ethernet" msgid="5044290963549500128">"ଇଥରନେଟ୍‌"</string>
+    <string name="status_bar_alarm" msgid="8536256753575881818">"ଆଲାର୍ମ"</string>
+    <string name="status_bar_work" msgid="6022553324802866373">"ୱର୍କ ପ୍ରୋଫାଇଲ୍‌"</string>
+    <string name="status_bar_airplane" msgid="7057575501472249002">"ଏରୋପ୍ଲେନ୍‍ ମୋଡ୍"</string>
+    <string name="add_tile" msgid="2995389510240786221">"ଟାଇଲ୍‍ ଯୋଡ଼ନ୍ତୁ"</string>
+    <string name="broadcast_tile" msgid="3894036511763289383">"ଟାଇଲ୍‍ ବ୍ରଡ୍‌କାଷ୍ଟ କରନ୍ତୁ"</string>
+    <string name="zen_alarm_warning_indef" msgid="3482966345578319605">"ଆପଣ <xliff:g id="WHEN">%1$s</xliff:g> ପୂର୍ବରୁ ଏହା ଅଫ୍‍ ନକଲେ ନିଜର ପରବର୍ତ୍ତୀ ଆଲାର୍ମ ଶୁଣିପାରିବେ ନାହିଁ"</string>
+    <string name="zen_alarm_warning" msgid="444533119582244293">"<xliff:g id="WHEN">%1$s</xliff:g>ବେଳେ ଆପଣ ନିଜର ପରବର୍ତ୍ତୀ ଆଲାର୍ମ ଶୁଣିପାରିବେ ନାହିଁ"</string>
+    <string name="alarm_template" msgid="3980063409350522735">"<xliff:g id="WHEN">%1$s</xliff:g>ରେ"</string>
+    <string name="alarm_template_far" msgid="4242179982586714810">"<xliff:g id="WHEN">%1$s</xliff:g> ବେଳେ"</string>
+    <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"ଦ୍ରୁତ ସେଟିଙ୍ଗ, <xliff:g id="TITLE">%s</xliff:g>।"</string>
+    <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"ହଟସ୍ପଟ୍‌"</string>
+    <!-- no translation found for accessibility_managed_profile (6613641363112584120) -->
+    <skip />
+    <!-- no translation found for tuner_warning_title (7094689930793031682) -->
+    <skip />
+    <!-- no translation found for tuner_warning (8730648121973575701) -->
+    <skip />
+    <!-- no translation found for tuner_persistent_warning (8597333795565621795) -->
+    <skip />
+    <!-- no translation found for got_it (2239653834387972602) -->
+    <skip />
+    <!-- no translation found for tuner_toast (603429811084428439) -->
+    <skip />
+    <!-- no translation found for remove_from_settings (8389591916603406378) -->
+    <skip />
+    <!-- no translation found for remove_from_settings_prompt (6069085993355887748) -->
+    <skip />
+    <!-- no translation found for activity_not_found (348423244327799974) -->
+    <skip />
+    <!-- no translation found for clock_seconds (7689554147579179507) -->
+    <skip />
+    <!-- no translation found for clock_seconds_desc (6282693067130470675) -->
+    <skip />
+    <!-- no translation found for qs_rearrange (8060918697551068765) -->
+    <skip />
+    <!-- no translation found for show_brightness (6613930842805942519) -->
+    <skip />
+    <!-- no translation found for experimental (6198182315536726162) -->
+    <skip />
+    <!-- no translation found for enable_bluetooth_title (5027037706500635269) -->
+    <skip />
+    <!-- no translation found for enable_bluetooth_message (9106595990708985385) -->
+    <skip />
+    <!-- no translation found for enable_bluetooth_confirmation_ok (6258074250948309715) -->
+    <skip />
+    <!-- no translation found for show_silently (6841966539811264192) -->
+    <skip />
+    <!-- no translation found for block (2734508760962682611) -->
+    <skip />
+    <!-- no translation found for do_not_silence (6878060322594892441) -->
+    <skip />
+    <!-- no translation found for do_not_silence_block (4070647971382232311) -->
+    <skip />
+    <!-- no translation found for tuner_full_importance_settings (3207312268609236827) -->
+    <skip />
+    <!-- no translation found for tuner_full_importance_settings_on (7545060756610299966) -->
+    <skip />
+    <!-- no translation found for tuner_full_importance_settings_off (8208165412614935229) -->
+    <skip />
+    <!-- no translation found for power_notification_controls_description (4372459941671353358) -->
+    <skip />
+    <!-- no translation found for notification_header_default_channel (7506845022070889909) -->
+    <skip />
+    <!-- no translation found for notification_channel_disabled (344536703863700565) -->
+    <skip />
+    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
+    <skip />
+    <!-- no translation found for inline_keep_showing (8945102997083836858) -->
+    <skip />
+    <!-- no translation found for inline_stop_button (4172980096860941033) -->
+    <skip />
+    <!-- no translation found for inline_keep_button (6665940297019018232) -->
+    <skip />
+    <!-- no translation found for inline_keep_showing_app (1723113469580031041) -->
+    <skip />
+    <!-- no translation found for notification_unblockable_desc (1037434112919403708) -->
+    <skip />
+    <!-- no translation found for notification_channel_controls_opened_accessibility (6553950422055908113) -->
+    <skip />
+    <!-- no translation found for notification_channel_controls_closed_accessibility (7521619812603693144) -->
+    <skip />
+    <!-- no translation found for notification_channel_switch_accessibility (3420796005601900717) -->
+    <skip />
+    <!-- no translation found for notification_more_settings (816306283396553571) -->
+    <skip />
+    <!-- no translation found for notification_app_settings (420348114670768449) -->
+    <skip />
+    <!-- no translation found for notification_done (5279426047273930175) -->
+    <skip />
+    <!-- no translation found for inline_undo (558916737624706010) -->
+    <skip />
+    <!-- no translation found for notification_menu_accessibility (2046162834248888553) -->
+    <skip />
+    <!-- no translation found for notification_menu_gear_description (2204480013726775108) -->
+    <skip />
+    <!-- no translation found for notification_menu_snooze_description (3653669438131034525) -->
+    <skip />
+    <!-- no translation found for snooze_undo (6074877317002985129) -->
+    <skip />
+    <!-- no translation found for snoozed_for_time (2390718332980204462) -->
+    <skip />
+    <!-- no translation found for snoozeHourOptions (2124335842674413030) -->
+    <!-- no translation found for snoozeMinuteOptions (4127251700591510196) -->
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
+    <!-- no translation found for battery_detail_charging_summary (1279095653533044008) -->
+    <skip />
+    <!-- no translation found for battery_detail_switch_title (6285872470260795421) -->
+    <skip />
+    <!-- no translation found for battery_detail_switch_summary (9049111149407626804) -->
+    <skip />
+    <!-- no translation found for keyboard_key_button_template (6230056639734377300) -->
+    <skip />
+    <!-- no translation found for keyboard_key_home (2243500072071305073) -->
+    <skip />
+    <!-- no translation found for keyboard_key_back (2337450286042721351) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_up (5584144111755734686) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_down (7331518671788337815) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_left (1346446024676962251) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_right (3317323247127515341) -->
+    <skip />
+    <!-- no translation found for keyboard_key_dpad_center (2566737770049304658) -->
+    <skip />
+    <!-- no translation found for keyboard_key_tab (3871485650463164476) -->
+    <skip />
+    <!-- no translation found for keyboard_key_space (2499861316311153293) -->
+    <skip />
+    <!-- no translation found for keyboard_key_enter (5739632123216118137) -->
+    <skip />
+    <!-- no translation found for keyboard_key_backspace (1559580097512385854) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_play_pause (3861975717393887428) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_stop (2859963958595908962) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_next (1894394911630345607) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_previous (4256072387192967261) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_rewind (2654808213360820186) -->
+    <skip />
+    <!-- no translation found for keyboard_key_media_fast_forward (3849417047738200605) -->
+    <skip />
+    <!-- no translation found for keyboard_key_page_up (5654098530106845603) -->
+    <skip />
+    <!-- no translation found for keyboard_key_page_down (8720502083731906136) -->
+    <skip />
+    <!-- no translation found for keyboard_key_forward_del (1391451334716490176) -->
+    <skip />
+    <!-- no translation found for keyboard_key_move_home (2765693292069487486) -->
+    <skip />
+    <!-- no translation found for keyboard_key_move_end (5901174332047975247) -->
+    <skip />
+    <!-- no translation found for keyboard_key_insert (8530501581636082614) -->
+    <skip />
+    <!-- no translation found for keyboard_key_num_lock (5052537581246772117) -->
+    <skip />
+    <!-- no translation found for keyboard_key_numpad_template (8729216555174634026) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_system (6472647649616541064) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_system_home (3054369431319891965) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_system_recents (3154851905021926744) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_system_back (2207004531216446378) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_system_notifications (8366964080041773224) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_system_shortcuts_helper (4892255911160332762) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_system_switch_input (2334164096341310324) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_applications (9129465955073449206) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_applications_assist (9095441910537146013) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_applications_browser (6465985474000766533) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_applications_contacts (2064197111278436375) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_applications_email (6257036897441939004) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_applications_sms (638701213803242744) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_applications_music (4775559515850922780) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_applications_youtube (6555453761294723317) -->
+    <skip />
+    <!-- no translation found for keyboard_shortcut_group_applications_calendar (9043614299194991263) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_title (4540823317772234308) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3373784330208603030) -->
+    <skip />
+    <!-- no translation found for volume_dnd_silent (4363882330723050727) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
+    <!-- no translation found for battery (7498329822413202973) -->
+    <skip />
+    <!-- no translation found for clock (7416090374234785905) -->
+    <skip />
+    <!-- no translation found for headset (4534219457597457353) -->
+    <skip />
+    <!-- no translation found for accessibility_status_bar_headphones (9156307120060559989) -->
+    <skip />
+    <!-- no translation found for accessibility_status_bar_headset (8666419213072449202) -->
+    <skip />
+    <!-- no translation found for data_saver (5037565123367048522) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_on (8454111686783887148) -->
+    <skip />
+    <!-- no translation found for accessibility_data_saver_off (8841582529453005337) -->
+    <skip />
+    <!-- no translation found for switch_bar_on (1142437840752794229) -->
+    <skip />
+    <!-- no translation found for switch_bar_off (8803270596930432874) -->
+    <skip />
+    <!-- no translation found for nav_bar (1993221402773877607) -->
+    <skip />
+    <!-- no translation found for nav_bar_layout (3664072994198772020) -->
+    <skip />
+    <!-- no translation found for left_nav_bar_button_type (8555981238887546528) -->
+    <skip />
+    <!-- no translation found for right_nav_bar_button_type (2481056627065649656) -->
+    <skip />
+    <!-- no translation found for nav_bar_default (8587114043070993007) -->
+    <skip />
+    <!-- no translation found for nav_bar_buttons:0 (1545641631806817203) -->
+    <!-- no translation found for nav_bar_buttons:1 (5742013440802239414) -->
+    <!-- no translation found for nav_bar_buttons:2 (1951959982985094069) -->
+    <!-- no translation found for nav_bar_buttons:3 (8175437057325747277) -->
+    <!-- no translation found for nav_bar_layouts:0 (8077901629964902399) -->
+    <!-- no translation found for nav_bar_layouts:1 (8256205964297588988) -->
+    <!-- no translation found for nav_bar_layouts:2 (8719936228094005878) -->
+    <!-- no translation found for nav_bar_layouts:3 (586019486955594690) -->
+    <!-- no translation found for menu_ime (4998010205321292416) -->
+    <skip />
+    <!-- no translation found for save (2311877285724540644) -->
+    <skip />
+    <string name="reset" msgid="2448168080964209908">"ରିସେଟ୍‍ କରନ୍ତୁ"</string>
+    <!-- no translation found for adjust_button_width (6138616087197632947) -->
+    <skip />
+    <!-- no translation found for clipboard (1313879395099896312) -->
+    <skip />
+    <!-- no translation found for accessibility_key (5701989859305675896) -->
+    <skip />
+    <!-- no translation found for left_keycode (2010948862498918135) -->
+    <skip />
+    <!-- no translation found for right_keycode (708447961000848163) -->
+    <skip />
+    <!-- no translation found for left_icon (3096287125959387541) -->
+    <skip />
+    <!-- no translation found for right_icon (3952104823293824311) -->
+    <skip />
+    <!-- no translation found for drag_to_add_tiles (7058945779098711293) -->
+    <skip />
+    <!-- no translation found for drag_to_remove_tiles (3361212377437088062) -->
+    <skip />
+    <!-- no translation found for qs_edit (2232596095725105230) -->
+    <skip />
+    <!-- no translation found for tuner_time (6572217313285536011) -->
+    <skip />
+    <!-- no translation found for clock_options:0 (5965318737560463480) -->
+    <!-- no translation found for clock_options:1 (1427801730816895300) -->
+    <!-- no translation found for clock_options:2 (3830170141562534721) -->
+    <!-- no translation found for battery_options:0 (3160236755818672034) -->
+    <!-- no translation found for battery_options:1 (2139628951880142927) -->
+    <!-- no translation found for battery_options:2 (3327323682209964956) -->
+    <!-- no translation found for other (4060683095962566764) -->
+    <skip />
+    <!-- no translation found for accessibility_divider (5903423481953635044) -->
+    <skip />
+    <!-- no translation found for accessibility_action_divider_left_full (2801570521881574972) -->
+    <skip />
+    <!-- no translation found for accessibility_action_divider_left_70 (3612060638991687254) -->
+    <skip />
+    <!-- no translation found for accessibility_action_divider_left_50 (1248083470322193075) -->
+    <skip />
+    <!-- no translation found for accessibility_action_divider_left_30 (543324403127069386) -->
+    <skip />
+    <!-- no translation found for accessibility_action_divider_right_full (4639381073802030463) -->
+    <skip />
+    <!-- no translation found for accessibility_action_divider_top_full (5357010904067731654) -->
+    <skip />
+    <!-- no translation found for accessibility_action_divider_top_70 (5090779195650364522) -->
+    <skip />
+    <!-- no translation found for accessibility_action_divider_top_50 (6385859741925078668) -->
+    <skip />
+    <!-- no translation found for accessibility_action_divider_top_30 (6201455163864841205) -->
+    <skip />
+    <!-- no translation found for accessibility_action_divider_bottom_full (301433196679548001) -->
+    <skip />
+    <!-- no translation found for accessibility_qs_edit_tile_label (8374924053307764245) -->
+    <skip />
+    <!-- no translation found for accessibility_qs_edit_add_tile_label (8133209638023882667) -->
+    <skip />
+    <!-- no translation found for accessibility_qs_edit_position_label (5055306305919289819) -->
+    <skip />
+    <!-- no translation found for accessibility_qs_edit_move_tile (2461819993780159542) -->
+    <skip />
+    <!-- no translation found for accessibility_qs_edit_remove_tile (7484493384665907197) -->
+    <skip />
+    <!-- no translation found for accessibility_qs_edit_tile_added (8050200862063548309) -->
+    <skip />
+    <!-- no translation found for accessibility_qs_edit_tile_removed (8584304916627913440) -->
+    <skip />
+    <!-- no translation found for accessibility_qs_edit_tile_moved (4343693412689365038) -->
+    <skip />
+    <!-- no translation found for accessibility_desc_quick_settings_edit (8073587401747016103) -->
+    <skip />
+    <!-- no translation found for accessibility_desc_notification_icon (8352414185263916335) -->
+    <skip />
+    <!-- no translation found for dock_forced_resizable (5914261505436217520) -->
+    <skip />
+    <!-- no translation found for dock_non_resizeble_failed_to_dock_text (3871617304250207291) -->
+    <skip />
+    <!-- no translation found for forced_resizable_secondary_display (4230857851756391925) -->
+    <skip />
+    <!-- no translation found for activity_launch_on_secondary_display_failed_text (7793821742158306742) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_settings (6132460890024942157) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_expand (2375165227880477530) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_collapse (1792625797142648105) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_alarm_set (1863000242431528676) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_user (1567445362870421770) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_no_internet (31890692343084075) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_open_details (4230931801728005194) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_open_settings (7806613775728380737) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_edit (7839992848995240393) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_page (5032979051755200721) -->
+    <skip />
+    <!-- no translation found for tuner_lock_screen (5755818559638850294) -->
+    <skip />
+    <!-- no translation found for pip_phone_expand (5889780005575693909) -->
+    <skip />
+    <!-- no translation found for pip_phone_minimize (1079119422589131792) -->
+    <skip />
+    <!-- no translation found for pip_phone_close (8416647892889710330) -->
+    <skip />
+    <!-- no translation found for pip_phone_settings (8080777499521528521) -->
+    <skip />
+    <!-- no translation found for pip_phone_dismiss_hint (6351678169095923899) -->
+    <skip />
+    <!-- no translation found for pip_menu_title (4707292089961887657) -->
+    <skip />
+    <!-- no translation found for pip_notification_title (3204024940158161322) -->
+    <skip />
+    <!-- no translation found for pip_notification_message (5619512781514343311) -->
+    <skip />
+    <!-- no translation found for pip_play (1417176722760265888) -->
+    <skip />
+    <!-- no translation found for pip_pause (8881063404466476571) -->
+    <skip />
+    <!-- no translation found for pip_skip_to_next (1948440006726306284) -->
+    <skip />
+    <!-- no translation found for pip_skip_to_prev (1955311326688637914) -->
+    <skip />
+    <!-- no translation found for thermal_shutdown_title (4458304833443861111) -->
+    <skip />
+    <!-- no translation found for thermal_shutdown_message (9006456746902370523) -->
+    <skip />
+    <!-- no translation found for thermal_shutdown_dialog_message (566347880005304139) -->
+    <skip />
+    <!-- no translation found for high_temp_title (4589508026407318374) -->
+    <skip />
+    <!-- no translation found for high_temp_notif_message (5642466103153429279) -->
+    <skip />
+    <!-- no translation found for high_temp_dialog_message (6840700639374113553) -->
+    <skip />
+    <!-- no translation found for lockscreen_shortcut_left (2182769107618938629) -->
+    <skip />
+    <!-- no translation found for lockscreen_shortcut_right (3328683699505226536) -->
+    <skip />
+    <!-- no translation found for lockscreen_unlock_left (2043092136246951985) -->
+    <skip />
+    <!-- no translation found for lockscreen_unlock_right (1529992940510318775) -->
+    <skip />
+    <!-- no translation found for lockscreen_none (4783896034844841821) -->
+    <skip />
+    <!-- no translation found for tuner_launch_app (1527264114781925348) -->
+    <skip />
+    <!-- no translation found for tuner_other_apps (4726596850501162493) -->
+    <skip />
+    <!-- no translation found for tuner_circle (2340998864056901350) -->
+    <skip />
+    <!-- no translation found for tuner_plus (6792960658533229675) -->
+    <skip />
+    <!-- no translation found for tuner_minus (4806116839519226809) -->
+    <skip />
+    <!-- no translation found for tuner_left (8404287986475034806) -->
+    <skip />
+    <!-- no translation found for tuner_right (6222734772467850156) -->
+    <skip />
+    <!-- no translation found for tuner_menu (191640047241552081) -->
+    <skip />
+    <!-- no translation found for tuner_app (3507057938640108777) -->
+    <skip />
+    <!-- no translation found for notification_channel_alerts (4496839309318519037) -->
+    <skip />
+    <!-- no translation found for notification_channel_battery (5786118169182888462) -->
+    <skip />
+    <!-- no translation found for notification_channel_screenshot (6314080179230000938) -->
+    <skip />
+    <!-- no translation found for notification_channel_general (4525309436693914482) -->
+    <skip />
+    <!-- no translation found for notification_channel_storage (3077205683020695313) -->
+    <skip />
+    <!-- no translation found for instant_apps (6647570248119804907) -->
+    <skip />
+    <!-- no translation found for instant_apps_message (8116608994995104836) -->
+    <skip />
+    <!-- no translation found for app_info (6856026610594615344) -->
+    <skip />
+    <!-- no translation found for go_to_web (2650669128861626071) -->
+    <skip />
+    <!-- no translation found for mobile_data (7094582042819250762) -->
+    <skip />
+    <!-- no translation found for wifi_is_off (1838559392210456893) -->
+    <skip />
+    <!-- no translation found for bt_is_off (2640685272289706392) -->
+    <skip />
+    <!-- no translation found for dnd_is_off (6167780215212497572) -->
+    <skip />
+    <!-- no translation found for qs_dnd_prompt_auto_rule (862559028345233052) -->
+    <skip />
+    <!-- no translation found for qs_dnd_prompt_app (7978037419334156034) -->
+    <skip />
+    <!-- no translation found for qs_dnd_prompt_auto_rule_app (2599343675391111951) -->
+    <skip />
+    <!-- no translation found for qs_dnd_until (3469471136280079874) -->
+    <skip />
+    <!-- no translation found for qs_dnd_keep (1825009164681928736) -->
+    <skip />
+    <!-- no translation found for qs_dnd_replace (8019520786644276623) -->
+    <skip />
+    <!-- no translation found for running_foreground_services_title (381024150898615683) -->
+    <skip />
+    <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
+    <skip />
+    <string name="data_usage_disable_mobile" msgid="5116269981510015864">"ମୋବାଇଲ୍‌ ଡାଟା ଅଫ୍‌ କରିବେ?"</string>
+    <!-- no translation found for touch_filtered_warning (8671693809204767551) -->
+    <skip />
+    <!-- no translation found for slice_permission_title (7465009437851044444) -->
+    <skip />
+    <!-- no translation found for slice_permission_text_1 (3514586565609596523) -->
+    <skip />
+    <!-- no translation found for slice_permission_text_2 (3146758297471143723) -->
+    <skip />
+    <!-- no translation found for slice_permission_checkbox (7986504458640562900) -->
+    <skip />
+    <!-- no translation found for slice_permission_allow (2340244901366722709) -->
+    <skip />
+    <!-- no translation found for slice_permission_deny (7683681514008048807) -->
+    <skip />
+</resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 9308fee..ce35a07 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"ਕੈਮਰਾ ਖੋਲ੍ਹੋ"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"ਨਵਾਂ ਕੰਮ ਲੇਆਉਟ ਚੁਣੋ"</string>
     <string name="cancel" msgid="6442560571259935130">"ਰੱਦ ਕਰੋ"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦਾ ਪ੍ਰਤੀਕ"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"ਐਪਲੀਕੇਸ਼ਨ ਦਾ ਪ੍ਰਤੀਕ"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"ਮਦਦ ਸੁਨੇਹਾ ਖੇਤਰ"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"ਡੈਜ਼ਰਟ ਕੇਸ"</string>
     <string name="start_dreams" msgid="5640361424498338327">"ਸਕ੍ਰੀਨ ਸੇਵਰ"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"ਈਥਰਨੈਟ"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"ਕੇਵਲ ਤਰਜੀਹੀ"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"ਕੇਵਲ ਅਲਾਰਮ"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"ਵਾਈ-ਫਾਈ ਬੰਦ"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"ਵਾਈ-ਫਾਈ ਚਾਲੂ"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"ਕੋਈ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ ਉਪਲਬਧ ਨਹੀਂ"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"ਅਲਾਰਮ"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"ਕਾਸਟ"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"ਕਾਸਟਿੰਗ"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"ਬਿਨਾਂ ਨਾਮ ਦਾ ਡੀਵਾਈਸ"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ਨੂੰ ਸੁਰੱਖਿਅਤ-ਮੋਡ ਵਿੱਚ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ।"</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"ਸਭ ਕਲੀਅਰ ਕਰੋ"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੀ ਵਰਤੋਂ ਕਰਨ ਲਈ ਇੱਥੇ ਘਸੀਟੋ"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"ਐਪਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ਹੌਰੀਜ਼ੌਂਟਲ ਸਪਲਿਟ"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"ਵਰਟੀਕਲ ਸਪਲਿਟ"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"ਵਿਉਂਂਤੀ ਸਪਲਿਟ"</string>
@@ -500,25 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"ਹੁਣੇ ਬੰਦ ਕਰੋ"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"ਵਿਸਤਾਰ ਕਰੋ"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ਨਸ਼ਟ ਕਰੋ"</string>
-    <!-- no translation found for accessibility_output_chooser (8185317493017988680) -->
-    <skip />
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"ਆਊਟਪੁੱਟ ਡੀਵਾਈਸ ਵਰਤੋ"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"ਸਕ੍ਰੀਨ ਪਿੰਨ ਕੀਤੀ"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"ਇਹ ਇਸ ਨੂੰ ਤਦ ਤੱਕ ਦ੍ਰਿਸ਼ ਵਿੱਚ ਰੱਖਦਾ ਹੈ ਜਦ ਤੱਕ ਤੁਸੀਂ ਅਨਪਿੰਨ ਨਹੀਂ ਕਰਦੇ। ਅਨਪਿੰਨ ਕਰਨ ਲਈ \'ਪਿੱਛੇ\' ਅਤੇ \'ਰੂਪ-ਰੇਖਾ\' ਨੂੰ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾ ਕੇ ਰੱਖੋ।"</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਅਨਪਿੰਨ ਨਾ ਕੀਤੇ ਜਾਣ ਤੱਕ ਇਸਨੂੰ ਦਿਖਾਇਆ ਜਾਂਦਾ ਹੈ। ਅਨਪਿੰਨ ਕਰਨ ਲਈ \'ਪਿੱਛੇ\' ਅਤੇ \'ਹੋਮ\' ਨੂੰ ਸਪੱਰਸ਼ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ।"</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"ਇਹ ਇਸ ਨੂੰ ਤਦ ਤੱਕ ਦ੍ਰਿਸ਼ ਵਿੱਚ ਰੱਖਦਾ ਹੈ ਜਦ ਤੱਕ ਤੁਸੀਂ ਅਨਪਿੰਨ ਨਹੀਂ ਕਰਦੇ। ਅਨਪਿੰਨ ਕਰਨ ਲਈ \'ਰੂਪ-ਰੇਖਾ\' ਨੂੰ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾ ਕੇ ਰੱਖੋ।"</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਅਨਪਿੰਨ ਨਾ ਕੀਤੇ ਜਾਣ ਤੱਕ ਇਸਨੂੰ ਦਿਖਾਇਆ ਜਾਂਦਾ ਹੈ। ਅਨਪਿੰਨ ਕਰਨ ਲਈ \'ਹੋਮ\' ਨੂੰ ਸਪੱਰਸ਼ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ।"</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"ਇਸ ਸਕ੍ਰੀਨ ਨੂੰ ਅਨਪਿੰਨ ਕਰਨ ਲਈ, \'ਪਿੱਛੇ\' ਅਤੇ \'ਰੂਪ-ਰੇਖਾ\' ਬਟਨਾਂ ਨੂੰ ਸਪੱਰਸ਼ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ਇਸ ਸਕ੍ਰੀਨ ਨੂੰ ਅਨਪਿੰਨ ਕਰਨ ਲਈ, \'ਪਿੱਛੇ\' ਅਤੇ \'ਹੋਮ\' ਬਟਨਾਂ ਨੂੰ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾਈ ਰੱਖੋ"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"ਸਮਝ ਲਿਆ"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"ਨਹੀਂ ਧੰਨਵਾਦ"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"ਸਕ੍ਰੀਨ ਪਿੰਨ ਕੀਤੀ ਗਈ"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"ਸਕ੍ਰੀਨ ਅਨਪਿੰਨ ਕੀਤੀ ਗਈ"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"ਕੀ <xliff:g id="TILE_LABEL">%1$s</xliff:g> ਨੂੰ ਲੁਕਾਉਣਾ ਹੈ?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"ਇਹ ਅਗਲੀ ਵਾਰ ਮੁੜ ਪ੍ਰਗਟ ਹੋਵੇਗਾ ਜਦੋਂ ਤੁਸੀਂ ਇਸਨੂੰ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਚਾਲੂ ਕਰਦੇ ਹੋ।"</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"ਲੁਕਾਓ"</string>
@@ -541,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s। ਮਿਊਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ। ਪਹੁੰਚਯੋਗਤਾ ਸੇਵਾਵਾਂ ਮਿਊਟ ਹੋ ਸਕਦੀਆਂ ਹਨ।"</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s। ਥਰਥਰਾਹਟ \'ਤੇ ਸੈੱਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s। ਮਿਊਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s ਅਵਾਜ਼ ਕੰਟਰੋਲ ਦਿਖਾਏ ਗਏ ਹਨ। ਖਾਰਜ ਕਰਨ ਲਈ ਉੱਪਰ ਸਵਾਈਪ ਕਰੋ।"</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"ਵੌਲਿਊਮ ਕੰਟਰੋਲ ਲੁਕਾਏ ਗਏ ਹਨ"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s ਵੌਲਿਊਮ ਕੰਟਰੋਲ"</string>
     <string name="output_title" msgid="5355078100792942802">"ਮੀਡੀਆ ਆਊਟਪੁੱਟ"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"ਫ਼ੋਨ ਕਾਲ ਆਊਟਪੁੱਟ"</string>
     <string name="output_none_found" msgid="5544982839808921091">"ਕੋਈ ਡੀਵਾਈਸ ਨਹੀਂ ਮਿਲੇ"</string>
@@ -692,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"ਕਲਿੱਪਬੋਰਡ"</item>
     <item msgid="5742013440802239414">"ਕੀ-ਕੋਡ"</item>
-    <item msgid="8802889973626281575">"ਕੀ-ਬੋਰਡ ਸਵਿੱਚਰ"</item>
-    <item msgid="7095517796293767867">"ਘੁਮਾਅ ਸੰਬੰਧੀ ਸੁਝਾਅ"</item>
-    <item msgid="8494159969042135235">"ਕੋਈ ਨਹੀਂ"</item>
+    <item msgid="1951959982985094069">"ਘੁਮਾਉਣ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ, ਕੀ-ਬੋਰਡ ਸਵਿੱਚਰ"</item>
+    <item msgid="8175437057325747277">"ਕੋਈ ਨਹੀਂ"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"ਸਧਾਰਨ"</item>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index d2a863a..5313c96 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -105,12 +105,11 @@
     <string name="camera_label" msgid="7261107956054836961">"otwórz aparat"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Wybierz nowy układ zadań"</string>
     <string name="cancel" msgid="6442560571259935130">"Anuluj"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona odcisku palca"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ikona aplikacji"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Obszar komunikatu pomocy"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Przycisk powiększenia na potrzeby zgodności."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Powiększa mniejszy ekran do większego."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth połączony."</string>
@@ -279,6 +278,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Półka ze słodkościami"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Wygaszacz ekranu"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Nie przeszkadzać"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Tylko priorytetowe"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Tylko alarmy"</string>
@@ -315,6 +316,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi wyłączone"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi wł."</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Brak dostępnych sieci Wi-Fi"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarm"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Przesyłanie"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Przesyłam"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Urządzenie bez nazwy"</string>
@@ -331,9 +333,13 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Łączę..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Powiązanie"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Włączam…"</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="few">%d urządzenia</item>
+      <item quantity="many">%d urządzeń</item>
+      <item quantity="other">%d urządzenia</item>
+      <item quantity="one">%d urządzenie</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Powiadomienia"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Latarka"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobilna transmisja danych"</string>
@@ -343,10 +349,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Wykorzystano <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Limit <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Ostrzeżenie: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Profil służbowy"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Powiadomienia i aplikacje są wyłączone"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Podświetlenie nocne"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Włącz o zachodzie"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Do wschodu słońca"</string>
@@ -364,8 +368,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplikacja <xliff:g id="APP">%s</xliff:g> została wyłączona w trybie bezpiecznym."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Wyczyść wszystko"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Przeciągnij tutaj, by podzielić ekran"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Podziel poziomo"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Podziel pionowo"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Podziel niestandardowo"</string>
@@ -454,7 +456,7 @@
     <string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8973606847896650284">"Organizacja <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> może monitorować ruch w sieci w Twoim profilu do pracy"</string>
     <string name="quick_settings_disclosure_monitoring" msgid="679658227269205728">"Sieć może być monitorowana"</string>
     <string name="quick_settings_disclosure_vpns" msgid="8170318392053156330">"Urządzenie połączone z sieciami VPN"</string>
-    <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="3494535754792751741">"Profil do pracy połączony z aplikacją <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="3494535754792751741">"Profil służbowy połączony z aplikacją <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="4467456202486569906">"Profil osobisty połączony z aplikacją <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="6943724064780847080">"Urządzenie połączone z aplikacją <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="1652495295941959815">"Zarządzanie urządzeniami"</string>
@@ -474,7 +476,7 @@
     <string name="monitoring_description_management_network_logging" msgid="7184005419733060736">"Administrator włączył rejestrowanie sieciowe, które pozwala monitorować ruch na Twoim urządzeniu."</string>
     <string name="monitoring_description_named_vpn" msgid="7403457334088909254">"Łączysz się z aplikacją <xliff:g id="VPN_APP">%1$s</xliff:g>, która może monitorować Twoją aktywność w sieci, w tym e-maile, aplikacje i strony internetowe."</string>
     <string name="monitoring_description_two_named_vpns" msgid="4198511413729213802">"Łączysz się z aplikacjami <xliff:g id="VPN_APP_0">%1$s</xliff:g> i <xliff:g id="VPN_APP_1">%2$s</xliff:g>, które mogą monitorować Twoją aktywność w sieci, w tym e-maile, aplikacje i strony internetowe."</string>
-    <string name="monitoring_description_managed_profile_named_vpn" msgid="1427905889862420559">"Twój profil do pracy jest połączony z aplikacją <xliff:g id="VPN_APP">%1$s</xliff:g>, która może monitorować Twoją aktywność w sieci, w tym e-maile, aplikacje i strony internetowe."</string>
+    <string name="monitoring_description_managed_profile_named_vpn" msgid="1427905889862420559">"Twój profil służbowy jest połączony z aplikacją <xliff:g id="VPN_APP">%1$s</xliff:g>, która może monitorować Twoją aktywność w sieci, w tym e-maile, aplikacje i strony internetowe."</string>
     <string name="monitoring_description_personal_profile_named_vpn" msgid="3133980926929069283">"Twój profil osobisty jest połączony z aplikacją <xliff:g id="VPN_APP">%1$s</xliff:g>, która może monitorować Twoją aktywność w sieci, w tym e-maile, aplikacje i strony internetowe."</string>
     <string name="monitoring_description_do_header_generic" msgid="96588491028288691">"Twoim urządzeniem zarządza <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g>."</string>
     <string name="monitoring_description_do_header_with_name" msgid="5511133708978206460">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> używa aplikacji <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> do zarządzania Twoim urządzeniem."</string>
@@ -506,11 +508,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Wyłącz teraz"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Rozwiń"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Zwiń"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Przełącz urządzenie wyjściowe"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Ekran jest przypięty"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Ekran będzie widoczny, dopóki go nie odepniesz. Aby to zrobić, kliknij i przytrzymaj Wstecz oraz Przegląd."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Ekran będzie widoczny, dopóki go nie odepniesz. Aby to zrobić, naciśnij i przytrzymaj Wstecz oraz Ekran główny."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Ekran będzie widoczny, dopóki go nie odepniesz. Aby to zrobić, kliknij i przytrzymaj Przegląd."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ekran będzie widoczny, dopóki go nie odepniesz. Aby to zrobić, naciśnij i przytrzymaj Ekran główny."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Aby odpiąć ten ekran, naciśnij i przytrzymaj przyciski Wstecz oraz Przegląd"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Aby odpiąć ten ekran, naciśnij i przytrzymaj przyciski Wstecz oraz Ekran główny"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nie, dziękuję"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Ekran przypięty"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Ekran odpięty"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Ukryć <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Pojawi się ponownie, gdy następnym włączysz go w ustawieniach."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Ukryj"</string>
@@ -533,8 +542,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Kliknij, by wyciszyć. Ułatwienia dostępu mogą być wyciszone."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Kliknij, by włączyć wibracje."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Kliknij, by wyciszyć."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Wyświetlane są elementy sterowania głośnością aplikacji %s. Przesuń palcem, by odrzucić."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Elementy sterowania głośnością ukryte"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Sterowanie głośnością: %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Wyjście multimediów"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Wyjście dla połączeń telefonicznych"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Nie znaleziono urządzeń"</string>
@@ -553,7 +561,7 @@
     <string name="show_demo_mode" msgid="2018336697782464029">"Pokaż tryb demonstracyjny"</string>
     <string name="status_bar_ethernet" msgid="5044290963549500128">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="8536256753575881818">"Alarm"</string>
-    <string name="status_bar_work" msgid="6022553324802866373">"Profil do pracy"</string>
+    <string name="status_bar_work" msgid="6022553324802866373">"Profil służbowy"</string>
     <string name="status_bar_airplane" msgid="7057575501472249002">"Tryb samolotowy"</string>
     <string name="add_tile" msgid="2995389510240786221">"Dodaj nazwę"</string>
     <string name="broadcast_tile" msgid="3894036511763289383">"Rozgłaszana nazwa"</string>
@@ -563,7 +571,7 @@
     <string name="alarm_template_far" msgid="4242179982586714810">"w: <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Szybkie ustawienia, <xliff:g id="TITLE">%s</xliff:g>."</string>
     <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string>
-    <string name="accessibility_managed_profile" msgid="6613641363112584120">"Profil do pracy"</string>
+    <string name="accessibility_managed_profile" msgid="6613641363112584120">"Profil służbowy"</string>
     <string name="tuner_warning_title" msgid="7094689930793031682">"Dobra zabawa, ale nie dla każdego"</string>
     <string name="tuner_warning" msgid="8730648121973575701">"Kalibrator System UI udostępnia dodatkowe sposoby dostrajania i dostosowywania interfejsu Androida. Te eksperymentalne funkcje mogą się zmienić, popsuć lub zniknąć w przyszłych wersjach. Zachowaj ostrożność."</string>
     <string name="tuner_persistent_warning" msgid="8597333795565621795">"Te eksperymentalne funkcje mogą się zmienić, popsuć lub zniknąć w przyszłych wersjach. Zachowaj ostrożność."</string>
@@ -590,8 +598,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Dzięki zaawansowanym ustawieniom możesz określić poziom ważności powiadomień z aplikacji w skali od 0 do 5. \n\n"<b>"Poziom 5"</b>" \n– Pokazuj u góry listy powiadomień \n– Zezwalaj na powiadomienia na pełnym ekranie \n– Zawsze pokazuj podgląd \n\n"<b>"Poziom 4"</b>" \n– Wyłącz powiadomienia na pełnym ekranie \n– Zawsze pokazuj podgląd \n\n"<b>"Poziom 3"</b>" \n– Wyłącz powiadomienia na pełnym ekranie \n– Nigdy nie pokazuj podglądu \n\n"<b>"Poziom 2"</b>" \n– Wyłącz powiadomienia na pełnym ekranie \n– Nigdy nie pokazuj podglądu \n– NIgdy nie powiadamiaj dźwiękiem ani wibracjami \n\n"<b>"Poziom 1"</b>" \n– Wyłącz powiadomienia na pełnym ekranie \n– Nigdy nie pokazuj podglądu \n– NIgdy nie powiadamiaj dźwiękiem ani wibracjami \n– Ukrywaj na ekranie blokady i pasku stanu \n– Pokazuj u dołu listy powiadomień \n\n"<b>"Poziom 0"</b>" \n– Blokuj wszystkie powiadomienia aplikacji"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Powiadomienia"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Te powiadomienia nie będą już wyświetlane"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Zwykle odrzucasz te powiadomienia. \nNadal je pokazywać?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Nadal pokazywać te powiadomienia?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Zatrzymaj powiadomienia"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Pokazuj nadal"</string>
@@ -689,9 +696,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Schowek"</item>
     <item msgid="5742013440802239414">"Klawisz"</item>
-    <item msgid="8802889973626281575">"Przełączanie klawiatury"</item>
-    <item msgid="7095517796293767867">"Sugestia obrotu"</item>
-    <item msgid="8494159969042135235">"Brak"</item>
+    <item msgid="1951959982985094069">"Potwierdzenie obrotu, przełącznik klawiatury"</item>
+    <item msgid="8175437057325747277">"Brak"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normalny"</item>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 982b8b7..29ac90e 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"abrir câmera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Selecionar novo layout da tarefa"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ícone de impressão digital"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ícone do app"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Área da mensagem de ajuda"</string>
@@ -274,6 +276,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Mostruário de sobremesas"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Protetor de tela"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Não perturbe"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Somente prioridade"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Somente alarmes"</string>
@@ -310,8 +314,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi desligado"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi ativado"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Nenhuma rede Wi-Fi disponível"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarme"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Transmitir"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Transmitindo"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Dispositivo sem nome"</string>
@@ -361,7 +364,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"O app <xliff:g id="APP">%s</xliff:g> está desativado no modo de segurança."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Limpar tudo"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Arraste aqui para usar a tela dividida"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Deslize para cima para alternar entre os apps"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisão horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Divisão vertical"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Divisão personalizada"</string>
@@ -505,21 +507,15 @@
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"Alterar dispositivo de saída"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"A tela está fixada"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Ela é mantida à vista até que seja liberada. Toque em Voltar e em Visão geral e mantenha essas opções pressionadas para liberar."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Ela é mantida à vista até que seja liberada. Toque em Voltar e em Início e mantenha essas opções pressionadas para liberar."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Ela é mantida à vista até que seja liberada. Toque em Visão geral e mantenha essa opção pressionada para liberar."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ela é mantida à vista até que seja liberada. Toque em Início e mantenha essa opção pressionada para liberar."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Para liberar esta tela, mantenha os botões Voltar e Visão geral pressionados"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Para liberar essa tela, toque nos botões Voltar e Início e mantenha-os pressionados"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Entendi"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Não, obrigado"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Tela fixada"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Tela liberada"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Esconder <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Ela reaparecerá na próxima vez que você ativá-la nas configurações."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Ocultar"</string>
@@ -542,8 +538,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Toque para silenciar. É possível que os serviços de acessibilidade sejam silenciados."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Toque para configurar para vibrar."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Toque para silenciar."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s controles de volume exibidos. Deslize para cima para dispensar."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Controles de volume ocultos"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Controles de volume %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Saída de mídia"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Saída de chamada telefônica"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Nenhum dispositivo foi encontrado"</string>
@@ -693,9 +688,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Área de transferência"</item>
     <item msgid="5742013440802239414">"Código de tecla"</item>
-    <item msgid="8802889973626281575">"Alternador de teclado"</item>
-    <item msgid="7095517796293767867">"Sugestão de rotação"</item>
-    <item msgid="8494159969042135235">"Nenhum"</item>
+    <item msgid="1951959982985094069">"Gire para confirmar a troca do teclado"</item>
+    <item msgid="8175437057325747277">"Nenhum"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normal"</item>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 2bc1c03..c5c4add 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"abrir câmara"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Selecionar novo esquema de tarefa"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ícone de impressão digital"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ícone de aplicação"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Área da mensagem de ajuda"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Vitrina de sobremesas"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Proteção de ecrã"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Não incomodar"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Apenas prioridade"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Apenas alarmes"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi Desligado"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi ligado"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Não estão disponíveis redes Wi-Fi"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarme"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Transmitir"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Transmissão"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Dispositivo sem nome"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"O <xliff:g id="APP">%s</xliff:g> está desativado no modo de segurança."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Limpar tudo"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Arraste aqui para utilizar o ecrã dividido"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Deslizar rapidamente para cima para mudar de aplicação"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisão horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Divisão vertical"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Divisão personalizada"</string>
@@ -503,21 +505,15 @@
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"Mudar de dispositivo de saída"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"O ecrã está fixado"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Esta opção mantém o item visível até o soltar. Toque sem soltar em Anterior e em Vista geral para soltar."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Esta opção mantém o item visível até o soltar. Toque sem soltar em Anterior e em Página inicial para soltar."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Esta opção mantém o item visível até o soltar. Toque sem soltar em Vista geral para soltar."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Esta opção mantém o item visível até o soltar. Toque sem soltar em Página inicial para soltar."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Para soltar este ecrã, toque sem soltar nos botões Anterior e Vista geral."</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Para soltar este ecrã, toque sem soltar nos botões Anterior e Página inicial."</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Compreendi"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Não, obrigado"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Ecrã fixo"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Ecrã solto"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Pretende ocultar <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Reaparecerá da próxima vez que a funcionalidade for ativada nas definições."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Ocultar"</string>
@@ -540,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Toque para desativar o som. Os serviços de acessibilidade podem ser silenciados."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Toque para ativar a vibração."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Toque para desativar o som."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Controlos de volume %s apresentados. Deslize rapidamente para cima para ignorar."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Controles de volume ocultados"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Controlos de volume de %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Saída de som multimédia"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Saída de som de chamada telefónica"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Nenhum dispositivo encontrado."</string>
@@ -691,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Área de transferência"</item>
     <item msgid="5742013440802239414">"Código de tecla"</item>
-    <item msgid="8802889973626281575">"Comutador de teclado"</item>
-    <item msgid="7095517796293767867">"Sugestão de rotação"</item>
-    <item msgid="8494159969042135235">"Nenhum"</item>
+    <item msgid="1951959982985094069">"Confirmar ao rodar, comutador de teclado"</item>
+    <item msgid="8175437057325747277">"Nenhum"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normal"</item>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 982b8b7..29ac90e 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"abrir câmera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Selecionar novo layout da tarefa"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ícone de impressão digital"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ícone do app"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Área da mensagem de ajuda"</string>
@@ -274,6 +276,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Mostruário de sobremesas"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Protetor de tela"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Não perturbe"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Somente prioridade"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Somente alarmes"</string>
@@ -310,8 +314,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi desligado"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi ativado"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Nenhuma rede Wi-Fi disponível"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarme"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Transmitir"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Transmitindo"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Dispositivo sem nome"</string>
@@ -361,7 +364,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"O app <xliff:g id="APP">%s</xliff:g> está desativado no modo de segurança."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Limpar tudo"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Arraste aqui para usar a tela dividida"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Deslize para cima para alternar entre os apps"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisão horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Divisão vertical"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Divisão personalizada"</string>
@@ -505,21 +507,15 @@
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"Alterar dispositivo de saída"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"A tela está fixada"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Ela é mantida à vista até que seja liberada. Toque em Voltar e em Visão geral e mantenha essas opções pressionadas para liberar."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Ela é mantida à vista até que seja liberada. Toque em Voltar e em Início e mantenha essas opções pressionadas para liberar."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Ela é mantida à vista até que seja liberada. Toque em Visão geral e mantenha essa opção pressionada para liberar."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ela é mantida à vista até que seja liberada. Toque em Início e mantenha essa opção pressionada para liberar."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Para liberar esta tela, mantenha os botões Voltar e Visão geral pressionados"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Para liberar essa tela, toque nos botões Voltar e Início e mantenha-os pressionados"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Entendi"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Não, obrigado"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Tela fixada"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Tela liberada"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Esconder <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Ela reaparecerá na próxima vez que você ativá-la nas configurações."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Ocultar"</string>
@@ -542,8 +538,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Toque para silenciar. É possível que os serviços de acessibilidade sejam silenciados."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Toque para configurar para vibrar."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Toque para silenciar."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s controles de volume exibidos. Deslize para cima para dispensar."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Controles de volume ocultos"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Controles de volume %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Saída de mídia"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Saída de chamada telefônica"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Nenhum dispositivo foi encontrado"</string>
@@ -693,9 +688,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Área de transferência"</item>
     <item msgid="5742013440802239414">"Código de tecla"</item>
-    <item msgid="8802889973626281575">"Alternador de teclado"</item>
-    <item msgid="7095517796293767867">"Sugestão de rotação"</item>
-    <item msgid="8494159969042135235">"Nenhum"</item>
+    <item msgid="1951959982985094069">"Gire para confirmar a troca do teclado"</item>
+    <item msgid="8175437057325747277">"Nenhum"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normal"</item>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index d765282..7753e11 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -104,6 +104,8 @@
     <string name="camera_label" msgid="7261107956054836961">"deschideți camera foto"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Selectați noul aspect pentru activitate"</string>
     <string name="cancel" msgid="6442560571259935130">"Anulați"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Pictograma amprentă"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Pictograma aplicației"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Zona mesajelor de ajutor"</string>
@@ -276,6 +278,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Vitrina cu dulciuri"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Economizor de ecran"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Nu deranja"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Numai cu prioritate"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Numai alarme"</string>
@@ -312,8 +316,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi deconectat"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi activat"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Nicio rețea Wi-Fi disponibilă"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarmă"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Proiectați"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Se proiectează"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Dispozitiv nedenumit"</string>
@@ -364,7 +367,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplicația <xliff:g id="APP">%s</xliff:g> este dezactivată în modul sigur."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Ștergeți tot"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Trageți aici pentru a folosi ecranul împărțit"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Glisați în sus pentru a comuta între aplicații"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divizare pe orizontală"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Divizare pe verticală"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Divizare personalizată"</string>
@@ -508,21 +510,15 @@
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"Comutați dispozitivul de ieșire"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Ecranul este fixat"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Astfel rămâne afișat până anulați fixarea. Atingeți lung opțiunile Înapoi și Recente pentru a anula fixarea."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Astfel rămâne afișat până anulați fixarea. Atingeți lung opțiunile Înapoi și Acasă pentru a anula fixarea."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Astfel rămâne afișat până anulați fixarea. Atingeți lung opțiunea Recente pentru a anula fixarea."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Astfel rămâne afișat până anulați fixarea. Atingeți lung opțiunea Acasă pentru a anula fixarea."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Pentru a anula fixarea acestui ecran, atingeți lung butoanele Înapoi și Recente"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Pentru a anula fixarea acestui ecran, atingeți lung butoanele Înapoi și Acasă"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Am înțeles"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nu, mulțumesc"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Ecran fixat"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Fixarea ecranului anulată"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Ascundeți <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Va reapărea la următoarea activare în setări."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Ascundeți"</string>
@@ -545,8 +541,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Atingeți pentru a dezactiva sunetul. Sunetul se poate dezactiva pentru serviciile de accesibilitate."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Atingeți pentru a seta pe vibrații."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Atingeți pentru a dezactiva sunetul."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Comenzile de volum pentru %s sunt afișate. Glisați pentru a închide."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Comenzile de volum sunt ascunse"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Comenzi de volum pentru %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Ieșire media"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Ieșire apel telefonic"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Nu s-a găsit niciun dispozitiv"</string>
@@ -698,9 +693,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Clipboard"</item>
     <item msgid="5742013440802239414">"Cod de tastă"</item>
-    <item msgid="8802889973626281575">"Comutator tastatură"</item>
-    <item msgid="7095517796293767867">"Sugestie de rotire"</item>
-    <item msgid="8494159969042135235">"Niciunul"</item>
+    <item msgid="1951959982985094069">"Confirmați rotirea, comutator de la tastatură"</item>
+    <item msgid="8175437057325747277">"Niciunul"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normal"</item>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 9cd9082..abeaf22 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -87,7 +87,7 @@
     <string name="use_ptp_button_title" msgid="7517127540301625751">"Установить как камеру (PTP)"</string>
     <string name="installer_cd_button_title" msgid="2312667578562201583">"Установить приложение"</string>
     <string name="accessibility_back" msgid="567011538994429120">"Назад"</string>
-    <string name="accessibility_home" msgid="8217216074895377641">"Домой"</string>
+    <string name="accessibility_home" msgid="8217216074895377641">"Главный экран"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Меню"</string>
     <string name="accessibility_accessibility_button" msgid="7601252764577607915">"Специальные возможности"</string>
     <string name="accessibility_rotate_button" msgid="7402949513740253006">"Поворот экрана"</string>
@@ -105,6 +105,8 @@
     <string name="camera_label" msgid="7261107956054836961">"Открыть камеру."</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Выберите другой макет"</string>
     <string name="cancel" msgid="6442560571259935130">"Отмена"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Значок отпечатка пальца"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Значок приложения"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Справочное сообщение"</string>
@@ -278,6 +280,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Коробка со сладостями"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Заставка"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Не беспокоить"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Только важные"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Только будильник"</string>
@@ -314,8 +318,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi выкл."</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi включен"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Не удалось найти доступные сети Wi-Fi"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Будильник"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Трансляция"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Передача изображения"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Безымянное устройство"</string>
@@ -367,7 +370,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Приложение \"<xliff:g id="APP">%s</xliff:g>\" отключено в безопасном режиме."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Очистить все"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Перетащите сюда, чтобы разделить экран"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Чтобы переключиться между приложениями, проведите по экрану вверх."</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Разделить по горизонтали"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Разделить по вертикали"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Разделить по-другому"</string>
@@ -511,21 +513,15 @@
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"Сменить устройство аудиовыхода"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Блокировка в приложении включена"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Приложение останется активным, пока вы не отмените блокировку, нажав и удерживая кнопки \"Назад\" и \"Обзор\"."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Приложение останется активным, пока вы не отмените блокировку, нажав и удерживая кнопки \"Назад\" и \"Главный экран\"."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Приложение останется активным, пока вы не отмените блокировку, нажав и удерживая кнопку \"Обзор\"."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Приложение останется активным, пока вы не отмените блокировку, нажав и удерживая кнопку \"Главный экран\"."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Чтобы отменить блокировку, нажмите и удерживайте кнопки \"Назад\" и \"Обзор\""</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Чтобы отменить блокировку, нажмите и удерживайте кнопки \"Назад\" и \"Главный экран\""</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"ОК"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Нет, спасибо"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Блокировка включена"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Блокировка выключена"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Скрыть параметр \"<xliff:g id="TILE_LABEL">%1$s</xliff:g>\"?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Этот параметр появится в следующий раз, когда вы включите его."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Скрыть"</string>
@@ -548,8 +544,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Нажмите, чтобы выключить звук. Специальные возможности могут прекратить работу."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Нажмите, чтобы включить вибрацию."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Нажмите, чтобы выключить звук."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Показаны регуляторы громкости: %s. Проведите вверх, чтобы скрыть."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Регуляторы громкости скрыты"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s: регулировка громкости"</string>
     <string name="output_title" msgid="5355078100792942802">"Выход мультимедиа"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Выход телефонных вызовов"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Устройств не найдено"</string>
@@ -703,9 +698,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Буфер обмена"</item>
     <item msgid="5742013440802239414">"Код клавиши"</item>
-    <item msgid="8802889973626281575">"Переключение раскладки"</item>
-    <item msgid="7095517796293767867">"Поворот"</item>
-    <item msgid="8494159969042135235">"Нет"</item>
+    <item msgid="1951959982985094069">"Подтвердить поворот, переключить раскладку"</item>
+    <item msgid="8175437057325747277">"Нет"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Обычная"</item>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index b041d48..effcac4 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"කැමරාව විවෘත කරන්න"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"නව කාර්යය සැකැස්ම තෝරන්න"</string>
     <string name="cancel" msgid="6442560571259935130">"අවලංගු කරන්න"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ඇඟිලි සලකුණු නිරූපකය"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"යෙදුම් නිරූපකය"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"උදවු පණිවිඩ ප්‍රදේශය"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"අතුරුපස අවස්තාව"</string>
     <string name="start_dreams" msgid="5640361424498338327">"තිර සුරැකුම"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"ඊතර නෙට්"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"බාධා නොකරන්න"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"ප්‍රමුඛතාව පමණයි"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"එලාම පමණි"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi අක්‍රියයි"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi ක්‍රියාත්මකයි"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Wi-Fi ජාල ලබා ගත නොහැකිය"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"එලාමය"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"කාස්ට් කිරීම"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"නම් නොකළ උපාංගය"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ආරක්ෂිත ප්‍රකාරය තුළ අබලයි."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"සියල්ල හිස් කරන්න"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"බෙදුම් තිරය භාවිත කිරීමට මෙතැනට අදින්න"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"යෙදුම් මාරු කිරීමට ස්වයිප් කරන්න"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"තිරස්ව වෙන් කරන්න"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"සිරස්ව වෙන් කරන්න"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"අභිමත ලෙස වෙන් කරන්න"</string>
@@ -503,21 +505,15 @@
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"ප්‍රතිදාන උපාංගය මාරු කරන්න"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"තීරය අමුණන ලදි"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"මෙය ඔබ ගලවන තෙක් එය දසුන තුළ තබයි. ගැලවීමට දළ විශ්ලේෂණය ස්පර්ශ කර ආපසු අල්ලාගෙන සිටින්න."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"මෙය ඔබ ගලවන තෙක් එය දසුන තුළ තබයි. ගැලවීමට මුල් පිටුව ස්පර්ශ කර අල්ලාගෙන සිටින්න."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"මෙය ඔබ ගලවන තෙක් එය දසුන තුළ තබයි. ගැලවීමට දළ විශ්ලේෂණය ස්පර්ශ කර අල්ලාගෙන සිටින්න."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"මෙය ඔබ ගලවන තෙක් එය දසුන තුළ තබයි. ගැලවීමට මුල් පිටුව ස්පර්ශ කර අල්ලාගෙන සිටින්න."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"මෙම තිර ඇමුණුම ගැලවීමට, දළ විශ්ලේෂණය බොත්තම් ස්පර්ශ කර අල්ලා ගෙන සිටින්න"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"මෙම තිරය ඇමුණුම ගැලවීමට, මුල් පිටුව බොත්තම් ස්පර්ශ කර අල්ලා ගෙන සිටින්න"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"හරි, තේරුණා"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"එපා ස්තූතියි"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"තිරය අමුණා ඇත"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"තිරයේ ගලවා ඇත"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> සඟවන්නද?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"ඊළඟ අවස්ථාවේ සැකසීම් තුළ ඔබ එය සක්‍රිය කළ විට එය නැවත දිසිවේ."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"සඟවන්න"</string>
@@ -540,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. නිහඬ කිරීමට තට්ටු කරන්න. ප්‍රවේශ්‍යතා සේවා නිහඬ කළ හැකිය."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. කම්පනය කිරීමට සකස් කිරීමට තට්ටු කරන්න."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. නිහඬ කිරීමට තට්ටු කරන්න."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s හඬ පරිමා පාලන පෙන්වයි. ඉවත දැමීමට ස්වයිප් කරන්න."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"හඩ පරිමා පාලන සඟවා ඇත"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"හඬ පරිමා පාලන %s"</string>
     <string name="output_title" msgid="5355078100792942802">"මාධ්‍ය ප්‍රතිදානය"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"දුරකථන ඇමතුම් ප්‍රතිදානය"</string>
     <string name="output_none_found" msgid="5544982839808921091">"උපාංග හමු නොවිණි"</string>
@@ -691,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"පසුරු පුවරුව"</item>
     <item msgid="5742013440802239414">"යතුරු කේතය"</item>
-    <item msgid="8802889973626281575">"යතුරු පුවරු මාරුව"</item>
-    <item msgid="7095517796293767867">"කැරකීමේ යෝජනාව"</item>
-    <item msgid="8494159969042135235">"කිසිවක් නැත"</item>
+    <item msgid="1951959982985094069">"තහවුරු කිරීම කරකවන්න, යතුරු පුවරු මාරුව"</item>
+    <item msgid="8175437057325747277">"කිසිවක් නැත"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"සාමාන්‍ය"</item>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index e9b4e9f..3a0a331 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -105,12 +105,10 @@
     <string name="camera_label" msgid="7261107956054836961">"spustiť fotoaparát"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Vyberte nové rozloženie úlohy"</string>
     <string name="cancel" msgid="6442560571259935130">"Zrušiť"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Klepnite na senzor odtlačkov prstov"</string>
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona odtlačku prsta"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ikona aplikácie"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Oblasť chybového hlásenia"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Tlačidlo úpravy veľkosti z dôvodu kompatibility."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zväčšiť menší obrázok na väčšiu obrazovku."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth pripojené."</string>
@@ -281,6 +279,7 @@
     <string name="dessert_case" msgid="1295161776223959221">"Pult s dezertami"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Šetrič obrazovky"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <string name="quick_settings_header_onboarding_text" msgid="7872508260264044734">"Pridržaním ikon zobrazíte ďalšie možnosti"</string>
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Nerušiť"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Iba prioritné"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Iba budíky"</string>
@@ -317,6 +316,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Sieť Wi‑Fi je vypnutá"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi‑Fi je zapnuté"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"K dispozícii nie sú žiadne siete Wi‑Fi"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Budík"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Prenos"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Prenáša sa"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Nepomenované zariadenie"</string>
@@ -333,9 +333,13 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Pripája sa..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Zdieľané pripojenie"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Zapína sa..."</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="few">%d zariadenia</item>
+      <item quantity="many">%d zariadenia</item>
+      <item quantity="other">%d zariadení</item>
+      <item quantity="one">%d zariadenie</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Upozornenia"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Baterka"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobilné dáta"</string>
@@ -345,10 +349,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Využité: <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Limit: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Upozornenie pri <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Pracovný profil"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Upozornenia a aplikácie sú vypnuté"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Nočný režim"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Zapne sa pri západe slnka"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Do východu slnka"</string>
@@ -366,8 +368,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplikácia <xliff:g id="APP">%s</xliff:g> je v núdzovom režime zakázaná."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Vymazať všetko"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Presuňte okno sem a použite tak rozdelenú obrazovku"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Rozdeliť vodorovné"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Rozdeliť zvislé"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Rozdeliť vlastné"</string>
@@ -508,11 +508,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Vypnúť"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Rozbaliť"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Zbaliť"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Prepnúť výstupné zariadenie"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Obrazovka je pripnutá"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Obsah bude pripnutý v zobrazení, dokým ho neuvoľníte. Uvoľníte ho stlačením a podržaním tlačidiel Späť a Prehľad."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Obsah bude pripnutý v zobrazení, dokým ho neuvoľníte. Uvoľníte ho pridržaním tlačidiel Späť a Domov."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Obsah bude pripnutý v zobrazení, dokým ho neuvoľníte. Uvoľníte ho stlačením a podržaním tlačidla Prehľad."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Obsah bude pripnutý v zobrazení, dokým ho neuvoľníte. Uvoľníte ho pridržaním tlačidla Domov."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Ak chcete odopnúť túto obrazovku, pridržte tlačidlá Späť a Prehľad"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Ak chcete odopnúť túto obrazovku, pridržte tlačidlá Späť a Prehľad"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Dobre"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nie, vďaka"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Obrazovka bola pripnutá"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Obrazovka bola odopnutá"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Skryť <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Táto položka sa znova zobrazí, keď ju v nastaveniach opätovne zapnete."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Skryť"</string>
@@ -535,8 +542,13 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Klepnutím vypnite zvuk. Služby dostupnosti je možné stlmiť."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Klepnutím nastavíte vibrovanie."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Klepnutím vypnete zvuk."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Zobrazujú sa ovládacie prvky hlasitosti zariadenia %s. Prejdením prstom nahor to odmietnete."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Ovládacie prvky hlasitosti sú skryté"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Ovládacie prvky hlasitosti %s"</string>
+    <!-- no translation found for volume_dialog_ringer_guidance_vibrate (8902050240801159042) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_silent (2128975224280276122) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_ring (6144469689490528338) -->
+    <skip />
     <string name="output_title" msgid="5355078100792942802">"Výstup médií"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Výstup telefonického hovoru"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Nenašli sa žiadne zariadenia"</string>
@@ -592,8 +604,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Pomocou ovládacích prvkov zobrazovania upozornení môžete nastaviť pre upozornenia aplikácie úroveň dôležitosti od 0 do 5. \n\n"<b>"Úroveň 5"</b>" \n– Zobrazovať v hornej časti zoznamu upozornení. \n– Povoliť prerušenia na celú obrazovku. \n– Vždy zobrazovať čiastočne. \n\n"<b>"Úroveň 4"</b>" \n– Zabrániť prerušeniam na celú obrazovku. \n– Vždy zobrazovať čiastočne. \n\n"<b>"Úroveň 3"</b>" \n– Zabrániť prerušeniam na celú obrazovku. \n– Nikdy nezobrazovať čiastočne. \n\n"<b>"Úroveň 2"</b>" \n– Zabrániť prerušeniam na celú obrazovku. \n– Nikdy nezobrazovať čiastočne. \n– Nikdy nespúšťať zvuk ani vibrácie. \n\n"<b>"Úroveň 1"</b>" \n– Zabrániť prerušeniam na celú obrazovku. \n– Nikdy nezobrazovať čiastočne. \n– Nikdy nespúšťať zvuk ani vibrácie. \n– Skryť na uzamknutej obrazovke a v stavovom riadku. \n– Zobraziť v dolnej časti zoznamu upozornení. \n\n"<b>"Úroveň 0"</b>" \n– Blokovať všetky upozornenia z aplikácie."</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Upozornenia"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Tieto upozornenia sa už nebudú zobrazovať"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Tieto upozornenia zvyčajne odmietate. \nChcete ich naďalej zobrazovať?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Majú sa tieto upozornenia naďalej zobrazovať?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Prestať zobrazovať upozornenia"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Naďalej zobrazovať"</string>
@@ -691,9 +702,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Schránka"</item>
     <item msgid="5742013440802239414">"Kód klávesnice"</item>
-    <item msgid="8802889973626281575">"Prepínač klávesnice"</item>
-    <item msgid="7095517796293767867">"Návrh otáčania"</item>
-    <item msgid="8494159969042135235">"Žiadne"</item>
+    <item msgid="1951959982985094069">"Potvrdenie otočenia, prepínač klávesnice"</item>
+    <item msgid="8175437057325747277">"Žiadne"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Štandardná"</item>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 65164cc..40b7539 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -105,12 +105,11 @@
     <string name="camera_label" msgid="7261107956054836961">"odpri fotoaparat"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Izberite novo postavitev opravil"</string>
     <string name="cancel" msgid="6442560571259935130">"Prekliči"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona prstnih odtisov"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ikona aplikacije"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Območje sporočila pomoči"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Gumb povečave za združljivost."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Povečava manjšega na večji zaslon."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Povezava Bluetooth vzpostavljena."</string>
@@ -281,6 +280,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Vitrina za sladice"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Ohranjeval. zaslona"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Ne moti"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Samo prednostno"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Samo alarmi"</string>
@@ -317,6 +318,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi izklopljen"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi je vklopljen."</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Na voljo ni nobeno omrežje Wi-Fi"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarm"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Predvajanje"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Predvajanje"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Neimenovana naprava"</string>
@@ -333,9 +335,13 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Vzpostavljanje povezave ..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Internet prek mobilne naprave"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Dostopna točka"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Vklapljanje …"</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="one">%d naprava</item>
+      <item quantity="two">%d napravi</item>
+      <item quantity="few">%d naprave</item>
+      <item quantity="other">%d naprav</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Obvestila"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Svetilka"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Prenos podatkov v mobilnem omrežju"</string>
@@ -345,10 +351,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Porabljeno: <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Omejitev: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Opozorilo – <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Delovni profil"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Obvestila in aplikacije so izklopljeni"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Nočna svetloba"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Ob sončnem zahodu"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Do sončnega vzhoda"</string>
@@ -366,8 +370,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplikacija <xliff:g id="APP">%s</xliff:g> je v varnem načinu onemogočena."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Izbriši vse"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Povlecite sem za razdeljeni zaslon"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Razdeli vodoravno"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Razdeli navpično"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Razdeli po meri"</string>
@@ -508,11 +510,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Izklopi"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Razširi"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Strni"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Izbira druge izhodne naprave"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Zaslon je pripet"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"S tem ostane zaslon viden, dokler ga ne odpnete. Če ga želite odpeti, hkrati pridržite gumba za nazaj in pregled."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"S tem ostane zaslon viden, dokler ga ne odpnete. Če ga želite odpeti, hkrati pridržite gumba za nazaj in za začetni zaslon."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"S tem ostane zaslon viden, dokler ga ne odpnete. Če ga želite odpeti, pridržite gumb za pregled."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"S tem ostane zaslon viden, dokler ga ne odpnete. Če ga želite odpeti, pridržite gumb za začetni zaslon."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Če želite odpeti ta zaslon, hkrati pridržite gumba za nazaj in za pregled."</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Če želite odpeti ta zaslon, hkrati pridržite gumba za nazaj in za začetni zaslon."</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Razumem"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Ne, hvala"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Zaslon je pripet"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Zaslon je odpet"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Želite skriti <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Znova se bo pojavila, ko jo naslednjič vklopite v nastavitvah."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Skrij"</string>
@@ -535,8 +544,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Dotaknite se, če želite izklopiti zvok. V storitvah za ljudi s posebnimi potrebami bo morda izklopljen zvok."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Dotaknite se, če želite nastaviti vibriranje."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Dotaknite se, če želite izklopiti zvok."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Prikazani so ti kontrolniki za glasnost: %s. Povlecite navzgor za opustitev."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Kontrolniki za glasnost so skriti."</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Kontrolniki glasnosti za %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Izhod predstavnosti"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Izhod telefonskih klicev"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Ni naprav"</string>
@@ -592,8 +600,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"S kontrolniki za pomebnost obvestila je mogoče za obvestila aplikacije nastaviti stopnjo pomembnosti od 0 do 5. \n\n"<b>"Stopnja 5"</b>" \n– Prikaz na vrhu seznama obvestil \n– Omogočanje prekinitev v celozaslonskem načinu \n– Vedno prikaži hitre predoglede \n\n"<b>"Stopnja 4"</b>" \n– Preprečevanje prekinitev v celozaslonskem načinu \n– Vedno prikaži hitre predoglede \n\n"<b>"Stopnja 3"</b>" \n– Preprečevanje prekinitev v celozaslonskem načinu \n– Nikoli ne prikaži hitrih predogledov \n\n"<b>"Stopnja 2"</b>" \n– Preprečevanje prekinitev v celozaslonskem načinu \n– Nikoli ne prikaži hitrih predogledov \n– Nikoli ne uporabi zvoka in vibriranja \n\n"<b>"Stopnja 1"</b>" \n– Preprečevanje prekinitev v celozaslonskem načinu \n– Nikoli ne prikaži hitrih predogledov \n– Nikoli ne uporabi zvoka in vibriranja \n– Skrivanje na zaklenjenem zaslonu in v vrstici stanja \n– Prikaz na dnu seznama obvestil \n\n"<b>"Stopnja 0"</b>" \n– Blokiranje vseh obvestil aplikacije"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Obvestila"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Ta obvestila ne bodo več prikazana"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Ta obvestila običajno opustite. \nAli želite, da se še naprej prikazujejo?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Želite, da so ta obvestila še naprej prikazana?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Ustavi prikazovanje obvestil"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Prikazuj še naprej"</string>
@@ -691,9 +698,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Odložišče"</item>
     <item msgid="5742013440802239414">"Koda tipke"</item>
-    <item msgid="8802889973626281575">"Preklopnik tipkovnice"</item>
-    <item msgid="7095517796293767867">"Predlog za vrtenje"</item>
-    <item msgid="8494159969042135235">"Brez"</item>
+    <item msgid="1951959982985094069">"Potrditev vrtenja, preklopnik tipkovnice"</item>
+    <item msgid="8175437057325747277">"Brez"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Običajna"</item>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 7634902..24c3538 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"hap kamerën"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Zgjidh strukturën e re të detyrës"</string>
     <string name="cancel" msgid="6442560571259935130">"Anulo"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona e gjurmës së gishtit"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ikona e aplikacionit"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Zona e mesazhit të ndihmës"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Butoni i zmadhimit të pajtueshmërisë."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zmadho nga një ekran i vogël në të madh."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Pajisja është lidhur me \"bluetooth\"."</string>
@@ -275,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"\"Kutia e ëmbëlsirës\""</string>
     <string name="start_dreams" msgid="5640361424498338327">"Mbrojtësi i ekranit"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Eternet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Mos shqetëso"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Vetëm me prioritet"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Vetëm alarmet"</string>
@@ -311,6 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi është i çaktivizuar"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi i aktivizuar"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Nuk ka rrjete Wi-Fi të disponueshme"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarmi"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Transmeto"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Po transmeton"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Pajisje e paemërtuar"</string>
@@ -327,9 +329,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Po lidhet..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Lidhje çiftimi"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Qasje në zona publike interneti"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Po aktivizon..."</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="other">%d pajisje</item>
+      <item quantity="one">%d pajisje</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Njoftimet"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Elektriku"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Të dhënat celulare"</string>
@@ -358,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> është i çaktivizuar në modalitetin e sigurt."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Pastroji të gjitha"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Zvarrit këtu për të përdorur ekranin e ndarë"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Rrëshqit shpejt lart për të ndërruar aplikacionet"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Ndaje horizontalisht"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Ndaj vertikalisht"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Ndaj të personalizuarën"</string>
@@ -499,11 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Çaktivizoje tani"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Zgjeroje"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Mbylle"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Ndërro pajisjen e daljes"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Ekrani u gozhdua"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Kjo e ruan në pamje deri sa ta heqësh nga gozhdimi. Prek dhe mbaj të shtypur \"Prapa\" dhe \"Përmbledhje\" për ta hequr nga gozhdimi."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Kjo e ruan në pamje deri sa ta heqësh nga gozhdimi. Prek dhe mbaj të shtypur \"Prapa\" dhe \"Kreu\" për ta hequr nga gozhdimi."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Kjo e ruan në pamje deri sa ta heqësh nga gozhdimi. Prek dhe mbaj të shtypur \"Përmbledhje\" për ta hequr nga gozhdimi."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Kjo e ruan në pamje deri sa ta heqësh nga gozhdimi. Prek dhe mbaj të shtypur \"Kreu\" për ta hequr nga gozhdimi."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Për të hequr gozhdimin e këtij ekrani, prek dhe mbaj butonat \"Prapa\" dhe \"Përmbledhja\"."</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Për të hequr gozhdimin e këtij ekrani, prek dhe mbaj butonat \"Prapa\" dhe \"Kreu\"."</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"E kuptova!"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Jo, faleminderit!"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Ekrani u gozhdua"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Ekrani u hoq nga gozhdimi"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Të fshihet <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Do të rishfaqet herën tjetër kur ta aktivizoni te cilësimet."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Fshih"</string>
@@ -526,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Trokit për të çaktivizuar. Shërbimet e qasshmërisë mund të çaktivizohen."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Trokit për ta vendosur në dridhje."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Trokit për ta çaktivizuar."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Tregohen %s kontrolle volumi. Rrëshqit lart për ta larguar."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Kontrollet e volumit janë fshehur"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Kontrollet e volumit %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Dalja e pajisjes"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Dalja e telefonatës"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Nuk u gjet asnjë pajisje"</string>
@@ -583,8 +592,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Me kontrollet e njoftimit të energjisë, mund të caktosh një nivel rëndësie nga 0 në 5 për njoftimet e një aplikacioni. \n\n"<b>"Niveli 5"</b>" \n- Shfaq në krye të listës së njoftimeve \n- Lejo ndërprerjen e ekranit të plotë \n- Gjithmonë shfaq shpejt \n\n"<b>"Niveli 4"</b>" \n- Parandalo ndërprerjen e ekranit të plotë \n- Gijthmonë shfaq shpejt \n\n"<b>"Niveli 3"</b>" \n- Parandalo ndërprerjen e ekranit të plotë \n- Asnjëherë mos shfaq shpejt \n\n"<b>"Niveli 2"</b>" \n- Parandalo ndërprerjen e ekranit të plotë \n- Asnjëherë mos shfaq shpejt \n- Asnjëherë mos lësho tingull dhe dridhje \n\n"<b>"Niveli 1"</b>" \n- Parandalo ndërprerjen e ekranit të plotë \n- Asnjëherë mos shfaq shpejt \n- Asnjëherë mos lësho tingull ose dridhje \n- Fshih nga ekrani i kyçjes dhe shiriti i statusit \n- Shfaq në fund të listës së njoftimeve \n\n"<b>"Niveli 0"</b>" \n- Blloko të gjitha njoftimet nga aplikacioni"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Njoftime"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Nuk do t\'i shikosh më këto njoftime"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Këto njoftime ti zakonisht i largon. \nDëshiron të vazhdosh t\'i shfaqësh ato?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Do të vazhdosh t\'i shfaqësh këto njoftime?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Ndalo njoftimet"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Vazhdo të shfaqësh"</string>
@@ -678,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Kujtesa e fragmenteve"</item>
     <item msgid="5742013440802239414">"Kodi i tasteve"</item>
-    <item msgid="8802889973626281575">"Ndërruesi i tastierës"</item>
-    <item msgid="7095517796293767867">"Sugjerimi i rrotullimit"</item>
-    <item msgid="8494159969042135235">"Asnjë"</item>
+    <item msgid="1951959982985094069">"Konfirmimi i rrotullimit, ndërruesi i tastierës"</item>
+    <item msgid="8175437057325747277">"Asnjë"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normale"</item>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index aa97eb2..346e2a3 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -104,12 +104,11 @@
     <string name="camera_label" msgid="7261107956054836961">"отвори камеру"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Изабери нови распоред задатака"</string>
     <string name="cancel" msgid="6442560571259935130">"Откажи"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Икона отиска прста"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Икона апликације"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Област поруке за помоћ"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Дугме Зум компатибилности."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Зумирање са мањег на већи екран."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth је прикључен."</string>
@@ -277,6 +276,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Витрина са посластицама"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Чувар екрана"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Етернет"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Не узнемиравај"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Само приоритетни прекиди"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Само аларми"</string>
@@ -313,6 +314,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi је искључен"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi је укључен"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Није доступна ниједна Wi-Fi мрежа"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Аларм"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Пребацивање"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Пребацивање"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Неименовани уређај"</string>
@@ -329,9 +331,12 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Повезује се..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Повезивање"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Хотспот"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Укључује се..."</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="one">%d уређај</item>
+      <item quantity="few">%d уређаја</item>
+      <item quantity="other">%d уређаја</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Обавештења"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Лампа"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Мобилни подаци"</string>
@@ -341,10 +346,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Искористили сте <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Ограничење од <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Упозорење за <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Профил за Work"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Обавештења и апликације су искључени"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Ноћно светло"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Укључује се по заласку сунца"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"До изласка сунца"</string>
@@ -362,8 +365,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Апликација <xliff:g id="APP">%s</xliff:g> је онемогућена у безбедном режиму."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Обриши све"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Превуците овде да бисте користили раздељени екран"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Подели хоризонтално"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Подели вертикално"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Прилагођено дељење"</string>
@@ -504,11 +505,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Искључи одмах"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Прошири"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Скупи"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Промените излазни уређај"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Екран је закачен"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"На овај начин се ово стално приказује док га не откачите. Додирните и задржите Назад и Преглед да бисте га откачили."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"На овај начин се ово стално приказује док га не откачите. Додирните и задржите Назад и Почетна да бисте га откачили."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"На овај начин се ово стално приказује док га не откачите. Додирните и задржите Преглед да бисте га откачили."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"На овај начин се ово стално приказује док га не откачите. Додирните и задржите Почетна да бисте га откачили."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Да бисте откачили овај екран, додирните и задржите дугмад Назад и Преглед"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Да бисте откачили овај екран, додирните и задржите дугмад Назад и Почетна"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Важи"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Не, хвала"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Екран је закачен"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Екран је откачен"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Желите ли да сакријете <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Ово ће се поново појавити када га следећи пут будете укључили у подешавањима."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Сакриј"</string>
@@ -531,8 +539,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Додирните да бисте искључили звук. Звук услуга приступачности ће можда бити искључен."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Додирните да бисте подесили на вибрацију."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Додирните да бисте искључили звук."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Контроле за јачину звука (%s) су приказане. Превуците нагоре да бисте их одбацили."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Контроле за јачину звука су сакривене"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Контроле за јачину звука за %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Излаз медија"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Излаз за телефонски позив"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Није пронађен ниједан уређај"</string>
@@ -588,8 +595,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Помоћу напредних контрола за обавештења можете да подесите ниво важности од 0. до 5. за обавештења апликације. \n\n"<b>"5. ниво"</b>" \n– Приказују се у врху листе обавештења \n- Дозволи прекид режима целог екрана \n– Увек завируј \n\n"<b>"4. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Увек завируј \n\n"<b>"3. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Никада не завируј \n\n"<b>"2. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Никада не завируј \n– Никада не производи звук или вибрацију \n\n"<b>"1. ниво"</b>" \n– Спречи прекид режима целог екрана \n– Никада не завируј \n– Никада не производи звук или вибрацију \n– Сакриј на закључаном екрану и статусној траци \n– Приказују се у дну листе обавештења \n\n"<b>"0. ниво"</b>" \n– Блокирај сва обавештења из апликације"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Обавештења"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Више нећете видети ова обавештења"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Обично одбацујете ова обавештења. \nЖелите ли да се и даље приказују?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Желите ли да се ова обавештења и даље приказују?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Престани да приказујеш обавештења"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Настави да приказујеш"</string>
@@ -685,9 +691,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Меморија"</item>
     <item msgid="5742013440802239414">"Кôд тастера"</item>
-    <item msgid="8802889973626281575">"Пребацивач за тастатуру"</item>
-    <item msgid="7095517796293767867">"Предлог за ротацију"</item>
-    <item msgid="8494159969042135235">"Ништа"</item>
+    <item msgid="1951959982985094069">"Потврда ротирања, пребацивач за тастатуру"</item>
+    <item msgid="8175437057325747277">"Ништа"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Нормални"</item>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index e5ae211..83efa68 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"öppna kameran"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Välj en ny layout för uppgiften"</string>
     <string name="cancel" msgid="6442560571259935130">"Avbryt"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikon för fingeravtryck"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Appikon"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Område för hjälpmeddelande"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Knapp för kompatibilitetszoom."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zooma mindre skärm till större."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth ansluten."</string>
@@ -275,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Dessertdisken"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Skärmsläckare"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Stör ej"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Endast prioriterade"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Endast alarm"</string>
@@ -311,6 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi av"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi är aktiverat"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Det finns inga tillgängliga Wi-Fi-nätverk"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarm"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Casta"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Castar"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Namnlös enhet"</string>
@@ -327,9 +329,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Ansluter ..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Internetdelning"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Surfzon"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Aktiverar …"</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="other">%d enheter</item>
+      <item quantity="one">%d enhet</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Aviseringar"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Ficklampa"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobildata"</string>
@@ -339,10 +343,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> används"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Gräns: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Varning <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Jobbprofil"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Aviseringar och appar är inaktiverade"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Nattljus"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"På från solnedgången"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Till soluppgången"</string>
@@ -360,8 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> är inaktiverad i säkert läge."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Rensa alla"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Dra hit för att dela upp skärmen"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Dela horisontellt"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Dela vertikalt"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Dela anpassad"</string>
@@ -502,11 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Inaktivera nu"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Utöka"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Komprimera"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Byt enhet för utdata"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Skärmen har fästs"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Skärmen visas tills du lossar den. Tryck länge på Tillbaka och Översikt om du vill lossa skärmen."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Skärmen visas tills du lossar den. Tryck länge på Tillbaka och Startsida om du vill lossa skärmen."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Skärmen visas tills du lossar den. Tryck länge på Översikt om du vill lossa skärmen."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Skärmen visas tills du lossar den. Tryck länge på Startsida om du vill lossa skärmen."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Om du vill lossa skärmen trycker du länge på knapparna Tillbaka och Översikt"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Om du vill lossa skärmen trycker du länge på knapparna Tillbaka och Startsida"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nej tack"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Skärmen är fäst"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Skärmen är inte längre fäst"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Vill du dölja <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Den visas på nytt nästa gång du aktiverar den i inställningarna."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Dölj"</string>
@@ -529,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Tryck här om du vill stänga av ljudet. Tillgänglighetstjänsterna kanske inaktiveras."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Tryck här om du vill aktivera vibrationsläget."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Tryck här om du vill stänga av ljudet."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Volymkontrollerna för %s visas. Svep uppåt för att ignorera."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Volymkontrollerna är dolda"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Volymkontroller för %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Medieuppspelning"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Utdata för samtal"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Inga enheter hittades"</string>
@@ -586,8 +592,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Med aviseringsinställningarna kan du ange prioritetsnivå från 0 till 5 för aviseringar från en app. \n\n"<b>"Nivå 5"</b>" \n– Visa högst upp i aviseringslistan\n– Tillåt avbrott i helskärmsläge \n– Snabbvisa alltid \n\n"<b>"Nivå 4"</b>" \n– Tillåt inte avbrott i helskärmsläge \n– Snabbvisa alltid \n\n"<b>"Nivå 3"</b>" \n- Tillåt inte avbrott i helskärmsläge \n– Snabbvisa aldrig \n\n"<b>"Nivå 2"</b>" \n– Tillåt inte avbrott i helskärmsläge \n– Snabbvisa aldrig \n– Aldrig med ljud eller vibration \n\n"<b>"Nivå 1"</b>" \n– Tillåt inte avbrott i helskärmsläge \n– Snabbvisa aldrig \n– Aldrig med ljud eller vibration \n– Visa inte på låsskärmen och i statusfältet \n– Visa längst ned i aviseringslistan \n\n"<b>"Nivå 0"</b>" \n– Blockera alla aviseringar från appen"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Aviseringar"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"De här aviseringarna visas inte längre"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Du brukar avvisa de här aviseringarna. \nVill du fortsätta att visa dem?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Vill du fortsätta visa de här aviseringarna?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Stoppa aviseringar"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Fortsätt visa"</string>
@@ -681,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Urklipp"</item>
     <item msgid="5742013440802239414">"Tangentkod"</item>
-    <item msgid="8802889973626281575">"Byt mellan meny/tangentbord"</item>
-    <item msgid="7095517796293767867">"Rotationsförslag"</item>
-    <item msgid="8494159969042135235">"Inga"</item>
+    <item msgid="1951959982985094069">"Bekräfta rotation, byt mellan meny/tangentbord"</item>
+    <item msgid="8175437057325747277">"Ingen"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normal"</item>
@@ -789,7 +793,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Skärmdumpar"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Allmänna meddelanden"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Lagring"</string>
-    <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
+    <string name="instant_apps" msgid="6647570248119804907">"Snabbappar"</string>
     <string name="instant_apps_message" msgid="8116608994995104836">"Snabbappar behöver inte installeras."</string>
     <string name="app_info" msgid="6856026610594615344">"Info om appen"</string>
     <string name="go_to_web" msgid="2650669128861626071">"Öppna webbläsaren"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index a74f8a4..e7a4e49 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"fungua kamera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Chagua muundo mpya wa kazi"</string>
     <string name="cancel" msgid="6442560571259935130">"Ghairi"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Aikoni ya alama ya kidole"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Aikoni ya programu"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Sehemu ya ujumbe wa usaidizi"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Sanduku la Vitindamlo"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Taswira ya skrini"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Usinisumbue"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Kipaumbele tu"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Kengele pekee"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi Imezimwa"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Imewasha Wi-Fi"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Hakuna mitandao ya Wi-Fi inayopatikana"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Kengele"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Tuma"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Inatuma"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Kifaa hakina jina"</string>
@@ -353,13 +356,12 @@
     <string name="recents_empty_message" msgid="808480104164008572">"Hakuna vipengee vya hivi karibuni"</string>
     <string name="recents_empty_message_dismissed_all" msgid="2791312568666558651">"Umeondoa vipengee vyote"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Maelezo ya Programu"</string>
-    <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"kudumisha programu moja"</string>
+    <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"kubandika kwenye skirini"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"tafuta"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Haikuweza kuanzisha <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> imezimwa katika hali salama."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Futa zote"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Buruta hapa ili utumie skrini iliyogawanywa"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Telezesha kidole juu ili ubadilishe programu"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Gawanya Mlalo"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Gawanya Wima"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Maalum Iliyogawanywa"</string>
@@ -503,21 +505,15 @@
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"Badilisha kifaa cha kutoa sauti"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Skrini imebandikwa"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Hali hii huifanya ionekane hadi utakapoibandua. Gusa na ushikilie kipengele cha Nyuma na Muhtasari ili ubandue."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Hali hii huifanya ionekane hadi utakapoibandua. Gusa na ushikilie kitufe cha kurudisha Nyuma na cha Mwanzo kwa pamoja ili ubandue."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Hali hii huifanya ionekane hadi utakapoibandua. Gusa na ushikilie kipengele cha Muhtasari ili ubandue."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Hali hii huifanya ionekane hadi utakapoibandua. Gusa na ushikilie kitufe cha Mwanzo ili ubandue."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Ili ubandue skrini hii, gusa na ushikilie kitufe cha Nyuma na Muhtasari"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Ili ubandue skrini hii, gusa na ushikilie vitufe vya Nyuma na Mwanzo"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Nimeelewa"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Hapana, asante"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Skrini imebandikwa"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Skrini imebanduliwa"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Ungependa kuficha <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Itaonekana tena wakati mwingine utakapoiwasha katika mipangilio."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Ficha"</string>
@@ -540,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Gusa ili ukomeshe. Huenda ikakomesha huduma za zana za walio na matatizo ya kuona au kusikia."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Gusa ili uweke mtetemo."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Gusa ili usitishe."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Inaonyesha %s ya vidhibiti vya sauti. Telezesha kidole juu ili uondoe."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Imeficha vidhibiti vya sauti"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Vidhibiti %s vya sauti"</string>
     <string name="output_title" msgid="5355078100792942802">"Vifaa vya kutoa maudhui"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Vifaa vya kutoa sauti ya simu"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Hakuna vifaa vilivyopatikana"</string>
@@ -691,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Ubao wa kunakili"</item>
     <item msgid="5742013440802239414">"Msimbo wa ufunguo"</item>
-    <item msgid="8802889973626281575">"Kibadilishaji cha kibodi"</item>
-    <item msgid="7095517796293767867">"Mapendekezo ya kuzungusha"</item>
-    <item msgid="8494159969042135235">"Hamna"</item>
+    <item msgid="1951959982985094069">"Thibitisha ugeuzaji, kibadilishaji cha kibodi"</item>
+    <item msgid="8175437057325747277">"Hamna"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Ya Kawaida"</item>
diff --git a/packages/SystemUI/res/values-sw372dp/dimens.xml b/packages/SystemUI/res/values-sw372dp/dimens.xml
index 635185d..3a7442a 100644
--- a/packages/SystemUI/res/values-sw372dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw372dp/dimens.xml
@@ -18,4 +18,5 @@
 <resources>
     <dimen name="nav_content_padding">8dp</dimen>
     <dimen name="rounded_corner_content_padding">8dp</dimen>
+    <dimen name="qs_header_tile_margin_horizontal">5dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp-land/config.xml b/packages/SystemUI/res/values-sw600dp-land/config.xml
index 6594bd28..c4c4671 100644
--- a/packages/SystemUI/res/values-sw600dp-land/config.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/config.xml
@@ -15,10 +15,6 @@
   ~ limitations under the License
   -->
 <resources>
-    <!-- The maximum count of notifications on Keyguard. The rest will be collapsed in an overflow
-         card. -->
-    <integer name="keyguard_max_notification_count">3</integer>
-
     <!-- Whether QuickSettings is in a phone landscape -->
     <bool name="quick_settings_wide">false</bool>
 
diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
index a5e37d5..f2df4b9 100644
--- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
@@ -16,9 +16,6 @@
 */
 -->
 <resources>
-    <fraction name="keyguard_clock_y_fraction_max">37%</fraction>
-    <fraction name="keyguard_clock_y_fraction_min">20%</fraction>
-
     <dimen name="keyguard_clock_notifications_margin">36dp</dimen>
 
     <dimen name="keyguard_indication_margin_bottom">80dp</dimen>
@@ -40,7 +37,7 @@
     <dimen name="battery_detail_graph_space_top">27dp</dimen>
     <dimen name="battery_detail_graph_space_bottom">27dp</dimen>
 
-    <dimen name="qs_tile_margin_top">16dp</dimen>
+    <dimen name="qs_tile_margin_top">32dp</dimen>
     <dimen name="qs_brightness_padding_top">6dp</dimen>
     <dimen name="qs_detail_margin_top">28dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp/config.xml b/packages/SystemUI/res/values-sw600dp/config.xml
index 63b9d75..67dabdb 100644
--- a/packages/SystemUI/res/values-sw600dp/config.xml
+++ b/packages/SystemUI/res/values-sw600dp/config.xml
@@ -26,10 +26,6 @@
     <!-- The number of columns that the top level tiles span in the QuickSettings -->
     <integer name="quick_settings_user_time_settings_tile_span">1</integer>
 
-    <!-- The maximum count of notifications on Keyguard. The rest will be collapsed in an overflow
-         card. -->
-    <integer name="keyguard_max_notification_count">5</integer>
-
     <!-- Set to true to enable the user switcher on the keyguard. -->
     <bool name="config_keyguardUserSwitcher">true</bool>
 
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index e95d9fe..923edc8 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -38,12 +38,6 @@
     <!-- On tablets this is just the close_handle_height -->
     <dimen name="peek_height">@dimen/close_handle_height</dimen>
 
-    <!-- The fraction of the screen height where the clock on the Keyguard has its center. The
-         max value is used when no notifications are displaying, and the min value is when the
-         highest possible number of notifications are showing. -->
-    <fraction name="keyguard_clock_y_fraction_max">34%</fraction>
-    <fraction name="keyguard_clock_y_fraction_min">24%</fraction>
-
     <!-- The margin between the clock and the notifications on Keyguard. See
          keyguard_clock_height_fraction_* for the difference between min and max.-->
     <dimen name="keyguard_clock_notifications_margin">44dp</dimen>
diff --git a/packages/SystemUI/res/values-sw720dp-land/config.xml b/packages/SystemUI/res/values-sw720dp-land/config.xml
deleted file mode 100644
index 1b50288..0000000
--- a/packages/SystemUI/res/values-sw720dp-land/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2014 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<resources>
-    <integer name="keyguard_max_notification_count">4</integer>
-</resources>
-
diff --git a/packages/SystemUI/res/values-sw720dp-land/dimens.xml b/packages/SystemUI/res/values-sw720dp-land/dimens.xml
deleted file mode 100644
index 511d45f..0000000
--- a/packages/SystemUI/res/values-sw720dp-land/dimens.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2014 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<resources>
-    <!-- The fraction of the screen height where the clock on the Keyguard has its center. The
-         min value is used when no notifications are displaying, and the max value is when the
-         highest possible number of notifications are showing. -->
-    <fraction name="keyguard_clock_y_fraction_max">35%</fraction>
-    <fraction name="keyguard_clock_y_fraction_min">24%</fraction>
-</resources>
diff --git a/packages/SystemUI/res/values-sw720dp/dimens.xml b/packages/SystemUI/res/values-sw720dp/dimens.xml
index 25e96c8..8cf4adb 100644
--- a/packages/SystemUI/res/values-sw720dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp/dimens.xml
@@ -28,11 +28,5 @@
     <dimen name="notification_panel_min_height">770dp</dimen>
     <!-- Bottom margin (from display edge) for status bar panels -->
     <dimen name="panel_float">56dp</dimen>
-
-    <!-- The fraction of the screen height where the clock on the Keyguard has its center. The
-     max value is used when no notifications are displaying, and the min value is when the
-     highest possible number of notifications are showing. -->
-    <fraction name="keyguard_clock_y_fraction_max">35%</fraction>
-    <fraction name="keyguard_clock_y_fraction_min">25%</fraction>
 </resources>
 
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index c8ff5a1..7777839 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"கேமராவைத் திற"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"புதிய பணி தளவமைப்பைத் தேர்ந்தெடுக்கவும்"</string>
     <string name="cancel" msgid="6442560571259935130">"ரத்துசெய்"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"கைரேகை ஐகான்"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"பயன்பாட்டு ஐகான்"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"உதவிச் செய்திக்கான பகுதி"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"இனிப்பு வடிவங்கள்"</string>
     <string name="start_dreams" msgid="5640361424498338327">"ஸ்கிரீன் சேவர்"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"ஈதர்நெட்"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"தொந்தரவு செய்யாதே"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"முதன்மை மட்டும்"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"அலாரங்கள் மட்டும்"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"வைஃபையை முடக்கு"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"வைஃபை இயக்கத்தில்"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"வைஃபை நெட்வொர்க்குகள் இல்லை"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"அலாரம்"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Cast"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"அனுப்புகிறது"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"பெயரிடப்படாத சாதனம்"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"பாதுகாப்புப் பயன்முறையில் <xliff:g id="APP">%s</xliff:g> முடக்கப்பட்டது."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"அனைத்தையும் அழி"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"திரைப் பிரிப்பைப் பயன்படுத்த, இங்கே இழுக்கவும்"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"ஆப்ஸிற்கு இடையே மாற்றுவதற்கு, மேல்நோக்கி ஸ்வைப் செய்க"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"கிடைமட்டமாகப் பிரி"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"செங்குத்தாகப் பிரி"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"தனிவிருப்பத்தில் பிரி"</string>
@@ -500,25 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"இப்போதே முடக்கு"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"விரிவாக்கு"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"சுருக்கு"</string>
-    <!-- no translation found for accessibility_output_chooser (8185317493017988680) -->
-    <skip />
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"வெளியீட்டுச் சாதனத்தை மாற்றுதல்"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"திரை பொருத்தப்பட்டது"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"பொருத்தியதை அகற்றும் வரை இதைக் காட்சியில் வைக்கும். அகற்ற, முந்தையது மற்றும் மேலோட்டப் பார்வையைத் தொட்டுப் பிடிக்கவும்."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"இதற்கான பின்னை அகற்றும் வரை, இந்தப் பயன்முறை செயல்பாட்டிலேயே இருக்கும். அகற்றுவதற்கு, முந்தையது மற்றும் முகப்புப் பொத்தான்களைத் தொட்டுப் பிடிக்கவும்."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"பொருத்தியதை அகற்றும் வரை இதைக் காட்சியில் வைக்கும். அகற்ற, மேலோட்டப் பார்வையைத் தொட்டுப் பிடிக்கவும்."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"இதற்கான பின்னை அகற்றும் வரை, இந்தப் பயன்முறை செயல்பாட்டிலேயே இருக்கும். அகற்றுவதற்கு, முகப்புப் பொத்தானைத் தொட்டுப் பிடிக்கவும்."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"இந்தத் திரையின் பின்னை அகற்ற, முந்தையது மற்றும் மேலோட்டப் பார்வைப் பொத்தான்களைத் தொட்டுப் பிடிக்கவும்"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"இந்தத் திரையின் பின்னை அகற்ற, முந்தையது மற்றும் முகப்புப் பொத்தான்களைத் தொட்டுப் பிடிக்கவும்"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"புரிந்தது"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"வேண்டாம்"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"திரை பின் செய்யப்பட்டது"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"திரையிலிருந்து பின் அகற்றப்பட்டது"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g>ஐ மறைக்கவா?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"அடுத்த முறை அமைப்புகளில் மீண்டும் இயக்கும்போது, இது மீண்டும் தோன்றும்."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"மறை"</string>
@@ -541,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. ஒலியடக்க, தட்டவும். அணுகல்தன்மை சேவைகள் ஒலியடக்கப்படக்கூடும்."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. அதிர்விற்கு அமைக்க, தட்டவும்."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. ஒலியடக்க, தட்டவும்."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s ஒலிக் கட்டுப்பாடுகள் காட்டப்பட்டன. நிராகரிக்க, மேலே ஸ்வைப் செய்யவும்."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"ஒலிக் கட்டுப்பாடுகள் மறைக்கப்பட்டன"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s ஒலியளவுக் கட்டுப்பாடுகள்"</string>
     <string name="output_title" msgid="5355078100792942802">"மீடியா வெளியீடு"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"ஃபோன் அழைப்பு வெளியீடு"</string>
     <string name="output_none_found" msgid="5544982839808921091">"சாதனங்கள் எதுவும் இல்லை"</string>
@@ -692,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"கிளிப்போர்டு"</item>
     <item msgid="5742013440802239414">"விசைக்குறியீடு"</item>
-    <item msgid="8802889973626281575">"விசைப்பலகை மாற்றி"</item>
-    <item msgid="7095517796293767867">"சுழற்சிப் பரிந்துரை"</item>
-    <item msgid="8494159969042135235">"ஏதுமில்லை"</item>
+    <item msgid="1951959982985094069">"சுழற்ற உறுதிப்படுத்து, விசைப்பலகை மாற்றி"</item>
+    <item msgid="8175437057325747277">"ஏதுமில்லை"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"இயல்பானது"</item>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 292fddd..38feaf5 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"కెమెరాను తెరువు"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"కొత్త విధి లేఅవుట్‌ను ఎంచుకోండి"</string>
     <string name="cancel" msgid="6442560571259935130">"రద్దు చేయి"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"వేలిముద్ర చిహ్నం"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"అప్లికేషన్ చిహ్నం"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"సహాయ సందేశ ప్రాంతం"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"డెజర్ట్ కేస్"</string>
     <string name="start_dreams" msgid="5640361424498338327">"స్క్రీన్ సేవర్"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"ఈథర్‌నెట్"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"అంతరాయం కలిగించవద్దు"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"ప్రాధాన్యత మాత్రమే"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"అలారాలు మాత్రమే"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi ఆఫ్‌లో ఉంది"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi ఆన్‌లో ఉంది"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Wi-Fi నెట్‌వర్క్‌లు ఏవీ అందుబాటులో లేవు"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"అలారం"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"ప్రసారం చేయండి"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"ప్రసారం చేస్తోంది"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"పేరులేని పరికరం"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> సురక్షిత-మోడ్‌లో నిలిపివేయబడింది."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"అన్నీ తీసివేయి"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"విభజన స్క్రీన్‌ను ఉపయోగించడానికి ఇక్కడ లాగండి"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"యాప్‌లను మార్చడం కోసం ఎగువకు స్వైప్ చేయండి"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"సమతలంగా విభజించు"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"లంబంగా విభజించు"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"అనుకూలంగా విభజించు"</string>
@@ -500,25 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"ఇప్పుడు ఆఫ్ చేయండి"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"విస్తరింపజేయండి"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"కుదించండి"</string>
-    <!-- no translation found for accessibility_output_chooser (8185317493017988680) -->
-    <skip />
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"పరికరం అవుట్‌పుట్‌ని మార్చండి"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"స్క్రీన్ పిన్ చేయబడింది"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"దీని వలన మీరు అన్‌పిన్ చేసే వరకు ఇది వీక్షణలో ఉంచబడుతుంది. అన్‌పిన్ చేయడానికి వెనుకకు మరియు స్థూలదృష్టి తాకి &amp; అలాగే పట్టుకోండి."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"దీని వలన మీరు అన్‌పిన్ చేసే వరకు ఇది వీక్షణలో ఉంచబడుతుంది. అన్‌పిన్ చేయడానికి వెనుకకు మరియు హోమ్‌ని తాకి &amp; అలాగే పట్టుకోండి."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"దీని వలన మీరు అన్‌పిన్ చేసే వరకు ఇది వీక్షణలో ఉంచబడుతుంది. అన్‌పిన్ చేయడానికి స్థూలదృష్టిని తాకి &amp; అలాగే పట్టుకోండి."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"దీని వలన మీరు అన్‌పిన్ చేసే వరకు ఇది వీక్షణలో ఉంచబడుతుంది. అన్‌పిన్ చేయడానికి హోమ్‌ని తాకి &amp; అలాగే పట్టుకోండి."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"ఈ స్క్రీన్‌ను అన్‌పిన్ చేయడానికి, వెనుకకు మరియు అవలోకనం బటన్‌లను తాకి &amp; అలాగే పట్టుకోండి"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ఈ స్క్రీన్‌ను అన్‌పిన్ చేయడానికి, వెనుకకు మరియు హోమ్ బటన్‌లను తాకి &amp; అలాగే పట్టుకోండి"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"అర్థమైంది"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"వద్దు, ధన్యవాదాలు"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"స్క్రీన్ పిన్ చేయబడింది"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"స్క్రీన్ అన్‌పిన్ చేయబడింది"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g>ని దాచాలా?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"మీరు సెట్టింగ్‌ల్లో దీన్ని ఆన్ చేసిన తదుపరిసారి ఇది కనిపిస్తుంది."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"దాచు"</string>
@@ -541,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. మ్యూట్ చేయడానికి నొక్కండి. యాక్సెస్ సామర్థ్య సేవలు మ్యూట్ చేయబడవచ్చు."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. వైబ్రేట్ అయ్యేలా సెట్ చేయడం కోసం నొక్కండి."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. మ్యూట్ చేయడానికి నొక్కండి."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s వాల్యూమ్ నియంత్రణలు చూపబడ్డాయి. తీసివేయడానికి పైకి స్వైప్ చేయండి."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"వాల్యూమ్ నియంత్రణలు దాచబడ్డాయి"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s వాల్యూమ్ నియంత్రణలు"</string>
     <string name="output_title" msgid="5355078100792942802">"మీడియా అవుట్‌పుట్"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"ఫోన్ కాల్ అవుట్‌పుట్"</string>
     <string name="output_none_found" msgid="5544982839808921091">"పరికరాలు ఏవీ కనుగొనబడలేదు"</string>
@@ -692,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"క్లిప్‌బోర్డ్"</item>
     <item msgid="5742013440802239414">"కీకోడ్"</item>
-    <item msgid="8802889973626281575">"కీబోర్డ్ స్విచర్"</item>
-    <item msgid="7095517796293767867">"భ్రమణ సూచన"</item>
-    <item msgid="8494159969042135235">"ఏదీ కాదు"</item>
+    <item msgid="1951959982985094069">"భ్రమణం నిర్ధారణ, కీబోర్డ్ స్విచర్"</item>
+    <item msgid="8175437057325747277">"ఏదీ వద్దు"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"సాధారణం"</item>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index ac4fbc9..a64ec0a 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"เปิดกล้อง"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"เลือกรูปแบบงานใหม่"</string>
     <string name="cancel" msgid="6442560571259935130">"ยกเลิก"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ไอคอนลายนิ้วมือ"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"ไอคอนแอปพลิเคชัน"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"พื้นที่ข้อความช่วยเหลือ"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"ปุ่มซูมที่ใช้งานร่วมกันได้"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"ซูมหน้าจอให้มีขนาดใหญ่ขึ้น"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"เชื่อมต่อบลูทูธแล้ว"</string>
@@ -275,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"ชั้นแสดงของหวาน"</string>
     <string name="start_dreams" msgid="5640361424498338327">"โปรแกรมรักษาหน้าจอ"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"อีเทอร์เน็ต"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"ห้ามรบกวน"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"เฉพาะเรื่องสำคัญ"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"เฉพาะปลุกเท่านั้น"</string>
@@ -311,6 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"ปิด WiFi"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi เปิดอยู่"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"ไม่มีเครือข่าย Wi-Fi พร้อมใช้งาน"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"การปลุก"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"แคสต์"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"กำลังส่ง"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"อุปกรณ์ที่ไม่มีชื่อ"</string>
@@ -327,9 +329,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"กำลังเชื่อมต่อ..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"การปล่อยสัญญาณ"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"ฮอตสปอต"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"กำลังเปิด..."</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="other">อุปกรณ์ %d เครื่อง</item>
+      <item quantity="one">อุปกรณ์ %d เครื่อง</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"การแจ้งเตือน"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"ไฟฉาย"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"อินเทอร์เน็ตมือถือ"</string>
@@ -339,10 +343,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"ใช้ไปแล้ว <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"ขีดจำกัด <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"คำเตือน <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"โปรไฟล์งาน"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"การแจ้งเตือนและแอปปิดอยู่"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"แสงตอนกลางคืน"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"เปิดตอนพระอาทิตย์ตก"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"จนพระอาทิตย์ขึ้น"</string>
@@ -360,8 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ปิดใช้ในโหมดปลอดภัย"</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"ล้างทั้งหมด"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"ลากมาที่นี่เพื่อใช้การแยกหน้าจอ"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"แยกในแนวนอน"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"แยกในแนวตั้ง"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"แยกแบบกำหนดเอง"</string>
@@ -502,11 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"ปิดเลย"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"ขยาย"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ยุบ"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"เปลี่ยนอุปกรณ์เอาต์พุต"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"ตรึงหน้าจอแล้ว"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"การดำเนินการนี้จะแสดงหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกตรึง แตะ \"กลับ\" และ \"ภาพรวม\" ค้างไว้เพื่อเลิกตรึง"</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"การดำเนินการนี้จะแสดงหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกตรึง แตะ \"กลับ\" และ \"หน้าแรก\" ค้างไว้เพื่อเลิกตรึง"</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"การดำเนินการนี้จะแสดงหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกตรึง แตะ \"ภาพรวม\" ค้างไว้เพื่อเลิกตรึง"</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"การดำเนินการนี้จะแสดงหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกตรึง แตะ \"หน้าแรก\" ค้างไว้เพื่อเลิกตรึง"</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"หากต้องการเลิกตรึงหน้าจอนี้ ให้แตะปุ่ม \"กลับ\" และ \"ภาพรวม\" ค้างไว้"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"หากต้องการเลิกตรึงหน้าจอนี้ ให้แตะปุ่ม \"กลับ\" และ \"หน้าแรก\" ค้างไว้"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"รับทราบ"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"ไม่เป็นไร ขอบคุณ"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"ตรึงหน้าจอแล้ว"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"เลิกตรึงหน้าจอแล้ว"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"ซ่อน <xliff:g id="TILE_LABEL">%1$s</xliff:g> ไหม"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"จะปรากฏอีกครั้งเมื่อคุณเปิดใช้ในการตั้งค่าครั้งถัดไป"</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"ซ่อน"</string>
@@ -529,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s แตะเพื่อปิดเสียง อาจมีการปิดเสียงบริการการเข้าถึง"</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s แตะเพื่อตั้งค่าให้สั่น"</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s แตะเพื่อปิดเสียง"</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s ตัวควบคุมระดับเสียงแสดงอยู่ เลื่อนขึ้นเพื่อปิด"</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"ตัวควบคุมระดับเสียงซ่อนอยู่"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"ตัวควบคุมระดับเสียง %s"</string>
     <string name="output_title" msgid="5355078100792942802">"เอาต์พุตสื่อ"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"เอาต์พุตการโทรออก"</string>
     <string name="output_none_found" msgid="5544982839808921091">"ไม่พบอุปกรณ์"</string>
@@ -586,8 +592,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"ส่วนควบคุมการแจ้งเตือนแบบเปิด/ปิดช่วยให้คุณตั้งค่าระดับความสำคัญสำหรับการแจ้งเตือนของแอปได้ตั้งแต่ระดับ 0-5 \n\n"<b>"ระดับ 5"</b>" \n- แสดงที่ด้านบนของรายการแจ้งเตือน \n- อนุญาตให้รบกวนแบบเต็มหน้าจอ \n- อนุญาตให้แสดงชั่วครู่ \n\n"<b>"ระดับ 4"</b>" \n- ป้องกันการรบกวนแบบเต็มหน้าจอ \n- แสดงชั่วครู่เสมอ \n\n"<b>"ระดับ 3"</b>" \n- ป้องกันการรบกวนแบบเต็มหน้าจอ \n- ไม่แสดงชั่วครู่เลย \n\n"<b>"ระดับ 2"</b>" \n- ป้องกันการรบกวนแบบเต็มหน้าจอ \n- ไม่แสดงชั่วครู่เลย \n- ไม่ส่งเสียงหรือสั่นเลย \n\n"<b>"ระดับ 1"</b>" \n- ป้องกันการรบกวนแบบเต็มหน้าจอ \n- ไม่แสดงชั่วครู่เลย \n- ไม่ส่งเสียงหรือสั่นเลย \n- ซ่อนจากหน้าจอล็อกและแถบสถานะ \n- แสดงที่ด้านล่างของรายการแจ้งเตือน \n\n"<b>"ระดับ 0"</b>" \n- บล็อกการแจ้งเตือนทั้งหมดจากแอป"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"การแจ้งเตือน"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"คุณจะไม่เห็นการแจ้งเตือนเหล่านี้อีก"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"โดยปกติแล้ว คุณจะปิดการแจ้งเตือนเหล่านี้ \nต้องการให้แสดงต่อไหม"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"แสดงการแจ้งเตือนเหล่านี้ต่อไปไหม"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"ปิดการแจ้งเตือน"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"แสดงต่อไป"</string>
@@ -681,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"คลิปบอร์ด"</item>
     <item msgid="5742013440802239414">"Keycode"</item>
-    <item msgid="8802889973626281575">"ปุ่มสลับแป้นพิมพ์"</item>
-    <item msgid="7095517796293767867">"คำแนะนำในการหมุน"</item>
-    <item msgid="8494159969042135235">"ไม่มี"</item>
+    <item msgid="1951959982985094069">"การยืนยันการหมุน, ปุ่มสลับแป้นพิมพ์"</item>
+    <item msgid="8175437057325747277">"ไม่มี"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"ปกติ"</item>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 97e332b..081b40f 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"buksan ang camera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Pumili ng bagong layout ng gawain"</string>
     <string name="cancel" msgid="6442560571259935130">"Kanselahin"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icon ng fingerprint"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Icon ng application"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Lugar ng mensahe ng tulong"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Button ng zoom ng pagiging tugma."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Mag-zoom nang mas maliit sa mas malaking screen."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Nakakonekta ang Bluetooth."</string>
@@ -275,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Dessert Case"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Screen saver"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Huwag istorbohin"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Priyoridad lang"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Mga alarm lang"</string>
@@ -311,6 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Naka-off ang Wi-Fi"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Naka-on Ang Wi-Fi"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Walang available na mga Wi-Fi network"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarm"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"I-cast"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Nagka-cast"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Walang pangalang device"</string>
@@ -327,9 +329,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Kumokonekta..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Nagte-tether"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Ino-on..."</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="one">%d device</item>
+      <item quantity="other">%d na device</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Mga Notification"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Flashlight"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobile data"</string>
@@ -339,10 +343,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> ang nagamit"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> ang limitasyon"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Babala sa <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Profile sa trabaho"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Naka-off ang mga notification at app"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Night Light"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Mao-on sa sunset"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Hanggang mag-umaga"</string>
@@ -360,8 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Naka-disable ang <xliff:g id="APP">%s</xliff:g> sa safe-mode."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"I-clear lahat"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"I-drag dito upang magamit ang split screen"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Split Horizontal"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Split Vertical"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Split Custom"</string>
@@ -502,11 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"I-off na ngayon"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Palawakin"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"I-collapse"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Lumipat ng output device"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Naka-pin ang screen"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Pinapanatili nitong nakikita ito hanggang sa mag-unpin ka. Pindutin nang matagal ang Bumalik at Overview upang mag-unpin."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Pinapanatili nitong nakikita ito hanggang sa mag-unpin ka. Pindutin nang matagal ang Bumalik at Home upang mag-unpin."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Pinapanatili nitong nakikita ito hanggang sa mag-unpin ka. Pindutin nang matagal ang Overview upang mag-unpin."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Pinapanatili nitong nakikita ito hanggang sa mag-unpin ka. Pindutin nang matagal ang Home upang mag-unpin."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Upang i-unpin ang screen na ito, pindutin nang matagal ang mga button na Bumalik at Overview"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Upang i-unpin ang screen na ito, pindutin nang matagal ang mga button na Bumalik at Home"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Nakuha ko"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Hindi, salamat na lang"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Na-pin ang screen"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Na-unpin ang screen"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Itago ang <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Lalabas itong muli sa susunod na pagkakataon na i-on mo ito sa mga setting."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Itago"</string>
@@ -529,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. I-tap upang i-mute. Maaaring i-mute ang mga serbisyo sa Accessibility."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. I-tap upang itakda na mag-vibrate."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. I-tap upang i-mute."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Ipinapakita ang mga kontrol ng volume ng %s. Mag-swipe pataas upang i-dismiss."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Nakatago ang mga kontrol ng volume"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Mga kontrol ng volume ng %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Output ng media"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Output ng tawag sa telepono"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Walang nakitang device"</string>
@@ -586,8 +592,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Sa pamamagitan ng mga kontrol sa notification ng power, magagawa mong itakda ang antas ng kahalagahan ng mga notification ng isang app mula 0 hanggang 5. \n\n"<b>"Antas 5"</b>" \n- Ipakita sa itaas ng listahan ng notification \n- Payagan ang pag-istorbo kapag full screen \n- Palaging sumilip \n\n"<b>"Antas 4"</b>" \n- Pigilan ang pag-istorbo kapag full screen \n- Palaging sumilip \n\n"<b>"Antas 3"</b>" \n- Pigilan ang pag-istorbo kapag full screen \n- Huwag kailanman sumilip \n\n"<b>"Antas 2"</b>" \n- Pigilan ang pag-istorbo kapag full screen \n- Huwag kailanman sumilip \n- Huwag kailanman tumunog o mag-vibrate \n\n"<b>"Antas 1"</b>" \n- Pigilan ang pag-istorbo kapag full screen \n- Huwag kailanman sumilip \n- Huwag kailanman tumunog o mag-vibrate \n- Itago sa lock screen at status bar \n- Ipakita sa ibaba ng listahan ng notification \n\n"<b>"Antas 0"</b>" \n- I-block ang lahat ng notification mula sa app"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Mga Notification"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Hindi mo na makikita ang mga notification na ito"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Karaniwan mong dini-dismiss ang mga ganitong notification. \nPatuloy na ipakita ang mga ito?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Patuloy na ipakita ang mga notification na ito?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Ihinto ang mga notification"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Patuloy na ipakita"</string>
@@ -681,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Clipboard"</item>
     <item msgid="5742013440802239414">"Keycode"</item>
-    <item msgid="8802889973626281575">"Keyboard switcher"</item>
-    <item msgid="7095517796293767867">"Suhestyon sa pag-rotate"</item>
-    <item msgid="8494159969042135235">"Wala"</item>
+    <item msgid="1951959982985094069">"Pagkumpirma ng pag-rotate, keyboard switcher"</item>
+    <item msgid="8175437057325747277">"Wala"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Karaniwan"</item>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 9adc141..92c42ec 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"kamerayı aç"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Yeni görev düzenini seçin"</string>
     <string name="cancel" msgid="6442560571259935130">"İptal"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Parmak izi simgesi"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Uygulama simgesi"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Yardım mesajı alanı"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Tatlı Kutusu"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Ekran koruyucu"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Rahatsız etmeyin"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Yalnızca öncelikliler"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Yalnızca alarmlar"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Kablosuz Kapalı"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Kablosuz Bağlantı Açık"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Kullanılabilir kablosuz ağ yok"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Alarm"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Yayınla"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Yayınlanıyor"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Adsız cihaz"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g>, güvenli modda devre dışıdır."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Tümünü temizle"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Ekranı bölünmüş olarak kullanmak için burayı sürükleyin"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Uygulamalar arasında geçiş yapmak için yukarı kaydırın"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Yatay Ayırma"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Dikey Ayırma"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Özel Ayırma"</string>
@@ -500,25 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Şimdi kapat"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Genişlet"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Daralt"</string>
-    <!-- no translation found for accessibility_output_chooser (8185317493017988680) -->
-    <skip />
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Çıkış cihazını değiştir"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Ekran sabitlendi"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Bu işlem, siz sabitlemeyi kaldırana kadar ekranı görünür durumda tutar. Sabitlemeyi kaldırmak için Geri\'ye ve Genel Bakış\'a dokunup basılı tutun."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Bu işlem, siz sabitlemeyi kaldırana kadar ekranı görünür durumda tutar. Sabitlemeyi kaldırmak için Geri\'ye ve Ana sayfaya dokunup basılı tutun."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Bu işlem, siz sabitlemeyi kaldırana kadar ekranı görünür durumda tutar. Sabitlemeyi kaldırmak için Genel bakış\'a dokunup basılı tutun."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Bu işlem, siz sabitlemeyi kaldırana kadar ekranı görünür durumda tutar. Sabitlemeyi kaldırmak için Ana sayfaya dokunup basılı tutun."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Bu ekranın sabitlemesini kaldırmak için Geri ve Genel Bakış düğmelerine dokunup basılı tutun"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Bu ekranın sabitlemesini kaldırmak için Geri ve Ana sayfa düğmelerine dokunup basılı tutun"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Anladım"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Hayır, teşekkürler"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Ekran sabitlendi"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Ekran sabitlemesi kaldırıldı"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> gizlensin mi?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Ayarlardan etkinleştirdiğiniz bir sonraki sefer tekrar görünür."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Gizle"</string>
@@ -541,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Sesi kapatmak için dokunun. Erişilebilirlik hizmetlerinin sesi kapatılabilir."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Titreşime ayarlamak için dokunun."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Sesi kapatmak için dokunun."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s ses denetimleri gösteriliyor. Kapatmak için hızlıca yukarı kaydırın."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Ses denetimleri gizlendi"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s ses denetimleri"</string>
     <string name="output_title" msgid="5355078100792942802">"Medya çıkışı"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Telefon çağrısı çıkışı"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Cihaz bulunamadı"</string>
@@ -692,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Pano"</item>
     <item msgid="5742013440802239414">"Tuş kodu"</item>
-    <item msgid="8802889973626281575">"Klavye değiştirici"</item>
-    <item msgid="7095517796293767867">"Rotasyon önerisi"</item>
-    <item msgid="8494159969042135235">"Yok"</item>
+    <item msgid="1951959982985094069">"Döndürmeyi onayla, klavye değiştirici"</item>
+    <item msgid="8175437057325747277">"Yok"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Normal"</item>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 3834753..4b34e25 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -105,6 +105,8 @@
     <string name="camera_label" msgid="7261107956054836961">"відкрити камеру"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Виберіть новий макет завдання"</string>
     <string name="cancel" msgid="6442560571259935130">"Скасувати"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Значок відбитка пальця"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Значок додатка"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Область довідкового повідомлення"</string>
@@ -278,6 +280,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Вітрина десертів"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Заставка"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Не турбувати"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Лише пріоритетні"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Лише будильник"</string>
@@ -314,8 +318,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi вимкнено"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi увімкнено"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Немає доступних мереж Wi-Fi"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Будильник"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Трансляція"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Трансляція"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Пристрій без назви"</string>
@@ -367,7 +370,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Додаток <xliff:g id="APP">%s</xliff:g> вимкнено в безпечному режимі."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Очистити все"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Перетягніть сюди, щоб увімкнути режим розділеного екрана"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Проводьте пальцем угору, щоб переходити між додатками"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Розділити горизонтально"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Розділити вертикально"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Розділити (власний варіант)"</string>
@@ -511,21 +513,15 @@
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"Увімкніть пристрій виведення"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Екран закріплено"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Ви постійно бачитимете екран, доки не відкріпите його. Щоб відкріпити екран, натисніть і втримуйте кнопки \"Назад\" та \"Огляд\"."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Ви бачитимете цей екран, доки не відкріпите його. Для цього натисніть і утримуйте кнопки \"Назад\" та \"Головний екран\"."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Ви постійно бачитимете екран, доки не відкріпите його. Щоб відкріпити екран, натисніть і втримуйте кнопку \"Огляд\"."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ви бачитимете цей екран, доки не відкріпите його. Для цього натисніть і утримуйте кнопку \"Головний екран\"."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Щоб відкріпити цей екран, натисніть і утримуйте кнопки \"Назад\" та \"Огляд\""</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Щоб відкріпити цей екран, натисніть і утримуйте кнопки \"Назад\" та \"Головний екран\""</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Зрозуміло"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Ні, дякую"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Екран закріплено"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Екран відкріплено"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Сховати <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"З’явиться знову, коли ви ввімкнете його в налаштуваннях."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Сховати"</string>
@@ -548,8 +544,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Торкніться, щоб вимкнути звук. Спеціальні можливості може бути вимкнено."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Торкніться, щоб налаштувати вібросигнал."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Торкніться, щоб вимкнути звук."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Показано регуляторів гучності: %s. Проведіть пальцем угору, щоб закрити."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Регулятори гучності сховано"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Регуляторів гучності: %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Вивід медіа-вмісту"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Вивід телефонного виклику"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Пристроїв не знайдено"</string>
@@ -703,9 +698,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Буфер обміну"</item>
     <item msgid="5742013440802239414">"Код клавіші"</item>
-    <item msgid="8802889973626281575">"Вибір клавіатури"</item>
-    <item msgid="7095517796293767867">"Пропозиція щодо обертання"</item>
-    <item msgid="8494159969042135235">"Немає"</item>
+    <item msgid="1951959982985094069">"Підтвердити обертання, вибір клавіатури"</item>
+    <item msgid="8175437057325747277">"Немає"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Звичайна панель"</item>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 9ebdfeb..2c01bf9 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"کیمرا کھولیں"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"نئے کام کا لے آؤٹ منتخب کریں"</string>
     <string name="cancel" msgid="6442560571259935130">"منسوخ کریں"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"فنگر پرنٹ آئیکن"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"ایپلیکیشن کا آئیکن"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"امدادی پیغام کا علاقہ"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"ڈیزرٹ کیس"</string>
     <string name="start_dreams" msgid="5640361424498338327">"اسکرین سیور"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"ایتھرنیٹ"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"ڈسٹرب نہ کریں"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"صرف ترجیحی"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"صرف الارمز"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"‏Wi-Fi آف ہے"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"‏Wi-Fi آن ہے"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"‏کوئی WI-FI نیٹ ورک دستیاب نہیں"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"الارم"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"کاسٹ کریں"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"کاسٹنگ"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"بغیر نام والا آلہ"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"محفوظ موڈ میں <xliff:g id="APP">%s</xliff:g> غیر فعال ہوتی ہے۔"</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"سبھی کو صاف کریں"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"اسپلٹ اسکرین استعمال کرنے کیلئے یہاں گھسیٹیں"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"ایپس سوئچ کرنے کیلئے اوپر سوائپ کریں"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"بلحاظ افقی الگ کریں"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"بلحاظ عمودی الگ کریں"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"بلحاظ حسب ضرورت الگ کریں"</string>
@@ -500,25 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"ابھی بند کریں"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"پھیلائیں"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"سکیڑیں"</string>
-    <!-- no translation found for accessibility_output_chooser (8185317493017988680) -->
-    <skip />
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"آؤٹ پٹ آلہ سوئچ کریں"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"اسکرین پن کردہ ہے"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"یہ اسے اس وقت تک نظر میں رکھتا ہے جب تک آپ اس سے پن ہٹا نہیں دیتے۔ پن ہٹانے کیلئے پیچھے اور مجموعی جائزہ بٹنز کو ٹچ کریں اور دبائے رکھیں۔"</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"یہ اس کو اس وقت تک مد نظر رکھتا ہے جب تک آپ اس سے پن نہیں ہٹا دیتے۔ پن ہٹانے کیلئے \"پیچھے\" اور \"ہوم\" بٹنز کو ٹچ کریں اور دبائے رکھیں۔"</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"یہ اسے اس وقت تک نظر میں رکھتا ہے جب تک آپ اس سے پن ہٹا نہیں دیتے۔ پن ہٹانے کیلئے مجموعی جائزہ بٹن کو ٹچ کریں اور دبائے رکھیں۔"</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"یہ اس کو اس وقت تک مد نظر رکھتا ہے جب تک آپ اس سے پن نہیں ہٹا دیتے۔ پن ہٹانے کیلئے \"ہوم\" بٹن کو ٹچ کریں اور دبائے رکھیں۔"</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"اس اسکرین سے پن ہٹانے کیلئے، \"پیچھے\" اور \"مجموعی جائزہ\" بٹنز کو ٹچ کریں اور دبائے رکھیں"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"اس اسکرین سے پن ہٹانے کیلئے، \"پیچھے\" اور \"ہوم\" بٹنز کو ٹچ کریں اور دبائے رکھیں"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"سمجھ آ گئی"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"نہیں شکریہ"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"اسکرین کو پن کر دیا گیا"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"اسکرین کا پن ہٹا دیا گیا"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> کو چھپائیں؟"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"اگلی بار جب آپ اسے ترتیبات میں آن کریں گے تو یہ ظاہر ہوگی۔"</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"چھپائیں"</string>
@@ -541,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"‏‎%1$s۔ خاموش کرنے کیلئے تھپتھپائیں۔ ایکسیسبیلٹی سروسز شاید خاموش ہوں۔"</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"‏‎%1$s۔ ارتعاش پر سیٹ کرنے کیلئے تھپتھپائیں۔"</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"‏‎%1$s۔ خاموش کرنے کیلئے تھپتھپائیں۔"</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"‏%s والیوم کے کنٹرولز دکھائے جا رہے ہیں۔ برخاست کرنے کیلئے سوائپ کریں۔"</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"والیوم کے کنٹرولز مخفی ہیں"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"‏‎%s والیوم کے کنٹرولز"</string>
     <string name="output_title" msgid="5355078100792942802">"میڈیا آؤٹ پٹ"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"فون کال کا آؤٹ پٹ"</string>
     <string name="output_none_found" msgid="5544982839808921091">"کوئی آلہ نہیں ملا"</string>
@@ -692,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"کلپ بورڈ"</item>
     <item msgid="5742013440802239414">"کی کوڈ"</item>
-    <item msgid="8802889973626281575">"کی بورڈ سوئچر"</item>
-    <item msgid="7095517796293767867">"گردش کی تجویز"</item>
-    <item msgid="8494159969042135235">"کوئی نہیں"</item>
+    <item msgid="1951959982985094069">"گردش کی تصدیق، کی بورڈ سوئچر"</item>
+    <item msgid="8175437057325747277">"کوئی نہیں"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"حسب معمول"</item>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 0279d16..e308ed3 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"kamerani ochish"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Yangi vazifa tartibini tanlash"</string>
     <string name="cancel" msgid="6442560571259935130">"Bekor qilish"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Barmoq izi belgisi"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Ilova ikonkasi"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Yordam xabari"</string>
@@ -274,6 +276,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Dessert Case"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Ekran lavhasi"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Bezovta qilinmasin"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Faqat muhimlari"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Faqat signallar"</string>
@@ -534,8 +538,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Ovozini o‘chirish uchun ustiga bosing. Maxsus imkoniyatlar ishlamasligi mumkin."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Tebranishni yoqish uchun ustiga bosing."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Ovozsiz qilish uchun ustiga bosing."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"Ovoz balandligini boshqarish tugmalari ko‘rsatilgan: %s. Yopish uchun tepaga suring."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Ovoz balandligini boshqarish tugmalari yashirilgan"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s tovush balandligi tugmalari"</string>
     <string name="output_title" msgid="5355078100792942802">"Media chiqishi"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Telefon chaqiruvlari"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Hech qanday qurilma topilmadi"</string>
@@ -685,9 +688,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Vaqtinchalik xotira"</item>
     <item msgid="5742013440802239414">"Tugma kodi"</item>
-    <item msgid="8802889973626281575">"Klaviaturani almashtirish"</item>
-    <item msgid="7095517796293767867">"Burilish"</item>
-    <item msgid="8494159969042135235">"Hech biri"</item>
+    <item msgid="1951959982985094069">"Burishni tasdiqlash, klaviaturani almashtirish"</item>
+    <item msgid="8175437057325747277">"Hech biri"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Odatiy"</item>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 83bcae5..67bba1d 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"mở máy ảnh"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Chọn bố cục tác vụ mới"</string>
     <string name="cancel" msgid="6442560571259935130">"Hủy"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Biểu tượng vân tay"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Biểu tượng ứng dụng"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Vùng thông báo trợ giúp"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Nút thu phóng khả năng tương thích."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Thu phóng màn hình lớn hơn hoặc nhỏ hơn."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Đã kết nối bluetooth."</string>
@@ -275,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Tủ trưng bày bánh ngọt"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Trình bảo vệ m.hình"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Không làm phiền"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Chỉ ưu tiên"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Chỉ báo thức"</string>
@@ -311,6 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Tắt Wi-Fi"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi đang bật"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Không có mạng Wi-Fi"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"Báo thức"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Truyền"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Đang truyền"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Thiết bị không có tên"</string>
@@ -327,9 +329,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"Đang kết nối..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Đang dùng làm điểm truy cập Internet"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Điểm phát sóng"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"Đang bật..."</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="other">%d thiết bị</item>
+      <item quantity="one">%d thiết bị</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Thông báo"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Đèn pin"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Dữ liệu di động"</string>
@@ -339,10 +343,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Đã sử dụng <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Giới hạn <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Cảnh báo <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"Hồ sơ công việc"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"Thông báo và ứng dụng đã tắt"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Đèn đọc sách"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Bật khi trời tối"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Cho đến khi trời sáng"</string>
@@ -360,8 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> bị tắt ở chế độ an toàn."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Xóa tất cả"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Kéo vào đây để sử dụng chế độ chia đôi màn hình"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Phân tách ngang"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Phân tách dọc"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Tùy chỉnh phân tách"</string>
@@ -502,11 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"Tắt ngay bây giờ"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Mở rộng"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Thu gọn"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"Chuyển đổi thiết bị đầu ra"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Màn hình được ghim"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Thao tác này sẽ duy trì hiển thị màn hình cho đến khi bạn bỏ ghim. Hãy chạm và giữ Quay lại và Tổng quan để bỏ ghim."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Thao tác này sẽ duy trì hiển thị màn hình cho đến khi bạn bỏ ghim. Hãy chạm và giữ nút Quay lại và nút Màn hình chính để bỏ ghim."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Thao tác này sẽ duy trì hiển thị màn hình cho đến khi bạn bỏ ghim. Hãy chạm và giữ Tổng quan để bỏ ghim."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Thao tác này sẽ duy trì hiển thị màn hình cho đến khi bạn bỏ ghim. Hãy chạm và giữ nút Màn hình chính để bỏ ghim."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Để bỏ ghim màn hình này, hãy chạm và giữ nút Quay lại và nút Tổng quan"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Để bỏ ghim màn hình này, hãy chạm và giữ nút Quay lại và nút Màn hình chính"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Ok"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Không, cảm ơn"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Đã ghim màn hình"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Đã bỏ ghim màn hình"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Ẩn <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Thông báo này sẽ xuất hiện lại vào lần tiếp theo bạn bật thông báo trong cài đặt."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Ẩn"</string>
@@ -529,10 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Nhấn để tắt tiếng. Bạn có thể tắt tiếng dịch vụ trợ năng."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Nhấn để đặt chế độ rung."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Nhấn để tắt tiếng."</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for volume_dialog_accessibility_shown_message (1834631467074259998) -->
-    <skip />
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Các điều khiển âm lượng bị ẩn"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"Điều khiển âm lượng %s"</string>
     <string name="output_title" msgid="5355078100792942802">"Đầu ra phương tiện"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Đầu ra cuộc gọi điệnt thoại"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Không tìm thấy thiết bị nào"</string>
@@ -588,8 +592,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"Với các kiểm soát thông báo nguồn, bạn có thể đặt cấp độ quan trọng từ 0 đến 5 cho các thông báo của ứng dụng. \n\n"<b>"Cấp 5"</b>" \n- Hiển thị ở đầu danh sách thông báo \n- Cho phép gián đoạn ở chế độ toàn màn hình \n- Luôn xem nhanh \n\n"<b>"Cấp 4"</b>" \n- Ngăn gián đoạn ở chế độ toàn màn hình \n- Luôn xem nhanh \n\n"<b>"Cấp 3"</b>" \n- Ngăn gián đoạn ở chế độ toàn màn hình \n- Không bao giờ xem nhanh \n\n"<b>"Cấp 2"</b>" \n- Ngăn gián đoạn ở chế độ toàn màn hình \n- Không bao giờ xem nhanh \n- Không bao giờ có âm báo và rung \n\n"<b>"Cấp 1"</b>" \n- Ngăn gián đoạn ở chế độ toàn màn hình \n- Không bao giờ xem nhanh \n- Không bao giờ có âm báo và rung \n- Ẩn khỏi màn hình khóa và thanh trạng thái \n- Hiển thị ở cuối danh sách thông báo \n\n"<b>"Cấp 0"</b>" \n- Chặn tất cả các thông báo từ ứng dụng"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"Thông báo"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"Bạn sẽ không thấy các thông báo này nữa"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"Bạn thường bỏ qua những thông báo này. \nTiếp tục hiển thị thông báo?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"Tiếp tục hiển thị các thông báo này?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"Dừng thông báo"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Tiếp tục hiển thị"</string>
@@ -680,13 +683,7 @@
     <string name="left_nav_bar_button_type" msgid="8555981238887546528">"Loại nút bổ sung bên trái"</string>
     <string name="right_nav_bar_button_type" msgid="2481056627065649656">"Loại nút bổ sung bên phải"</string>
     <string name="nav_bar_default" msgid="8587114043070993007">"(mặc định)"</string>
-  <string-array name="nav_bar_buttons">
-    <item msgid="1545641631806817203">"Khay nhớ tạm"</item>
-    <item msgid="5742013440802239414">"Mã phím"</item>
-    <item msgid="8802889973626281575">"Trình chuyển đổi bàn phím"</item>
-    <item msgid="7095517796293767867">"Đề xuất xoay"</item>
-    <item msgid="8494159969042135235">"Không có"</item>
-  </string-array>
+    <!-- no translation found for nav_bar_buttons:2 (1951959982985094069) -->
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Bình thường"</item>
     <item msgid="8256205964297588988">"Cao"</item>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 559b2ea..ba25a2b 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"打开相机"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"选择新的任务布局"</string>
     <string name="cancel" msgid="6442560571259935130">"取消"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"指纹图标"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"应用图标"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"帮助消息区域"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"兼容性缩放按钮。"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"将小屏幕的图片放大在较大屏幕上显示。"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"蓝牙已连接。"</string>
@@ -275,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"甜品盒"</string>
     <string name="start_dreams" msgid="5640361424498338327">"屏保"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"有线网络"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"勿扰"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"仅限优先事项"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"仅限闹钟"</string>
@@ -311,6 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"WLAN:关闭"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"WLAN 已开启"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"没有 WLAN 网络"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"闹钟"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"投射"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"正在投射"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"未命名设备"</string>
@@ -327,9 +329,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"正在连接…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"网络共享"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"热点"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"正在开启…"</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="other">%d 台设备</item>
+      <item quantity="one">%d 台设备</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"通知"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"手电筒"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"移动数据"</string>
@@ -339,10 +343,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"已使用<xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"上限为<xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g>警告"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"工作资料"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"通知和应用均已关闭"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"夜间模式"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"在日落时开启"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"在日出时关闭"</string>
@@ -360,8 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g>已在安全模式下停用。"</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"全部清除"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"在此处拖动即可使用分屏功能"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"水平分割"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"垂直分割"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"自定义分割"</string>
@@ -502,11 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"立即关闭"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"展开"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"收起"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"切换输出设备"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"已固定屏幕"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"这将会固定显示此屏幕,直到您取消固定为止。触摸并按住“返回”和“概览”即可取消固定屏幕。"</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"这将会固定显示此屏幕,直到您取消固定为止。触摸并按住“返回”和“主屏幕”即可取消固定屏幕。"</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"这将会固定显示此屏幕,直到您取消固定为止。触摸并按住“概览”即可取消固定屏幕。"</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"这将会固定显示此屏幕,直到您取消固定为止。触摸并按住“主屏幕”即可取消固定屏幕。"</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"要取消固定此屏幕,请触摸并按住“返回”和“概览”按钮"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"要取消固定此屏幕,请触摸并按住“返回”和“主屏幕”按钮"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"知道了"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"不用了"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"已固定屏幕"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"已取消固定屏幕"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"要隐藏“<xliff:g id="TILE_LABEL">%1$s</xliff:g>”吗?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"下次在设置中将其开启后,此快捷设置条目将会重新显示。"</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"隐藏"</string>
@@ -529,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s。点按即可设为静音,但可能会同时将无障碍服务设为静音。"</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s。点按即可设为振动。"</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s。点按即可设为静音。"</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"已显示%s音量控件。向上滑动即可关闭。"</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"已隐藏音量控件"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s音量控件"</string>
     <string name="output_title" msgid="5355078100792942802">"媒体输出"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"通话输出"</string>
     <string name="output_none_found" msgid="5544982839808921091">"未找到任何设备"</string>
@@ -586,8 +592,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"利用高级通知设置,您可以为应用通知设置从 0 级到 5 级的重要程度等级。\n\n"<b>"5 级"</b>" \n- 在通知列表顶部显示 \n- 允许全屏打扰 \n- 一律短暂显示通知 \n\n"<b>"4 级"</b>" \n- 禁止全屏打扰 \n- 一律短暂显示通知 \n\n"<b>"3 级"</b>" \n- 禁止全屏打扰 \n- 一律不短暂显示通知 \n\n"<b>"2 级"</b>" \n- 禁止全屏打扰 \n- 一律不短暂显示通知 \n- 一律不发出声音或振动 \n\n"<b>"1 级"</b>" \n- 禁止全屏打扰 \n- 一律不短暂显示通知 \n- 一律不发出声音或振动 \n- 不在锁定屏幕和状态栏中显示 \n- 在通知列表底部显示 \n\n"<b>"0 级"</b>" \n- 屏蔽应用的所有通知"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"通知"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"您将不会再看到这些通知"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"您通常会关闭这些通知。\n是否继续显示通知?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"要继续显示这些通知吗?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"停止通知"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"继续显示"</string>
@@ -681,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"剪贴板"</item>
     <item msgid="5742013440802239414">"键码"</item>
-    <item msgid="8802889973626281575">"键盘切换器"</item>
-    <item msgid="7095517796293767867">"旋转建议"</item>
-    <item msgid="8494159969042135235">"无"</item>
+    <item msgid="1951959982985094069">"确认旋转、键盘切换器"</item>
+    <item msgid="8175437057325747277">"无"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"一般"</item>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 0283092..5c56bbf 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -103,12 +103,11 @@
     <string name="camera_label" msgid="7261107956054836961">"開啟相機"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"選取新的工作版面配置"</string>
     <string name="cancel" msgid="6442560571259935130">"取消"</string>
-    <!-- no translation found for accessibility_fingerprint_dialog_fingerprint_icon (3125122495414253226) -->
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
     <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_app_icon (3228052542929174609) -->
-    <skip />
-    <!-- no translation found for accessibility_fingerprint_dialog_help_area (5730471601819225159) -->
-    <skip />
+    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"指紋圖示"</string>
+    <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"應用程式圖示"</string>
+    <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"說明訊息區域"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"相容性縮放按鈕。"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"將較小螢幕的畫面放大在較大螢幕上顯示。"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"藍牙連線已建立。"</string>
@@ -277,6 +276,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Dessert Case"</string>
     <string name="start_dreams" msgid="5640361424498338327">"螢幕保護程式"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"以太網"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"請勿騷擾"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"只限優先"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"只限鬧鐘"</string>
@@ -313,6 +314,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi 關閉"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi 已開啟"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"沒有可用的 Wi-Fi 網絡"</string>
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"鬧鐘"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"投放"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"正在放送"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"未命名的裝置"</string>
@@ -329,9 +331,11 @@
     <string name="quick_settings_connecting" msgid="47623027419264404">"正在連線…"</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"網絡共享"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"熱點"</string>
-    <!-- no translation found for quick_settings_hotspot_secondary_label_transient (7161046712706277215) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_secondary_label_num_devices (2324635800672199428) -->
+    <string name="quick_settings_hotspot_secondary_label_transient" msgid="7161046712706277215">"正在開啟…"</string>
+    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="2324635800672199428">
+      <item quantity="other">%d 部裝置</item>
+      <item quantity="one">%d 部裝置</item>
+    </plurals>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"通知"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"閃光燈"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"流動數據"</string>
@@ -341,10 +345,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"已使用 <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"上限為 <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> 警告"</string>
-    <!-- no translation found for quick_settings_work_mode_on_label (3421274215098764735) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_off_label (8856918707867192186) -->
-    <skip />
+    <string name="quick_settings_work_mode_on_label" msgid="3421274215098764735">"工作設定檔"</string>
+    <string name="quick_settings_work_mode_off_label" msgid="8856918707867192186">"通知和應用程式已關閉"</string>
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"夜燈模式"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"在日落時開啟"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"在日出時關閉"</string>
@@ -362,8 +364,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"「<xliff:g id="APP">%s</xliff:g>」已在安全模式中停用。"</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"全部清除"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"在這裡拖曳即可分割螢幕"</string>
-    <!-- no translation found for recents_swipe_up_onboarding (3824607135920170001) -->
-    <skip />
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"水平分割"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"垂直分割"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"自訂分割"</string>
@@ -504,11 +504,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"立即關閉"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"展開"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"收合"</string>
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"切換輸出裝置"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"螢幕已固定"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"畫面將會繼續顯示,直至您取消固定。按住 [返回] 和 [概覽] 即可取消固定。"</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"畫面將會繼續顯示,直至您取消固定為止。按住 [返回] 按鈕和主按鈕即可取消固定。"</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"畫面將會繼續顯示,直至您取消固定。按住 [概覽] 即可取消固定。"</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"畫面將會繼續顯示,直至您取消固定為止。按住主按鈕即可取消固定。"</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"如要取消固定此畫面,請按住 [返回] 按鈕和 [概覽] 按鈕"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"如要取消固定此畫面,請按住 [返回] 按鈕和主按鈕"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"知道了"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"不用了,謝謝"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"已固定畫面"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"已取消固定畫面"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"隱藏 <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"下一次您在設定開啟它時,它將再次出現。"</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"隱藏"</string>
@@ -531,8 +538,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s。輕按即可設為靜音。無障礙功能服務可能已經設為靜音。"</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s。輕按即可設為震動。"</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s。輕按即可設為靜音。"</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"已顯示 %s 音量控制項。向上快速滑動即可關閉。"</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"已隱藏音量控制"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s音量控制項"</string>
     <string name="output_title" msgid="5355078100792942802">"媒體輸出"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"通話輸出"</string>
     <string name="output_none_found" msgid="5544982839808921091">"找不到裝置"</string>
@@ -588,8 +594,7 @@
     <string name="power_notification_controls_description" msgid="4372459941671353358">"通知控制項讓您設定應用程式通知的重要性 (0 至 5 級)。\n\n"<b>"第 5 級"</b>" \n- 在通知清單頂部顯示 \n- 允許全螢幕騷擾 \n- 一律顯示通知 \n\n"<b>"第 4 級"</b>" \n- 阻止全螢幕騷擾 \n- 一律顯示通知 \n\n"<b>"第 3 級"</b>" \n- 阻止全螢幕騷擾 \n- 永不顯示通知 \n\n"<b>"第 2 級"</b>" \n- 阻止全螢幕騷擾 \n- 永不顯示通知 \n- 永不發出聲響和震動 \n\n"<b>"第 1 級"</b>" \n- 阻止全螢幕騷擾 \n- 永不顯示通知 \n- 永不發出聲響和震動 \n- 從上鎖畫面和狀態列中隱藏 \n- 在通知清單底部顯示 \n\n"<b>"第 0 級"</b>" \n- 封鎖所有應用程式通知"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"通知"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"您不會再看到這些通知"</string>
-    <!-- no translation found for inline_blocking_helper (3055064577771478591) -->
-    <skip />
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"您通常會關閉這些通知。\n要繼續顯示通知嗎?"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"要繼續顯示這些通知嗎?"</string>
     <string name="inline_stop_button" msgid="4172980096860941033">"停止通知"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"繼續顯示"</string>
@@ -683,9 +688,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"剪貼簿"</item>
     <item msgid="5742013440802239414">"按鍵碼"</item>
-    <item msgid="8802889973626281575">"鍵盤切換工具"</item>
-    <item msgid="7095517796293767867">"旋轉建議"</item>
-    <item msgid="8494159969042135235">"無"</item>
+    <item msgid="1951959982985094069">"確認旋轉、鍵盤切換工具"</item>
+    <item msgid="8175437057325747277">"無"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"一般"</item>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 9c425b0..ffc5b6d 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"開啟攝影機"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"選取新工作版面配置"</string>
     <string name="cancel" msgid="6442560571259935130">"取消"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"指紋圖示"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"應用程式圖示"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"說明訊息區域"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Dessert Case"</string>
     <string name="start_dreams" msgid="5640361424498338327">"螢幕保護程式"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"乙太網路"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"零打擾"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"僅限優先通知"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"僅限鬧鐘"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi 已關閉"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"已開啟 Wi-Fi"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"沒有 Wi-Fi 網路"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"鬧鐘"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"投放"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"投放"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"未命名的裝置"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"「<xliff:g id="APP">%s</xliff:g>」在安全模式中為停用狀態。"</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"全部清除"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"拖曳到這裡即可使用分割畫面"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"向上滑動即可切換應用程式"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"水平分割"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"垂直分割"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"自訂分割"</string>
@@ -500,25 +502,18 @@
     <string name="volume_zen_end_now" msgid="6930243045593601084">"立即停用"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"展開"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"收合"</string>
-    <!-- no translation found for accessibility_output_chooser (8185317493017988680) -->
-    <skip />
+    <string name="accessibility_output_chooser" msgid="8185317493017988680">"切換輸出裝置"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"螢幕已固定"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"這會讓目前的螢幕畫面保持顯示狀態,直到取消固定為止。按住 [返回] 按鈕和 [總覽] 按鈕即可取消固定。"</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"這會讓應用程式顯示在螢幕上,直到取消固定為止。按住 [返回] 按鈕和主螢幕按鈕即可取消固定。"</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"這會讓目前的螢幕畫面保持顯示狀態,直到取消固定為止。按住 [總覽] 按鈕即可取消固定。"</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"這會讓應用程式顯示在螢幕上,直到取消固定為止。按住主螢幕按鈕即可取消固定。"</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"如要取消固定這個螢幕畫面,請按住「返回」按鈕和「總覽」按鈕"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"如要取消固定這個螢幕畫面,請按住「返回」按鈕和主螢幕按鈕"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"知道了"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"不用了,謝謝"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"已固定螢幕畫面"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"已取消固定螢幕畫面"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"隱藏<xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"只要在設定頁面中重新啟用,就能再次看到快捷設定選項。"</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"隱藏"</string>
@@ -541,8 +536,13 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s。輕觸即可設為靜音,但系統可能會將無障礙服務一併設為靜音。"</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s。輕觸即可設為震動。"</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s。輕觸即可設為靜音。"</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"已顯示 %s 個音量控制項。向上滑動即可關閉。"</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"已隱藏音量控制項"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"「%s」音量控制項"</string>
+    <!-- no translation found for volume_dialog_ringer_guidance_vibrate (8902050240801159042) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_silent (2128975224280276122) -->
+    <skip />
+    <!-- no translation found for volume_dialog_ringer_guidance_ring (6144469689490528338) -->
+    <skip />
     <string name="output_title" msgid="5355078100792942802">"媒體輸出"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"通話輸出"</string>
     <string name="output_none_found" msgid="5544982839808921091">"找不到裝置"</string>
@@ -692,9 +692,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"剪貼簿"</item>
     <item msgid="5742013440802239414">"按鍵碼"</item>
-    <item msgid="8802889973626281575">"鍵盤切換工具"</item>
-    <item msgid="7095517796293767867">"旋轉建議"</item>
-    <item msgid="8494159969042135235">"無"</item>
+    <item msgid="1951959982985094069">"確認旋轉,鍵盤切換工具"</item>
+    <item msgid="8175437057325747277">"無"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"一般"</item>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index d291a19..1195ebc 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -103,6 +103,8 @@
     <string name="camera_label" msgid="7261107956054836961">"vula ikhamera"</string>
     <string name="recents_caption_resize" msgid="3517056471774958200">"Khetha isakhiwo somsebenzi omusha"</string>
     <string name="cancel" msgid="6442560571259935130">"Khansela"</string>
+    <!-- no translation found for fingerprint_dialog_touch_sensor (8511557690663181761) -->
+    <skip />
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Isithonjana sezigxivizo zeminwe"</string>
     <string name="accessibility_fingerprint_dialog_app_icon" msgid="3228052542929174609">"Isithonjana sohlelo lokusebenza"</string>
     <string name="accessibility_fingerprint_dialog_help_area" msgid="5730471601819225159">"Indawo yosizo lomlayezo"</string>
@@ -272,6 +274,8 @@
     <string name="dessert_case" msgid="1295161776223959221">"Isikhwama soswidi"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Isigcini sihenqo"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"I-Ethernet"</string>
+    <!-- no translation found for quick_settings_header_onboarding_text (7872508260264044734) -->
+    <skip />
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Ungaphazamisi"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Okubalulekile kuphela"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Ama-alamu kuphela"</string>
@@ -308,8 +312,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"I-Wi-Fi icimile"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"I-Wi-Fi ivuliwe"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Awekho amanethiwekhi we-Wi-Fi atholakalayo"</string>
-    <!-- no translation found for quick_settings_alarm_title (2416759007342260676) -->
-    <skip />
+    <string name="quick_settings_alarm_title" msgid="2416759007342260676">"I-alamu"</string>
     <string name="quick_settings_cast_title" msgid="7709016546426454729">"Abalingisi"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Ukusakaza"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Idivayisi engenalo igama"</string>
@@ -359,7 +362,6 @@
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"I-<xliff:g id="APP">%s</xliff:g> ikhutshaziwe kumodi yokuphepha."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Sula konke"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"Hudulela lapha ukuze usebenzise ukuhlukanisa kwesikrini"</string>
-    <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Swayiphela phezulu ukuze ushintshe izinhlelo zokusebenza"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Hlukanisa okuvundlile"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Hlukanisa okumile"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Hlukanisa kwezifiso"</string>
@@ -503,21 +505,15 @@
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"Shintsha idivayisi yokukhipha"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Isikrini siphiniwe"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Lokhu kuyigcina ibukeka uze ususe ukuphina. Thinta uphinde ubambe okuthi Emuva Nokubuka konke ukuze ususe ukuphina."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible (8281145542163727971) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Lokhu kuyigcina ibonakala uze uyisuse. Thinta uphinde ubambe okuthi Emuva nokuthi Ekhaya ukuze ususe ukuphina."</string>
     <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Lokhu kuyigcina ibukeka uze ususe ukuphina. Thinta uphinde ubambe Ukubuka konke ukuze ususe ukuphina."</string>
-    <!-- no translation found for screen_pinning_description_recents_invisible_accessible (6134833683151189507) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast (2266705122951934150) -->
-    <skip />
-    <!-- no translation found for screen_pinning_toast_recents_invisible (8252402309499161281) -->
-    <skip />
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Lokhu kuyigcina ibukeka uze ususe ukuphina. Thinta uphinde ubambe okuthi Ekhaya ukuze ususe ukuphina."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Ukuze ususe ukuphina lesi sikrini, thinta uphinde ubambe izinkinobho zokubuyela emuva nezokubuka konke"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Ukuze ususe ukuphina lesi sikrini, thinta uphinde ubambe izinkinobho nezithi Emuva nethi Ekhaya"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Ngiyitholile"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Cha ngiyabonga"</string>
-    <!-- no translation found for screen_pinning_start (1022122128489278317) -->
-    <skip />
-    <!-- no translation found for screen_pinning_exit (5187339744262325372) -->
-    <skip />
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Isikrini siphiniwe"</string>
+    <string name="screen_pinning_exit" msgid="5187339744262325372">"Isikrini sisuswe ukuphina"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Fihla i-<xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Izovela ngesikhathi esilandelayo uma uvule lesi silungiselelo."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Fihla"</string>
@@ -540,8 +536,7 @@
     <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Thepha ukuze uthulise. Amasevisi okufinyelela angathuliswa."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Thepha ukuze usethele ekudlidlizeni."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Thepha ukuze uthulise."</string>
-    <string name="volume_dialog_accessibility_shown_message" msgid="1834631467074259998">"%s izilawuli zevolumu ziyaboniswa. Swayiphela phezulu ukuze ulahle."</string>
-    <string name="volume_dialog_accessibility_dismissed_message" msgid="51543526013711399">"Izilawuli zevolumi zifihliwe"</string>
+    <string name="volume_dialog_title" msgid="7272969888820035876">"%s izilawuli zevolomu"</string>
     <string name="output_title" msgid="5355078100792942802">"Okukhiphayo kwemidiya"</string>
     <string name="output_calls_title" msgid="8717692905017206161">"Okukhiphayo kwekholi yefoni"</string>
     <string name="output_none_found" msgid="5544982839808921091">"Awekho amadivayisi atholiwe"</string>
@@ -691,9 +686,8 @@
   <string-array name="nav_bar_buttons">
     <item msgid="1545641631806817203">"Ibhodi lokumanathisela"</item>
     <item msgid="5742013440802239414">"Ikhodi yokhiye"</item>
-    <item msgid="8802889973626281575">"Isishintshi sekhibhodi"</item>
-    <item msgid="7095517796293767867">"Isiphakamiso sokuzungezisa"</item>
-    <item msgid="8494159969042135235">"Lutho"</item>
+    <item msgid="1951959982985094069">"Qinisekisa ukuzungezisa, isishintshi sekhibhodi"</item>
+    <item msgid="8175437057325747277">"Akunalutho"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="8077901629964902399">"Okujwayelekile"</item>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index f0a5fe4..b11266a 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -136,5 +136,9 @@
         <attr name="singleLineButtonPaddingHorizontal" format="dimension" />
         <attr name="doubleLineButtonPaddingHorizontal" format="dimension" />
     </declare-styleable>
+
+    <!-- Used to style rotate suggestion button AVD animations -->
+    <attr name="rotateButtonStartAngle" format="float" />
+    <attr name="rotateButtonEndAngle" format="float" />
 </resources>
 
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index cf0659a..a444ff9 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -124,7 +124,7 @@
 
     <!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" -->
     <string name="quick_settings_tiles_stock" translatable="false">
-        wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,saver,work,cast,night,alarm
+        wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,saver,work,cast,night
     </string>
 
     <!-- The tiles to display in QuickSettings -->
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index e679fcd..7b1a9e1 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -259,16 +259,28 @@
 
     <dimen name="notification_panel_width">@dimen/match_parent</dimen>
 
+    <dimen name="brightness_mirror_height">108dp</dimen>
+
     <!-- The width of the panel that holds the quick settings. -->
     <dimen name="qs_panel_width">@dimen/notification_panel_width</dimen>
 
     <!-- the amount the volume panel should be offset at the end from the view next to it (or
-    the scren edge, in portrait-->
-    <dimen name="volume_dialog_base_margin">12dp</dimen>
+    the screen edge, in portrait-->
+    <dimen name="volume_dialog_base_margin">8dp</dimen>
 
-    <dimen name="volume_dialog_panel_width">100dp</dimen>
+    <dimen name="volume_dialog_panel_width">64dp</dimen>
 
-    <dimen name="output_chooser_panel_width">320dp</dimen>
+    <dimen name="volume_dialog_slider_height">101dp</dimen>
+
+    <dimen name="volume_dialog_row_height">252dp</dimen>
+
+    <dimen name="volume_dialog_ringer_size">64dp</dimen>
+
+    <dimen name="volume_dialog_tap_target_size">48dp</dimen>
+
+    <dimen name="volume_dialog_spacer">4dp</dimen>
+
+    <dimen name="volume_dialog_slider_margin_top">13dp</dimen>
 
     <!-- Gravity for the notification panel -->
     <integer name="notification_panel_layout_gravity">0x31</integer><!-- center_horizontal|top -->
@@ -289,11 +301,13 @@
     <dimen name="pull_span_min">25dp</dimen>
 
     <dimen name="qs_tile_height">106dp</dimen>
-    <dimen name="qs_tile_margin">19dp</dimen>
-    <dimen name="qs_tile_margin_top">16dp</dimen>
+    <dimen name="qs_tile_margin_horizontal">18dp</dimen>
+    <dimen name="qs_tile_margin_vertical">24dp</dimen>
+    <dimen name="qs_tile_margin_top">18dp</dimen>
     <dimen name="qs_quick_tile_size">48dp</dimen>
     <dimen name="qs_quick_tile_padding">12dp</dimen>
     <dimen name="qs_header_gear_translation">16dp</dimen>
+    <dimen name="qs_header_tile_margin_horizontal">0dp</dimen>
     <dimen name="qs_page_indicator_width">16dp</dimen>
     <dimen name="qs_page_indicator_height">8dp</dimen>
     <dimen name="qs_tile_icon_size">24dp</dimen>
@@ -309,13 +323,13 @@
     <dimen name="qs_tile_padding_bottom">16dp</dimen>
     <dimen name="qs_tile_spacing">4dp</dimen>
     <dimen name="qs_panel_padding_bottom">0dp</dimen>
+    <dimen name="qs_panel_padding_top">30dp</dimen>
     <dimen name="qs_detail_header_height">56dp</dimen>
     <dimen name="qs_detail_header_padding">0dp</dimen>
     <dimen name="qs_detail_image_width">56dp</dimen>
     <dimen name="qs_detail_image_height">56dp</dimen>
     <dimen name="qs_detail_image_padding">16dp</dimen>
     <dimen name="qs_detail_item_height">48dp</dimen>
-    <dimen name="qs_brightness_padding_top">6dp</dimen>
     <dimen name="qs_detail_header_text_size">20sp</dimen>
     <dimen name="qs_detail_button_text_size">14sp</dimen>
     <dimen name="qs_detail_item_primary_text_size">16sp</dimen>
@@ -333,11 +347,12 @@
     <dimen name="qs_detail_item_icon_width">32dp</dimen>
     <dimen name="qs_detail_item_icon_marginStart">0dp</dimen>
     <dimen name="qs_detail_item_icon_marginEnd">20dp</dimen>
+    <dimen name="qs_header_tooltip_height">18dp</dimen>
+    <dimen name="qs_header_alarm_icon_size">18dp</dimen>
+    <dimen name="qs_header_alarm_text_margin_start">6dp</dimen>
     <dimen name="qs_footer_padding_start">16dp</dimen>
     <dimen name="qs_footer_padding_end">24dp</dimen>
     <dimen name="qs_footer_icon_size">16dp</dimen>
-    <!-- Difference between drag handle margin in QQS and expanded QS -->
-    <dimen name="qs_footer_drag_handle_offset">10dp</dimen>
 
     <dimen name="qs_notif_collapsed_space">64dp</dimen>
 
@@ -359,6 +374,9 @@
     <!-- Padding between subtitles and the following text in the QSFooter dialog -->
     <dimen name="qs_footer_dialog_subtitle_padding">20dp</dimen>
 
+    <dimen name="seek_bar_height">3dp</dimen>
+    <dimen name="seek_bar_corner_radius">3dp</dimen>
+
     <!-- Zen mode panel: condition item button padding -->
     <dimen name="zen_mode_condition_detail_button_padding">8dp</dimen>
 
@@ -423,15 +441,10 @@
     <!-- Minimum distance the user has to drag down to go to the full shade. -->
     <dimen name="keyguard_drag_down_min_distance">100dp</dimen>
 
-    <!-- The fraction of the screen height where the clock on the Keyguard has its center. The
-         max value is used when no notifications are displaying, and the min value is when the
-         highest possible number of notifications are showing. -->
-    <fraction name="keyguard_clock_y_fraction_max">45%</fraction>
-    <fraction name="keyguard_clock_y_fraction_min">19.8%</fraction>
-
-    <!-- The margin between the clock and the notifications on Keyguard. See
-         keyguard_clock_height_fraction_* for the difference between min and max.-->
+    <!-- The margin between the clock and the notifications on Keyguard.-->
     <dimen name="keyguard_clock_notifications_margin">30dp</dimen>
+    <!-- Minimum margin between clock and top of screen or ambient indication -->
+    <dimen name="keyguard_clock_top_margin">26dp</dimen>
     <dimen name="heads_up_scrim_height">250dp</dimen>
 
     <item name="scrim_behind_alpha" format="float" type="dimen">0.62</item>
@@ -869,9 +882,6 @@
             burn-in on AOD -->
     <dimen name="burn_in_prevention_offset_y">50dp</dimen>
 
-    <!-- padding between the notification stack and the keyguard status view when dozing -->
-    <dimen name="dozing_stack_padding">30dp</dimen>
-
     <dimen name="corner_size">16dp</dimen>
     <dimen name="top_padding">0dp</dimen>
     <dimen name="bottom_padding">48dp</dimen>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 2d30f4c..0e92c60 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -47,7 +47,6 @@
     <item type="id" name="qs_icon_tag"/>
     <item type="id" name="qs_slash_tag"/>
     <item type="id" name="scrim"/>
-    <item type="id" name="scrim_target"/>
     <item type="id" name="scrim_alpha_start"/>
     <item type="id" name="scrim_alpha_end"/>
     <item type="id" name="notification_power"/>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 0b5b7bd..9245ac1 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -668,6 +668,8 @@
     <!-- Textual description of Ethernet connections -->
     <string name="ethernet_label">Ethernet</string>
 
+    <!-- QuickSettings: Onboarding text that introduces users to long press on an option in order to view the option's menu in Settings [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_header_onboarding_text">Press &amp; hold on the icons for more options</string>
     <!-- QuickSettings: Do not disturb [CHAR LIMIT=NONE] -->
     <string name="quick_settings_dnd_label">Do not disturb</string>
     <!-- QuickSettings: Do not disturb - Priority only [CHAR LIMIT=NONE] -->
@@ -741,8 +743,6 @@
     <string name="quick_settings_wifi_on_label">Wi-Fi On</string>
     <!-- QuickSettings: Wifi detail panel, text when there are no items [CHAR LIMIT=NONE] -->
     <string name="quick_settings_wifi_detail_empty_text">No Wi-Fi networks available</string>
-    <!-- QuickSettings: Alarm title [CHAR LIMIT=NONE] -->
-    <string name="quick_settings_alarm_title">Alarm</string>
     <!-- QuickSettings: Cast title [CHAR LIMIT=NONE] -->
     <string name="quick_settings_cast_title">Cast</string>
     <!-- QuickSettings: Cast detail panel, status text when casting [CHAR LIMIT=NONE] -->
@@ -947,13 +947,13 @@
     <string name="interruption_level_alarms_twoline">Alarms\nonly</string>
 
     <!-- Indication on the keyguard that is shown when the device is charging. [CHAR LIMIT=40]-->
-    <string name="keyguard_indication_charging_time">Charging (<xliff:g id="charging_time_left" example="4 hours and 2 minutes">%s</xliff:g> until full)</string>
+    <string name="keyguard_indication_charging_time"><xliff:g id="percentage">%2$s</xliff:g> • Charging (<xliff:g id="charging_time_left" example="4 hours and 2 minutes">%s</xliff:g> until full)</string>
 
     <!-- Indication on the keyguard that is shown when the device is charging rapidly. Should match keyguard_plugged_in_charging_fast [CHAR LIMIT=40]-->
-    <string name="keyguard_indication_charging_time_fast">Charging rapidly (<xliff:g id="charging_time_left" example="4 hours and 2 minutes">%s</xliff:g> until full)</string>
+    <string name="keyguard_indication_charging_time_fast"><xliff:g id="percentage">%2$s</xliff:g> • Charging rapidly (<xliff:g id="charging_time_left" example="4 hours and 2 minutes">%s</xliff:g> until full)</string>
 
     <!-- Indication on the keyguard that is shown when the device is charging slowly. Should match keyguard_plugged_in_charging_slowly [CHAR LIMIT=40]-->
-    <string name="keyguard_indication_charging_time_slowly">Charging slowly (<xliff:g id="charging_time_left" example="4 hours and 2 minutes">%s</xliff:g> until full)</string>
+    <string name="keyguard_indication_charging_time_slowly"><xliff:g id="percentage">%2$s</xliff:g> • Charging slowly (<xliff:g id="charging_time_left" example="4 hours and 2 minutes">%s</xliff:g> until full)</string>
 
     <!-- Related to user switcher --><skip/>
 
@@ -1344,6 +1344,10 @@
 
     <string name="volume_dialog_title">%s volume controls</string>
 
+    <string name="volume_dialog_ringer_guidance_vibrate">Calls and notifications will vibrate</string>
+    <string name="volume_dialog_ringer_guidance_silent">Calls and notifications will be muted</string>
+    <string name="volume_dialog_ringer_guidance_ring">Calls and notifications will ring</string>
+
     <string name="output_title">Media output</string>
     <string name="output_calls_title">Phone call output</string>
     <string name="output_none_found">No devices found</string>
@@ -2134,4 +2138,8 @@
     <!-- Option to grant the slice permission request on the screen [CHAR LIMIT=15] -->
     <string name="slice_permission_deny">Deny</string>
 
+    <!-- List of packages for which we don't want to show recents onboarding, add into overlay as needed. -->
+    <string-array name="recents_onboarding_blacklisted_packages" translatable="false">
+    </string-array>
+
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index d2ed4d1..a01f71a 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -485,4 +485,25 @@
         <item name="android:colorBackground">?android:attr/colorSecondary</item>
     </style>
 
+    <!-- Used to style rotate suggestion button AVD animations -->
+    <style name="RotateButtonCCWStart0">
+        <item name="rotateButtonStartAngle">0</item>
+        <item name="rotateButtonEndAngle">-90</item>
+    </style>
+
+    <style name="RotateButtonCCWStart90">
+        <item name="rotateButtonStartAngle">90</item>
+        <item name="rotateButtonEndAngle">0</item>
+    </style>
+
+    <style name="RotateButtonCWStart0">
+        <item name="rotateButtonStartAngle">0</item>
+        <item name="rotateButtonEndAngle">90</item>
+    </style>
+
+    <style name="RotateButtonCWStart90">
+        <item name="rotateButtonStartAngle">90</item>
+        <item name="rotateButtonEndAngle">180</item>
+    </style>
+
 </resources>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
index b8319a8e..846aadd 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
@@ -28,25 +28,30 @@
      * Proxies SurfaceControl.screenshotToBuffer().
      */
     GraphicBufferCompat screenshot(in Rect sourceCrop, int width, int height, int minLayer,
-            int maxLayer, boolean useIdentityTransform, int rotation);
+            int maxLayer, boolean useIdentityTransform, int rotation) = 0;
 
     /**
      * Begins screen pinning on the provided {@param taskId}.
      */
-    void startScreenPinning(int taskId);
+    void startScreenPinning(int taskId) = 1;
 
     /**
      * Called when the overview service has started the recents animation.
      */
-    void onRecentsAnimationStarted();
+    void onRecentsAnimationStarted() = 2;
 
     /**
      * Specifies the text to be shown for onboarding the new swipe-up gesture to access recents.
      */
-    void setRecentsOnboardingText(CharSequence text);
+    void setRecentsOnboardingText(CharSequence text) = 3;
 
     /**
      * Enables/disables launcher/overview interaction features {@link InteractionType}.
      */
-    void setInteractionState(int flags);
+    void setInteractionState(int flags) = 4;
+
+    /**
+    * Notifies SystemUI that split screen has been invoked.
+    */
+    void onSplitScreenInvoked() = 5;
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/BackgroundTaskLoader.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/BackgroundTaskLoader.java
index ddd27b0..a0e7752 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/BackgroundTaskLoader.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/BackgroundTaskLoader.java
@@ -17,15 +17,12 @@
 package com.android.systemui.shared.recents.model;
 
 import android.content.Context;
-import android.content.pm.ActivityInfo;
-import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.util.Log;
 
 import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.PackageManagerWrapper;
 
 /**
  * Background task resource loader
@@ -40,8 +37,7 @@
     private final Handler mMainThreadHandler;
 
     private final TaskResourceLoadQueue mLoadQueue;
-    private final TaskKeyLruCache<Drawable> mIconCache;
-    private final BitmapDrawable mDefaultIcon;
+    private final IconLoader mIconLoader;
 
     private boolean mStarted;
     private boolean mCancelled;
@@ -51,11 +47,9 @@
 
     /** Constructor, creates a new loading thread that loads task resources in the background */
     public BackgroundTaskLoader(TaskResourceLoadQueue loadQueue,
-            TaskKeyLruCache<Drawable> iconCache, BitmapDrawable defaultIcon,
-            OnIdleChangedListener onIdleChangedListener) {
+            IconLoader iconLoader, OnIdleChangedListener onIdleChangedListener) {
         mLoadQueue = loadQueue;
-        mIconCache = iconCache;
-        mDefaultIcon = defaultIcon;
+        mIconLoader = iconLoader;
         mMainThreadHandler = new Handler();
         mOnIdleChangedListener = onIdleChangedListener;
         mLoadThread = new HandlerThread("Recents-TaskResourceLoader",
@@ -140,32 +134,7 @@
         // Load the next item from the queue
         final Task t = mLoadQueue.nextTask();
         if (t != null) {
-            Drawable cachedIcon = mIconCache.get(t.key);
-
-            // Load the icon if it is stale or we haven't cached one yet
-            if (cachedIcon == null) {
-                cachedIcon = ActivityManagerWrapper.getInstance().getBadgedTaskDescriptionIcon(
-                        mContext, t.taskDescription, t.key.userId, mContext.getResources());
-
-                if (cachedIcon == null) {
-                    ActivityInfo info = PackageManagerWrapper.getInstance().getActivityInfo(
-                            t.key.getComponent(), t.key.userId);
-                    if (info != null) {
-                        if (DEBUG) Log.d(TAG, "Loading icon: " + t.key);
-                        cachedIcon = ActivityManagerWrapper.getInstance().getBadgedActivityIcon(
-                                info, t.key.userId);
-                    }
-                }
-
-                if (cachedIcon == null) {
-                    cachedIcon = mDefaultIcon;
-                }
-
-                // At this point, even if we can't load the icon, we will set the
-                // default icon.
-                mIconCache.put(t.key, cachedIcon);
-            }
-
+            final Drawable icon = mIconLoader.getIcon(t);
             if (DEBUG) Log.d(TAG, "Loading thumbnail: " + t.key);
             final ThumbnailData thumbnailData =
                     ActivityManagerWrapper.getInstance().getTaskThumbnail(t.key.id,
@@ -173,9 +142,8 @@
 
             if (!mCancelled) {
                 // Notify that the task data has changed
-                final Drawable finalIcon = cachedIcon;
                 mMainThreadHandler.post(
-                        () -> t.notifyTaskDataLoaded(thumbnailData, finalIcon));
+                        () -> t.notifyTaskDataLoaded(thumbnailData, icon));
             }
         }
     }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/IconLoader.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/IconLoader.java
new file mode 100644
index 0000000..3bc1d9a
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/IconLoader.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.shared.recents.model;
+
+import android.app.ActivityManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
+import android.util.IconDrawableFactory;
+import android.util.Log;
+import android.util.LruCache;
+
+import com.android.systemui.shared.system.PackageManagerWrapper;
+
+public abstract class IconLoader {
+
+    private static final String TAG = "IconLoader";
+
+    protected final Context mContext;
+    protected final TaskKeyLruCache<Drawable> mIconCache;
+    protected final LruCache<ComponentName, ActivityInfo> mActivityInfoCache;
+
+    public IconLoader(Context context, TaskKeyLruCache<Drawable> iconCache, LruCache<ComponentName,
+            ActivityInfo> activityInfoCache) {
+        mContext = context;
+        mIconCache = iconCache;
+        mActivityInfoCache = activityInfoCache;
+    }
+
+    /**
+     * Returns the activity info for the given task key, retrieving one from the system if the
+     * task key is expired.
+     *
+     * TODO: Move this to an ActivityInfoCache class
+     */
+    public ActivityInfo getAndUpdateActivityInfo(Task.TaskKey taskKey) {
+        ComponentName cn = taskKey.getComponent();
+        ActivityInfo activityInfo = mActivityInfoCache.get(cn);
+        if (activityInfo == null) {
+            activityInfo = PackageManagerWrapper.getInstance().getActivityInfo(cn, taskKey.userId);
+            if (cn == null || activityInfo == null) {
+                Log.e(TAG, "Unexpected null component name or activity info: " + cn + ", " +
+                        activityInfo);
+                return null;
+            }
+            mActivityInfoCache.put(cn, activityInfo);
+        }
+        return activityInfo;
+    }
+
+    public Drawable getIcon(Task t) {
+        Drawable cachedIcon = mIconCache.get(t.key);
+        if (cachedIcon == null) {
+            cachedIcon = createNewIconForTask(t.key, t.taskDescription, true /* returnDefault */);
+            mIconCache.put(t.key, cachedIcon);
+        }
+        return cachedIcon;
+    }
+
+    /**
+     * Returns the cached task icon if the task key is not expired, updating the cache if it is.
+     */
+    public Drawable getAndInvalidateIfModified(Task.TaskKey taskKey,
+            ActivityManager.TaskDescription td, boolean loadIfNotCached) {
+        // Return the cached activity icon if it exists
+        Drawable icon = mIconCache.getAndInvalidateIfModified(taskKey);
+        if (icon != null) {
+            return icon;
+        }
+
+        if (loadIfNotCached) {
+            icon = createNewIconForTask(taskKey, td, false /* returnDefault */);
+            if (icon != null) {
+                mIconCache.put(taskKey, icon);
+                return icon;
+            }
+        }
+
+        // We couldn't load any icon
+        return null;
+    }
+
+    private Drawable createNewIconForTask(Task.TaskKey taskKey,
+            ActivityManager.TaskDescription desc, boolean returnDefault) {
+        int userId = taskKey.userId;
+        Bitmap tdIcon = desc.getInMemoryIcon();
+        if (tdIcon != null) {
+            return createDrawableFromBitmap(tdIcon, userId);
+        }
+        if (desc.getIconResource() != 0) {
+            // TODO: Use task context here
+            try {
+                return createBadgedDrawable(mContext.getDrawable(desc.getIconResource()), userId);
+            } catch (Resources.NotFoundException e) {
+                Log.e(TAG, "Could not find icon drawable from resource", e);
+            }
+        }
+
+        tdIcon = ActivityManager.TaskDescription.loadTaskDescriptionIcon(
+                desc.getIconFilename(), userId);
+        if (tdIcon != null) {
+            return createDrawableFromBitmap(tdIcon, userId);
+        }
+
+        // Load the icon from the activity info and cache it
+        ActivityInfo activityInfo = getAndUpdateActivityInfo(taskKey);
+        if (activityInfo != null) {
+            Drawable icon = getBadgedActivityIcon(activityInfo, userId);
+            if (icon != null) {
+                return icon;
+            }
+        }
+
+        // At this point, even if we can't load the icon, we will set the default icon.
+        return returnDefault ? getDefaultIcon(userId) : null;
+    }
+
+    public abstract Drawable getDefaultIcon(int userId);
+
+    protected Drawable createDrawableFromBitmap(Bitmap icon, int userId) {
+        return createBadgedDrawable(new BitmapDrawable(mContext.getResources(), icon), userId);
+    }
+
+    protected abstract Drawable createBadgedDrawable(Drawable icon, int userId);
+
+    /**
+     * @return the activity icon for the ActivityInfo for a user, badging if necessary.
+     */
+    protected abstract Drawable getBadgedActivityIcon(ActivityInfo info, int userId);
+
+    public static class DefaultIconLoader extends IconLoader {
+
+        private final BitmapDrawable mDefaultIcon;
+        private final IconDrawableFactory mDrawableFactory;
+
+        public DefaultIconLoader(Context context, TaskKeyLruCache<Drawable> iconCache,
+                LruCache<ComponentName, ActivityInfo> activityInfoCache) {
+            super(context, iconCache, activityInfoCache);
+
+            // Create the default assets
+            Bitmap icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);
+            icon.eraseColor(0);
+            mDefaultIcon = new BitmapDrawable(context.getResources(), icon);
+            mDrawableFactory = IconDrawableFactory.newInstance(context);
+        }
+
+        @Override
+        public Drawable getDefaultIcon(int userId) {
+            return mDefaultIcon;
+        }
+
+        @Override
+        protected Drawable createBadgedDrawable(Drawable icon, int userId) {
+            if (userId != UserHandle.myUserId()) {
+                icon = mContext.getPackageManager().getUserBadgedIcon(icon, new UserHandle(userId));
+            }
+            return icon;
+        }
+
+        @Override
+        protected Drawable getBadgedActivityIcon(ActivityInfo info, int userId) {
+            return mDrawableFactory.getBadgedIcon(info, info.applicationInfo, userId);
+        }
+    }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoadPlan.java
index 4834bb1..76204df 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoadPlan.java
@@ -123,7 +123,7 @@
                     ? loader.getAndUpdateContentDescription(taskKey, t.taskDescription)
                     : "";
             Drawable icon = isStackTask
-                    ? loader.getAndUpdateActivityIcon(taskKey, t.taskDescription, res, false)
+                    ? loader.getAndUpdateActivityIcon(taskKey, t.taskDescription, false)
                     : null;
             ThumbnailData thumbnail = loader.getAndUpdateThumbnail(taskKey,
                     false /* loadIfNotCached */, false /* storeInCache */);
@@ -179,7 +179,7 @@
 
             if (opts.loadIcons && (isRunningTask || isVisibleTask)) {
                 if (task.icon == null) {
-                    task.icon = loader.getAndUpdateActivityIcon(taskKey, task.taskDescription, res,
+                    task.icon = loader.getAndUpdateActivityIcon(taskKey, task.taskDescription,
                             true);
                 }
             }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoader.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoader.java
index 0f68026..1309a60 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoader.java
@@ -21,9 +21,6 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Looper;
 import android.os.Trace;
@@ -36,7 +33,6 @@
 import com.android.systemui.shared.recents.model.Task.TaskKey;
 import com.android.systemui.shared.recents.model.TaskKeyLruCache.EvictionCallback;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.PackageManagerWrapper;
 
 import java.io.PrintWriter;
 import java.util.Map;
@@ -61,8 +57,6 @@
     // Disable all thumbnail loading.
     public static final int SVELTE_DISABLE_LOADING = 3;
 
-    private final Context mContext;
-
     // This activity info LruCache is useful because it can be expensive to retrieve ActivityInfos
     // for many tasks, which we use to get the activity labels and icons.  Unlike the other caches
     // below, this is per-package so we can't invalidate the items in the cache based on the last
@@ -73,6 +67,7 @@
     private final TaskKeyLruCache<String> mActivityLabelCache;
     private final TaskKeyLruCache<String> mContentDescriptionCache;
     private final TaskResourceLoadQueue mLoadQueue;
+    private final IconLoader mIconLoader;
     private final BackgroundTaskLoader mLoader;
     private final HighResThumbnailLoader mHighResThumbnailLoader;
     @GuardedBy("this")
@@ -86,7 +81,6 @@
 
     private int mDefaultTaskBarBackgroundColor;
     private int mDefaultTaskViewBackgroundColor;
-    private final BitmapDrawable mDefaultIcon;
 
     private EvictionCallback mClearActivityInfoOnEviction = new EvictionCallback() {
         @Override
@@ -99,16 +93,10 @@
 
     public RecentsTaskLoader(Context context, int maxThumbnailCacheSize, int maxIconCacheSize,
             int svelteLevel) {
-        mContext = context;
         mMaxThumbnailCacheSize = maxThumbnailCacheSize;
         mMaxIconCacheSize = maxIconCacheSize;
         mSvelteLevel = svelteLevel;
 
-        // Create the default assets
-        Bitmap icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);
-        icon.eraseColor(0);
-        mDefaultIcon = new BitmapDrawable(context.getResources(), icon);
-
         // Initialize the proxy, cache and loaders
         int numRecentTasks = ActivityManager.getMaxRecentTasksStatic();
         mHighResThumbnailLoader = new HighResThumbnailLoader(ActivityManagerWrapper.getInstance(),
@@ -119,10 +107,17 @@
         mContentDescriptionCache = new TaskKeyLruCache<>(numRecentTasks,
                 mClearActivityInfoOnEviction);
         mActivityInfoCache = new LruCache<>(numRecentTasks);
-        mLoader = new BackgroundTaskLoader(mLoadQueue, mIconCache, mDefaultIcon,
+
+        mIconLoader = createNewIconLoader(context, mIconCache, mActivityInfoCache);
+        mLoader = new BackgroundTaskLoader(mLoadQueue, mIconLoader,
                 mHighResThumbnailLoader::setTaskLoadQueueIdle);
     }
 
+    protected IconLoader createNewIconLoader(Context context,TaskKeyLruCache<Drawable> iconCache,
+            LruCache<ComponentName, ActivityInfo> activityInfoCache) {
+        return new IconLoader.DefaultIconLoader(context, iconCache, activityInfoCache);
+    }
+
     /**
      * Sets the default task bar/view colors if none are provided by the app.
      */
@@ -187,7 +182,7 @@
      */
     public void loadTaskData(Task t) {
         Drawable icon = mIconCache.getAndInvalidateIfModified(t.key);
-        icon = icon != null ? icon : mDefaultIcon;
+        icon = icon != null ? icon : mIconLoader.getDefaultIcon(t.key.userId);
         mLoadQueue.addTask(t);
         t.notifyTaskDataLoaded(t.thumbnail, icon);
     }
@@ -195,7 +190,7 @@
     /** Releases the task resource data back into the pool. */
     public void unloadTaskData(Task t) {
         mLoadQueue.removeTask(t);
-        t.notifyTaskDataUnloaded(mDefaultIcon);
+        t.notifyTaskDataUnloaded(mIconLoader.getDefaultIcon(t.key.userId));
     }
 
     /** Completely removes the resource data from the pool. */
@@ -205,7 +200,7 @@
         mActivityLabelCache.remove(t.key);
         mContentDescriptionCache.remove(t.key);
         if (notifyTaskDataUnloaded) {
-            t.notifyTaskDataUnloaded(mDefaultIcon);
+            t.notifyTaskDataUnloaded(mIconLoader.getDefaultIcon(t.key.userId));
         }
     }
 
@@ -326,35 +321,8 @@
      * Returns the cached task icon if the task key is not expired, updating the cache if it is.
      */
     Drawable getAndUpdateActivityIcon(TaskKey taskKey, ActivityManager.TaskDescription td,
-            Resources res, boolean loadIfNotCached) {
-        // Return the cached activity icon if it exists
-        Drawable icon = mIconCache.getAndInvalidateIfModified(taskKey);
-        if (icon != null) {
-            return icon;
-        }
-
-        if (loadIfNotCached) {
-            // Return and cache the task description icon if it exists
-            icon = ActivityManagerWrapper.getInstance().getBadgedTaskDescriptionIcon(mContext, td,
-                    taskKey.userId, res);
-            if (icon != null) {
-                mIconCache.put(taskKey, icon);
-                return icon;
-            }
-
-            // Load the icon from the activity info and cache it
-            ActivityInfo activityInfo = getAndUpdateActivityInfo(taskKey);
-            if (activityInfo != null) {
-                icon = ActivityManagerWrapper.getInstance().getBadgedActivityIcon(activityInfo,
-                        taskKey.userId);
-                if (icon != null) {
-                    mIconCache.put(taskKey, icon);
-                    return icon;
-                }
-            }
-        }
-        // We couldn't load any icon
-        return null;
+            boolean loadIfNotCached) {
+        return mIconLoader.getAndInvalidateIfModified(taskKey, td, loadIfNotCached);
     }
 
     /**
@@ -417,18 +385,7 @@
      * task key is expired.
      */
     ActivityInfo getAndUpdateActivityInfo(TaskKey taskKey) {
-        ComponentName cn = taskKey.getComponent();
-        ActivityInfo activityInfo = mActivityInfoCache.get(cn);
-        if (activityInfo == null) {
-            activityInfo = PackageManagerWrapper.getInstance().getActivityInfo(cn, taskKey.userId);
-            if (cn == null || activityInfo == null) {
-                Log.e(TAG, "Unexpected null component name or activity info: " + cn + ", " +
-                        activityInfo);
-                return null;
-            }
-            mActivityInfoCache.put(cn, activityInfo);
-        }
-        return activityInfo;
+        return mIconLoader.getAndUpdateActivityInfo(taskKey);
     }
 
     /**
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
index 138910c..2f28c81 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
@@ -40,25 +40,19 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
-import android.content.res.Resources;
-import android.content.res.Resources.NotFoundException;
 import android.graphics.Bitmap;
 import android.graphics.Rect;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.provider.Settings;
-import android.util.IconDrawableFactory;
 import android.util.Log;
 import android.view.IRecentsAnimationController;
 import android.view.IRecentsAnimationRunner;
 
 import android.view.RemoteAnimationTarget;
-import android.view.WindowManagerGlobal;
 import com.android.systemui.shared.recents.model.Task;
 import com.android.systemui.shared.recents.model.Task.TaskKey;
 import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -74,14 +68,12 @@
     private static final ActivityManagerWrapper sInstance = new ActivityManagerWrapper();
 
     private final PackageManager mPackageManager;
-    private final IconDrawableFactory mDrawableFactory;
     private final BackgroundExecutor mBackgroundExecutor;
     private final TaskStackChangeListeners mTaskStackChangeListeners;
 
     private ActivityManagerWrapper() {
         final Context context = AppGlobals.getInitialApplication();
         mPackageManager = context.getPackageManager();
-        mDrawableFactory = IconDrawableFactory.newInstance(context);
         mBackgroundExecutor = BackgroundExecutor.get();
         mTaskStackChangeListeners = new TaskStackChangeListeners(Looper.getMainLooper());
     }
@@ -156,58 +148,6 @@
     }
 
     /**
-     * @return the task description icon, loading and badging it if it necessary.
-     */
-    public Drawable getBadgedTaskDescriptionIcon(Context context,
-            ActivityManager.TaskDescription taskDescription, int userId, Resources res) {
-        Bitmap tdIcon = taskDescription.getInMemoryIcon();
-        Drawable dIcon = null;
-        if (tdIcon != null) {
-            dIcon = new BitmapDrawable(res, tdIcon);
-        } else if (taskDescription.getIconResource() != 0) {
-            try {
-                dIcon = context.getDrawable(taskDescription.getIconResource());
-            } catch (NotFoundException e) {
-                Log.e(TAG, "Could not find icon drawable from resource", e);
-            }
-        } else {
-            tdIcon = ActivityManager.TaskDescription.loadTaskDescriptionIcon(
-                    taskDescription.getIconFilename(), userId);
-            if (tdIcon != null) {
-                dIcon = new BitmapDrawable(res, tdIcon);
-            }
-        }
-        if (dIcon != null) {
-            return getBadgedIcon(dIcon, userId);
-        }
-        return null;
-    }
-
-    /**
-     * @return the given icon for a user, badging if necessary.
-     */
-    private Drawable getBadgedIcon(Drawable icon, int userId) {
-        if (userId != UserHandle.myUserId()) {
-            icon = mPackageManager.getUserBadgedIcon(icon, new UserHandle(userId));
-        }
-        return icon;
-    }
-
-    /**
-     * @return the activity icon for the ActivityInfo for a user, badging if necessary.
-     */
-    public Drawable getBadgedActivityIcon(ActivityInfo info, int userId) {
-        return mDrawableFactory.getBadgedIcon(info, info.applicationInfo, userId);
-    }
-
-    /**
-     * @return the application icon for the ApplicationInfo for a user, badging if necessary.
-     */
-    public Drawable getBadgedApplicationIcon(ApplicationInfo appInfo, int userId) {
-        return mDrawableFactory.getBadgedIcon(appInfo, userId);
-    }
-
-    /**
      * @return the activity label, badging if necessary.
      */
     public String getBadgedActivityLabel(ActivityInfo info, int userId) {
@@ -464,6 +404,25 @@
     }
 
     /**
+     * @return whether screen pinning is active.
+     */
+    public boolean isScreenPinningActive() {
+        try {
+            return ActivityManager.getService().getLockTaskModeState() == LOCK_TASK_MODE_PINNED;
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /**
+     * @return whether screen pinning is enabled.
+     */
+    public boolean isScreenPinningEnabled() {
+        final ContentResolver cr = AppGlobals.getInitialApplication().getContentResolver();
+        return Settings.System.getInt(cr, Settings.System.LOCK_TO_APP_ENABLED, 0) != 0;
+    }
+
+    /**
      * @return whether there is currently a locked task (ie. in screen pinning).
      */
     public boolean isLockToAppActive() {
@@ -476,9 +435,9 @@
 
     /**
      * @return whether screen pinning is enabled.
+     * @deprecated See {@link #isScreenPinningEnabled}
      */
     public boolean isLockToAppEnabled() {
-        final ContentResolver cr = AppGlobals.getInitialApplication().getContentResolver();
-        return Settings.System.getInt(cr, Settings.System.LOCK_TO_APP_ENABLED, 0) != 0;
+        return isScreenPinningEnabled();
     }
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
index 68400fc..5b49e67 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
@@ -101,4 +101,12 @@
             Log.w(TAG, "Failed to override pending app transition (remote): ", e);
         }
     }
+
+    public void endProlongedAnimations() {
+        try {
+            WindowManagerGlobal.getWindowManagerService().endProlongedAnimations();
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to end prolonged animations: ", e);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
index f1a5ca9..474fc90 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
@@ -197,16 +197,6 @@
         return false;
     }
 
-    @Override
-    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
-            event.getText().add(mSecurityContainer.getCurrentSecurityModeContentDescription());
-            return true;
-        } else {
-            return super.dispatchPopulateAccessibilityEvent(event);
-        }
-    }
-
     protected KeyguardSecurityContainer getSecurityContainer() {
         return mSecurityContainer;
     }
@@ -255,6 +245,10 @@
         }
     }
 
+    public CharSequence getAccessibilityTitleForCurrentMode() {
+        return mSecurityContainer.getTitle();
+    }
+
     public void userActivity() {
         if (mViewMediatorCallback != null) {
             mViewMediatorCallback.userActivity();
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
index ff5f5e7..75c52d8 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
@@ -361,4 +361,10 @@
         }
         return false;
     }
+
+    @Override
+    public CharSequence getTitle() {
+        return getContext().getString(
+                com.android.internal.R.string.keyguard_accessibility_password_unlock);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
index cb066a1..651831e 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
@@ -491,4 +491,10 @@
     public boolean hasOverlappingRendering() {
         return false;
     }
+
+    @Override
+    public CharSequence getTitle() {
+        return getContext().getString(
+                com.android.internal.R.string.keyguard_accessibility_pattern_unlock);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
index 6539ccf..1d3f9a1 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -252,4 +252,10 @@
         }
         return false;
     }
+
+    @Override
+    public CharSequence getTitle() {
+        return getContext().getString(
+                com.android.internal.R.string.keyguard_accessibility_pin_unlock);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 8dc4609..cb5a050 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -25,6 +25,7 @@
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Slog;
+import android.util.StatsLog;
 import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -119,19 +120,8 @@
         return false;
     }
 
-    public void announceCurrentSecurityMethod() {
-        View v = (View) getSecurityView(mCurrentSecuritySelection);
-        if (v != null) {
-            v.announceForAccessibility(v.getContentDescription());
-        }
-    }
-
-    public CharSequence getCurrentSecurityModeContentDescription() {
-        View v = (View) getSecurityView(mCurrentSecuritySelection);
-        if (v != null) {
-            return v.getContentDescription();
-        }
-        return "";
+    public CharSequence getTitle() {
+        return mSecurityViewFlipper.getTitle();
     }
 
     private KeyguardSecurityView getSecurityView(SecurityMode securityMode) {
@@ -441,9 +431,13 @@
         public void reportUnlockAttempt(int userId, boolean success, int timeoutMs) {
             KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
             if (success) {
+                StatsLog.write(StatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED,
+                    StatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED__RESULT__SUCCESS);
                 monitor.clearFailedUnlockAttempts();
                 mLockPatternUtils.reportSuccessfulPasswordAttempt(userId);
             } else {
+                StatsLog.write(StatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED,
+                    StatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED__RESULT__FAILURE);
                 KeyguardSecurityContainer.this.reportFailedUnlockAttempt(userId, timeoutMs);
             }
         }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java
index 360dba3b..6e445ff 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java
@@ -127,4 +127,12 @@
      *         animation started and {@code finishRunnable} will not be run
      */
     boolean startDisappearAnimation(Runnable finishRunnable);
+
+    /**
+     * The localized name of the security view, provided to accessibility. This may be the content
+     * description, but content descriptions have other implications, so the title is kept separate.
+     *
+     * @return The View's title.
+     */
+    CharSequence getTitle();
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
index a2ff8f7..3aede56 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
@@ -173,6 +173,15 @@
     }
 
     @Override
+    public CharSequence getTitle() {
+        KeyguardSecurityView ksv = getSecurityView();
+        if (ksv != null) {
+            return ksv.getTitle();
+        }
+        return "";
+    }
+
+    @Override
     protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
         return p instanceof LayoutParams;
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
index 703b205..c71c433 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
@@ -390,5 +390,11 @@
     public boolean startDisappearAnimation(Runnable finishRunnable) {
         return false;
     }
+
+    @Override
+    public CharSequence getTitle() {
+        return getContext().getString(
+                com.android.internal.R.string.keyguard_accessibility_sim_pin_unlock);
+    }
 }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
index 347c979..1b61568 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
@@ -460,6 +460,12 @@
     public boolean startDisappearAnimation(Runnable finishRunnable) {
         return false;
     }
+
+    @Override
+    public CharSequence getTitle() {
+        return getContext().getString(
+                com.android.internal.R.string.keyguard_accessibility_sim_puk_unlock);
+    }
 }
 
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
index 5d1bdab..4c2aa63 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
@@ -16,6 +16,7 @@
 
 package com.android.keyguard;
 
+import android.annotation.ColorInt;
 import android.app.PendingIntent;
 import android.arch.lifecycle.LiveData;
 import android.arch.lifecycle.Observer;
@@ -34,6 +35,7 @@
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.graphics.ColorUtils;
 import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
@@ -165,7 +167,8 @@
             }
             mClickActions.put(button, pendingIntent);
 
-            button.setText(rc.getTitleItem().getText());
+            final SliceItem titleItem = rc.getTitleItem();
+            button.setText(titleItem == null ? null : titleItem.getText());
 
             Drawable iconDrawable = null;
             SliceItem icon = SliceQuery.find(item.getSlice(),
@@ -307,10 +310,17 @@
         }
     }
 
-    public int getTextColor() {
+    @VisibleForTesting
+    int getTextColor() {
         return ColorUtils.blendARGB(mTextColor, Color.WHITE, mDarkAmount);
     }
 
+    @VisibleForTesting
+    void setTextColor(@ColorInt int textColor) {
+        mTextColor = textColor;
+        updateTextColors();
+    }
+
     /**
      * Representation of an item that appears under the clock on main keyguard message.
      */
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index f3f8d91f..6098e4e 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -736,7 +736,8 @@
 
     private DisplayClientState mDisplayClientState = new DisplayClientState();
 
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+    @VisibleForTesting
+    final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
 
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -773,6 +774,13 @@
                                 maxChargingMicroWatt));
                 mHandler.sendMessage(msg);
             } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
+                // ACTION_SIM_STATE_CHANGED is rebroadcast after unlocking the device to
+                // keep compatibility with apps that aren't direct boot aware.
+                // SysUI should just ignore this broadcast because it was already received
+                // and processed previously.
+                if (intent.getBooleanExtra(TelephonyIntents.EXTRA_REBROADCAST_ON_UNLOCK, false)) {
+                    return;
+                }
                 SimData args = SimData.fromIntent(intent);
                 if (DEBUG_SIM_STATES) {
                     Log.v(TAG, "action " + action
@@ -1508,7 +1516,8 @@
     /**
      * Handle {@link #MSG_SIM_STATE_CHANGE}
      */
-    private void handleSimStateChange(int subId, int slotId, State state) {
+    @VisibleForTesting
+    protected void handleSimStateChange(int subId, int slotId, State state) {
 
         if (DEBUG_SIM_STATES) {
             Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId="
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 7403ddc..cad155c 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -44,6 +44,7 @@
 import com.android.systemui.power.EnhancedEstimatesImpl;
 import com.android.systemui.power.PowerNotificationWarnings;
 import com.android.systemui.power.PowerUI;
+import com.android.systemui.statusbar.AppOpsListener;
 import com.android.systemui.statusbar.phone.ConfigurationControllerImpl;
 import com.android.systemui.statusbar.phone.DarkIconDispatcherImpl;
 import com.android.systemui.statusbar.phone.LightBarController;
@@ -314,6 +315,8 @@
 
         mProviders.put(EnhancedEstimates.class, () -> new EnhancedEstimatesImpl());
 
+        mProviders.put(AppOpsListener.class, () -> new AppOpsListener(mContext));
+
         // Put all dependencies above here so the factory can override them if it wants.
         SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
index a2c9ab4..5a2263c 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
@@ -14,7 +14,9 @@
 
 package com.android.systemui;
 
+import android.annotation.Nullable;
 import android.service.notification.StatusBarNotification;
+import android.util.ArraySet;
 
 public interface ForegroundServiceController {
     /**
@@ -46,4 +48,32 @@
      * @return true if sbn is the system-provided "dungeon" (list of running foreground services).
      */
     boolean isDungeonNotification(StatusBarNotification sbn);
+
+    /**
+     * @return true if sbn is one of the window manager "drawing over other apps" notifications
+     */
+    boolean isSystemAlertNotification(StatusBarNotification sbn);
+
+    /**
+     * Returns the key of the foreground service from this package using the standard template,
+     * if one exists.
+     */
+    @Nullable String getStandardLayoutKey(int userId, String pkg);
+
+    /**
+     * @return true if this user/pkg has a missing or custom layout notification and therefore needs
+     * a disclosure notification for system alert windows.
+     */
+    boolean isSystemAlertWarningNeeded(int userId, String pkg);
+
+    /**
+     * Records active app ops. App Ops are stored in FSC in addition to NotificationData in
+     * case they change before we have a notification to tag.
+     */
+    void onAppOpChanged(int code, int uid, String packageName, boolean active);
+
+    /**
+     * Gets active app ops for this user and package.
+     */
+    @Nullable ArraySet<Integer> getAppOps(int userId, String packageName);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java
index 3714c4e..fc2b5b4 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java
@@ -18,13 +18,13 @@
 import android.app.NotificationManager;
 import android.content.Context;
 import android.os.Bundle;
+import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
 import android.util.SparseArray;
 
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.messages.nano.SystemMessageProto;
 
 import java.util.Arrays;
@@ -34,17 +34,19 @@
  */
 public class ForegroundServiceControllerImpl
         implements ForegroundServiceController {
-  
+
     // shelf life of foreground services before they go bad
     public static final long FG_SERVICE_GRACE_MILLIS = 5000;
 
     private static final String TAG = "FgServiceController";
     private static final boolean DBG = false;
 
+    private final Context mContext;
     private final SparseArray<UserServices> mUserServices = new SparseArray<>();
     private final Object mMutex = new Object();
 
     public ForegroundServiceControllerImpl(Context context) {
+        mContext = context;
     }
 
     @Override
@@ -57,6 +59,52 @@
     }
 
     @Override
+    public boolean isSystemAlertWarningNeeded(int userId, String pkg) {
+        synchronized (mMutex) {
+            final UserServices services = mUserServices.get(userId);
+            if (services == null) return false;
+            return services.getStandardLayoutKey(pkg) == null;
+        }
+    }
+
+    @Override
+    public String getStandardLayoutKey(int userId, String pkg) {
+        synchronized (mMutex) {
+            final UserServices services = mUserServices.get(userId);
+            if (services == null) return null;
+            return services.getStandardLayoutKey(pkg);
+        }
+    }
+
+    @Override
+    public ArraySet<Integer> getAppOps(int userId, String pkg) {
+        synchronized (mMutex) {
+            final UserServices services = mUserServices.get(userId);
+            if (services == null) {
+                return null;
+            }
+            return services.getFeatures(pkg);
+        }
+    }
+
+    @Override
+    public void onAppOpChanged(int code, int uid, String packageName, boolean active) {
+        int userId = UserHandle.getUserId(uid);
+        synchronized (mMutex) {
+            UserServices userServices = mUserServices.get(userId);
+            if (userServices == null) {
+                userServices = new UserServices();
+                mUserServices.put(userId, userServices);
+            }
+            if (active) {
+                userServices.addOp(packageName, code);
+            } else {
+                userServices.removeOp(packageName, code);
+            }
+        }
+    }
+
+    @Override
     public void addNotification(StatusBarNotification sbn, int importance) {
         updateNotification(sbn, importance);
     }
@@ -102,9 +150,16 @@
                 }
             } else {
                 userServices.removeNotification(sbn.getPackageName(), sbn.getKey());
-                if (0 != (sbn.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE)
-                        && newImportance > NotificationManager.IMPORTANCE_MIN) {
-                    userServices.addNotification(sbn.getPackageName(), sbn.getKey());
+                if (0 != (sbn.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE)) {
+                    if (newImportance > NotificationManager.IMPORTANCE_MIN) {
+                        userServices.addImportantNotification(sbn.getPackageName(), sbn.getKey());
+                    }
+                    final Notification.Builder builder = Notification.Builder.recoverBuilder(
+                            mContext, sbn.getNotification());
+                    if (builder.usesStandardHeader()) {
+                        userServices.addStandardLayoutNotification(
+                                sbn.getPackageName(), sbn.getKey());
+                    }
                 }
             }
         }
@@ -117,42 +172,105 @@
                 && sbn.getPackageName().equals("android");
     }
 
+    @Override
+    public boolean isSystemAlertNotification(StatusBarNotification sbn) {
+        // TODO: tag system alert notifications so they can be suppressed if app's notification
+        // is tagged
+        return false;
+    }
+
     /**
      * Struct to track relevant packages and notifications for a userid's foreground services.
      */
     private static class UserServices {
         private String[] mRunning = null;
         private long mServiceStartTime = 0;
-        private ArrayMap<String, ArraySet<String>> mNotifications = new ArrayMap<>(1);
+        // package -> sufficiently important posted notification keys
+        private ArrayMap<String, ArraySet<String>> mImportantNotifications = new ArrayMap<>(1);
+        // package -> standard layout posted notification keys
+        private ArrayMap<String, ArraySet<String>> mStandardLayoutNotifications = new ArrayMap<>(1);
+
+        // package -> app ops
+        private ArrayMap<String, ArraySet<Integer>> mAppOps = new ArrayMap<>(1);
+
         public void setRunningServices(String[] pkgs, long serviceStartTime) {
             mRunning = pkgs != null ? Arrays.copyOf(pkgs, pkgs.length) : null;
             mServiceStartTime = serviceStartTime;
         }
-        public void addNotification(String pkg, String key) {
-            if (mNotifications.get(pkg) == null) {
-                mNotifications.put(pkg, new ArraySet<String>());
+
+        public void addOp(String pkg, int op) {
+            if (mAppOps.get(pkg) == null) {
+                mAppOps.put(pkg, new ArraySet<>(3));
             }
-            mNotifications.get(pkg).add(key);
+            mAppOps.get(pkg).add(op);
         }
-        public boolean removeNotification(String pkg, String key) {
+
+        public boolean removeOp(String pkg, int op) {
             final boolean found;
-            final ArraySet<String> keys = mNotifications.get(pkg);
+            final ArraySet<Integer> keys = mAppOps.get(pkg);
+            if (keys == null) {
+                found = false;
+            } else {
+                found = keys.remove(op);
+                if (keys.size() == 0) {
+                    mAppOps.remove(pkg);
+                }
+            }
+            return found;
+        }
+
+        public void addImportantNotification(String pkg, String key) {
+            addNotification(mImportantNotifications, pkg, key);
+        }
+
+        public boolean removeImportantNotification(String pkg, String key) {
+            return removeNotification(mImportantNotifications, pkg, key);
+        }
+
+        public void addStandardLayoutNotification(String pkg, String key) {
+            addNotification(mStandardLayoutNotifications, pkg, key);
+        }
+
+        public boolean removeStandardLayoutNotification(String pkg, String key) {
+            return removeNotification(mStandardLayoutNotifications, pkg, key);
+        }
+
+        public boolean removeNotification(String pkg, String key) {
+            boolean removed = false;
+            removed |= removeImportantNotification(pkg, key);
+            removed |= removeStandardLayoutNotification(pkg, key);
+            return removed;
+        }
+
+        public void addNotification(ArrayMap<String, ArraySet<String>> map, String pkg,
+                String key) {
+            if (map.get(pkg) == null) {
+                map.put(pkg, new ArraySet<>());
+            }
+            map.get(pkg).add(key);
+        }
+
+        public boolean removeNotification(ArrayMap<String, ArraySet<String>> map,
+                String pkg, String key) {
+            final boolean found;
+            final ArraySet<String> keys = map.get(pkg);
             if (keys == null) {
                 found = false;
             } else {
                 found = keys.remove(key);
                 if (keys.size() == 0) {
-                    mNotifications.remove(pkg);
+                    map.remove(pkg);
                 }
             }
             return found;
         }
+
         public boolean isDungeonNeeded() {
             if (mRunning != null
                 && System.currentTimeMillis() - mServiceStartTime >= FG_SERVICE_GRACE_MILLIS) {
 
                 for (String pkg : mRunning) {
-                    final ArraySet<String> set = mNotifications.get(pkg);
+                    final ArraySet<String> set = mImportantNotifications.get(pkg);
                     if (set == null || set.size() == 0) {
                         return true;
                     }
@@ -160,5 +278,27 @@
             }
             return false;
         }
+
+        public ArraySet<Integer> getFeatures(String pkg) {
+            return mAppOps.get(pkg);
+        }
+
+        public String getStandardLayoutKey(String pkg) {
+            final ArraySet<String> set = mStandardLayoutNotifications.get(pkg);
+            if (set == null || set.size() == 0) {
+                return null;
+            }
+            return set.valueAt(0);
+        }
+
+        @Override
+        public String toString() {
+            return "UserServices{" +
+                    "mRunning=" + Arrays.toString(mRunning) +
+                    ", mServiceStartTime=" + mServiceStartTime +
+                    ", mImportantNotifications=" + mImportantNotifications +
+                    ", mStandardLayoutNotifications=" + mStandardLayoutNotifications +
+                    '}';
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
index 1185f45..3c666e4 100644
--- a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
@@ -34,6 +34,8 @@
 import android.view.SurfaceControl;
 
 import com.android.systemui.OverviewProxyService.OverviewProxyListener;
+import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.events.activity.DockedFirstAnimationFrameEvent;
 import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.system.GraphicBufferCompat;
@@ -108,6 +110,15 @@
             }
         }
 
+        public void onSplitScreenInvoked() {
+            long token = Binder.clearCallingIdentity();
+            try {
+                EventBus.getDefault().post(new DockedFirstAnimationFrameEvent());
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
         public void setRecentsOnboardingText(CharSequence text) {
             mOnboardingText = text;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java
index adb4e33..396d317 100644
--- a/packages/SystemUI/src/com/android/systemui/Prefs.java
+++ b/packages/SystemUI/src/com/android/systemui/Prefs.java
@@ -24,32 +24,35 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.Map;
+import java.util.Set;
 
 public final class Prefs {
     private Prefs() {} // no instantation
 
     @Retention(RetentionPolicy.SOURCE)
     @StringDef({
-        Key.OVERVIEW_LAST_STACK_TASK_ACTIVE_TIME,
-        Key.DEBUG_MODE_ENABLED,
-        Key.HOTSPOT_TILE_LAST_USED,
-        Key.COLOR_INVERSION_TILE_LAST_USED,
-        Key.DND_TILE_VISIBLE,
-        Key.DND_TILE_COMBINED_ICON,
-        Key.DND_CONFIRMED_PRIORITY_INTRODUCTION,
-        Key.DND_CONFIRMED_SILENCE_INTRODUCTION,
-        Key.DND_FAVORITE_BUCKET_INDEX,
-        Key.DND_NONE_SELECTED,
-        Key.DND_FAVORITE_ZEN,
-        Key.QS_HOTSPOT_ADDED,
-        Key.QS_DATA_SAVER_ADDED,
-        Key.QS_DATA_SAVER_DIALOG_SHOWN,
-        Key.QS_INVERT_COLORS_ADDED,
-        Key.QS_WORK_ADDED,
-        Key.QS_NIGHTDISPLAY_ADDED,
-        Key.SEEN_MULTI_USER,
-        Key.NUM_APPS_LAUNCHED,
-        Key.HAS_SEEN_RECENTS_ONBOARDING,
+            Key.OVERVIEW_LAST_STACK_TASK_ACTIVE_TIME,
+            Key.DEBUG_MODE_ENABLED,
+            Key.HOTSPOT_TILE_LAST_USED,
+            Key.COLOR_INVERSION_TILE_LAST_USED,
+            Key.DND_TILE_VISIBLE,
+            Key.DND_TILE_COMBINED_ICON,
+            Key.DND_CONFIRMED_PRIORITY_INTRODUCTION,
+            Key.DND_CONFIRMED_SILENCE_INTRODUCTION,
+            Key.DND_FAVORITE_BUCKET_INDEX,
+            Key.DND_NONE_SELECTED,
+            Key.DND_FAVORITE_ZEN,
+            Key.QS_HOTSPOT_ADDED,
+            Key.QS_DATA_SAVER_ADDED,
+            Key.QS_DATA_SAVER_DIALOG_SHOWN,
+            Key.QS_INVERT_COLORS_ADDED,
+            Key.QS_WORK_ADDED,
+            Key.QS_NIGHTDISPLAY_ADDED,
+            Key.QS_LONG_PRESS_TOOLTIP_SHOWN_COUNT,
+            Key.SEEN_MULTI_USER,
+            Key.NUM_APPS_LAUNCHED,
+            Key.HAS_SEEN_RECENTS_ONBOARDING,
+            Key.SEEN_RINGER_GUIDANCE_COUNT
     })
     public @interface Key {
         @Deprecated
@@ -76,9 +79,16 @@
         String QS_WORK_ADDED = "QsWorkAdded";
         @Deprecated
         String QS_NIGHTDISPLAY_ADDED = "QsNightDisplayAdded";
+        /**
+         * Used for tracking how many times the user has seen the long press tooltip in the Quick
+         * Settings panel.
+         */
+        String QS_LONG_PRESS_TOOLTIP_SHOWN_COUNT = "QsLongPressTooltipShownCount";
         String SEEN_MULTI_USER = "HasSeenMultiUser";
         String NUM_APPS_LAUNCHED = "NumAppsLaunched";
         String HAS_SEEN_RECENTS_ONBOARDING = "HasSeenRecentsOnboarding";
+        String SEEN_RINGER_GUIDANCE_COUNT = "RingerGuidanceCount";
+        String QS_TILE_SPECS_REVEALED = "QsTileSpecsRevealed";
     }
 
     public static boolean getBoolean(Context context, @Key String key, boolean defaultValue) {
@@ -113,6 +123,15 @@
         get(context).edit().putString(key, value).apply();
     }
 
+    public static void putStringSet(Context context, @Key String key, Set<String> value) {
+        get(context).edit().putStringSet(key, value).apply();
+    }
+
+    public static Set<String> getStringSet(
+            Context context, @Key String key, Set<String> defaultValue) {
+        return get(context).getStringSet(key, defaultValue);
+    }
+
     public static Map<String, ?> getAll(Context context) {
         return get(context).getAll();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
index c7d276c..26618bf 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
@@ -19,6 +19,7 @@
 import android.app.ActivityManager;
 import android.app.AlarmManager;
 import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -27,6 +28,7 @@
 import android.icu.text.DisplayContext;
 import android.net.Uri;
 import android.os.Handler;
+import android.os.SystemClock;
 import android.text.TextUtils;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -36,6 +38,7 @@
 
 import java.util.Date;
 import java.util.Locale;
+import java.util.concurrent.TimeUnit;
 
 import androidx.app.slice.Slice;
 import androidx.app.slice.SliceProvider;
@@ -53,6 +56,12 @@
     public static final String KEYGUARD_NEXT_ALARM_URI =
             "content://com.android.systemui.keyguard/alarm";
 
+    /**
+     * Only show alarms that will ring within N hours.
+     */
+    @VisibleForTesting
+    static final int ALARM_VISIBILITY_HOURS = 12;
+
     private final Date mCurrentTime = new Date();
     protected final Uri mSliceUri;
     protected final Uri mDateUri;
@@ -65,6 +74,10 @@
     private boolean mRegisteredEveryMinute;
     private String mNextAlarm;
     private NextAlarmController mNextAlarmController;
+    protected AlarmManager mAlarmManager;
+    protected ContentResolver mContentResolver;
+    private AlarmManager.AlarmClockInfo mNextAlarmInfo;
+    private final AlarmManager.OnAlarmListener mUpdateNextAlarm = this::updateNextAlarm;
 
     /**
      * Receiver responsible for time ticking and updating the date format.
@@ -105,17 +118,26 @@
     public Slice onBindSlice(Uri sliceUri) {
         ListBuilder builder = new ListBuilder(getContext(), mSliceUri);
         builder.addRow(new RowBuilder(builder, mDateUri).setTitle(mLastText));
-        if (!TextUtils.isEmpty(mNextAlarm)) {
-            Icon icon = Icon.createWithResource(getContext(), R.drawable.ic_access_alarms_big);
-            builder.addRow(new RowBuilder(builder, mAlarmUri)
-                    .setTitle(mNextAlarm).addEndItem(icon));
+        addNextAlarm(builder);
+        return builder.build();
+    }
+
+    protected void addNextAlarm(ListBuilder builder) {
+        if (TextUtils.isEmpty(mNextAlarm)) {
+            return;
         }
 
-        return builder.build();
+        Icon alarmIcon = Icon.createWithResource(getContext(), R.drawable.ic_access_alarms_big);
+        RowBuilder alarmRowBuilder = new RowBuilder(builder, mAlarmUri)
+                .setTitle(mNextAlarm)
+                .addEndItem(alarmIcon);
+        builder.addRow(alarmRowBuilder);
     }
 
     @Override
     public boolean onCreateSliceProvider() {
+        mAlarmManager = getContext().getSystemService(AlarmManager.class);
+        mContentResolver = getContext().getContentResolver();
         mNextAlarmController = new NextAlarmControllerImpl(getContext());
         mNextAlarmController.addCallback(this);
         mDatePattern = getContext().getString(R.string.system_ui_aod_date_pattern);
@@ -124,15 +146,25 @@
         return true;
     }
 
-    public static String formatNextAlarm(Context context, AlarmManager.AlarmClockInfo info) {
-        if (info == null) {
-            return "";
+    private void updateNextAlarm() {
+        if (withinNHours(mNextAlarmInfo, ALARM_VISIBILITY_HOURS)) {
+            String pattern = android.text.format.DateFormat.is24HourFormat(getContext(),
+                    ActivityManager.getCurrentUser()) ? "H:mm" : "h:mm";
+            mNextAlarm = android.text.format.DateFormat.format(pattern,
+                    mNextAlarmInfo.getTriggerTime()).toString();
+        } else {
+            mNextAlarm = "";
         }
-        String skeleton = android.text.format.DateFormat
-                .is24HourFormat(context, ActivityManager.getCurrentUser()) ? "EHm" : "Ehma";
-        String pattern = android.text.format.DateFormat
-                .getBestDateTimePattern(Locale.getDefault(), skeleton);
-        return android.text.format.DateFormat.format(pattern, info.getTriggerTime()).toString();
+        mContentResolver.notifyChange(mSliceUri, null /* observer */);
+    }
+
+    private boolean withinNHours(AlarmManager.AlarmClockInfo alarmClockInfo, int hours) {
+        if (alarmClockInfo == null) {
+            return false;
+        }
+
+        long limit = System.currentTimeMillis() + TimeUnit.HOURS.toMillis(hours);
+        return mNextAlarmInfo.getTriggerTime() <= limit;
     }
 
     /**
@@ -181,7 +213,7 @@
         final String text = getFormattedDate();
         if (!text.equals(mLastText)) {
             mLastText = text;
-            getContext().getContentResolver().notifyChange(mSliceUri, null /* observer */);
+            mContentResolver.notifyChange(mSliceUri, null /* observer */);
         }
     }
 
@@ -203,7 +235,15 @@
 
     @Override
     public void onNextAlarmChanged(AlarmManager.AlarmClockInfo nextAlarm) {
-        mNextAlarm = formatNextAlarm(getContext(), nextAlarm);
-        getContext().getContentResolver().notifyChange(mSliceUri, null /* observer */);
+        mNextAlarmInfo = nextAlarm;
+        mAlarmManager.cancel(mUpdateNextAlarm);
+
+        long triggerAt = mNextAlarmInfo == null ? -1 : mNextAlarmInfo.getTriggerTime()
+                - TimeUnit.HOURS.toMillis(ALARM_VISIBILITY_HOURS);
+        if (triggerAt > 0) {
+            mAlarmManager.setExact(AlarmManager.RTC, triggerAt, "lock_screen_next_alarm",
+                    mUpdateNextAlarm, mHandler);
+        }
+        updateNextAlarm();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java b/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java
index f201165..be3168c 100644
--- a/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java
@@ -16,6 +16,9 @@
 
 package com.android.systemui.net;
 
+import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
+import static android.net.NetworkTemplate.MATCH_MOBILE;
+
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
@@ -32,11 +35,6 @@
 
 import com.android.systemui.R;
 
-import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
-import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER;
-import static android.net.NetworkTemplate.MATCH_MOBILE_4G;
-import static android.net.NetworkTemplate.MATCH_MOBILE_ALL;
-
 /**
  * Notify user that a {@link NetworkTemplate} is over its
  * {@link NetworkPolicy#limitBytes}, giving them the choice of acknowledging or
@@ -85,11 +83,7 @@
 
     private static int getLimitedDialogTitleForTemplate(NetworkTemplate template) {
         switch (template.getMatchRule()) {
-            case MATCH_MOBILE_3G_LOWER:
-                return R.string.data_usage_disabled_dialog_3g_title;
-            case MATCH_MOBILE_4G:
-                return R.string.data_usage_disabled_dialog_4g_title;
-            case MATCH_MOBILE_ALL:
+            case MATCH_MOBILE:
                 return R.string.data_usage_disabled_dialog_mobile_title;
             default:
                 return R.string.data_usage_disabled_dialog_title;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipAppOpsListener.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipAppOpsListener.java
index f0e4ccc..1e0d4d0 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipAppOpsListener.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipAppOpsListener.java
@@ -26,12 +26,14 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Handler;
 import android.util.Pair;
 
 public class PipAppOpsListener {
     private static final String TAG = PipAppOpsListener.class.getSimpleName();
 
     private Context mContext;
+    private Handler mHandler;
     private IActivityManager mActivityManager;
     private AppOpsManager mAppOpsManager;
 
@@ -50,7 +52,7 @@
                     if (appInfo.packageName.equals(topPipActivityInfo.first.getPackageName()) &&
                             mAppOpsManager.checkOpNoThrow(OP_PICTURE_IN_PICTURE, appInfo.uid,
                                     packageName) != MODE_ALLOWED) {
-                        mMotionHelper.dismissPip();
+                        mHandler.post(() -> mMotionHelper.dismissPip());
                     }
                 }
             } catch (NameNotFoundException e) {
@@ -63,6 +65,7 @@
     public PipAppOpsListener(Context context, IActivityManager activityManager,
             PipMotionHelper motionHelper) {
         mContext = context;
+        mHandler = new Handler(mContext.getMainLooper());
         mActivityManager = activityManager;
         mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
         mMotionHelper = motionHelper;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java b/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java
index b22ea4c..2629f30 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java
@@ -24,7 +24,7 @@
     // The size of a single dot in relation to the whole animation.
     private static final float SINGLE_SCALE = .4f;
 
-    private static final float MINOR_ALPHA = .3f;
+    private static final float MINOR_ALPHA = .42f;
 
     private final ArrayList<Integer> mQueuedPositions = new ArrayList<>();
 
@@ -53,7 +53,7 @@
             removeViewAt(getChildCount() - 1);
         }
         TypedArray array = getContext().obtainStyledAttributes(
-                new int[]{android.R.attr.colorForeground});
+                new int[]{android.R.attr.colorControlActivated});
         int color = array.getColor(0, 0);
         array.recycle();
         while (numPages > getChildCount()) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index f3417dc..ea3a60b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -1,5 +1,10 @@
 package com.android.systemui.qs;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -8,20 +13,34 @@
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.LayoutInflater;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.animation.Interpolator;
+import android.view.animation.OvershootInterpolator;
+import android.widget.Scroller;
 
 import com.android.systemui.R;
 import com.android.systemui.qs.QSPanel.QSTileLayout;
 import com.android.systemui.qs.QSPanel.TileRecord;
 
 import java.util.ArrayList;
+import java.util.Set;
 
 public class PagedTileLayout extends ViewPager implements QSTileLayout {
 
     private static final boolean DEBUG = false;
 
     private static final String TAG = "PagedTileLayout";
+    private static final int REVEAL_SCROLL_DURATION_MILLIS = 750;
+    private static final float BOUNCE_ANIMATION_TENSION = 1.3f;
+    private static final long BOUNCE_ANIMATION_DURATION = 450L;
+    private static final int TILE_ANIMATION_STAGGER_DELAY = 85;
+    private static final Interpolator SCROLL_CUBIC = (t) -> {
+        t -= 1.0f;
+        return t * t * t + 1.0f;
+    };
+
 
     private final ArrayList<TileRecord> mTiles = new ArrayList<TileRecord>();
     private final ArrayList<TilePage> mPages = new ArrayList<TilePage>();
@@ -34,37 +53,17 @@
     private int mPosition;
     private boolean mOffPage;
     private boolean mListening;
+    private Scroller mScroller;
+
+    private AnimatorSet mBounceAnimatorSet;
+    private int mAnimatingToPage = -1;
 
     public PagedTileLayout(Context context, AttributeSet attrs) {
         super(context, attrs);
+        mScroller = new Scroller(context, SCROLL_CUBIC);
         setAdapter(mAdapter);
-        setOnPageChangeListener(new OnPageChangeListener() {
-            @Override
-            public void onPageSelected(int position) {
-                if (mPageIndicator == null) return;
-                if (mPageListener != null) {
-                    mPageListener.onPageChanged(isLayoutRtl() ? position == mPages.size() - 1
-                            : position == 0);
-                }
-            }
-
-            @Override
-            public void onPageScrolled(int position, float positionOffset,
-                    int positionOffsetPixels) {
-                if (mPageIndicator == null) return;
-                setCurrentPage(position, positionOffset != 0);
-                mPageIndicator.setLocation(position + positionOffset);
-                if (mPageListener != null) {
-                    mPageListener.onPageChanged(positionOffsetPixels == 0 &&
-                            (isLayoutRtl() ? position == mPages.size() - 1 : position == 0));
-                }
-            }
-
-            @Override
-            public void onPageScrollStateChanged(int state) {
-            }
-        });
-        setCurrentItem(0);
+        setOnPageChangeListener(mOnPageChangeListener);
+        setCurrentItem(0, false);
     }
 
     @Override
@@ -99,6 +98,45 @@
         }
     }
 
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        // Suppress all touch event during reveal animation.
+        if (mAnimatingToPage != -1) {
+            return true;
+        }
+        return super.onInterceptTouchEvent(ev);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        // Suppress all touch event during reveal animation.
+        if (mAnimatingToPage != -1) {
+            return true;
+        }
+        return super.onTouchEvent(ev);
+    }
+
+    @Override
+    public void computeScroll() {
+        if (!mScroller.isFinished() && mScroller.computeScrollOffset()) {
+            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
+            float pageFraction = (float) getScrollX() / getWidth();
+            int position = (int) pageFraction;
+            float positionOffset = pageFraction - position;
+            mOnPageChangeListener.onPageScrolled(position, positionOffset, getScrollX());
+            // Keep on drawing until the animation has finished.
+            postInvalidateOnAnimation();
+            return;
+        }
+        if (mAnimatingToPage != -1) {
+            setCurrentItem(mAnimatingToPage, true);
+            mBounceAnimatorSet.start();
+            setOffscreenPageLimit(1);
+            mAnimatingToPage = -1;
+        }
+        super.computeScroll();
+    }
+
     /**
      * Sets individual pages to listening or not.  If offPage it will set
      * the next page after position to listening as well since we are in between
@@ -257,9 +295,84 @@
         return mPages.get(0).mColumns;
     }
 
+    public void startTileReveal(Set<String> tileSpecs, final Runnable postAnimation) {
+        if (tileSpecs.isEmpty() || mPages.size() < 2 || getScrollX() != 0) {
+            // Do not start the reveal animation unless there are tiles to animate, multiple
+            // TilePages available and the user has not already started dragging.
+            return;
+        }
+
+        final int lastPageNumber = mPages.size() - 1;
+        final TilePage lastPage = mPages.get(lastPageNumber);
+        final ArrayList<Animator> bounceAnims = new ArrayList<>();
+        for (TileRecord tr : lastPage.mRecords) {
+            if (tileSpecs.contains(tr.tile.getTileSpec())) {
+                bounceAnims.add(setupBounceAnimator(tr.tileView, bounceAnims.size()));
+            }
+        }
+
+        if (bounceAnims.isEmpty()) {
+            // All tileSpecs are on the first page. Nothing to do.
+            // TODO: potentially show a bounce animation for first page QS tiles
+            return;
+        }
+
+        mBounceAnimatorSet = new AnimatorSet();
+        mBounceAnimatorSet.playTogether(bounceAnims);
+        mBounceAnimatorSet.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mBounceAnimatorSet = null;
+                postAnimation.run();
+            }
+        });
+        mAnimatingToPage = lastPageNumber;
+        setOffscreenPageLimit(mAnimatingToPage); // Ensure the page to reveal has been inflated.
+        mScroller.startScroll(getScrollX(), getScrollY(), getWidth() * mAnimatingToPage, 0,
+                REVEAL_SCROLL_DURATION_MILLIS);
+        postInvalidateOnAnimation();
+    }
+
+    private static Animator setupBounceAnimator(View view, int ordinal) {
+        view.setAlpha(0f);
+        view.setScaleX(0f);
+        view.setScaleY(0f);
+        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(view,
+                PropertyValuesHolder.ofFloat(View.ALPHA, 1),
+                PropertyValuesHolder.ofFloat(View.SCALE_X, 1),
+                PropertyValuesHolder.ofFloat(View.SCALE_Y, 1));
+        animator.setDuration(BOUNCE_ANIMATION_DURATION);
+        animator.setStartDelay(ordinal * TILE_ANIMATION_STAGGER_DELAY);
+        animator.setInterpolator(new OvershootInterpolator(BOUNCE_ANIMATION_TENSION));
+        return animator;
+    }
+
+    private final ViewPager.OnPageChangeListener mOnPageChangeListener =
+            new ViewPager.SimpleOnPageChangeListener() {
+                @Override
+                public void onPageSelected(int position) {
+                    if (mPageIndicator == null) return;
+                    if (mPageListener != null) {
+                        mPageListener.onPageChanged(isLayoutRtl() ? position == mPages.size() - 1
+                                : position == 0);
+                    }
+                }
+
+                @Override
+                public void onPageScrolled(int position, float positionOffset,
+                        int positionOffsetPixels) {
+                    if (mPageIndicator == null) return;
+                    setCurrentPage(position, positionOffset != 0);
+                    mPageIndicator.setLocation(position + positionOffset);
+                    if (mPageListener != null) {
+                        mPageListener.onPageChanged(positionOffsetPixels == 0 &&
+                                (isLayoutRtl() ? position == mPages.size() - 1 : position == 0));
+                    }
+                }
+            };
+
     public static class TilePage extends TileLayout {
         private int mMaxRows = 3;
-
         public TilePage(Context context, AttributeSet attrs) {
             super(context, attrs);
             updateResources();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index c3f7eb1..2a4bb60 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -44,6 +44,7 @@
 
     public static final float EXPANDED_TILE_DELAY = .86f;
 
+
     private final ArrayList<View> mAllViews = new ArrayList<>();
     /**
      * List of {@link View}s representing Quick Settings that are being animated from the quick QS
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
index 993df759..e9888df 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
@@ -86,14 +86,9 @@
 
     private View mActionsContainer;
     private View mDragHandle;
-    private final int mDragHandleExpandOffset;
 
     public QSFooterImpl(Context context, AttributeSet attrs) {
         super(context, attrs);
-
-        mDragHandleExpandOffset = getResources().
-                getDimensionPixelSize(R.dimen.qs_footer_drag_handle_offset);
-
     }
 
     @Override
@@ -169,10 +164,9 @@
     private TouchAnimator createFooterAnimator() {
         return new TouchAnimator.Builder()
                 .addFloat(mDivider, "alpha", 0, 1)
-                .addFloat(mCarrierText, "alpha", 0, 1)
+                .addFloat(mCarrierText, "alpha", 0, 0, 1)
                 .addFloat(mActionsContainer, "alpha", 0, 1)
-                .addFloat(mDragHandle, "translationY", mDragHandleExpandOffset, 0)
-                .addFloat(mDragHandle, "alpha", 1, 0)
+                .addFloat(mDragHandle, "alpha", 1, 0, 0)
                 .setStartDelay(0.15f)
                 .build();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index d437f49..29f3c43 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -272,21 +272,28 @@
         mContainer.setExpansion(expansion);
         final float translationScaleY = expansion - 1;
         if (!mHeaderAnimating) {
-            int height = mHeader.getHeight();
-            getView().setTranslationY(mKeyguardShowing ? (translationScaleY * height)
-                    : headerTranslation);
+            getView().setTranslationY(
+                    mKeyguardShowing
+                            ? translationScaleY * mHeader.getHeight()
+                            : headerTranslation);
         }
         if (expansion == mLastQSExpansion) {
             return;
         }
         mLastQSExpansion = expansion;
-        mHeader.setExpansion(mKeyguardShowing ? 1 : expansion);
-        mFooter.setExpansion(mKeyguardShowing ? 1 : expansion);
+
+        boolean fullyExpanded = expansion == 1;
         int heightDiff = mQSPanel.getBottom() - mHeader.getBottom() + mHeader.getPaddingBottom()
                 + mFooter.getHeight();
+        float panelTranslationY = translationScaleY * heightDiff;
+
+        // Let the views animate their contents correctly by giving them the necessary context.
+        mHeader.setExpansion(mKeyguardShowing, expansion, panelTranslationY);
+        mFooter.setExpansion(mKeyguardShowing ? 1 : expansion);
+        mQSPanel.getQsTileRevealController().setExpansion(expansion);
         mQSPanel.setTranslationY(translationScaleY * heightDiff);
-        boolean fullyExpanded = expansion == 1;
         mQSDetail.setFullyExpanded(fullyExpanded);
+
         if (fullyExpanded) {
             // Always draw within the bounds of the view when fully expanded.
             mQSPanel.setClipBounds(null);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index cdcc5e6..61e3065 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -18,6 +18,7 @@
 
 import static com.android.systemui.qs.tileimpl.QSTileImpl.getColorForState;
 
+import android.annotation.Nullable;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -28,7 +29,6 @@
 import android.service.quicksettings.Tile;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
-import android.view.MotionEvent;
 import android.view.View;
 import android.widget.LinearLayout;
 
@@ -53,17 +53,19 @@
 import java.util.ArrayList;
 import java.util.Collection;
 
-/** View that represents the quick settings tile panel. **/
+/** View that represents the quick settings tile panel (when expanded/pulled down). **/
 public class QSPanel extends LinearLayout implements Tunable, Callback, BrightnessMirrorListener {
 
     public static final String QS_SHOW_BRIGHTNESS = "qs_show_brightness";
+    public static final String QS_SHOW_HEADER = "qs_show_header";
 
     protected final Context mContext;
-    protected final ArrayList<TileRecord> mRecords = new ArrayList<TileRecord>();
+    protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
     protected final View mBrightnessView;
     private final H mHandler = new H();
     private final View mPageIndicator;
     private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
+    private final QSTileRevealController mQsTileRevealController;
 
     protected boolean mExpanded;
     protected boolean mListening;
@@ -107,6 +109,8 @@
         addView(mPageIndicator);
 
         ((PagedTileLayout) mTileLayout).setPageIndicator((PageIndicator) mPageIndicator);
+        mQsTileRevealController = new QSTileRevealController(mContext, this,
+                ((PagedTileLayout) mTileLayout));
 
         addDivider();
 
@@ -135,6 +139,10 @@
         return mPageIndicator;
     }
 
+    public QSTileRevealController getQsTileRevealController() {
+        return mQsTileRevealController;
+    }
+
     public boolean isShowingCustomize() {
         return mCustomizePanel != null && mCustomizePanel.isCustomizing();
     }
@@ -142,7 +150,9 @@
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
-        Dependency.get(TunerService.class).addTunable(this, QS_SHOW_BRIGHTNESS);
+        final TunerService tunerService = Dependency.get(TunerService.class);
+        tunerService.addTunable(this, QS_SHOW_BRIGHTNESS);
+
         if (mHost != null) {
             setTiles(mHost.getTiles());
         }
@@ -174,11 +184,14 @@
     @Override
     public void onTuningChanged(String key, String newValue) {
         if (QS_SHOW_BRIGHTNESS.equals(key)) {
-            mBrightnessView.setVisibility(newValue == null || Integer.parseInt(newValue) != 0
-                    ? VISIBLE : GONE);
+            updateViewVisibilityForTuningValue(mBrightnessView, newValue);
         }
     }
 
+    private void updateViewVisibilityForTuningValue(View view, @Nullable String newValue) {
+        view.setVisibility(newValue == null || Integer.parseInt(newValue) != 0 ? VISIBLE : GONE);
+    }
+
     public void openDetails(String subPanel) {
         QSTile tile = getTile(subPanel);
         showDetailAdapter(true, tile.getDetailAdapter(), new int[]{getWidth() / 2, 0});
@@ -234,8 +247,7 @@
 
     public void updateResources() {
         final Resources res = mContext.getResources();
-        setPadding(0, res.getDimensionPixelSize(R.dimen.qs_brightness_padding_top),
-                0, res.getDimensionPixelSize(R.dimen.qs_panel_padding_bottom));
+        setPadding(0, res.getDimensionPixelSize(R.dimen.qs_panel_padding_top), 0, res.getDimensionPixelSize(R.dimen.qs_panel_padding_bottom));
         for (TileRecord r : mRecords) {
             r.tile.clearState();
         }
@@ -347,6 +359,9 @@
     }
 
     public void setTiles(Collection<QSTile> tiles, boolean collapsedView) {
+        if (!collapsedView) {
+            mQsTileRevealController.updateRevealedTiles(tiles);
+        }
         for (TileRecord record : mRecords) {
             mTileLayout.removeTile(record);
             record.tile.removeCallback(record.callback);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java
new file mode 100644
index 0000000..2f012e6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java
@@ -0,0 +1,76 @@
+package com.android.systemui.qs;
+
+import static com.android.systemui.Prefs.Key.QS_TILE_SPECS_REVEALED;
+
+import android.content.Context;
+import android.os.Handler;
+import android.util.ArraySet;
+
+import com.android.systemui.Prefs;
+import com.android.systemui.plugins.qs.QSTile;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+
+public class QSTileRevealController {
+    private static final long QS_REVEAL_TILES_DELAY = 500L;
+
+    private final Context mContext;
+    private final QSPanel mQSPanel;
+    private final PagedTileLayout mPagedTileLayout;
+    private final ArraySet<String> mTilesToReveal = new ArraySet<>();
+    private final Handler mHandler = new Handler();
+
+    private final Runnable mRevealQsTiles = new Runnable() {
+        @Override
+        public void run() {
+            mPagedTileLayout.startTileReveal(mTilesToReveal, () -> {
+                if (mQSPanel.isExpanded()) {
+                    addTileSpecsToRevealed(mTilesToReveal);
+                    mTilesToReveal.clear();
+                }
+            });
+        }
+    };
+
+    QSTileRevealController(Context context, QSPanel qsPanel, PagedTileLayout pagedTileLayout) {
+        mContext = context;
+        mQSPanel = qsPanel;
+        mPagedTileLayout = pagedTileLayout;
+    }
+
+    public void setExpansion(float expansion) {
+        if (expansion == 1f) {
+            mHandler.postDelayed(mRevealQsTiles, QS_REVEAL_TILES_DELAY);
+        } else {
+            mHandler.removeCallbacks(mRevealQsTiles);
+        }
+    }
+
+    public void updateRevealedTiles(Collection<QSTile> tiles) {
+        ArraySet<String> tileSpecs = new ArraySet<>();
+        for (QSTile tile : tiles) {
+            tileSpecs.add(tile.getTileSpec());
+        }
+
+        final Set<String> revealedTiles = Prefs.getStringSet(
+                mContext, QS_TILE_SPECS_REVEALED, Collections.EMPTY_SET);
+        if (revealedTiles.isEmpty() || mQSPanel.isShowingCustomize()) {
+            // Do not reveal QS tiles the user has upon first load or those that they directly
+            // added through customization.
+            addTileSpecsToRevealed(tileSpecs);
+        } else {
+            // Animate all tiles that the user has not directly added themselves.
+            tileSpecs.removeAll(revealedTiles);
+            mTilesToReveal.addAll(tileSpecs);
+        }
+    }
+
+    private void addTileSpecsToRevealed(ArraySet<String> specs) {
+        final ArraySet<String> revealedTiles = new ArraySet<>(
+                Prefs.getStringSet(mContext, QS_TILE_SPECS_REVEALED, Collections.EMPTY_SET));
+        revealedTiles.addAll(specs);
+        Prefs.putStringSet(mContext, QS_TILE_SPECS_REVEALED, revealedTiles);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index bdda3b9..2270b60 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -20,7 +20,6 @@
 import android.util.AttributeSet;
 import android.view.Gravity;
 import android.view.View;
-import android.view.ViewGroup;
 import android.widget.LinearLayout;
 import android.widget.Space;
 
@@ -123,9 +122,8 @@
 
     @Override
     public void onTuningChanged(String key, String newValue) {
-        // No tunings for you.
-        if (key.equals(QS_SHOW_BRIGHTNESS)) {
-            // No Brightness for you.
+        if (QS_SHOW_BRIGHTNESS.equals(key)) {
+            // No Brightness or Tooltip for you!
             super.onTuningChanged(key, "0");
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 4d7333b..2151436 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -15,24 +15,30 @@
 package com.android.systemui.qs;
 
 import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS;
-import static android.app.StatusBarManager.DISABLE_NONE;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.app.ActivityManager;
+import android.app.AlarmManager;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Configuration;
-import android.content.res.Resources;
 import android.graphics.Color;
 import android.graphics.Rect;
+import android.os.Handler;
 import android.provider.AlarmClock;
 import android.support.annotation.VisibleForTesting;
+import android.text.TextUtils;
+import android.text.format.DateUtils;
 import android.util.AttributeSet;
 import android.view.View;
 import android.widget.RelativeLayout;
-import android.widget.TextClock;
+import android.widget.TextView;
 
 import com.android.settingslib.Utils;
 import com.android.systemui.BatteryMeterView;
 import com.android.systemui.Dependency;
+import com.android.systemui.Prefs;
 import com.android.systemui.R;
 import com.android.systemui.R.id;
 import com.android.systemui.SysUiServiceProvider;
@@ -43,11 +49,25 @@
 import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager;
 import com.android.systemui.statusbar.policy.DarkIconDispatcher;
 import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver;
+import com.android.systemui.statusbar.policy.NextAlarmController;
 
-public class QuickStatusBarHeader extends RelativeLayout
-        implements CommandQueue.Callbacks, View.OnClickListener {
+import java.util.Locale;
 
-    private ActivityStarter mActivityStarter;
+/**
+ * View that contains the top-most bits of the screen (primarily the status bar with date, time, and
+ * battery) and also contains the {@link QuickQSPanel} along with some of the panel's inner
+ * contents.
+ */
+public class QuickStatusBarHeader extends RelativeLayout implements CommandQueue.Callbacks,
+        View.OnClickListener, NextAlarmController.NextAlarmChangeCallback {
+
+    /** Delay for auto fading out the long press tooltip after it's fully visible (in ms). */
+    private static final long AUTO_FADE_OUT_DELAY_MS = DateUtils.SECOND_IN_MILLIS * 6;
+    private static final int FADE_ANIMATION_DURATION_MS = 300;
+    private static final int TOOLTIP_NOT_YET_SHOWN_COUNT = 0;
+    public static final int MAX_TOOLTIP_SHOWN_COUNT = 3;
+
+    private final Handler mHandler = new Handler();
 
     private QSPanel mQsPanel;
 
@@ -58,20 +78,39 @@
     protected QuickQSPanel mHeaderQsPanel;
     protected QSTileHost mHost;
     private TintedIconManager mIconManager;
-    private TouchAnimator mAlphaAnimator;
+    private TouchAnimator mStatusIconsAlphaAnimator;
+    private TouchAnimator mHeaderTextContainerAlphaAnimator;
 
     private View mQuickQsStatusIcons;
-
     private View mDate;
+    private View mHeaderTextContainerView;
+    /** View corresponding to the next alarm info (including the icon). */
+    private View mNextAlarmView;
+    /** Tooltip for educating users that they can long press on icons to see more details. */
+    private View mLongPressTooltipView;
+    /** {@link TextView} containing the actual text indicating when the next alarm will go off. */
+    private TextView mNextAlarmTextView;
+
+    private NextAlarmController mAlarmController;
+    private String mNextAlarmText;
+    /** Counts how many times the long press tooltip has been shown to the user. */
+    private int mShownCount;
+
+    /**
+     * Runnable for automatically fading out the long press tooltip (as if it were animating away).
+     */
+    private final Runnable mAutoFadeOutTooltipRunnable = () -> hideLongPressTooltip(false);
 
     public QuickStatusBarHeader(Context context, AttributeSet attrs) {
         super(context, attrs);
+
+        mAlarmController = Dependency.get(NextAlarmController.class);
+        mShownCount = getStoredShownCount();
     }
 
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        Resources res = getResources();
 
         mHeaderQsPanel = findViewById(R.id.quick_qs_panel);
         mDate = findViewById(R.id.date);
@@ -79,8 +118,11 @@
         mQuickQsStatusIcons = findViewById(R.id.quick_qs_status_icons);
         mIconManager = new TintedIconManager(findViewById(R.id.statusIcons));
 
-        // RenderThread is doing more harm than good when touching the header (to expand quick
-        // settings), so disable it for this view
+        // Views corresponding to the header info section (e.g. tooltip and next alarm).
+        mHeaderTextContainerView = findViewById(R.id.header_text_container);
+        mLongPressTooltipView = findViewById(R.id.long_press_tooltip);
+        mNextAlarmView = findViewById(R.id.next_alarm);
+        mNextAlarmTextView = findViewById(R.id.next_alarm_text);
 
         updateResources();
 
@@ -98,8 +140,6 @@
 
         BatteryMeterView battery = findViewById(R.id.battery);
         battery.setForceShowPercent(true);
-
-        mActivityStarter = Dependency.get(ActivityStarter.class);
     }
 
     private void applyDarkness(int id, Rect tintArea, float intensity, int color) {
@@ -129,21 +169,26 @@
     }
 
     private void updateResources() {
-        updateAlphaAnimator();
+        // Update height, especially due to landscape mode restricting space.
+        mHeaderTextContainerView.getLayoutParams().height =
+                mContext.getResources().getDimensionPixelSize(R.dimen.qs_header_tooltip_height);
+        mHeaderTextContainerView.setLayoutParams(mHeaderTextContainerView.getLayoutParams());
+
+        updateStatusIconAlphaAnimator();
+        updateHeaderTextContainerAlphaAnimator();
     }
 
-    private void updateAlphaAnimator() {
-        mAlphaAnimator = new TouchAnimator.Builder()
+    private void updateStatusIconAlphaAnimator() {
+        mStatusIconsAlphaAnimator = new TouchAnimator.Builder()
                 .addFloat(mQuickQsStatusIcons, "alpha", 1, 0)
                 .build();
     }
 
-    public int getCollapsedHeight() {
-        return getHeight();
-    }
-
-    public int getExpandedHeight() {
-        return getHeight();
+    private void updateHeaderTextContainerAlphaAnimator() {
+        mHeaderTextContainerAlphaAnimator = new TouchAnimator.Builder()
+                .addFloat(mHeaderTextContainerView, "alpha", 0, 1)
+                .setStartDelay(.5f)
+                .build();
     }
 
     public void setExpanded(boolean expanded) {
@@ -153,10 +198,47 @@
         updateEverything();
     }
 
-    public void setExpansion(float headerExpansionFraction) {
-        if (mAlphaAnimator != null ) {
-            mAlphaAnimator.setPosition(headerExpansionFraction);
+    /**
+     * Animates the inner contents based on the given expansion details.
+     *
+     * @param isKeyguardShowing whether or not we're showing the keyguard (a.k.a. lockscreen)
+     * @param expansionFraction how much the QS panel is expanded/pulled out (up to 1f)
+     * @param panelTranslationY how much the panel has physically moved down vertically (required
+     *                          for keyguard animations only)
+     */
+    public void setExpansion(boolean isKeyguardShowing, float expansionFraction,
+                             float panelTranslationY) {
+        final float keyguardExpansionFraction = isKeyguardShowing ? 1f : expansionFraction;
+        if (mStatusIconsAlphaAnimator != null) {
+            mStatusIconsAlphaAnimator.setPosition(keyguardExpansionFraction);
         }
+
+        if (isKeyguardShowing) {
+            // If the keyguard is showing, we want to offset the text so that it comes in at the
+            // same time as the panel as it slides down.
+            mHeaderTextContainerView.setTranslationY(panelTranslationY);
+        } else {
+            mHeaderTextContainerView.setTranslationY(0f);
+        }
+
+        if (mHeaderTextContainerAlphaAnimator != null) {
+            mHeaderTextContainerAlphaAnimator.setPosition(keyguardExpansionFraction);
+        }
+
+        // Check the original expansion fraction - we don't want to show the tooltip until the
+        // panel is pulled all the way out.
+        if (expansionFraction == 1f) {
+            // QS is fully expanded, bring in the tooltip.
+            showLongPressTooltip();
+        }
+    }
+
+    /** Returns the latest stored tooltip shown count from SharedPreferences. */
+    private int getStoredShownCount() {
+        return Prefs.getInt(
+                mContext,
+                Prefs.Key.QS_LONG_PRESS_TOOLTIP_SHOWN_COUNT,
+                TOOLTIP_NOT_YET_SHOWN_COUNT);
     }
 
     @Override
@@ -191,6 +273,12 @@
         }
         mHeaderQsPanel.setListening(listening);
         mListening = listening;
+
+        if (listening) {
+            mAlarmController.addCallback(this);
+        } else {
+            mAlarmController.removeCallback(this);
+        }
     }
 
     @Override
@@ -201,6 +289,125 @@
         }
     }
 
+    @Override
+    public void onNextAlarmChanged(AlarmManager.AlarmClockInfo nextAlarm) {
+        mNextAlarmText = nextAlarm != null ? formatNextAlarm(nextAlarm) : null;
+        if (mNextAlarmText != null) {
+            hideLongPressTooltip(true /* shouldFadeInAlarmText */);
+        } else {
+            hideAlarmText();
+        }
+        updateHeaderTextContainerAlphaAnimator();
+    }
+
+    /**
+     * Animates in the long press tooltip (as long as the next alarm text isn't currently occupying
+     * the space).
+     */
+    public void showLongPressTooltip() {
+        // If we have alarm text to show, don't bother fading in the tooltip.
+        if (!TextUtils.isEmpty(mNextAlarmText)) {
+            return;
+        }
+
+        if (mShownCount < MAX_TOOLTIP_SHOWN_COUNT) {
+            mLongPressTooltipView.animate().cancel();
+            mLongPressTooltipView.setVisibility(View.VISIBLE);
+            mLongPressTooltipView.animate()
+                    .alpha(1f)
+                    .setDuration(FADE_ANIMATION_DURATION_MS)
+                    .setListener(new AnimatorListenerAdapter() {
+                        @Override
+                        public void onAnimationEnd(Animator animation) {
+                            mHandler.postDelayed(
+                                    mAutoFadeOutTooltipRunnable, AUTO_FADE_OUT_DELAY_MS);
+                        }
+                    })
+                    .start();
+
+            // Increment and drop the shown count in prefs for the next time we're deciding to
+            // fade in the tooltip. We first sanity check that the tooltip count hasn't changed yet
+            // in prefs (say, from a long press).
+            if (getStoredShownCount() <= mShownCount) {
+                Prefs.putInt(mContext, Prefs.Key.QS_LONG_PRESS_TOOLTIP_SHOWN_COUNT, ++mShownCount);
+            }
+        }
+    }
+
+    /**
+     * Fades out the long press tooltip if it's partially visible - short circuits any running
+     * animation. Additionally has the ability to fade in the alarm info text.
+     *
+     * @param shouldShowAlarmText whether we should fade in the next alarm text
+     */
+    private void hideLongPressTooltip(boolean shouldShowAlarmText) {
+        mLongPressTooltipView.animate().cancel();
+        if (mLongPressTooltipView.getVisibility() == View.VISIBLE
+                && mLongPressTooltipView.getAlpha() != 0f) {
+            mHandler.removeCallbacks(mAutoFadeOutTooltipRunnable);
+            mLongPressTooltipView.animate()
+                    .alpha(0f)
+                    .setDuration(FADE_ANIMATION_DURATION_MS)
+                    .setListener(new AnimatorListenerAdapter() {
+                        @Override
+                        public void onAnimationEnd(Animator animation) {
+                            mLongPressTooltipView.setVisibility(View.INVISIBLE);
+
+                            if (shouldShowAlarmText) {
+                                showAlarmText();
+                            }
+                        }
+                    })
+                    .start();
+        } else {
+            mLongPressTooltipView.setVisibility(View.INVISIBLE);
+
+            if (shouldShowAlarmText) {
+                showAlarmText();
+            }
+        }
+    }
+
+    /**
+     * Fades in the updated alarm text. Note that if there's already an alarm showing, this will
+     * immediately hide it and fade in the updated time.
+     */
+    private void showAlarmText() {
+        mNextAlarmView.setAlpha(0f);
+        mNextAlarmView.setVisibility(View.VISIBLE);
+        mNextAlarmTextView.setText(mNextAlarmText);
+
+        mNextAlarmView.animate()
+                .alpha(1f)
+                .setDuration(FADE_ANIMATION_DURATION_MS)
+                .start();
+    }
+
+    /**
+     * Fades out and hides the next alarm text. This also resets the text contents to null in
+     * preparation for the next alarm update.
+     */
+    private void hideAlarmText() {
+        if (mNextAlarmView.getVisibility() == View.VISIBLE) {
+            mNextAlarmView.animate()
+                    .alpha(0f)
+                    .setListener(new AnimatorListenerAdapter() {
+                        @Override
+                        public void onAnimationEnd(Animator animation) {
+                            // Reset the alpha regardless of how the animation ends for the next
+                            // time we show this view/want to animate it.
+                            mNextAlarmView.setVisibility(View.INVISIBLE);
+                            mNextAlarmView.setAlpha(1f);
+                            mNextAlarmTextView.setText(null);
+                        }
+                    })
+                    .start();
+        } else {
+            // Next alarm view is already hidden, only need to clear the text.
+            mNextAlarmTextView.setText(null);
+        }
+    }
+
     public void updateEverything() {
         post(() -> setClickable(false));
     }
@@ -225,4 +432,15 @@
     public void setCallback(Callback qsPanelCallback) {
         mHeaderQsPanel.setCallback(qsPanelCallback);
     }
+
+    private String formatNextAlarm(AlarmManager.AlarmClockInfo info) {
+        if (info == null) {
+            return "";
+        }
+        String skeleton = android.text.format.DateFormat
+                .is24HourFormat(mContext, ActivityManager.getCurrentUser()) ? "EHm" : "Ehma";
+        String pattern = android.text.format.DateFormat
+                .getBestDateTimePattern(Locale.getDefault(), skeleton);
+        return android.text.format.DateFormat.format(pattern, info.getTriggerTime()).toString();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
index 65135ab..66823ca 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
@@ -21,7 +21,8 @@
     protected int mColumns;
     protected int mCellWidth;
     protected int mCellHeight;
-    protected int mCellMargin;
+    protected int mCellMarginHorizontal;
+    protected int mCellMarginVertical;
 
     protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
     private int mCellMarginTop;
@@ -76,7 +77,8 @@
         final Resources res = mContext.getResources();
         final int columns = Math.max(1, res.getInteger(R.integer.quick_settings_num_columns));
         mCellHeight = mContext.getResources().getDimensionPixelSize(R.dimen.qs_tile_height);
-        mCellMargin = res.getDimensionPixelSize(R.dimen.qs_tile_margin);
+        mCellMarginHorizontal = res.getDimensionPixelSize(R.dimen.qs_tile_margin_horizontal);
+        mCellMarginVertical= res.getDimensionPixelSize(R.dimen.qs_tile_margin_vertical);
         mCellMarginTop = res.getDimensionPixelSize(R.dimen.qs_tile_margin_top);
         if (mColumns != columns) {
             mColumns = columns;
@@ -91,7 +93,7 @@
         final int numTiles = mRecords.size();
         final int width = MeasureSpec.getSize(widthMeasureSpec);
         final int rows = (numTiles + mColumns - 1) / mColumns;
-        mCellWidth = (width - (mCellMargin * (mColumns + 1))) / mColumns;
+        mCellWidth = (width - (mCellMarginHorizontal * (mColumns + 1))) / mColumns;
 
         View previousView = this;
         for (TileRecord record : mRecords) {
@@ -99,7 +101,11 @@
             record.tileView.measure(exactly(mCellWidth), exactly(mCellHeight));
             previousView = record.tileView.updateAccessibilityOrder(previousView);
         }
-        int height = (mCellHeight + mCellMargin) * rows + (mCellMarginTop - mCellMargin);
+
+        // Only include the top margin in our measurement if we have more than 1 row to show.
+        // Otherwise, don't add the extra margin buffer at top.
+        int height = (mCellHeight + mCellMarginVertical) * rows +
+                (rows != 0 ? (mCellMarginTop - mCellMarginVertical) : 0);
         if (height < 0) height = 0;
         setMeasuredDimension(width, height);
     }
@@ -139,10 +145,10 @@
     }
 
     private int getRowTop(int row) {
-        return row * (mCellHeight + mCellMargin) + mCellMarginTop;
+        return row * (mCellHeight + mCellMarginVertical) + mCellMarginTop;
     }
 
     private int getColumnStart(int column) {
-        return column * (mCellWidth + mCellMargin) + mCellMargin;
+        return column * (mCellWidth + mCellMarginHorizontal) + mCellMarginHorizontal;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java
index 37f2528..f673364 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java
@@ -107,7 +107,7 @@
         void onAnimationAtStart();
 
         /**
-         * Called when the animator moves into a position of "0". Start and end delays are
+         * Called when the animator moves into a position of "1". Start and end delays are
          * taken into account, so this position may cover a range of fractional inputs.
          */
         void onAnimationAtEnd();
@@ -200,7 +200,6 @@
     }
 
     private static abstract class KeyframeSet {
-
         private final float mFrameWidth;
         private final int mSize;
 
@@ -210,9 +209,8 @@
         }
 
         void setValue(float fraction, Object target) {
-            int i;
-            for (i = 1; i < mSize - 1 && fraction > mFrameWidth; i++);
-            float amount = fraction / mFrameWidth;
+            int i = MathUtils.constrain((int) Math.ceil(fraction / mFrameWidth), 1, mSize - 1);
+            float amount = (fraction - mFrameWidth * (i - 1)) / mFrameWidth;
             interpolate(i, amount, target);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
index bf9746e..77c3bfa 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
@@ -23,7 +23,6 @@
 import com.android.systemui.plugins.qs.QSTileView;
 import com.android.systemui.qs.external.CustomTile;
 import com.android.systemui.qs.tiles.AirplaneModeTile;
-import com.android.systemui.qs.tiles.AlarmTile;
 import com.android.systemui.qs.tiles.BatterySaverTile;
 import com.android.systemui.qs.tiles.BluetoothTile;
 import com.android.systemui.qs.tiles.CastTile;
@@ -70,7 +69,6 @@
         else if (tileSpec.equals("saver")) return new DataSaverTile(mHost);
         else if (tileSpec.equals("night")) return new NightDisplayTile(mHost);
         else if (tileSpec.equals("nfc")) return new NfcTile(mHost);
-        else if (tileSpec.equals("alarm")) return new AlarmTile(mHost);
         // Intent tiles.
         else if (tileSpec.startsWith(IntentTile.PREFIX)) return IntentTile.create(mHost, tileSpec);
         else if (tileSpec.startsWith(CustomTile.PREFIX)) return CustomTile.create(mHost, tileSpec);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index 72592829..04dbb88 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -42,6 +42,7 @@
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
+import com.android.systemui.Prefs;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.DetailAdapter;
 import com.android.systemui.plugins.qs.QSIconView;
@@ -49,6 +50,7 @@
 import com.android.systemui.plugins.qs.QSTile.State;
 import com.android.systemui.qs.PagedTileLayout.TilePage;
 import com.android.systemui.qs.QSHost;
+import com.android.systemui.qs.QuickStatusBarHeader;
 
 import java.util.ArrayList;
 
@@ -191,6 +193,11 @@
     public void longClick() {
         mMetricsLogger.write(populate(new LogMaker(ACTION_QS_LONG_PRESS).setType(TYPE_ACTION)));
         mHandler.sendEmptyMessage(H.LONG_CLICK);
+
+        Prefs.putInt(
+                mContext,
+                Prefs.Key.QS_LONG_PRESS_TOOLTIP_SHOWN_COUNT,
+                QuickStatusBarHeader.MAX_TOOLTIP_SHOWN_COUNT);
     }
 
     public LogMaker populate(LogMaker logMaker) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.java
deleted file mode 100644
index ff3fe73..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT 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 static android.service.quicksettings.Tile.STATE_ACTIVE;
-import static android.service.quicksettings.Tile.STATE_UNAVAILABLE;
-
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.QS_ALARM;
-import static com.android.systemui.keyguard.KeyguardSliceProvider.formatNextAlarm;
-
-import android.app.AlarmManager.AlarmClockInfo;
-import android.app.PendingIntent;
-import android.content.Intent;
-import android.provider.AlarmClock;
-
-import com.android.systemui.Dependency;
-import com.android.systemui.R;
-import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.qs.QSTileHost;
-import com.android.systemui.qs.tileimpl.QSTileImpl;
-import com.android.systemui.statusbar.policy.NextAlarmController;
-import com.android.systemui.statusbar.policy.NextAlarmController.NextAlarmChangeCallback;
-
-public class AlarmTile extends QSTileImpl implements NextAlarmChangeCallback {
-    private final NextAlarmController mController;
-    private String mNextAlarm;
-    private PendingIntent mIntent;
-
-    public AlarmTile(QSTileHost host) {
-        super(host);
-        mController = Dependency.get(NextAlarmController.class);
-    }
-
-    @Override
-    public State newTileState() {
-        return new BooleanState();
-    }
-
-    @Override
-    protected void handleClick() {
-        if (mIntent != null) {
-            Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard(mIntent);
-        }
-    }
-
-    @Override
-    protected void handleUpdateState(State state, Object arg) {
-        state.state = mNextAlarm != null ? STATE_ACTIVE : STATE_UNAVAILABLE;
-        state.label = getTileLabel();
-        state.secondaryLabel = mNextAlarm;
-        state.icon = ResourceIcon.get(R.drawable.stat_sys_alarm);
-        ((BooleanState) state).value = mNextAlarm != null;
-    }
-
-    @Override
-    public void onNextAlarmChanged(AlarmClockInfo nextAlarm) {
-        if (nextAlarm != null) {
-            mNextAlarm = formatNextAlarm(mContext, nextAlarm);
-            mIntent = nextAlarm.getShowIntent();
-        } else {
-            mNextAlarm = null;
-            mIntent = null;
-        }
-        refreshState();
-    }
-
-    @Override
-    public int getMetricsCategory() {
-        return QS_ALARM;
-    }
-
-    @Override
-    public Intent getLongClickIntent() {
-        return new Intent(AlarmClock.ACTION_SET_ALARM);
-    }
-
-    @Override
-    protected void handleSetListening(boolean listening) {
-        if (listening) {
-            mController.addCallback(this);
-        } else {
-            mController.removeCallback(this);
-        }
-    }
-
-    @Override
-    public CharSequence getTileLabel() {
-        return mContext.getString(R.string.status_bar_alarm);
-    }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
index 3597929..5aace97 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
@@ -16,12 +16,16 @@
 
 package com.android.systemui.qs.tiles;
 
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_QS_MODE;
+
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.content.Intent;
+import android.metrics.LogMaker;
 import android.provider.Settings;
 import android.service.quicksettings.Tile;
 import android.support.annotation.StringRes;
+import android.util.Log;
 import android.widget.Switch;
 
 import com.android.internal.app.ColorDisplayController;
@@ -65,6 +69,15 @@
 
     @Override
     protected void handleClick() {
+        // Enroll in forced auto mode if eligible.
+        if ("1".equals(Settings.Global.getString(mContext.getContentResolver(),
+                Settings.Global.NIGHT_DISPLAY_FORCED_AUTO_MODE_AVAILABLE))
+                && mController.getAutoModeRaw() == -1) {
+            mController.setAutoMode(ColorDisplayController.AUTO_MODE_CUSTOM);
+            Log.i("NightDisplayTile", "Enrolled in forced night display auto mode");
+        }
+
+        // Change current activation state.
         final boolean activated = !mState.value;
         mController.setActivated(activated);
     }
@@ -147,6 +160,11 @@
     }
 
     @Override
+    public LogMaker populate(LogMaker logMaker) {
+        return super.populate(logMaker).addTaggedData(FIELD_QS_MODE, mController.getAutoModeRaw());
+    }
+
+    @Override
     public Intent getLongClickIntent() {
         return new Intent(Settings.ACTION_NIGHT_DISPLAY_SETTINGS);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 409c753..df4a975 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -45,8 +45,10 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.Dependency;
 import com.android.systemui.EventLogConstants;
 import com.android.systemui.EventLogTags;
+import com.android.systemui.OverviewProxyService;
 import com.android.systemui.R;
 import com.android.systemui.RecentsComponent;
 import com.android.systemui.SystemUI;
@@ -100,6 +102,8 @@
     private static RecentsTaskLoader sTaskLoader;
     private static RecentsConfiguration sConfiguration;
 
+    private OverviewProxyService mOverviewProxyService;
+
     private Handler mHandler;
     private RecentsImpl mImpl;
     private int mDraggingInRecentsCurrentUser;
@@ -208,6 +212,7 @@
         sTaskLoader.setDefaultColors(defaultTaskBarBackgroundColor, defaultTaskViewBackgroundColor);
         mHandler = new Handler();
         mImpl = new RecentsImpl(mContext);
+        mOverviewProxyService = Dependency.get(OverviewProxyService.class);
 
         // Register with the event bus
         EventBus.getDefault().register(this, EVENT_BUS_PRIORITY);
@@ -247,6 +252,13 @@
             return;
         }
 
+        if (mOverviewProxyService.getProxy() != null) {
+            // TODO: Proxy to Launcher
+            if (!triggeredFromAltTab) {
+                return;
+            }
+        }
+
         ActivityManagerWrapper.getInstance().closeSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS);
         int recentsGrowTarget = getComponent(Divider.class).getView().growsRecents();
         int currentUser = sSystemServicesProxy.getCurrentUser();
@@ -282,6 +294,13 @@
             return;
         }
 
+        if (mOverviewProxyService.getProxy() != null) {
+            // TODO: Proxy to Launcher
+            if (!triggeredFromAltTab) {
+                return;
+            }
+        }
+
         int currentUser = sSystemServicesProxy.getCurrentUser();
         if (sSystemServicesProxy.isSystemUser(currentUser)) {
             mImpl.hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
@@ -313,6 +332,11 @@
             return;
         }
 
+        if (mOverviewProxyService.getProxy() != null) {
+            // TODO: Proxy to Launcher
+            return;
+        }
+
         int growTarget = getComponent(Divider.class).getView().growsRecents();
         int currentUser = sSystemServicesProxy.getCurrentUser();
         if (sSystemServicesProxy.isSystemUser(currentUser)) {
@@ -345,6 +369,11 @@
             return;
         }
 
+        if (mOverviewProxyService.getProxy() != null) {
+            // TODO: Proxy to Launcher
+            return;
+        }
+
         int currentUser = sSystemServicesProxy.getCurrentUser();
         if (sSystemServicesProxy.isSystemUser(currentUser)) {
             mImpl.preloadRecents();
@@ -373,6 +402,11 @@
             return;
         }
 
+        if (mOverviewProxyService.getProxy() != null) {
+            // TODO: Proxy to Launcher
+            return;
+        }
+
         int currentUser = sSystemServicesProxy.getCurrentUser();
         if (sSystemServicesProxy.isSystemUser(currentUser)) {
             mImpl.cancelPreloadingRecents();
@@ -415,7 +449,7 @@
         final int activityType = runningTask != null
                 ? runningTask.configuration.windowConfiguration.getActivityType()
                 : ACTIVITY_TYPE_UNDEFINED;
-        boolean screenPinningActive = ActivityManagerWrapper.getInstance().isLockToAppActive();
+        boolean screenPinningActive = ActivityManagerWrapper.getInstance().isScreenPinningActive();
         boolean isRunningTaskInHomeOrRecentsStack =
                 activityType == ACTIVITY_TYPE_HOME || activityType == ACTIVITY_TYPE_RECENTS;
         if (runningTask != null && !isRunningTaskInHomeOrRecentsStack && !screenPinningActive) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index b0a2fad..95b311f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -96,6 +96,7 @@
 import com.android.systemui.recents.views.SystemBarScrimViews;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 
+import com.android.systemui.shared.system.WindowManagerWrapper;
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
@@ -836,12 +837,7 @@
         mRecentsView.getViewTreeObserver().removeOnPreDrawListener(this);
         // We post to make sure that this information is delivered after this traversals is
         // finished.
-        mRecentsView.post(new Runnable() {
-            @Override
-            public void run() {
-                Recents.getSystemServices().endProlongedAnimations();
-            }
-        });
+        mRecentsView.post(() -> WindowManagerWrapper.getInstance().endProlongedAnimations());
         return true;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 3f6f30b..055e72e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -24,7 +24,6 @@
 
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
-import android.app.KeyguardManager;
 import android.app.trust.TrustManager;
 import android.content.ActivityNotFoundException;
 import android.content.Context;
@@ -34,7 +33,6 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
-import android.os.AsyncTask.Status;
 import android.os.Handler;
 import android.os.SystemClock;
 import android.util.ArraySet;
@@ -385,8 +383,7 @@
     }
 
     public void toggleRecents(int growTarget) {
-        // Skip preloading if the task is locked
-        if (ActivityManagerWrapper.getInstance().isLockToAppActive()) {
+        if (ActivityManagerWrapper.getInstance().isScreenPinningActive()) {
             return;
         }
 
@@ -464,8 +461,7 @@
     }
 
     public void preloadRecents() {
-        // Skip preloading if the task is locked
-        if (ActivityManagerWrapper.getInstance().isLockToAppActive()) {
+        if (ActivityManagerWrapper.getInstance().isScreenPinningActive()) {
             return;
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
index 26fac6c..127361a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
@@ -49,6 +49,10 @@
 import com.android.systemui.recents.misc.SysUiTaskStackChangeListener;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
 /**
  * Shows onboarding for the new recents interaction in P (codenamed quickstep).
  */
@@ -65,6 +69,7 @@
     private final Context mContext;
     private final WindowManager mWindowManager;
     private final OverviewProxyService mOverviewProxyService;
+    private Set<String> mBlacklistedPackages;
     private final View mLayout;
     private final TextView mTextView;
     private final ImageView mDismissView;
@@ -85,6 +90,10 @@
         public void onTaskStackChanged() {
             ActivityManager.RunningTaskInfo info = ActivityManagerWrapper.getInstance()
                     .getRunningTask(ACTIVITY_TYPE_UNDEFINED /* ignoreActivityType */);
+            if (mBlacklistedPackages.contains(info.baseActivity.getPackageName())) {
+                hide(true);
+                return;
+            }
             int activityType = info.configuration.windowConfiguration.getActivityType();
             int numAppsLaunched = Prefs.getInt(mContext, Prefs.Key.NUM_APPS_LAUNCHED, 0);
             if (activityType == ACTIVITY_TYPE_STANDARD) {
@@ -122,6 +131,9 @@
         mOverviewProxyService = overviewProxyService;
         final Resources res = context.getResources();
         mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+        mBlacklistedPackages = new HashSet<>();
+        Collections.addAll(mBlacklistedPackages, res.getStringArray(
+                R.array.recents_onboarding_blacklisted_packages));
         mLayout = LayoutInflater.from(mContext).inflate(R.layout.recents_onboarding, null);
         mTextView = mLayout.findViewById(R.id.onboarding_text);
         mDismissView = mLayout.findViewById(R.id.dismiss);
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 93fd34a..544d95c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -444,17 +444,6 @@
         }
     }
 
-    public void endProlongedAnimations() {
-        if (mWm == null) {
-            return;
-        }
-        try {
-            mIwm.endProlongedAnimations();
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
     public void registerDockedStackListener(IDockedStackListener listener) {
         if (mWm == null) return;
 
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 3cc3273..89288d8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -2188,7 +2188,8 @@
     private void readSystemFlags() {
         SystemServicesProxy ssp = Recents.getSystemServices();
         mTouchExplorationEnabled = ssp.isTouchExplorationEnabled();
-        mScreenPinningEnabled = ActivityManagerWrapper.getInstance().isLockToAppEnabled();
+        mScreenPinningEnabled = ActivityManagerWrapper.getInstance().isScreenPinningEnabled()
+                && !ActivityManagerWrapper.getInstance().isLockToAppActive();
     }
 
     private void updateStackActionButtonVisibility() {
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 0272a90..842899b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -22,6 +22,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.annotation.Nullable;
+import android.app.AppGlobals;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
@@ -37,6 +38,7 @@
 import android.os.CountDownTimer;
 import android.support.v4.graphics.ColorUtils;
 import android.util.AttributeSet;
+import android.util.IconDrawableFactory;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewAnimationUtils;
@@ -65,6 +67,8 @@
 public class TaskViewHeader extends FrameLayout
         implements View.OnClickListener, View.OnLongClickListener {
 
+    private static IconDrawableFactory sDrawableFactory;
+
     private static final float HIGHLIGHT_LIGHTNESS_INCREMENT = 0.075f;
     private static final float OVERLAY_LIGHTNESS_INCREMENT = -0.0625f;
     private static final int OVERLAY_REVEAL_DURATION = 250;
@@ -628,7 +632,7 @@
                 activityInfo.applicationInfo, userId));
         mAppTitleView.setTextColor(mTask.useLightOnPrimaryColor ?
                 mTaskBarViewLightTextColor : mTaskBarViewDarkTextColor);
-        mAppIconView.setImageDrawable(ActivityManagerWrapper.getInstance().getBadgedApplicationIcon(
+        mAppIconView.setImageDrawable(getIconDrawableFactory().getBadgedIcon(
                 activityInfo.applicationInfo, userId));
         mAppInfoView.setImageDrawable(mTask.useLightOnPrimaryColor
                 ? mLightInfoIcon
@@ -671,4 +675,11 @@
             revealAnim.start();
         }
     }
+
+    private static IconDrawableFactory getIconDrawableFactory() {
+        if (sDrawableFactory == null) {
+            sDrawableFactory = IconDrawableFactory.newInstance(AppGlobals.getInitialApplication());
+        }
+        return sDrawableFactory;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AppOpsListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/AppOpsListener.java
new file mode 100644
index 0000000..2ec78cf
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AppOpsListener.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.app.AppOpsManager;
+import android.content.Context;
+
+import com.android.systemui.Dependency;
+import com.android.systemui.ForegroundServiceController;
+
+/**
+ * This class handles listening to notification updates and passing them along to
+ * NotificationPresenter to be displayed to the user.
+ */
+public class AppOpsListener implements AppOpsManager.OnOpActiveChangedListener {
+    private static final String TAG = "NotificationListener";
+
+    // Dependencies:
+    private final ForegroundServiceController mFsc =
+            Dependency.get(ForegroundServiceController.class);
+
+    private final Context mContext;
+    protected NotificationPresenter mPresenter;
+    protected NotificationEntryManager mEntryManager;
+    protected final AppOpsManager mAppOps;
+
+    protected static final int[] OPS = new int[] {AppOpsManager.OP_CAMERA,
+            AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
+            AppOpsManager.OP_RECORD_AUDIO};
+
+    public AppOpsListener(Context context) {
+        mContext = context;
+        mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+    }
+
+    public void setUpWithPresenter(NotificationPresenter presenter,
+            NotificationEntryManager entryManager) {
+        mPresenter = presenter;
+        mEntryManager = entryManager;
+        mAppOps.startWatchingActive(OPS, this);
+    }
+
+    public void destroy() {
+        mAppOps.stopWatchingActive(this);
+    }
+
+    @Override
+    public void onOpActiveChanged(int code, int uid, String packageName, boolean active) {
+        mFsc.onAppOpChanged(code, uid, packageName, active);
+        mPresenter.getHandler().post(() -> {
+          mEntryManager.updateNotificationsForAppOps(code, uid, packageName, active);
+        });
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 2723df7..785fc1c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -36,6 +36,7 @@
 import android.os.Bundle;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
+import android.util.ArraySet;
 import android.util.AttributeSet;
 import android.util.FloatProperty;
 import android.util.MathUtils;
@@ -82,7 +83,6 @@
 import com.android.systemui.statusbar.stack.AnimationProperties;
 import com.android.systemui.statusbar.stack.ExpandableViewState;
 import com.android.systemui.statusbar.stack.NotificationChildrenContainer;
-import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.stack.StackScrollState;
 
 import java.util.ArrayList;
@@ -181,6 +181,7 @@
     private AboveShelfChangedListener mAboveShelfChangedListener;
     private HeadsUpManager mHeadsUpManager;
     private View mHelperButton;
+    private boolean mChildIsExpanding;
 
     private boolean mJustClicked;
     private boolean mIconAnimationRunning;
@@ -575,8 +576,13 @@
      * @param isChildInGroup Is this notification now in a group
      * @param parent the new parent notification
      */
-    public void setIsChildInGroup(boolean isChildInGroup, ExpandableNotificationRow parent) {;
+    public void setIsChildInGroup(boolean isChildInGroup, ExpandableNotificationRow parent) {
         boolean childInGroup = StatusBar.ENABLE_CHILD_NOTIFICATIONS && isChildInGroup;
+        if (mExpandAnimationRunning && !isChildInGroup && mNotificationParent != null) {
+            mNotificationParent.setChildIsExpanding(false);
+            mNotificationParent.setExtraWidthForClipping(0.0f);
+            mNotificationParent.setMinimumHeightForClipping(0);
+        }
         mNotificationParent = childInGroup ? parent : null;
         mPrivateLayout.setIsChildInGroup(childInGroup);
         mNotificationInflater.setIsChildInGroup(childInGroup);
@@ -651,10 +657,11 @@
                 visualStabilityManager, callback);
     }
 
-    public void getChildrenStates(StackScrollState resultState) {
+    public void getChildrenStates(StackScrollState resultState,
+            AmbientState ambientState) {
         if (mIsSummaryWithChildren) {
             ExpandableViewState parentState = resultState.getViewStateForView(this);
-            mChildrenContainer.getState(resultState, parentState);
+            mChildrenContainer.getState(resultState, parentState, ambientState);
         }
     }
 
@@ -1348,6 +1355,14 @@
         mHelperButton.setVisibility(show ? View.VISIBLE : View.GONE);
     }
 
+    public void showAppOpsIcons(ArraySet<Integer> activeOps) {
+        if (mIsSummaryWithChildren && mChildrenContainer.getHeaderView() != null) {
+            mChildrenContainer.getHeaderView().showAppOpsIcons(activeOps);
+        }
+        mPrivateLayout.showAppOpsIcons(activeOps);
+        mPublicLayout.showAppOpsIcons(activeOps);
+    }
+
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
@@ -1601,28 +1616,52 @@
         if (params == null) {
             return;
         }
-        setTranslationY(params.getTop());
         float zProgress = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(
                 params.getProgress(0, 50));
         float translationZ = MathUtils.lerp(params.getStartTranslationZ(),
                 mNotificationLaunchHeight,
                 zProgress);
         setTranslationZ(translationZ);
+        float extraWidthForClipping = params.getWidth() - getWidth()
+                + MathUtils.lerp(0, mOutlineRadius * 2, params.getProgress());
+        setExtraWidthForClipping(extraWidthForClipping);
+        int top = params.getTop();
+        float interpolation = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(params.getProgress());
+        int startClipTopAmount = params.getStartClipTopAmount();
+        if (mNotificationParent != null) {
+            top -= mNotificationParent.getTranslationY();
+            mNotificationParent.setTranslationZ(translationZ);
+            int parentStartClipTopAmount = params.getParentStartClipTopAmount();
+            if (startClipTopAmount != 0) {
+                int clipTopAmount = (int) MathUtils.lerp(parentStartClipTopAmount,
+                        parentStartClipTopAmount - startClipTopAmount,
+                        interpolation);
+                mNotificationParent.setClipTopAmount(clipTopAmount);
+            }
+            mNotificationParent.setExtraWidthForClipping(extraWidthForClipping);
+            mNotificationParent.setMinimumHeightForClipping(params.getHeight()
+                    + mNotificationParent.getActualHeight());
+        } else if (startClipTopAmount != 0) {
+            int clipTopAmount = (int) MathUtils.lerp(startClipTopAmount, 0, interpolation);
+            setClipTopAmount(clipTopAmount);
+        }
+        setTranslationY(top);
         setActualHeight(params.getHeight());
+
         mBackgroundNormal.setExpandAnimationParams(params);
     }
 
     public void setExpandAnimationRunning(boolean expandAnimationRunning) {
+        View contentView;
+        if (mIsSummaryWithChildren) {
+            contentView =  mChildrenContainer;
+        } else {
+            contentView = getShowingLayout();
+        }
+        if (mGuts != null && mGuts.isExposed()) {
+            contentView = mGuts;
+        }
         if (expandAnimationRunning) {
-            View contentView;
-            if (mIsSummaryWithChildren) {
-                contentView =  mChildrenContainer;
-            } else {
-                contentView = getShowingLayout();
-            }
-            if (mGuts != null && mGuts.isExposed()) {
-                contentView = mGuts;
-            }
             contentView.animate()
                     .alpha(0f)
                     .setDuration(ActivityLaunchAnimator.ANIMATION_DURATION_FADE_CONTENT)
@@ -1637,15 +1676,35 @@
             if (mGuts != null) {
                 mGuts.setAlpha(1.0f);
             }
+            if (contentView != null) {
+                contentView.setAlpha(1.0f);
+            }
+            setExtraWidthForClipping(0.0f);
+            if (mNotificationParent != null) {
+                mNotificationParent.setExtraWidthForClipping(0.0f);
+                mNotificationParent.setMinimumHeightForClipping(0);
+            }
+        }
+        if (mNotificationParent != null) {
+            mNotificationParent.setChildIsExpanding(mExpandAnimationRunning);
         }
         updateChildrenVisibility();
         updateClipping();
         mBackgroundNormal.setExpandAnimationRunning(expandAnimationRunning);
     }
 
+    private void setChildIsExpanding(boolean isExpanding) {
+        mChildIsExpanding = isExpanding;
+    }
+
+    @Override
+    public boolean hasExpandingChild() {
+        return mChildIsExpanding;
+    }
+
     @Override
     protected boolean shouldClipToActualHeight() {
-        return super.shouldClipToActualHeight() && !mExpandAnimationRunning;
+        return super.shouldClipToActualHeight() && !mExpandAnimationRunning && !mChildIsExpanding;
     }
 
     @Override
@@ -1947,18 +2006,10 @@
         }
     }
 
-    private void updateMaxHeights() {
+    public void updateMaxHeights() {
         int intrinsicBefore = getIntrinsicHeight();
-        View expandedChild = mPrivateLayout.getExpandedChild();
-        if (expandedChild == null) {
-            expandedChild = mPrivateLayout.getContractedChild();
-        }
-        mMaxExpandHeight = expandedChild.getHeight();
-        View headsUpChild = mPrivateLayout.getHeadsUpChild();
-        if (headsUpChild == null) {
-            headsUpChild = mPrivateLayout.getContractedChild();
-        }
-        mHeadsUpHeight = headsUpChild.getHeight();
+        mMaxExpandHeight = mPrivateLayout.getExpandHeight();
+        mHeadsUpHeight = mPrivateLayout.getHeadsUpHeight();
         if (intrinsicBefore != getIntrinsicHeight()) {
             notifyHeightChanged(true  /* needsAnimation */);
         }
@@ -2245,7 +2296,7 @@
                 mGuts.setClipBottomAmount(clipBottomAmount);
             }
         }
-        if (mChildrenContainer != null) {
+        if (mChildrenContainer != null && !mChildIsExpanding) {
             // We have to update this even if it hasn't changed, since the children locations can
             // have changed
             mChildrenContainer.setClipBottomAmount(clipBottomAmount);
@@ -2453,7 +2504,7 @@
     public boolean isAboveShelf() {
         return !isOnKeyguard()
                 && (mIsPinned || mHeadsupDisappearRunning || (mIsHeadsUp && mAboveShelf)
-                || mExpandAnimationRunning);
+                || mExpandAnimationRunning || mChildIsExpanding);
     }
 
     public void setShowAmbient(boolean showAmbient) {
@@ -2478,7 +2529,7 @@
                 return true;
             }
         } else if (child == mChildrenContainer) {
-            if (isClippingNeeded() || !hasNoRounding()) {
+            if (!mChildIsExpanding && (isClippingNeeded() || !hasNoRounding())) {
                 return true;
             }
         } else if (child instanceof NotificationGuts) {
@@ -2544,11 +2595,19 @@
                 if (row.isExpandAnimationRunning()) {
                     return;
                 }
+                handleFixedTranslationZ(row);
                 super.applyToView(view);
                 row.applyChildrenState(mOverallState);
             }
         }
 
+        private void handleFixedTranslationZ(ExpandableNotificationRow row) {
+            if (row.hasExpandingChild()) {
+                zTranslation = row.getTranslationZ();
+                clipTopAmount = row.getClipTopAmount();
+            }
+        }
+
         @Override
         protected void onYTranslationAnimationFinished(View view) {
             super.onYTranslationAnimationFinished(view);
@@ -2567,6 +2626,7 @@
                 if (row.isExpandAnimationRunning()) {
                     return;
                 }
+                handleFixedTranslationZ(row);
                 super.animateTo(child, properties);
                 row.startChildAnimation(mOverallState, properties);
             }
@@ -2578,6 +2638,16 @@
         mChildrenContainer = childrenContainer;
     }
 
+    @VisibleForTesting
+    protected void setPrivateLayout(NotificationContentView privateLayout) {
+        mPrivateLayout = privateLayout;
+    }
+
+    @VisibleForTesting
+    protected void setPublicLayout(NotificationContentView publicLayout) {
+        mPublicLayout = publicLayout;
+    }
+
     /**
      * Equivalent to View.OnLongClickListener with coordinates
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
index 66b3a75..8bc2201 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
@@ -61,7 +61,7 @@
     private final Path mClipPath = new Path();
     private boolean mCustomOutline;
     private float mOutlineAlpha = -1f;
-    private float mOutlineRadius;
+    protected float mOutlineRadius;
     private boolean mAlwaysRoundBothCorners;
     private Path mTmpPath = new Path();
     private Path mTmpPath2 = new Path();
@@ -78,6 +78,8 @@
     protected boolean mShouldTranslateContents;
     private boolean mClipRoundedToClipTopAmount;
     private float mDistanceToTopRoundness = -1;
+    private float mExtraWidthForClipping;
+    private int mMinimumHeightForClipping = 0;
 
     private final ViewOutlineProvider mProvider = new ViewOutlineProvider() {
         @Override
@@ -202,11 +204,11 @@
         canvas.save();
         Path intersectPath = null;
         if (mClipRoundedToClipTopAmount) {
-            int left = 0;
+            int left = (int) (- mExtraWidthForClipping / 2.0f);
             int top = (int) (mClipTopAmount - mDistanceToTopRoundness);
-            int right = getWidth();
-            int bottom = (int) Math.max(getActualHeight() - mClipBottomAmount,
-                    top + mOutlineRadius);
+            int right = getWidth() + (int) (mExtraWidthForClipping + left);
+            int bottom = (int) Math.max(mMinimumHeightForClipping,
+                    Math.max(getActualHeight() - mClipBottomAmount, top + mOutlineRadius));
             ExpandableOutlineView.getRoundedRectPath(left, top, right, bottom, mOutlineRadius,
                     0.0f,
                     mClipPath);
@@ -234,6 +236,14 @@
         return result;
     }
 
+    public void setExtraWidthForClipping(float extraWidthForClipping) {
+        mExtraWidthForClipping = extraWidthForClipping;
+    }
+
+    public void setMinimumHeightForClipping(int minimumHeightForClipping) {
+        mMinimumHeightForClipping = minimumHeightForClipping;
+    }
+
     @Override
     public void setDistanceToTopRoundness(float distanceToTopRoundness) {
         super.setDistanceToTopRoundness(distanceToTopRoundness);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index 1496a41..204adc8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -543,6 +543,10 @@
         return false;
     }
 
+    public boolean hasExpandingChild() {
+        return false;
+    }
+
     /**
      * A listener notifying when {@link #getActualHeight} changes.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 22e8909..bc14203 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -411,12 +411,14 @@
                 break;
         }
 
+        String percentage = NumberFormat.getPercentInstance()
+                .format(mBatteryLevel / 100f);
         if (hasChargingTime) {
             String chargingTimeFormatted = Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                     mContext, chargingTimeRemaining);
-            return mContext.getResources().getString(chargingId, chargingTimeFormatted);
+            return mContext.getResources().getString(chargingId, chargingTimeFormatted, percentage);
         } else {
-            return mContext.getResources().getString(chargingId);
+            return mContext.getResources().getString(chargingId, percentage);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index c4d0b79..73c8795 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -23,6 +23,7 @@
 import android.graphics.Rect;
 import android.os.Build;
 import android.service.notification.StatusBarNotification;
+import android.util.ArraySet;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.NotificationHeaderView;
@@ -143,6 +144,8 @@
     private int mClipBottomAmount;
     private boolean mIsLowPriority;
     private boolean mIsContentExpandable;
+    private boolean mRemoteInputVisible;
+    private int mUnrestrictedContentHeight;
 
 
     public NotificationContentView(Context context, AttributeSet attrs) {
@@ -293,6 +296,24 @@
         setMeasuredDimension(width, ownHeight);
     }
 
+    /**
+     * Get the extra height that needs to be added to the notification height for a given
+     * {@link RemoteInputView}.
+     * This is needed when the user is inline replying in order to ensure that the reply bar has
+     * enough padding.
+     *
+     * @param remoteInput The remote input to check.
+     * @return The extra height needed.
+     */
+    private int getExtraRemoteInputHeight(RemoteInputView remoteInput) {
+        if (remoteInput != null && remoteInput.getVisibility() == VISIBLE
+                && remoteInput.isActive()) {
+            return getResources().getDimensionPixelSize(
+                    com.android.internal.R.dimen.notification_content_margin);
+        }
+        return 0;
+    }
+
     private boolean updateContractedHeaderWidth() {
         // We need to update the expanded and the collapsed header to have exactly the same with to
         // have the expand buttons laid out at the same location.
@@ -538,19 +559,23 @@
     }
 
     public void setContentHeight(int contentHeight) {
-        mContentHeight = Math.max(Math.min(contentHeight, getHeight()), getMinHeight());
+        mUnrestrictedContentHeight = Math.max(contentHeight, getMinHeight());
+        int maxContentHeight = mContainingNotification.getIntrinsicHeight()
+                - getExtraRemoteInputHeight(mExpandedRemoteInput)
+                - getExtraRemoteInputHeight(mHeadsUpRemoteInput);
+        mContentHeight = Math.min(mUnrestrictedContentHeight, maxContentHeight);
         selectLayout(mAnimate /* animate */, false /* force */);
 
         int minHeightHint = getMinContentHeightHint();
 
         NotificationViewWrapper wrapper = getVisibleWrapper(mVisibleType);
         if (wrapper != null) {
-            wrapper.setContentHeight(mContentHeight, minHeightHint);
+            wrapper.setContentHeight(mUnrestrictedContentHeight, minHeightHint);
         }
 
         wrapper = getVisibleWrapper(mTransformationStartVisibleType);
         if (wrapper != null) {
-            wrapper.setContentHeight(mContentHeight, minHeightHint);
+            wrapper.setContentHeight(mUnrestrictedContentHeight, minHeightHint);
         }
 
         updateClipping();
@@ -692,9 +717,9 @@
         if (mContainingNotification.isShowingAmbient()) {
             return getShowingAmbientView().getHeight();
         } else if (mExpandedChild != null) {
-            return mExpandedChild.getHeight();
+            return mExpandedChild.getHeight() + getExtraRemoteInputHeight(mExpandedRemoteInput);
         } else if (mIsHeadsUp && mHeadsUpChild != null && !mContainingNotification.isOnKeyguard()) {
-            return mHeadsUpChild.getHeight();
+            return mHeadsUpChild.getHeight() + getExtraRemoteInputHeight(mHeadsUpRemoteInput);
         }
         return mContractedChild.getHeight();
     }
@@ -746,7 +771,7 @@
     private void updateClipping() {
         if (mClipToActualHeight) {
             int top = (int) (mClipTopAmount - getTranslationY());
-            int bottom = (int) (mContentHeight - mClipBottomAmount - getTranslationY());
+            int bottom = (int) (mUnrestrictedContentHeight - mClipBottomAmount - getTranslationY());
             bottom = Math.max(top, bottom);
             mClipBounds.set(0, top, getWidth(), bottom);
             setClipBounds(mClipBounds);
@@ -790,7 +815,8 @@
                 }
                 NotificationViewWrapper visibleWrapper = getVisibleWrapper(visibleType);
                 if (visibleWrapper != null) {
-                    visibleWrapper.setContentHeight(mContentHeight, getMinContentHeightHint());
+                    visibleWrapper.setContentHeight(mUnrestrictedContentHeight,
+                            getMinContentHeightHint());
                 }
                 updateBackgroundColor(animate);
             }
@@ -1276,6 +1302,7 @@
                         mContext.getColor(R.color.remote_input_hint)));
 
                 existing.setWrapper(wrapper);
+                existing.setOnVisibilityChangedListener(this::setRemoteInputVisible);
 
                 if (existingPendingIntent != null || existing.isActive()) {
                     // The current action could be gone, or the pending intent no longer valid.
@@ -1397,6 +1424,17 @@
         return header;
     }
 
+    public void showAppOpsIcons(ArraySet<Integer> activeOps) {
+        if (mContractedChild != null && mContractedWrapper.getNotificationHeader() != null) {
+            mContractedWrapper.getNotificationHeader().showAppOpsIcons(activeOps);
+        }
+        if (mExpandedChild != null && mExpandedWrapper.getNotificationHeader() != null) {
+            mExpandedWrapper.getNotificationHeader().showAppOpsIcons(activeOps);
+        }
+        if (mHeadsUpChild != null && mHeadsUpWrapper.getNotificationHeader() != null) {
+            mHeadsUpWrapper.getNotificationHeader().showAppOpsIcons(activeOps);
+        }
+    }
 
     public NotificationHeaderView getContractedNotificationHeader() {
         if (mContractedChild != null) {
@@ -1576,4 +1614,31 @@
         }
         return null;
     }
+
+    public int getExpandHeight() {
+        View expandedChild = mExpandedChild;
+        if (expandedChild == null) {
+            expandedChild = mContractedChild;
+        }
+        return expandedChild.getHeight() + getExtraRemoteInputHeight(mExpandedRemoteInput);
+    }
+
+    public int getHeadsUpHeight() {
+        View headsUpChild = mHeadsUpChild;
+        if (headsUpChild == null) {
+            headsUpChild = mContractedChild;
+        }
+        return headsUpChild.getHeight()+ getExtraRemoteInputHeight(mHeadsUpRemoteInput);
+    }
+
+    public void setRemoteInputVisible(boolean remoteInputVisible) {
+        mRemoteInputVisible = remoteInputVisible;
+        setClipChildren(!remoteInputVisible);
+    }
+
+    @Override
+    public void setClipChildren(boolean clipChildren) {
+        clipChildren = clipChildren && !mRemoteInputVisible;
+        super.setClipChildren(clipChildren);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 127f3f9..d53cb03 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar;
 
 import android.app.AppGlobals;
+import android.app.AppOpsManager;
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
@@ -34,6 +35,7 @@
 import android.service.notification.SnoozeCriterion;
 import android.service.notification.StatusBarNotification;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.RemoteViews;
@@ -65,6 +67,8 @@
     private final Environment mEnvironment;
     private HeadsUpManager mHeadsUpManager;
 
+    final ForegroundServiceController mFsc = Dependency.get(ForegroundServiceController.class);
+
     public static final class Entry {
         private static final long LAUNCH_COOLDOWN = 2000;
         private static final long REMOTE_INPUT_COOLDOWN = 500;
@@ -95,6 +99,7 @@
         private Throwable mDebugThrowable;
         public CharSequence remoteInputTextWhenReset;
         public long lastRemoteInputSent = NOT_LAUNCHED_YET;
+        public ArraySet<Integer> mActiveAppOps = new ArraySet<>(3);
 
         public Entry(StatusBarNotification n) {
             this.key = n.getKey();
@@ -194,7 +199,7 @@
         /**
          * Update the notification icons.
          * @param context the context to create the icons with.
-         * @param n the notification to read the icon from.
+         * @param sbn the notification to read the icon from.
          * @throws InflationException
          */
         public void updateIcons(Context context, StatusBarNotification sbn)
@@ -375,6 +380,8 @@
         }
         mGroupManager.onEntryAdded(entry);
 
+        updateAppOps(entry);
+
         updateRankingAndSort(mRankingMap);
     }
 
@@ -393,6 +400,35 @@
         updateRankingAndSort(ranking);
     }
 
+    private void updateAppOps(Entry entry) {
+        final int uid = entry.notification.getUid();
+        final String pkg = entry.notification.getPackageName();
+        ArraySet<Integer> activeOps = mFsc.getAppOps(entry.notification.getUserId(), pkg);
+        if (activeOps != null) {
+            int N = activeOps.size();
+            for (int i = 0; i < N; i++) {
+                updateAppOp(activeOps.valueAt(i), uid, pkg, true);
+            }
+        }
+    }
+
+    public void updateAppOp(int appOp, int uid, String pkg, boolean showIcon) {
+        synchronized (mEntries) {
+            final int N = mEntries.size();
+            for (int i = 0; i < N; i++) {
+                Entry entry = mEntries.valueAt(i);
+                if (uid == entry.notification.getUid()
+                    && pkg.equals(entry.notification.getPackageName())) {
+                    if (showIcon) {
+                        entry.mActiveAppOps.add(appOp);
+                    } else {
+                        entry.mActiveAppOps.remove(appOp);
+                    }
+                }
+            }
+        }
+    }
+
     public boolean isAmbient(String key) {
         if (mRankingMap != null) {
             getRanking(key, mTmpRanking);
@@ -545,11 +581,14 @@
             return true;
         }
 
-        final ForegroundServiceController fsc = Dependency.get(ForegroundServiceController.class);
-        if (fsc.isDungeonNotification(sbn) && !fsc.isDungeonNeededForUser(sbn.getUserId())) {
+        if (mFsc.isDungeonNotification(sbn) && !mFsc.isDungeonNeededForUser(sbn.getUserId())) {
             // this is a foreground-service disclosure for a user that does not need to show one
             return true;
         }
+        if (mFsc.isSystemAlertNotification(sbn) && !mFsc.isSystemAlertWarningNeeded(
+                sbn.getUserId(), sbn.getPackageName())) {
+            return true;
+        }
 
         return false;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
index 7360486..71f7911 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
@@ -31,6 +31,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.NotificationStats;
@@ -77,7 +78,7 @@
 public class NotificationEntryManager implements Dumpable, NotificationInflater.InflationCallback,
         ExpandableNotificationRow.ExpansionLogger, NotificationUpdateHandler,
         VisualStabilityManager.Callback {
-    private static final String TAG = "NotificationEntryManager";
+    private static final String TAG = "NotificationEntryMgr";
     protected static final boolean DEBUG = false;
     protected static final boolean ENABLE_HEADS_UP = true;
     protected static final String SETTING_HEADS_UP_TICKER = "ticker_gets_heads_up";
@@ -734,6 +735,14 @@
         }
     }
 
+    public void updateNotificationsForAppOps(int appOp, int uid, String pkg, boolean showIcon) {
+        if (mForegroundServiceController.getStandardLayoutKey(
+                UserHandle.getUserId(uid), pkg) != null) {
+            mNotificationData.updateAppOp(appOp, uid, pkg, showIcon);
+            updateNotifications();
+        }
+    }
+
     private boolean alertAgain(NotificationData.Entry oldEntry, Notification newNotification) {
         return oldEntry == null || !oldEntry.hasInterrupted()
                 || (newNotification.flags & Notification.FLAG_ONLY_ALERT_ONCE) == 0;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index cad956c..4f09133 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -698,7 +698,7 @@
         if (!hasOverflow) {
             // we have to ensure that adding the low priority notification won't lead to an
             // overflow
-            collapsedPadding -= (1.0f + OVERFLOW_EARLY_AMOUNT) * mCollapsedIcons.getIconSize();
+            collapsedPadding -= mCollapsedIcons.getNoOverflowExtraPadding();
         } else {
             // Partial overflow padding will fill enough space to add extra dots
             collapsedPadding -= mCollapsedIcons.getPartialOverflowExtraPadding();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index cd4c7ae..75b8b37 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -342,6 +342,8 @@
 
             row.showBlockingHelper(entry.userSentiment ==
                     NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE);
+
+            row.showAppOpsIcons(entry.mActiveAppOps);
         }
 
         mPresenter.onUpdateRowStates();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
index ef44ad1..1d9cdf7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
@@ -42,8 +42,6 @@
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarWindowView;
 
-import java.util.function.Consumer;
-
 /**
  * A class that allows activities to be launched in a seamless way where the notification
  * transforms nicely into the starting window.
@@ -134,8 +132,24 @@
                         ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
                         mParams.startPosition = mSourceNotification.getLocationOnScreen();
                         mParams.startTranslationZ = mSourceNotification.getTranslationZ();
+                        mParams.startClipTopAmount = mSourceNotification.getClipTopAmount();
+                        if (mSourceNotification.isChildInGroup()) {
+                            int parentClip = mSourceNotification
+                                    .getNotificationParent().getClipTopAmount();
+                            mParams.parentStartClipTopAmount = parentClip;
+                            // We need to calculate how much the child is clipped by the parent
+                            // because children always have 0 clipTopAmount
+                            if (parentClip != 0) {
+                                float childClip = parentClip
+                                        - mSourceNotification.getTranslationY();
+                                if (childClip > 0.0f) {
+                                    mParams.startClipTopAmount = (int) Math.ceil(childClip);
+                                }
+                            }
+                        }
                         int targetWidth = app.sourceContainerBounds.width();
-                        int notificationHeight = mSourceNotification.getActualHeight();
+                        int notificationHeight = mSourceNotification.getActualHeight()
+                                - mSourceNotification.getClipBottomAmount();
                         int notificationWidth = mSourceNotification.getWidth();
                         anim.setDuration(ANIMATION_DURATION);
                         anim.setInterpolator(Interpolators.LINEAR);
@@ -241,6 +255,8 @@
         int top;
         int right;
         int bottom;
+        int startClipTopAmount;
+        int parentStartClipTopAmount;
 
         public ExpandAnimationParameters() {
         }
@@ -258,15 +274,32 @@
         }
 
         public int getTopChange() {
-            return Math.min(top - startPosition[1], 0);
+            // We need this compensation to ensure that the QS moves in sync.
+            int clipTopAmountCompensation = 0;
+            if (startClipTopAmount != 0.0f) {
+                clipTopAmountCompensation = (int) MathUtils.lerp(0, startClipTopAmount,
+                        Interpolators.FAST_OUT_SLOW_IN.getInterpolation(linearProgress));
+            }
+            return Math.min(top - startPosition[1] - clipTopAmountCompensation, 0);
         }
 
+        public float getProgress() {
+            return linearProgress;
+        }
 
         public float getProgress(long delay, long duration) {
             return MathUtils.constrain((linearProgress * ANIMATION_DURATION - delay)
                     / duration, 0.0f, 1.0f);
         }
 
+        public int getStartClipTopAmount() {
+            return startClipTopAmount;
+        }
+
+        public int getParentStartClipTopAmount() {
+            return parentStartClipTopAmount;
+        }
+
         public float getStartTranslationZ() {
             return startTranslationZ;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
index b220686..446a1d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -14,7 +14,6 @@
 
 package com.android.systemui.statusbar.phone;
 
-import android.app.AlarmManager.AlarmClockInfo;
 import android.content.Context;
 import android.os.Handler;
 import android.provider.Settings.Secure;
@@ -28,8 +27,6 @@
 import com.android.systemui.statusbar.policy.DataSaverController.Listener;
 import com.android.systemui.statusbar.policy.HotspotController;
 import com.android.systemui.statusbar.policy.HotspotController.Callback;
-import com.android.systemui.statusbar.policy.NextAlarmController;
-import com.android.systemui.statusbar.policy.NextAlarmController.NextAlarmChangeCallback;
 
 /**
  * Manages which tiles should be automatically added to QS.
@@ -40,7 +37,6 @@
     public static final String INVERSION = "inversion";
     public static final String WORK = "work";
     public static final String NIGHT = "night";
-    public static final String ALARM = "alarm";
 
     private final Context mContext;
     private final QSTileHost mHost;
@@ -87,9 +83,6 @@
             && ColorDisplayController.isAvailable(mContext)) {
             Dependency.get(ColorDisplayController.class).setListener(mColorDisplayCallback);
         }
-        if (!mAutoTracker.isAdded(ALARM)) {
-            Dependency.get(NextAlarmController.class).addCallback(mNextAlarmChangeCallback);
-        }
     }
 
     public void destroy() {
@@ -101,7 +94,6 @@
         Dependency.get(DataSaverController.class).removeCallback(mDataSaverListener);
         Dependency.get(ManagedProfileController.class).removeCallback(mProfileCallback);
         Dependency.get(ColorDisplayController.class).setListener(null);
-        Dependency.get(NextAlarmController.class).removeCallback(mNextAlarmChangeCallback);
     }
 
     private final ManagedProfileController.Callback mProfileCallback =
@@ -150,19 +142,6 @@
         }
     };
 
-    private final NextAlarmChangeCallback mNextAlarmChangeCallback = new NextAlarmChangeCallback() {
-        @Override
-        public void onNextAlarmChanged(AlarmClockInfo nextAlarm) {
-            if (mAutoTracker.isAdded(ALARM)) return;
-            if (nextAlarm != null) {
-                mHost.addTile(ALARM);
-                mAutoTracker.setTileAdded(ALARM);
-                mHandler.post(() -> Dependency.get(NextAlarmController.class)
-                    .removeCallback(mNextAlarmChangeCallback));
-            }
-        }
-    };
-
     @VisibleForTesting
     final ColorDisplayController.Callback mColorDisplayCallback =
             new ColorDisplayController.Callback() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
index f7f791e..f42473d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -51,6 +51,7 @@
 
     public static final String TAG = "CollapsedStatusBarFragment";
     private static final String EXTRA_PANEL_STATE = "panel_state";
+    public static final String STATUS_BAR_ICON_MANAGER_TAG = "status_bar_icon_manager";
     public static final int FADE_IN_DURATION = 320;
     public static final int FADE_IN_DELAY = 50;
     private PhoneStatusBarView mStatusBar;
@@ -94,6 +95,7 @@
             mStatusBar.go(savedInstanceState.getInt(EXTRA_PANEL_STATE));
         }
         mDarkIconManager = new DarkIconManager(view.findViewById(R.id.statusIcons));
+        mDarkIconManager.setShouldLog(true);
         Dependency.get(StatusBarIconController.class).addIconGroup(mDarkIconManager);
         mSystemIconArea = mStatusBar.findViewById(R.id.system_icon_area);
         mClockView = mStatusBar.findViewById(R.id.clock);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
index c499619..edfd02b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.graphics.Rect;
 import android.graphics.drawable.Icon;
 import android.os.Bundle;
 import android.os.UserHandle;
@@ -25,21 +26,27 @@
 import android.widget.LinearLayout;
 
 import com.android.internal.statusbar.StatusBarIcon;
+import com.android.settingslib.Utils;
 import com.android.systemui.DemoMode;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.StatusBarIconView;
+import com.android.systemui.statusbar.policy.DarkIconDispatcher;
+import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver;
 import com.android.systemui.statusbar.policy.LocationControllerImpl;
+import com.android.systemui.util.leak.LeakDetector;
 
-public class DemoStatusIcons extends LinearLayout implements DemoMode {
+public class DemoStatusIcons extends StatusIconContainer implements DemoMode, DarkReceiver {
     private final LinearLayout mStatusIcons;
     private final int mIconSize;
 
     private boolean mDemoMode;
+    private int mColor;
 
     public DemoStatusIcons(LinearLayout statusIcons, int iconSize) {
         super(statusIcons.getContext());
         mStatusIcons = statusIcons;
         mIconSize = iconSize;
+        mColor = DarkIconDispatcher.DEFAULT_ICON_TINT;
 
         setLayoutParams(mStatusIcons.getLayoutParams());
         setOrientation(mStatusIcons.getOrientation());
@@ -48,6 +55,22 @@
         p.addView(this, p.indexOfChild(mStatusIcons));
     }
 
+    public void remove() {
+        ((ViewGroup) getParent()).removeView(this);
+    }
+
+    public void setColor(int color) {
+        mColor = color;
+        updateColors();
+    }
+
+    private void updateColors() {
+        for (int i = 0; i < getChildCount(); i++) {
+            StatusBarIconView child = (StatusBarIconView) getChildAt(i);
+            child.setStaticDrawableColor(mColor);
+        }
+    }
+
     @Override
     public void dispatchDemoCommand(String command, Bundle args) {
         if (!mDemoMode && command.equals(COMMAND_ENTER)) {
@@ -136,6 +159,7 @@
                     break;
                 } else {
                     StatusBarIcon icon = v.getStatusBarIcon();
+                    icon.visible = true;
                     icon.icon = Icon.createWithResource(icon.icon.getResPackage(), iconId);
                     v.set(icon);
                     v.updateDrawable();
@@ -150,9 +174,16 @@
             return;
         }
         StatusBarIcon icon = new StatusBarIcon(iconPkg, UserHandle.SYSTEM, iconId, 0, 0, "Demo");
+        icon.visible = true;
         StatusBarIconView v = new StatusBarIconView(getContext(), null, null);
         v.setTag(slot);
         v.set(icon);
+        v.setStaticDrawableColor(mColor);
         addView(v, 0, new LinearLayout.LayoutParams(mIconSize, mIconSize));
     }
+
+    @Override
+    public void onDarkChanged(Rect area, float darkIntensity, int tint) {
+        setColor(DarkIconDispatcher.getTint(area, mStatusIcons, tint));
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index aba5cdf..d2cdc27 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.support.v4.util.ArraySet;
 import android.util.Log;
@@ -32,6 +33,7 @@
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
+import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
 
@@ -45,12 +47,12 @@
  */
 public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
        ViewTreeObserver.OnComputeInternalInsetsListener, VisualStabilityManager.Callback,
-       OnHeadsUpChangedListener {
+       OnHeadsUpChangedListener, ConfigurationController.ConfigurationListener {
     private static final String TAG = "HeadsUpManagerPhone";
     private static final boolean DEBUG = false;
 
     private final View mStatusBarWindowView;
-    private final int mStatusBarHeight;
+    private int mStatusBarHeight;
     private final NotificationGroupManager mGroupManager;
     private final StatusBar mBar;
     private final VisualStabilityManager mVisualStabilityManager;
@@ -291,6 +293,13 @@
         }
     }
 
+    @Override
+    public void onConfigChanged(Configuration newConfig) {
+        Resources resources = mContext.getResources();
+        mStatusBarHeight = resources.getDimensionPixelSize(
+                com.android.internal.R.dimen.status_bar_height);
+    }
+
     ///////////////////////////////////////////////////////////////////////////////////////////////
     //  VisualStabilityManager.Callback overrides:
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index 699e8cf..edfbd3f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -21,6 +21,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.Slog;
+import android.util.StatsLog;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -152,7 +153,8 @@
                 mKeyguardView.requestLayout();
             }
             mShowingSoon = false;
-            mKeyguardView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+            StatsLog.write(StatsLog.KEYGUARD_BOUNCER_STATE_CHANGED,
+                StatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SHOWN);
         }
     };
 
@@ -184,6 +186,8 @@
 
     public void hide(boolean destroyView) {
         if (isShowing()) {
+            StatsLog.write(StatsLog.KEYGUARD_BOUNCER_STATE_CHANGED,
+                StatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__HIDDEN);
             mDismissCallbackRegistry.notifyDismissCancelled();
         }
         mFalsingManager.onBouncerHidden();
@@ -264,6 +268,7 @@
         mStatusBarHeight = mRoot.getResources().getDimensionPixelOffset(
                 com.android.systemui.R.dimen.status_bar_height);
         mRoot.setVisibility(View.INVISIBLE);
+        mRoot.setAccessibilityPaneTitle(mKeyguardView.getAccessibilityTitleForCurrentMode());
 
         final WindowInsets rootInsets = mRoot.getRootWindowInsets();
         if (rootInsets != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index 389be1a..0cf26df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -19,11 +19,10 @@
 import static com.android.systemui.statusbar.notification.NotificationUtils.interpolate;
 
 import android.content.res.Resources;
-import android.graphics.Path;
 import android.util.MathUtils;
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.PathInterpolator;
+import com.android.keyguard.KeyguardStatusView;
 
+import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 
 /**
@@ -31,54 +30,83 @@
  */
 public class KeyguardClockPositionAlgorithm {
 
-    private static final float SLOW_DOWN_FACTOR = 0.4f;
-
-    private static final float CLOCK_RUBBERBAND_FACTOR_MIN = 0.08f;
-    private static final float CLOCK_RUBBERBAND_FACTOR_MAX = 0.8f;
-    private static final float CLOCK_SCALE_FADE_START = 0.95f;
-    private static final float CLOCK_SCALE_FADE_END = 0.75f;
-    private static final float CLOCK_SCALE_FADE_END_NO_NOTIFS = 0.5f;
-
-    private static final float CLOCK_ADJ_TOP_PADDING_MULTIPLIER_MIN = 1.4f;
-    private static final float CLOCK_ADJ_TOP_PADDING_MULTIPLIER_MAX = 3.2f;
-
     private static final long MILLIS_PER_MINUTES = 1000 * 60;
     private static final float BURN_IN_PREVENTION_PERIOD_Y = 521;
     private static final float BURN_IN_PREVENTION_PERIOD_X = 83;
 
+    /**
+     * How much the clock height influences the shade position.
+     * 0 means nothing, 1 means move the shade up by the height of the clock
+     * 0.5f means move the shade up by half of the size of the clock.
+     */
+    private static float CLOCK_HEIGHT_WEIGHT = 0.7f;
+
+    /**
+     * Margin between the bottom of the clock and the notification shade.
+     */
     private int mClockNotificationsMargin;
-    private float mClockYFractionMin;
-    private float mClockYFractionMax;
-    private int mMaxKeyguardNotifications;
-    private int mMaxPanelHeight;
+
+    /**
+     * Current height of {@link NotificationPanelView}, considering how much the
+     * user collapsed it.
+     */
     private float mExpandedHeight;
-    private int mNotificationCount;
+
+    /**
+     * Height of the parent view - display size in px.
+     */
     private int mHeight;
+
+    /**
+     * Height of {@link KeyguardStatusView}.
+     */
     private int mKeyguardStatusHeight;
-    private float mEmptyDragAmount;
-    private float mDensity;
+
+    /**
+     * Height of notification stack: Sum of height of each notification.
+     */
+    private int mNotificationStackHeight;
+
+    /**
+     * Minimum top margin to avoid overlap with status bar.
+     */
+    private int mMinTopMargin;
+
+    /**
+     * Maximum bottom padding to avoid overlap with {@link KeyguardBottomAreaView} or
+     * the ambient indication.
+     */
+    private int mMaxShadeBottom;
+
+    /**
+     * Margin that we should respect within the available space.
+     */
+    private int mContainerPadding;
+
+    /**
+     * Position where clock should be when the panel is collapsed.
+     */
+    private int mClockYTarget;
+
+    /**
+     * @see NotificationPanelView#getMaxPanelHeight()
+     */
+    private float mMaxPanelHeight;
+
+    /**
+     * Burn-in prevention x translation.
+     */
     private int mBurnInPreventionOffsetX;
+
+    /**
+     * Burn-in prevention y translation.
+     */
     private int mBurnInPreventionOffsetY;
 
     /**
-     * The number (fractional) of notifications the "more" card counts when calculating how many
-     * notifications are currently visible for the y positioning of the clock.
+     * Doze/AOD transition amount.
      */
-    private float mMoreCardNotificationAmount;
-
-    private static final PathInterpolator sSlowDownInterpolator;
-
-    static {
-        Path path = new Path();
-        path.moveTo(0, 0);
-        path.cubicTo(0.3f, 0.875f, 0.6f, 1f, 1f, 1f);
-        sSlowDownInterpolator = new PathInterpolator(path);
-    }
-
-    private AccelerateInterpolator mAccelerateInterpolator = new AccelerateInterpolator();
-    private int mClockBottom;
     private float mDarkAmount;
-    private int mDozingStackPadding;
 
     /**
      * Refreshes the dimension values.
@@ -86,79 +114,95 @@
     public void loadDimens(Resources res) {
         mClockNotificationsMargin = res.getDimensionPixelSize(
                 R.dimen.keyguard_clock_notifications_margin);
-        mClockYFractionMin = res.getFraction(R.fraction.keyguard_clock_y_fraction_min, 1, 1);
-        mClockYFractionMax = res.getFraction(R.fraction.keyguard_clock_y_fraction_max, 1, 1);
-        mMoreCardNotificationAmount =
-                (float) res.getDimensionPixelSize(R.dimen.notification_shelf_height) /
-                        res.getDimensionPixelSize(R.dimen.notification_min_height);
-        mDensity = res.getDisplayMetrics().density;
+        mContainerPadding = res.getDimensionPixelSize(
+                R.dimen.keyguard_clock_top_margin);
         mBurnInPreventionOffsetX = res.getDimensionPixelSize(
                 R.dimen.burn_in_prevention_offset_x);
         mBurnInPreventionOffsetY = res.getDimensionPixelSize(
                 R.dimen.burn_in_prevention_offset_y);
-        mDozingStackPadding = res.getDimensionPixelSize(R.dimen.dozing_stack_padding);
     }
 
-    public void setup(int maxKeyguardNotifications, int maxPanelHeight, float expandedHeight,
-            int notificationCount, int height, int keyguardStatusHeight, float emptyDragAmount,
-            int clockBottom, float dark) {
-        mMaxKeyguardNotifications = maxKeyguardNotifications;
-        mMaxPanelHeight = maxPanelHeight;
+    public void setup(int minTopMargin, int maxShadeBottom, int notificationStackHeight,
+            float expandedHeight, float maxPanelHeight, int parentHeight, int keyguardStatusHeight,
+            float dark) {
+        mMinTopMargin = minTopMargin;
+        mMaxShadeBottom = maxShadeBottom;
+        mNotificationStackHeight = notificationStackHeight;
         mExpandedHeight = expandedHeight;
-        mNotificationCount = notificationCount;
-        mHeight = height;
+        mMaxPanelHeight = maxPanelHeight;
+        mHeight = parentHeight;
         mKeyguardStatusHeight = keyguardStatusHeight;
-        mEmptyDragAmount = emptyDragAmount;
-        mClockBottom = clockBottom;
         mDarkAmount = dark;
-    }
 
-    public float getMinStackScrollerPadding(int height, int keyguardStatusHeight) {
-        return mClockYFractionMin * height + keyguardStatusHeight / 2
-                + mClockNotificationsMargin;
+        // Where the clock should stop when swiping up.
+        // This should be outside of the display when unlocked or
+        // under then status bar when the bouncer will be shown
+        mClockYTarget = -mKeyguardStatusHeight;
+        // TODO: on bouncer animation follow-up CL
+        // mClockYTarget = mMinTopMargin + mContainerPadding;
     }
 
     public void run(Result result) {
-        int y = getClockY() - mKeyguardStatusHeight / 2;
-        float clockAdjustment = getClockYExpansionAdjustment();
-        float topPaddingAdjMultiplier = getTopPaddingAdjMultiplier();
-        result.stackScrollerPaddingAdjustment = (int) (clockAdjustment*topPaddingAdjMultiplier);
+        final int y = getClockY();
         result.clockY = y;
-        int clockNotificationsPadding = mClockNotificationsMargin
-                + result.stackScrollerPaddingAdjustment;
-        int padding = y + clockNotificationsPadding;
-        result.clockScale = getClockScale(mKeyguardStatusHeight + padding,
-                y, y + mClockNotificationsMargin + mKeyguardStatusHeight);
-        result.clockAlpha = getClockAlpha(result.clockScale);
-
-        result.stackScrollerPadding = mClockBottom + y + mDozingStackPadding;
+        result.clockAlpha = getClockAlpha(y);
+        result.stackScrollerPadding = y + mKeyguardStatusHeight;
         result.clockX = (int) interpolate(0, burnInPreventionOffsetX(), mDarkAmount);
     }
 
-    private float getClockScale(int notificationPadding, int clockY, int startPadding) {
-        float scaleMultiplier = getNotificationAmountT() == 0 ? 6.0f : 5.0f;
-        float scaleEnd = clockY - mKeyguardStatusHeight * scaleMultiplier;
-        float distanceToScaleEnd = notificationPadding - scaleEnd;
-        float progress = distanceToScaleEnd / (startPadding - scaleEnd);
-        progress = Math.max(0.0f, Math.min(progress, 1.0f));
-        progress = mAccelerateInterpolator.getInterpolation(progress);
-        progress *= Math.pow(1 + mEmptyDragAmount / mDensity / 300, 0.3f);
-        return interpolate(progress, 1, mDarkAmount);
+    public float getMinStackScrollerPadding() {
+        return mMinTopMargin + mKeyguardStatusHeight + mClockNotificationsMargin;
     }
 
-    private float getClockYFraction() {
-        float t = getNotificationAmountT();
-        t = Math.min(t, 1.0f);
-        return MathUtils.lerp(mClockYFractionMax, mClockYFractionMin, t);
+    private int getMaxClockY() {
+        return mHeight / 2 - mKeyguardStatusHeight - mClockNotificationsMargin;
+    }
+
+    public int getExpandedClockBottom() {
+        return getExpandedClockPosition() + mKeyguardStatusHeight;
+    }
+
+    /**
+     * Vertically align the clock and the shade in the available space considering only
+     * a percentage of the clock height defined by {@code CLOCK_HEIGHT_WEIGHT}.
+     * @return Clock Y in pixels.
+     */
+    private int getExpandedClockPosition() {
+        final int availableHeight = mMaxShadeBottom - mMinTopMargin;
+        final int containerCenter = mMinTopMargin + availableHeight / 2;
+
+        float y = containerCenter - mKeyguardStatusHeight * CLOCK_HEIGHT_WEIGHT
+                - mClockNotificationsMargin - mNotificationStackHeight / 2;
+        if (y < mMinTopMargin + mContainerPadding) {
+            y = mMinTopMargin + mContainerPadding;
+        }
+
+        // Don't allow the clock base to be under half of the screen
+        final float maxClockY = getMaxClockY();
+        if (y > maxClockY) {
+            y = maxClockY;
+        }
+
+        return (int) y;
     }
 
     private int getClockY() {
         // Dark: Align the bottom edge of the clock at about half of the screen:
-        float clockYDark = (mClockYFractionMax * mHeight +
-                (float) mKeyguardStatusHeight / 2 - mClockBottom)
-                + burnInPreventionOffsetY();
-        float clockYRegular = getClockYFraction() * mHeight;
-        return (int) interpolate(clockYRegular, clockYDark, mDarkAmount);
+        final float clockYDark = getMaxClockY() + burnInPreventionOffsetY();
+        float clockYRegular = getExpandedClockPosition();
+
+        // Move clock up while collapsing the shade
+        final float shadeExpansion = mExpandedHeight / mMaxPanelHeight;
+        final float clockY = MathUtils.lerp(mClockYTarget, clockYRegular, shadeExpansion);
+
+        return (int) MathUtils.lerp(clockY, clockYDark, mDarkAmount);
+    }
+
+    private float getClockAlpha(int y) {
+        float alphaKeyguard = Math.max(0, Math.min(1, (y - mMinTopMargin)
+                / Math.max(1f, getExpandedClockPosition() - mMinTopMargin)));
+        alphaKeyguard = Interpolators.ACCELERATE.getInterpolation(alphaKeyguard);
+        return MathUtils.lerp(alphaKeyguard, 1f, mDarkAmount);
     }
 
     private float burnInPreventionOffsetY() {
@@ -190,63 +234,19 @@
         return interpolate(0, amplitude, interpolationAmount);
     }
 
-    private float getClockYExpansionAdjustment() {
-        float rubberbandFactor = getClockYExpansionRubberbandFactor();
-        float value = (rubberbandFactor * (mMaxPanelHeight - mExpandedHeight));
-        float t = value / mMaxPanelHeight;
-        float slowedDownValue = -sSlowDownInterpolator.getInterpolation(t) * SLOW_DOWN_FACTOR
-                * mMaxPanelHeight;
-        if (mNotificationCount == 0) {
-            return (-2*value + slowedDownValue)/3;
-        } else {
-            return slowedDownValue;
-        }
-    }
-
-    private float getClockYExpansionRubberbandFactor() {
-        float t = getNotificationAmountT();
-        t = Math.min(t, 1.0f);
-        t = (float) Math.pow(t, 0.3f);
-        return (1 - t) * CLOCK_RUBBERBAND_FACTOR_MAX + t * CLOCK_RUBBERBAND_FACTOR_MIN;
-    }
-
-    private float getTopPaddingAdjMultiplier() {
-        float t = getNotificationAmountT();
-        t = Math.min(t, 1.0f);
-        return (1 - t) * CLOCK_ADJ_TOP_PADDING_MULTIPLIER_MIN
-                + t * CLOCK_ADJ_TOP_PADDING_MULTIPLIER_MAX;
-    }
-
-    private float getClockAlpha(float scale) {
-        float fadeEnd = getNotificationAmountT() == 0.0f
-                ? CLOCK_SCALE_FADE_END_NO_NOTIFS
-                : CLOCK_SCALE_FADE_END;
-        float alpha = (scale - fadeEnd)
-                / (CLOCK_SCALE_FADE_START - fadeEnd);
-        return Math.max(0, Math.min(1, alpha));
-    }
-
-    /**
-     * @return a value from 0 to 1 depending on how many notification there are
-     */
-    private float getNotificationAmountT() {
-        return mNotificationCount
-                / (mMaxKeyguardNotifications + mMoreCardNotificationAmount);
-    }
-
     public static class Result {
 
         /**
+         * The x translation of the clock.
+         */
+        public int clockX;
+
+        /**
          * The y translation of the clock.
          */
         public int clockY;
 
         /**
-         * The scale of the Clock
-         */
-        public float clockScale;
-
-        /**
          * The alpha value of the clock.
          */
         public float clockAlpha;
@@ -255,14 +255,5 @@
          * The top padding of the stack scroller, in pixels.
          */
         public int stackScrollerPadding;
-
-        /**
-         * The top padding adjustment of the stack scroller, in pixels. This value is used to adjust
-         * the padding, but not the overall panel size.
-         */
-        public int stackScrollerPaddingAdjustment;
-
-        /** The x translation of the clock. */
-        public int clockX;
     }
 }
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 09acf3e..2375b6a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -87,10 +87,10 @@
         super.onFinishInflate();
         mSystemIconsSuperContainer = findViewById(R.id.system_icons_super_container);
         mSystemIconsContainer = findViewById(R.id.system_icons_container);
-        mMultiUserSwitch = (MultiUserSwitch) findViewById(R.id.multi_user_switch);
-        mMultiUserAvatar = (ImageView) findViewById(R.id.multi_user_avatar);
-        mCarrierLabel = (TextView) findViewById(R.id.keyguard_carrier_text);
-        mBatteryView = (BatteryMeterView) mSystemIconsContainer.findViewById(R.id.battery);
+        mMultiUserSwitch = findViewById(R.id.multi_user_switch);
+        mMultiUserAvatar = findViewById(R.id.multi_user_avatar);
+        mCarrierLabel = findViewById(R.id.keyguard_carrier_text);
+        mBatteryView = mSystemIconsContainer.findViewById(R.id.battery);
 
         loadDimens();
         updateUserSwitcher();
@@ -220,7 +220,7 @@
         Dependency.get(ConfigurationController.class).addCallback(this);
         mIconManager = new TintedIconManager(findViewById(R.id.statusIcons));
         Dependency.get(StatusBarIconController.class).addIconGroup(mIconManager);
-        onOverlayChanged();
+        onThemeChanged();
     }
 
     @Override
@@ -291,12 +291,9 @@
                             .setDuration(300)
                             .setStartDelay(0)
                             .setInterpolator(Interpolators.ALPHA_OUT)
-                            .withEndAction(new Runnable() {
-                                @Override
-                                public void run() {
-                                    mMultiUserSwitch.setAlpha(1f);
-                                    getOverlay().remove(mMultiUserSwitch);
-                                }
+                            .withEndAction(() -> {
+                                mMultiUserSwitch.setAlpha(1f);
+                                getOverlay().remove(mMultiUserSwitch);
                             })
                             .start();
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 79c605e..0ed69e6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -46,6 +46,7 @@
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.Drawable;
 import android.inputmethodservice.InputMethodService;
 import android.os.Binder;
 import android.os.Bundle;
@@ -77,8 +78,8 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.LatencyTracker;
 import com.android.systemui.Dependency;
-import com.android.systemui.OverviewProxyService;
 import com.android.systemui.Interpolators;
+import com.android.systemui.OverviewProxyService;
 import com.android.systemui.R;
 import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.assist.AssistManager;
@@ -111,6 +112,11 @@
     private static final boolean DEBUG = false;
     private static final String EXTRA_DISABLE_STATE = "disabled_state";
 
+    private final static int BUTTON_FADE_IN_OUT_DURATION_MS = 100;
+    private final static int ROTATE_BUTTON_LOOP_DURATION_MS = 2000;
+
+    private static final int NUM_ACCEPTED_ROTATION_SUGGESTIONS_FOR_INTRODUCTION = 3;
+
     /** Allow some time inbetween the long press for back and recents. */
     private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200;
 
@@ -150,9 +156,9 @@
     private RotationLockController mRotationLockController;
     private TaskStackListenerImpl mTaskStackListener;
 
-    private final Runnable mRemoveRotationProposal = () -> safeSetRotationButtonState(false);
-    private Animator mRotateShowAnimator;
+    private final Runnable mRemoveRotationProposal = () -> setRotateSuggestionButtonState(false);
     private Animator mRotateHideAnimator;
+    private ViewRippler mViewRippler = new ViewRippler();
 
     private final OverviewProxyListener mOverviewProxyListener = new OverviewProxyListener() {
         @Override
@@ -164,6 +170,9 @@
         @Override
         public void onRecentsAnimationStarted() {
             mNavigationBarView.setRecentsAnimationStarted(true);
+
+            // Use navbar dragging as a signal to hide the rotate button
+            setRotateSuggestionButtonState(false);
         }
 
         @Override
@@ -364,29 +373,135 @@
         // rotate button if shown.
 
         if (!isValid) {
-            safeSetRotationButtonState(false);
+            setRotateSuggestionButtonState(false);
             return;
         }
 
-        if (rotation == mWindowManager.getDefaultDisplay().getRotation()) {
+        final int winRotation = mWindowManager.getDefaultDisplay().getRotation();
+        if (rotation == winRotation) {
             // Use this as a signal to remove any current suggestions
             getView().getHandler().removeCallbacks(mRemoveRotationProposal);
-            safeSetRotationButtonState(false);
+            setRotateSuggestionButtonState(false);
         } else {
             mLastRotationSuggestion = rotation; // Remember rotation for click
-            safeSetRotationButtonState(true);
+
+            // Update the icon style to change animation parameters
+            if (mNavigationBarView != null) {
+                final boolean rotationCCW = isRotationAnimationCCW(winRotation, rotation);
+                int style;
+                if (winRotation == Surface.ROTATION_0 || winRotation == Surface.ROTATION_180) {
+                    style = rotationCCW ? R.style.RotateButtonCCWStart90 :
+                            R.style.RotateButtonCWStart90;
+                } else { // 90 or 270
+                    style = rotationCCW ? R.style.RotateButtonCCWStart0 :
+                            R.style.RotateButtonCWStart0;
+                }
+                mNavigationBarView.updateRotateSuggestionButtonStyle(style, true);
+            }
+
+            setRotateSuggestionButtonState(true);
             rescheduleRotationTimeout(false);
             mMetricsLogger.visible(MetricsEvent.ROTATION_SUGGESTION_SHOWN);
         }
     }
 
-    private void safeSetRotationButtonState(boolean vis) {
-        if (mNavigationBarView != null) mNavigationBarView.setRotateSuggestionButtonState(vis);
+    private boolean isRotationAnimationCCW(int from, int to) {
+        // All 180deg WM rotation animations are CCW, match that
+        if (from == Surface.ROTATION_0 && to == Surface.ROTATION_90) return false;
+        if (from == Surface.ROTATION_0 && to == Surface.ROTATION_180) return true; //180d so CCW
+        if (from == Surface.ROTATION_0 && to == Surface.ROTATION_270) return true;
+        if (from == Surface.ROTATION_90 && to == Surface.ROTATION_0) return true;
+        if (from == Surface.ROTATION_90 && to == Surface.ROTATION_180) return false;
+        if (from == Surface.ROTATION_90 && to == Surface.ROTATION_270) return true; //180d so CCW
+        if (from == Surface.ROTATION_180 && to == Surface.ROTATION_0) return true; //180d so CCW
+        if (from == Surface.ROTATION_180 && to == Surface.ROTATION_90) return true;
+        if (from == Surface.ROTATION_180 && to == Surface.ROTATION_270) return false;
+        if (from == Surface.ROTATION_270 && to == Surface.ROTATION_0) return false;
+        if (from == Surface.ROTATION_270 && to == Surface.ROTATION_90) return true; //180d so CCW
+        if (from == Surface.ROTATION_270 && to == Surface.ROTATION_180) return true;
+        return false; // Default
     }
 
-    private void safeSetRotationButtonState(boolean vis, boolean force) {
-        if (mNavigationBarView != null) {
-            mNavigationBarView.setRotateSuggestionButtonState(vis, force);
+    public void setRotateSuggestionButtonState(final boolean visible) {
+        setRotateSuggestionButtonState(visible, false);
+    }
+
+    public void setRotateSuggestionButtonState(final boolean visible, final boolean force) {
+        if (mNavigationBarView == null) return;
+
+        // At any point the the button can become invisible because an a11y service became active.
+        // Similarly, a call to make the button visible may be rejected because an a11y service is
+        // active. Must account for this.
+
+        ButtonDispatcher rotBtn = mNavigationBarView.getRotateSuggestionButton();
+        final boolean currentlyVisible = mNavigationBarView.isRotateButtonVisible();
+
+        // Rerun a show animation to indicate change but don't rerun a hide animation
+        if (!visible && !currentlyVisible) return;
+
+        View view = rotBtn.getCurrentView();
+        if (view == null) return;
+
+        KeyButtonDrawable kbd = rotBtn.getImageDrawable();
+        if (kbd == null) return;
+
+        // The KBD and AVD is recreated every new valid suggestion because of style changes.
+        AnimatedVectorDrawable animIcon = null;
+        if (kbd.getDrawable(0) instanceof AnimatedVectorDrawable) {
+            animIcon = (AnimatedVectorDrawable) kbd.getDrawable(0);
+        }
+
+        if (visible) { // Appear and change (cannot force)
+            // Stop and clear any currently running hide animations
+            if (mRotateHideAnimator != null && mRotateHideAnimator.isRunning()) {
+                mRotateHideAnimator.cancel();
+            }
+            mRotateHideAnimator = null;
+
+            // Reset the alpha if any has changed due to hide animation
+            view.setAlpha(1f);
+
+            // Run the rotate icon's animation if it has one
+            if (animIcon != null) {
+                animIcon.reset();
+                animIcon.start();
+            }
+
+            if (!isRotateSuggestionIntroduced()) mViewRippler.start(view);
+
+            // Set visibility, may fail if a11y service is active.
+            // If invisible, call will stop animation.
+            mNavigationBarView.setRotateButtonVisibility(true);
+
+        } else { // Hide
+
+            mViewRippler.stop(); // Prevent any pending ripples, force hide or not
+
+            if (force) {
+                // If a hide animator is running stop it and make invisible
+                if (mRotateHideAnimator != null && mRotateHideAnimator.isRunning()) {
+                    mRotateHideAnimator.pause();
+                }
+                mNavigationBarView.setRotateButtonVisibility(false);
+                return;
+            }
+
+            // Don't start any new hide animations if one is running
+            if (mRotateHideAnimator != null && mRotateHideAnimator.isRunning()) return;
+
+            ObjectAnimator fadeOut = ObjectAnimator.ofFloat(view, "alpha",
+                    0f);
+            fadeOut.setDuration(BUTTON_FADE_IN_OUT_DURATION_MS);
+            fadeOut.setInterpolator(Interpolators.LINEAR);
+            fadeOut.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    mNavigationBarView.setRotateButtonVisibility(false);
+                }
+            });
+
+            mRotateHideAnimator = fadeOut;
+            fadeOut.start();
         }
     }
 
@@ -394,13 +509,9 @@
         // May be called due to a new rotation proposal or a change in hover state
         if (reasonHover) {
             // Don't reschedule if a hide animator is running
-            if (mRotateHideAnimator != null && mRotateHideAnimator.isRunning()) {
-                return;
-            }
+            if (mRotateHideAnimator != null && mRotateHideAnimator.isRunning()) return;
             // Don't reschedule if not visible
-            if (mNavigationBarView.getRotateSuggestionButton().getVisibility() != View.VISIBLE) {
-                return;
-            }
+            if (!mNavigationBarView.isRotateButtonVisible()) return;
         }
 
         Handler h = getView().getHandler();
@@ -415,6 +526,25 @@
         return 6000;
     }
 
+    private boolean isRotateSuggestionIntroduced() {
+        ContentResolver cr = getContext().getContentResolver();
+        return Settings.Secure.getInt(cr, Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED, 0)
+                >= NUM_ACCEPTED_ROTATION_SUGGESTIONS_FOR_INTRODUCTION;
+    }
+
+    private void incrementNumAcceptedRotationSuggestionsIfNeeded() {
+        // Get the number of accepted suggestions
+        ContentResolver cr = getContext().getContentResolver();
+        final int numSuggestions = Settings.Secure.getInt(cr,
+                Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED, 0);
+
+        // Increment the number of accepted suggestions only if it would change intro mode
+        if (numSuggestions < NUM_ACCEPTED_ROTATION_SUGGESTIONS_FOR_INTRODUCTION) {
+            Settings.Secure.putInt(cr, Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED,
+                    numSuggestions + 1);
+        }
+    }
+
     // Injected from StatusBar at creation.
     public void setCurrentSysuiVisibility(int systemUiVisibility) {
         mSystemUiVisibility = systemUiVisibility;
@@ -480,8 +610,7 @@
 
     private boolean shouldDisableNavbarGestures() {
         return !mStatusBar.isDeviceProvisioned()
-                || (mDisabledFlags1 & StatusBarManager.DISABLE_SEARCH) != 0
-                || mNavigationBarView.getRecentsButton().getVisibility() != View.VISIBLE;
+                || (mDisabledFlags1 & StatusBarManager.DISABLE_SEARCH) != 0;
     }
 
     private void repositionNavigationBar() {
@@ -500,13 +629,10 @@
 
         // Change the cancel pin gesture to home and back if recents button is invisible
         boolean recentsVisible = mNavigationBarView.isRecentsButtonVisible();
-        ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
         ButtonDispatcher backButton = mNavigationBarView.getBackButton();
         if (recentsVisible) {
-            homeButton.setOnLongClickListener(this::onHomeLongClick);
             backButton.setOnLongClickListener(this::onLongPressBackRecents);
         } else {
-            homeButton.setOnLongClickListener(this::onLongPressBackHome);
             backButton.setOnLongClickListener(this::onLongPressBackHome);
         }
     }
@@ -529,6 +655,7 @@
 
         ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
         homeButton.setOnTouchListener(this::onHomeTouch);
+        homeButton.setOnLongClickListener(this::onHomeLongClick);
 
         ButtonDispatcher accessibilityButton = mNavigationBarView.getAccessibilityButton();
         accessibilityButton.setOnClickListener(this::onAccessibilityClick);
@@ -581,6 +708,10 @@
 
     @VisibleForTesting
     boolean onHomeLongClick(View v) {
+        if (!mNavigationBarView.isRecentsButtonVisible()
+                && ActivityManagerWrapper.getInstance().isScreenPinningActive()) {
+            return onLongPressBackHome(v);
+        }
         if (shouldDisableNavbarGestures()) {
             return false;
         }
@@ -757,6 +888,7 @@
 
     private void onRotateSuggestionClick(View v) {
         mMetricsLogger.action(MetricsEvent.ACTION_ROTATION_SUGGESTION_ACCEPTED);
+        incrementNumAcceptedRotationSuggestionsIfNeeded();
         mRotationLockController.setRotationLockedAtAngle(true, mLastRotationSuggestion);
     }
 
@@ -827,7 +959,7 @@
                     if (shouldOverrideUserLockPrefs(rotation)) {
                         mRotationLockController.setRotationLockedAtAngle(true, rotation);
                     }
-                    safeSetRotationButtonState(false, true);
+                    setRotateSuggestionButtonState(false, true);
                 }
 
                 if (mNavigationBarView != null
@@ -863,25 +995,57 @@
 
         @Override
         public void onTaskStackChanged() {
-            safeSetRotationButtonState(false);
+            setRotateSuggestionButtonState(false);
         }
 
         @Override
         public void onTaskRemoved(int taskId) {
-            safeSetRotationButtonState(false);
+            setRotateSuggestionButtonState(false);
         }
 
         @Override
         public void onTaskMovedToFront(int taskId) {
-            safeSetRotationButtonState(false);
+            setRotateSuggestionButtonState(false);
         }
 
         @Override
         public void onActivityRequestedOrientationChanged(int taskId, int requestedOrientation) {
-            safeSetRotationButtonState(false);
+            // Only hide the icon if the top task changes its requestedOrientation
+            // Launcher can alter its requestedOrientation while it's not on top, don't hide on this
+            final boolean top = ActivityManagerWrapper.getInstance().getRunningTask().id == taskId;
+            if (top) setRotateSuggestionButtonState(false);
         }
     }
 
+    private class ViewRippler {
+        private static final int RIPPLE_OFFSET_MS = 50;
+        private static final int RIPPLE_INTERVAL_MS = 2000;
+        private View mRoot;
+
+        public void start(View root) {
+            stop(); // Stop any pending ripple animations
+
+            mRoot = root;
+
+            // Schedule pending ripples, offset the 1st to avoid problems with visibility change
+            mRoot.postOnAnimationDelayed(mRipple, RIPPLE_OFFSET_MS);
+            mRoot.postOnAnimationDelayed(mRipple, RIPPLE_INTERVAL_MS);
+            mRoot.postOnAnimationDelayed(mRipple, 2*RIPPLE_INTERVAL_MS);
+        }
+
+        public void stop() {
+            if (mRoot != null) mRoot.removeCallbacks(mRipple);
+        }
+
+        private final Runnable mRipple = new Runnable() {
+            @Override
+            public void run() { // Cause the ripple to fire via false presses
+                mRoot.setPressed(true);
+                mRoot.setPressed(false);
+            }
+        };
+    }
+
     public static View create(Context context, FragmentListener listener) {
         WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
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 57d78dd..a4daed9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
@@ -43,6 +43,7 @@
 import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper;
 import com.android.systemui.shared.recents.IOverviewProxy;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.tuner.TunerService;
 
@@ -149,7 +150,8 @@
     }
 
     public boolean onInterceptTouchEvent(MotionEvent event) {
-        if (mNavigationBarView.inScreenPinning()) {
+        if (ActivityManagerWrapper.getInstance().isScreenPinningActive()
+                || mStatusBar.isKeyguardShowing()) {
             return false;
         }
 
@@ -182,7 +184,8 @@
     }
 
     public boolean onTouchEvent(MotionEvent event) {
-        if (mNavigationBarView.inScreenPinning()) {
+        if (ActivityManagerWrapper.getInstance().isScreenPinningActive()
+                || mStatusBar.isKeyguardShowing()) {
             return false;
         }
 
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 285980b..74fbed1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -21,15 +21,13 @@
 import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_HOME;
 import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
 import android.animation.LayoutTransition;
 import android.animation.LayoutTransition.TransitionListener;
 import android.animation.ObjectAnimator;
 import android.animation.TimeInterpolator;
 import android.animation.ValueAnimator;
 import android.annotation.DrawableRes;
-import android.app.ActivityManager;
+import android.annotation.StyleRes;
 import android.app.StatusBarManager;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -37,9 +35,9 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.os.Message;
-import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.support.annotation.ColorInt;
 import android.util.AttributeSet;
@@ -58,7 +56,6 @@
 import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
 import com.android.systemui.DockedStackExistsListener;
-import com.android.systemui.Interpolators;
 import com.android.systemui.OverviewProxyService;
 import com.android.systemui.R;
 import com.android.systemui.RecentsComponent;
@@ -87,8 +84,6 @@
     final static boolean DEBUG = false;
     final static String TAG = "StatusBar/NavBarView";
 
-    final static int BUTTON_FADE_IN_OUT_DURATION_MS = 100;
-
     // slippery nav bar when everything is disabled, e.g. during setup
     final static boolean SLIPPERY_WHEN_DISABLED = true;
 
@@ -152,7 +147,7 @@
     private RecentsOnboarding mRecentsOnboarding;
     private NotificationPanelView mPanelView;
 
-    private Animator mRotateHideAnimator;
+    private int mRotateBtnStyle = R.style.RotateButtonCCWStart90;
 
     private class NavTransitionListener implements TransitionListener {
         private boolean mBackTransitioning;
@@ -379,15 +374,20 @@
         return getRecentsButton().getVisibility() == View.VISIBLE;
     }
 
+    public boolean isOverviewEnabled() {
+        return (mDisabledFlags & View.STATUS_BAR_DISABLE_RECENT) == 0;
+    }
+
     public boolean isQuickStepSwipeUpEnabled() {
         return mOverviewProxyService.getProxy() != null
+                && isOverviewEnabled()
                 && ((mOverviewProxyService.getInteractionFlags()
                         & FLAG_DISABLE_SWIPE_UP) == 0);
     }
 
     public boolean isQuickScrubEnabled() {
         return SystemProperties.getBoolean("persist.quickstep.scrub.enabled", true)
-                && mOverviewProxyService.getProxy() != null && !isRecentsButtonVisible()
+                && mOverviewProxyService.getProxy() != null && isOverviewEnabled()
                 && ((mOverviewProxyService.getInteractionFlags()
                         & FLAG_DISABLE_QUICK_SCRUB) == 0);
     }
@@ -429,10 +429,7 @@
             mImeIcon = getDrawable(darkContext, lightContext,
                     R.drawable.ic_ime_switcher_default, R.drawable.ic_ime_switcher_default);
 
-            int lightColor = Utils.getColorAttr(lightContext, R.attr.singleToneColor);
-            int darkColor = Utils.getColorAttr(darkContext, R.attr.singleToneColor);
-            mRotateSuggestionIcon = getDrawable(ctx, R.drawable.ic_sysbar_rotate_button,
-                    lightColor, darkColor);
+            updateRotateSuggestionButtonStyle(mRotateBtnStyle, false);
 
             if (ALTERNATE_CAR_MODE_UI) {
                 updateCarModeIcons(ctx);
@@ -578,8 +575,7 @@
         boolean disableHome = ((disabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0);
 
         // Always disable recents when alternate car mode UI is active.
-        boolean disableRecent = mUseCarModeUi
-                || ((disabledFlags & View.STATUS_BAR_DISABLE_RECENT) != 0);
+        boolean disableRecent = mUseCarModeUi || !isOverviewEnabled();
 
         boolean disableBack = ((disabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0)
                 && ((mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) == 0);
@@ -587,17 +583,18 @@
         // When screen pinning, don't hide back and home when connected service or back and
         // recents buttons when disconnected from launcher service in screen pinning mode,
         // as they are used for exiting.
+        final boolean pinningActive = ActivityManagerWrapper.getInstance().isScreenPinningActive();
         if (mOverviewProxyService.getProxy() != null) {
             // Use interaction flags to show/hide navigation buttons but will be shown if required
             // to exit screen pinning.
             final int flags = mOverviewProxyService.getInteractionFlags();
             disableRecent |= (flags & FLAG_SHOW_OVERVIEW_BUTTON) == 0;
-            if (inScreenPinning()) {
+            if (pinningActive) {
                 disableBack = disableHome = false;
             } else {
                 disableBack |= (flags & FLAG_HIDE_BACK_BUTTON) != 0;
             }
-        } else if (inScreenPinning()) {
+        } else if (pinningActive) {
             disableBack = disableRecent = false;
         }
 
@@ -617,7 +614,7 @@
     }
 
     public boolean inScreenPinning() {
-        return ActivityManagerWrapper.getInstance().isLockToAppActive();
+        return ActivityManagerWrapper.getInstance().isScreenPinningActive();
     }
 
     public void setLayoutTransitionsEnabled(boolean enabled) {
@@ -726,93 +723,61 @@
             // Accessibility button overrides Menu, IME switcher and rotate buttons.
             setMenuVisibility(false, true);
             getImeSwitchButton().setVisibility(View.INVISIBLE);
-            setRotateSuggestionButtonState(false, true);
+            setRotateButtonVisibility(false);
         }
 
         getAccessibilityButton().setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
         getAccessibilityButton().setLongClickable(longClickable);
     }
 
-    public void setRotateSuggestionButtonState(final boolean visible) {
-        setRotateSuggestionButtonState(visible, false);
+    public void updateRotateSuggestionButtonStyle(@StyleRes int style, boolean setIcon) {
+        mRotateBtnStyle = style;
+        final Context ctx = getContext();
+
+        // Extract the dark and light tints
+        final int dualToneDarkTheme = Utils.getThemeAttr(ctx, R.attr.darkIconTheme);
+        final int dualToneLightTheme = Utils.getThemeAttr(ctx, R.attr.lightIconTheme);
+        Context darkContext = new ContextThemeWrapper(ctx, dualToneDarkTheme);
+        Context lightContext = new ContextThemeWrapper(ctx, dualToneLightTheme);
+        final int lightColor = Utils.getColorAttr(lightContext, R.attr.singleToneColor);
+        final int darkColor = Utils.getColorAttr(darkContext, R.attr.singleToneColor);
+
+        // Use the supplied style to set the icon's rotation parameters
+        Context rotateContext = new ContextThemeWrapper(ctx, style);
+
+        // Recreate the icon and set it if needed
+        mRotateSuggestionIcon = getDrawable(rotateContext, R.drawable.ic_sysbar_rotate_button,
+                lightColor, darkColor);
+        if (setIcon) getRotateSuggestionButton().setImageDrawable(mRotateSuggestionIcon);
     }
 
-    public void setRotateSuggestionButtonState(final boolean visible, final boolean force) {
-        ButtonDispatcher rotBtn = getRotateSuggestionButton();
-        final boolean currentlyVisible = mShowRotateButton;
-
-        // Rerun a show animation to indicate change but don't rerun a hide animation
-        if (!visible && !currentlyVisible) return;
-
-        View currentView = rotBtn.getCurrentView();
-        if (currentView == null) return;
-
-        KeyButtonDrawable kbd = rotBtn.getImageDrawable();
-        if (kbd == null) return;
-
-        AnimatedVectorDrawable animIcon = null;
-        if (kbd.getDrawable(0) instanceof AnimatedVectorDrawable) {
-            animIcon = (AnimatedVectorDrawable) kbd.getDrawable(0);
-        }
-
-        if (visible) { // Appear and change, cannot force
-            setRotateButtonVisibility(true);
-
-            // Stop any currently running hide animations
-            if (mRotateHideAnimator != null && mRotateHideAnimator.isRunning()) {
-                mRotateHideAnimator.pause();
-            }
-
-            // Reset the alpha if any has changed due to hide animation
-            currentView.setAlpha(1f);
-
-            // Run the rotate icon's animation if it has one
-            if (animIcon != null) {
-                animIcon.reset();
-                animIcon.start();
-            }
-
-        } else { // Hide
-            if (force) {
-                // If a hide animator is running stop it and instantly make invisible
-                if (mRotateHideAnimator != null && mRotateHideAnimator.isRunning()) {
-                    mRotateHideAnimator.pause();
-                }
-                setRotateButtonVisibility(false);
-                return;
-            }
-
-            // Don't start any new hide animations if one is running
-            if (mRotateHideAnimator != null && mRotateHideAnimator.isRunning()) return;
-
-            ObjectAnimator fadeOut = ObjectAnimator.ofFloat(currentView, "alpha",
-                    0f);
-            fadeOut.setDuration(BUTTON_FADE_IN_OUT_DURATION_MS);
-            fadeOut.setInterpolator(Interpolators.LINEAR);
-            fadeOut.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    setRotateButtonVisibility(false);
-                }
-            });
-
-            mRotateHideAnimator = fadeOut;
-            fadeOut.start();
-        }
-    }
-
-    private void setRotateButtonVisibility(final boolean visible) {
+    public void setRotateButtonVisibility(final boolean visible) {
         // Never show if a11y is visible
         final boolean adjVisible = visible && !mShowAccessibilityButton;
         final int vis = adjVisible ? View.VISIBLE : View.INVISIBLE;
 
+        // No need to do anything if the request matches the current state
+        if (vis == getRotateSuggestionButton().getVisibility()) return;
+
         getRotateSuggestionButton().setVisibility(vis);
         mShowRotateButton = visible;
 
+        // Stop any active animations if hidden
+        if (!visible) {
+            Drawable d = mRotateSuggestionIcon.getDrawable(0);
+            if (d instanceof AnimatedVectorDrawable) {
+                AnimatedVectorDrawable avd = (AnimatedVectorDrawable) d;
+                avd.clearAnimationCallbacks();
+                avd.reset();
+            }
+        }
+
         // Hide/restore other button visibility, if necessary
         setNavigationIconHints(mNavigationIconHints, true);
     }
 
+    public boolean isRotateButtonVisible() { return mShowRotateButton; }
+
     @Override
     public void onFinishInflate() {
         mNavigationInflaterView = (NavigationBarInflaterView) findViewById(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index 40fe50f..e77b135 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -140,6 +140,11 @@
             return false;
         }
 
+        // showAmbient == show in shade but not shelf
+        if (!showAmbient && notificationData.shouldSuppressScreenOn(entry.key)) {
+            return false;
+        }
+
         return true;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index 5cf4c4c..5479dd8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -56,6 +56,7 @@
     private static final int NO_VALUE = Integer.MIN_VALUE;
     private static final String TAG = "NotificationIconContainer";
     private static final boolean DEBUG = false;
+    private static final boolean DEBUG_OVERFLOW = false;
     private static final int CANNED_ANIMATION_DURATION = 100;
     private static final AnimationProperties DOT_ANIMATION_PROPERTIES = new AnimationProperties() {
         private AnimationFilter mAnimationFilter = new AnimationFilter().animateX();
@@ -107,6 +108,7 @@
     private final HashMap<View, IconState> mIconStates = new HashMap<>();
     private int mDotPadding;
     private int mStaticDotRadius;
+    private int mStaticDotDiameter;
     private int mActualLayoutWidth = NO_VALUE;
     private float mActualPaddingEnd = NO_VALUE;
     private float mActualPaddingStart = NO_VALUE;
@@ -122,17 +124,21 @@
     private ArrayMap<String, ArrayList<StatusBarIcon>> mReplacingIcons;
     // Keep track of the last visible icon so collapsed container can report on its location
     private IconState mLastVisibleIconState;
+    private float mVisualOverflowStart;
+    // Keep track of overflow in range [0, 3]
+    private int mNumDots;
 
 
     public NotificationIconContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
         initDimens();
-        setWillNotDraw(!DEBUG);
+        setWillNotDraw(!(DEBUG || DEBUG_OVERFLOW));
     }
 
     private void initDimens() {
         mDotPadding = getResources().getDimensionPixelSize(R.dimen.overflow_icon_dot_padding);
         mStaticDotRadius = getResources().getDimensionPixelSize(R.dimen.overflow_dot_radius);
+        mStaticDotDiameter = 2 * mStaticDotRadius;
     }
 
     @Override
@@ -142,6 +148,30 @@
         paint.setColor(Color.RED);
         paint.setStyle(Paint.Style.STROKE);
         canvas.drawRect(getActualPaddingStart(), 0, getLayoutEnd(), getHeight(), paint);
+
+        if (DEBUG_OVERFLOW) {
+            if (mLastVisibleIconState == null) {
+                return;
+            }
+
+            int height = getHeight();
+            int end = getFinalTranslationX();
+
+            // Visualize the "end" of the layout
+            paint.setColor(Color.BLUE);
+            canvas.drawLine(end, 0, end, height, paint);
+
+            paint.setColor(Color.BLACK);
+            int lastIcon = (int) mLastVisibleIconState.xTranslation;
+            canvas.drawLine(lastIcon, 0, lastIcon, height, paint);
+
+            paint.setColor(Color.RED);
+            canvas.drawLine(mVisualOverflowStart, 0, mVisualOverflowStart, height, paint);
+
+            paint.setColor(Color.YELLOW);
+            float overflow = getMaxOverflowStart();
+            canvas.drawLine(overflow, 0, overflow, height, paint);
+        }
     }
 
     @Override
@@ -282,7 +312,7 @@
     }
 
     /**
-     * Calulate the horizontal translations for each notification based on how much the icons
+     * Calculate the horizontal translations for each notification based on how much the icons
      * are inserted into the notification container.
      * If this is not a whole number, the fraction means by how much the icon is appearing.
      */
@@ -293,9 +323,9 @@
         int maxVisibleIcons = mDark ? MAX_VISIBLE_ICONS_WHEN_DARK :
                     mIsStaticLayout ? MAX_STATIC_ICONS : childCount;
         float layoutEnd = getLayoutEnd();
-        float overflowStart = layoutEnd - mIconSize * (2 + OVERFLOW_EARLY_AMOUNT);
+        float overflowStart = getMaxOverflowStart();
+        mVisualOverflowStart = 0;
         boolean hasAmbient = mSpeedBumpIndex != -1 && mSpeedBumpIndex < getChildCount();
-        float visualOverflowStart = 0;
         for (int i = 0; i < childCount; i++) {
             View view = getChildAt(i);
             IconState iconState = mIconStates.get(view);
@@ -310,45 +340,40 @@
                 noOverflowAfter = noOverflowAfter && !hasAmbient && !forceOverflow;
             }
             iconState.visibleState = StatusBarIconView.STATE_ICON;
-            if (firstOverflowIndex == -1 && (forceOverflow
-                    || (translationX >= (noOverflowAfter ? layoutEnd - mIconSize : overflowStart)))) {
+
+            boolean isOverflowing =
+                    (translationX >= (noOverflowAfter ? layoutEnd - mIconSize : overflowStart));
+            if (firstOverflowIndex == -1 && (forceOverflow || isOverflowing)) {
                 firstOverflowIndex = noOverflowAfter && !forceOverflow ? i - 1 : i;
-                int totalDotLength = mStaticDotRadius * 6 + 2 * mDotPadding;
-                visualOverflowStart = overflowStart + mIconSize * (1 + OVERFLOW_EARLY_AMOUNT)
-                        - totalDotLength / 2
-                        - mIconSize * 0.5f + mStaticDotRadius;
+                mVisualOverflowStart = layoutEnd - mIconSize
+                        - 2 * (mStaticDotDiameter + mDotPadding);
                 if (forceOverflow) {
-                    visualOverflowStart = Math.min(translationX, visualOverflowStart
-                            + mStaticDotRadius * 2 + mDotPadding);
-                } else {
-                    visualOverflowStart += (translationX - overflowStart) / mIconSize
-                            * (mStaticDotRadius * 2 + mDotPadding);
+                    mVisualOverflowStart = Math.min(translationX, mVisualOverflowStart);
                 }
             }
             translationX += iconState.iconAppearAmount * view.getWidth() * drawingScale;
         }
+        mNumDots = 0;
         if (firstOverflowIndex != -1) {
-            int numDots = 1;
-            translationX = visualOverflowStart;
+            translationX = mVisualOverflowStart;
             for (int i = firstOverflowIndex; i < childCount; i++) {
                 View view = getChildAt(i);
                 IconState iconState = mIconStates.get(view);
                 int dotWidth = mStaticDotRadius * 2 + mDotPadding;
                 iconState.xTranslation = translationX;
-                if (numDots <= MAX_DOTS) {
-                    if (numDots == 1 && iconState.iconAppearAmount < 0.8f) {
+                if (mNumDots < MAX_DOTS) {
+                    if (mNumDots == 0 && iconState.iconAppearAmount < 0.8f) {
                         iconState.visibleState = StatusBarIconView.STATE_ICON;
-                        numDots--;
                     } else {
                         iconState.visibleState = StatusBarIconView.STATE_DOT;
+                        mNumDots++;
                     }
-                    translationX += (numDots == MAX_DOTS ? MAX_DOTS * dotWidth : dotWidth)
+                    translationX += (mNumDots == MAX_DOTS ? MAX_DOTS * dotWidth : dotWidth)
                             * iconState.iconAppearAmount;
                     mLastVisibleIconState = iconState;
                 } else {
                     iconState.visibleState = StatusBarIconView.STATE_HIDDEN;
                 }
-                numDots++;
             }
         } else if (childCount > 0) {
             View lastChild = getChildAt(childCount - 1);
@@ -360,7 +385,7 @@
             if (firstOverflowIndex != -1) {
                 // If we have an overflow, only count those half for centering because the dots
                 // don't have a lot of visual weight.
-                float deltaIgnoringOverflow = (getLayoutEnd() - visualOverflowStart) / 2;
+                float deltaIgnoringOverflow = (getLayoutEnd() - mVisualOverflowStart) / 2;
                 delta = (deltaIgnoringOverflow + delta) / 2;
             }
             for (int i = 0; i < childCount; i++) {
@@ -440,7 +465,13 @@
             return 0;
         }
 
-        return (int) (mLastVisibleIconState.xTranslation + mIconSize * (1 + OVERFLOW_EARLY_AMOUNT));
+        int translation = (int) (mLastVisibleIconState.xTranslation + mIconSize);
+        // There's a chance that last translation goes beyond the edge maybe
+        return Math.min(getWidth(), translation);
+    }
+
+    private float getMaxOverflowStart() {
+        return getLayoutEnd() - mIconSize * (2 + OVERFLOW_EARLY_AMOUNT);
     }
 
     public void setChangingViewPositions(boolean changingViewPositions) {
@@ -471,12 +502,7 @@
     }
 
     public boolean hasOverflow() {
-        if (mIsStaticLayout) {
-            return getChildCount() > MAX_STATIC_ICONS;
-        }
-
-        float width = (getChildCount() + OVERFLOW_EARLY_AMOUNT) * mIconSize;
-        return width - (getWidth() - getActualPaddingStart() - getActualPaddingEnd()) > 0;
+        return mNumDots > 0;
     }
 
     /**
@@ -486,12 +512,7 @@
      * This method has no meaning for non-static containers
      */
     public boolean hasPartialOverflow() {
-        if (mIsStaticLayout) {
-            int count = getChildCount();
-            return count > MAX_STATIC_ICONS && count <= MAX_STATIC_ICONS + MAX_DOTS;
-        }
-
-        return false;
+        return mNumDots > 0 && mNumDots < MAX_DOTS;
     }
 
     /**
@@ -504,7 +525,30 @@
             return 0;
         }
 
-        return (MAX_STATIC_ICONS + MAX_DOTS - getChildCount()) * (mStaticDotRadius + mDotPadding);
+        int partialOverflowAmount = (MAX_DOTS - mNumDots) * (mStaticDotRadius * 2 + mDotPadding);
+
+        int adjustedWidth = getFinalTranslationX() + partialOverflowAmount;
+        // In case we actually give too much padding...
+        if (adjustedWidth > getWidth()) {
+            partialOverflowAmount = getWidth() - getFinalTranslationX();
+        }
+
+        return partialOverflowAmount;
+    }
+
+    // Give some extra room for btw notifications if we can
+    public int getNoOverflowExtraPadding() {
+        if (mNumDots != 0) {
+            return 0;
+        }
+
+        int collapsedPadding = (int) ((1.0f + OVERFLOW_EARLY_AMOUNT) * getIconSize());
+
+        if (collapsedPadding + getFinalTranslationX() > getWidth()) {
+            collapsedPadding = getWidth() - getFinalTranslationX();
+        }
+
+        return collapsedPadding;
     }
 
     public int getIconSize() {
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 3b129fc..9d2480b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -37,6 +37,7 @@
 import android.os.PowerManager;
 import android.util.AttributeSet;
 import android.util.FloatProperty;
+import android.util.Log;
 import android.util.MathUtils;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -172,7 +173,6 @@
     private Animator mClockAnimator;
     private int mClockAnimationTargetX = Integer.MIN_VALUE;
     private int mClockAnimationTargetY = Integer.MIN_VALUE;
-    private int mTopPaddingAdjustment;
     private KeyguardClockPositionAlgorithm mClockPositionAlgorithm =
             new KeyguardClockPositionAlgorithm();
     private KeyguardClockPositionAlgorithm.Result mClockPositionResult =
@@ -205,7 +205,6 @@
     private int mQsFalsingThreshold;
 
     private float mKeyguardStatusBarAnimateAlpha = 1f;
-    private float mQsClockAlphaOverride = 1f;
     private int mOldLayoutDirection;
     private HeadsUpTouchHelper mHeadsUpTouchHelper;
     private boolean mIsExpansionFromHeadsUp;
@@ -244,6 +243,7 @@
     private int mQsNotificationTopPadding;
     private float mExpandOffset;
     private boolean mHideIconsDuringNotificationLaunch = true;
+    private int mStackScrollerMeasuringPass;
 
     public NotificationPanelView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -459,17 +459,17 @@
         if (mStatusBarState != StatusBarState.KEYGUARD) {
             stackScrollerPadding = (mQs != null ? mQs.getHeader().getHeight() : 0) + mQsPeekHeight
             +  mQsNotificationTopPadding;
-            mTopPaddingAdjustment = 0;
         } else {
+            final int totalHeight = getHeight();
+            final int bottomPadding = Math.max(mIndicationBottomPadding, mAmbientIndicationBottomPadding);
             mClockPositionAlgorithm.setup(
-                    mStatusBar.getMaxNotificationsWhileLocked(),
-                    getMaxPanelHeight(),
+                    mStatusBarMinHeight,
+                    totalHeight - bottomPadding,
+                    calculatePanelHeightShade() - mNotificationStackScroller.getTopPadding(),
                     getExpandedHeight(),
-                    mNotificationStackScroller.getNotGoneChildCount(),
-                    getHeight(),
+                    getMaxPanelHeight(),
+                    totalHeight,
                     mKeyguardStatusView.getHeight(),
-                    mEmptyDragAmount,
-                    mKeyguardStatusView.getClockBottom(),
                     mDarkAmount);
             mClockPositionAlgorithm.run(mClockPositionResult);
             if (animate || mClockAnimator != null) {
@@ -478,14 +478,16 @@
                 mKeyguardStatusView.setX(mClockPositionResult.clockX);
                 mKeyguardStatusView.setY(mClockPositionResult.clockY);
             }
-            updateClock(mClockPositionResult.clockAlpha, mClockPositionResult.clockScale);
+            updateClock();
             stackScrollerPadding = mClockPositionResult.stackScrollerPadding;
-            mTopPaddingAdjustment = mClockPositionResult.stackScrollerPaddingAdjustment;
         }
         mNotificationStackScroller.setIntrinsicPadding(stackScrollerPadding);
         mNotificationStackScroller.setAntiBurnInOffsetX(mClockPositionResult.clockX);
         mKeyguardBottomArea.setBurnInXOffset(mClockPositionResult.clockX);
+
+        mStackScrollerMeasuringPass++;
         requestScrollerTopPaddingUpdate(animate);
+        mStackScrollerMeasuringPass = 0;
     }
 
     /**
@@ -493,8 +495,7 @@
      * @return the maximum keyguard notifications that can fit on the screen
      */
     public int computeMaxKeyguardNotifications(int maximum) {
-        float minPadding = mClockPositionAlgorithm.getMinStackScrollerPadding(getHeight(),
-                mKeyguardStatusView.getHeight());
+        float minPadding = mClockPositionAlgorithm.getMinStackScrollerPadding();
         int notificationPadding = Math.max(1, getResources().getDimensionPixelSize(
                 R.dimen.notification_divider_height));
         NotificationShelf shelf = mNotificationStackScroller.getNotificationShelf();
@@ -579,12 +580,10 @@
         });
     }
 
-    private void updateClock(float alpha, float scale) {
+    private void updateClock() {
         if (!mKeyguardStatusViewAnimating) {
-            mKeyguardStatusView.setAlpha(alpha * mQsClockAlphaOverride);
+            mKeyguardStatusView.setAlpha(mClockPositionResult.clockAlpha);
         }
-        mKeyguardStatusView.setScaleX(scale);
-        mKeyguardStatusView.setScaleY(scale);
     }
 
     public void animateToFullShade(long delay) {
@@ -1310,15 +1309,6 @@
             mQsNavbarScrim.setAlpha(getQsExpansionFraction());
         }
 
-        // Fade clock when QS is on top of it
-        float newClockAlpha = (height - mKeyguardStatusView.getY()) /
-                mKeyguardStatusView.getHeight();
-        newClockAlpha = 1 - MathUtils.constrain(newClockAlpha, 0, 1);
-        if (newClockAlpha != mQsClockAlphaOverride) {
-            mQsClockAlphaOverride = Interpolators.ALPHA_OUT.getInterpolation(newClockAlpha);
-            updateClock(mClockPositionResult.clockAlpha, mClockPositionResult.clockScale);
-        }
-
         if (mAccessibilityManager.isEnabled()) {
             setAccessibilityPaneTitle(determineAccessibilityPaneTitle());
         }
@@ -1356,15 +1346,15 @@
                 && (mQsExpandImmediate || mIsExpanding && mQsExpandedWhenExpandingStarted)) {
 
             // Either QS pushes the notifications down when fully expanded, or QS is fully above the
-            // notifications (mostly on tablets). maxNotifications denotes the normal top padding
-            // 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;
-            int maxQs = mQsMaxExpansionHeight + mQsNotificationTopPadding;
+            // notifications (mostly on tablets). maxNotificationPadding denotes the normal top
+            // padding on Keyguard, maxQsPadding 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 maxNotificationPadding = mClockPositionResult.stackScrollerPadding;
+            int maxQsPadding = mQsMaxExpansionHeight + mQsNotificationTopPadding;
             int max = mStatusBarState == StatusBarState.KEYGUARD
-                    ? Math.max(maxNotifications, maxQs)
-                    : maxQs;
+                    ? Math.max(maxNotificationPadding, maxQsPadding)
+                    : maxQsPadding;
             return (int) interpolate(getExpandedFraction(),
                     mQsMinExpansionHeight, max);
         } else if (mQsSizeChangeAnimator != null) {
@@ -1507,7 +1497,7 @@
         if (mQsExpandImmediate || mQsExpanded || mIsExpanding && mQsExpandedWhenExpandingStarted) {
             maxHeight = calculatePanelHeightQsExpanded();
         } else {
-            maxHeight = calculatePanelHeightShade();
+            maxHeight = Math.max(calculatePanelHeightShade(), calculatePanelHeightShadeExpanded());
         }
         maxHeight = Math.max(maxHeight, min);
         return maxHeight;
@@ -1524,7 +1514,15 @@
     @Override
     protected void onHeightUpdated(float expandedHeight) {
         if (!mQsExpanded || mQsExpandImmediate || mIsExpanding && mQsExpandedWhenExpandingStarted) {
-            positionClockAndNotifications();
+            // Updating the clock position will set the top padding which might
+            // trigger a new panel height and re-position the clock.
+            // This is a circular dependency and should be avoided, otherwise we'll have
+            // a stack overflow.
+            if (mStackScrollerMeasuringPass > 2) {
+                if (DEBUG) Log.d(TAG, "Unstable notification panel height. Aborting.");
+            } else {
+                positionClockAndNotifications();
+            }
         }
         if (mQsExpandImmediate || mQsExpanded && !mQsTracking && mQsExpansionAnimator == null
                 && !mQsExpansionFromOverscroll) {
@@ -1568,12 +1566,18 @@
 
     private int calculatePanelHeightShade() {
         int emptyBottomMargin = mNotificationStackScroller.getEmptyBottomMargin();
-        int maxHeight = mNotificationStackScroller.getHeight() - emptyBottomMargin
-                - mTopPaddingAdjustment;
+        int maxHeight = mNotificationStackScroller.getHeight() - emptyBottomMargin;
         maxHeight += mNotificationStackScroller.getTopPaddingOverflow();
         return maxHeight;
     }
 
+    private int calculatePanelHeightShadeExpanded() {
+        return mNotificationStackScroller.getHeight()
+                - mNotificationStackScroller.getEmptyBottomMargin()
+                - mNotificationStackScroller.getTopPadding()
+                + mClockPositionAlgorithm.getExpandedClockBottom();
+    }
+
     private int calculatePanelHeightQsExpanded() {
         float notificationHeight = mNotificationStackScroller.getHeight()
                 - mNotificationStackScroller.getEmptyBottomMargin()
@@ -1598,8 +1602,7 @@
         }
         float totalHeight = Math.max(
                 maxQsHeight, mStatusBarState == StatusBarState.KEYGUARD
-                        ? mClockPositionResult.stackScrollerPadding - mTopPaddingAdjustment
-                        : 0)
+                        ? mClockPositionResult.stackScrollerPadding : 0)
                 + notificationHeight + mNotificationStackScroller.getTopPaddingOverflow();
         if (totalHeight > mNotificationStackScroller.getHeight()) {
             float fullyCollapsedHeight = maxQsHeight
@@ -2272,8 +2275,9 @@
     }
 
     @Override
-    protected void dispatchDraw(Canvas canvas) {
-        super.dispatchDraw(canvas);
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+
         if (DEBUG) {
             Paint p = new Paint();
             p.setColor(Color.RED);
@@ -2288,6 +2292,9 @@
             p.setColor(Color.YELLOW);
             canvas.drawLine(0, calculatePanelHeightShade(), getWidth(),
                     calculatePanelHeightShade(), p);
+            p.setColor(Color.GRAY);
+            canvas.drawLine(0, calculatePanelHeightShadeExpanded(), getWidth(),
+                    calculatePanelHeightShadeExpanded(), p);
             p.setColor(Color.MAGENTA);
             canvas.drawLine(0, calculateQsTopPadding(), getWidth(),
                     calculateQsTopPadding(), p);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 747a551..c326fee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -762,20 +762,31 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
-            if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION) ||
-                    action.equals(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION)) {
-                updateVolumeZen();
-            } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
-                updateSimState(intent);
-            } else if (action.equals(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED)) {
-                updateTTY(intent.getIntExtra(TelecomManager.EXTRA_CURRENT_TTY_MODE,
-                        TelecomManager.TTY_MODE_OFF));
-            } else if (action.equals(Intent.ACTION_MANAGED_PROFILE_AVAILABLE) ||
-                    action.equals(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE) ||
-                    action.equals(Intent.ACTION_MANAGED_PROFILE_REMOVED)) {
-                updateManagedProfile();
-            } else if (action.equals(AudioManager.ACTION_HEADSET_PLUG)) {
-                updateHeadsetPlug(intent);
+            switch (action) {
+                case AudioManager.RINGER_MODE_CHANGED_ACTION:
+                case AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION:
+                    updateVolumeZen();
+                    break;
+                case TelephonyIntents.ACTION_SIM_STATE_CHANGED:
+                    // Avoid rebroadcast because SysUI is direct boot aware.
+                    if (intent.getBooleanExtra(TelephonyIntents.EXTRA_REBROADCAST_ON_UNLOCK,
+                            false)) {
+                        break;
+                    }
+                    updateSimState(intent);
+                    break;
+                case TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED:
+                    updateTTY(intent.getIntExtra(TelecomManager.EXTRA_CURRENT_TTY_MODE,
+                            TelecomManager.TTY_MODE_OFF));
+                    break;
+                case Intent.ACTION_MANAGED_PROFILE_AVAILABLE:
+                case Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE:
+                case Intent.ACTION_MANAGED_PROFILE_REMOVED:
+                    updateManagedProfile();
+                    break;
+                case AudioManager.ACTION_HEADSET_PLUG:
+                    updateHeadsetPlug(intent);
+                    break;
             }
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index cc5a93c..900ec0b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -264,7 +264,7 @@
         mScrimController.setPanelExpansion(scrimFraction);
     }
 
-    public void onDensityOrFontScaleChanged() {
+    public void updateResources() {
         ViewGroup.LayoutParams layoutParams = getLayoutParams();
         layoutParams.height = getResources().getDimensionPixelSize(
                 R.dimen.status_bar_height);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubController.java
index dc0ea1c..00aff53 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubController.java
@@ -124,9 +124,10 @@
         @Override
         public void onAnimationEnd(Animator animation) {
             mNavigationBarView.getHomeButton().setClickable(true);
-            mHomeButtonView = null;
             mQuickScrubActive = false;
             mTranslation = 0;
+            mQuickScrubEndAnimator.setCurrentPlayTime(mQuickScrubEndAnimator.getDuration());
+            mHomeButtonView = null;
         }
     };
 
@@ -147,8 +148,7 @@
                         mIsVertical ? (absVelY > velocityX) : (velocityX > absVelY);
                 if (isValidFling) {
                     mDraggingActive = false;
-                    mButtonAnimator.setIntValues((int) mTranslation, 0);
-                    mButtonAnimator.start();
+                    animateEnd();
                     mHandler.removeCallbacks(mLongPressRunnable);
                     try {
                         final IOverviewProxy overviewProxy = mOverviewEventSender.getProxy();
@@ -176,8 +176,10 @@
 
         mTrackAnimator = ObjectAnimator.ofFloat();
         mTrackAnimator.addUpdateListener(mTrackAnimatorListener);
+        mTrackAnimator.setFloatValues(0);
         mButtonAnimator = ObjectAnimator.ofInt();
         mButtonAnimator.addUpdateListener(mButtonTranslationListener);
+        mButtonAnimator.setIntValues(0);
         mQuickScrubEndAnimator = new AnimatorSet();
         mQuickScrubEndAnimator.playTogether(mTrackAnimator, mButtonAnimator);
         mQuickScrubEndAnimator.setDuration(ANIM_DURATION_MS);
@@ -226,7 +228,7 @@
                 int x = (int) event.getX();
                 int y = (int) event.getY();
                 // End any existing quickscrub animations before starting the new transition
-                if (mQuickScrubEndAnimator != null) {
+                if (mHomeButtonView != null) {
                     mQuickScrubEndAnimator.end();
                 }
                 mHomeButtonView = homeButton.getCurrentView();
@@ -380,7 +382,7 @@
     }
 
     private void startQuickScrub() {
-        if (!mQuickScrubActive) {
+        if (!mQuickScrubActive && mDraggingActive) {
             mQuickScrubActive = true;
             mLightTrackColor = mContext.getColor(R.color.quick_step_track_background_light);
             mDarkTrackColor = mContext.getColor(R.color.quick_step_track_background_dark);
@@ -394,15 +396,16 @@
             } catch (RemoteException e) {
                 Log.e(TAG, "Failed to send start of quick scrub.", e);
             }
+        } else {
+            // After long press do not allow quick scrub/switch
+            mTouchDownX = -1;
         }
     }
 
     private void endQuickScrub(boolean animate) {
         mHandler.removeCallbacks(mLongPressRunnable);
         if (mDraggingActive || mQuickScrubActive) {
-            mButtonAnimator.setIntValues((int) mTranslation, 0);
-            mTrackAnimator.setFloatValues(mTrackAlpha, 0);
-            mQuickScrubEndAnimator.start();
+            animateEnd();
             try {
                 mOverviewEventSender.getProxy().onQuickScrubEnd();
                 if (DEBUG_OVERVIEW_PROXY) {
@@ -411,9 +414,9 @@
             } catch (RemoteException e) {
                 Log.e(TAG, "Failed to send end of quick scrub.", e);
             }
-            if (!animate) {
-                mQuickScrubEndAnimator.end();
-            }
+        }
+        if (mHomeButtonView != null && !animate) {
+            mQuickScrubEndAnimator.end();
         }
         mDraggingActive = false;
     }
@@ -430,6 +433,13 @@
         mHandler.removeCallbacks(mLongPressRunnable);
     }
 
+    private void animateEnd() {
+        mButtonAnimator.setIntValues((int) mTranslation, 0);
+        mTrackAnimator.setFloatValues(mTrackAlpha, 0);
+        mQuickScrubEndAnimator.setCurrentPlayTime(0);
+        mQuickScrubEndAnimator.start();
+    }
+
     private int getDimensionPixelSize(Context context, @DimenRes int resId) {
         return context.getResources().getDimensionPixelSize(resId);
     }
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 2b50853..d8d388c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -112,7 +112,6 @@
     protected static final float SCRIM_IN_FRONT_ALPHA_LOCKED = GRADIENT_SCRIM_ALPHA_BUSY;
 
     static final int TAG_KEY_ANIM = R.id.scrim;
-    private static final int TAG_KEY_ANIM_TARGET = R.id.scrim_target;
     private static final int TAG_START_ALPHA = R.id.scrim_alpha_start;
     private static final int TAG_END_ALPHA = R.id.scrim_alpha_end;
     private static final float NOT_INITIALIZED = -1;
@@ -138,7 +137,8 @@
     protected float mScrimBehindAlphaKeyguard = SCRIM_BEHIND_ALPHA_KEYGUARD;
     protected float mScrimBehindAlphaUnlocking = SCRIM_BEHIND_ALPHA_UNLOCKING;
 
-    private float mFraction;
+    // Assuming the shade is expanded during initialization
+    private float mExpansionFraction = 1f;
 
     private boolean mDarkenWhileDragging;
     protected boolean mAnimateChange;
@@ -167,6 +167,7 @@
     private Callback mCallback;
     private boolean mWallpaperSupportsAmbientMode;
     private boolean mScreenOn;
+    private float mNotificationDensity;
 
     // Scrim blanking callbacks
     private Choreographer.FrameCallback mPendingFrameCallback;
@@ -251,7 +252,8 @@
         mCurrentInFrontTint = state.getFrontTint();
         mCurrentBehindTint = state.getBehindTint();
         mCurrentInFrontAlpha = state.getFrontAlpha();
-        mCurrentBehindAlpha = state.getBehindAlpha();
+        mCurrentBehindAlpha = state.getBehindAlpha(mNotificationDensity);
+        applyExpansionToAlpha();
 
         // Cancel blanking transitions that were pending before we requested a new state
         if (mPendingFrameCallback != null) {
@@ -363,45 +365,51 @@
      * @param fraction From 0 to 1 where 0 means collapse and 1 expanded.
      */
     public void setPanelExpansion(float fraction) {
-        if (mFraction != fraction) {
-            mFraction = fraction;
+        if (mExpansionFraction != fraction) {
+            mExpansionFraction = fraction;
 
-            if (mState == ScrimState.UNLOCKED) {
-                // Darken scrim as you pull down the shade when unlocked
-                float behindFraction = getInterpolatedFraction();
-                behindFraction = (float) Math.pow(behindFraction, 0.8f);
-                mCurrentBehindAlpha = behindFraction * mScrimBehindAlphaKeyguard;
-                mCurrentInFrontAlpha = 0;
-            } else if (mState == ScrimState.KEYGUARD) {
-                if (mUpdatePending) {
-                    return;
-                }
+            if (!(mState == ScrimState.UNLOCKED || mState == ScrimState.KEYGUARD)) {
+                return;
+            }
 
-                // Either darken of make the scrim transparent when you
-                // pull down the shade
-                float interpolatedFract = getInterpolatedFraction();
-                if (mDarkenWhileDragging) {
-                    mCurrentBehindAlpha = MathUtils.lerp(mScrimBehindAlphaUnlocking,
-                            mScrimBehindAlphaKeyguard, interpolatedFract);
-                    mCurrentInFrontAlpha = (1f - interpolatedFract) * SCRIM_IN_FRONT_ALPHA_LOCKED;
-                } else {
-                    mCurrentBehindAlpha = MathUtils.lerp(0 /* start */, mScrimBehindAlphaKeyguard,
-                            interpolatedFract);
-                    mCurrentInFrontAlpha = 0;
-                }
-            } else {
+            applyExpansionToAlpha();
+
+            if (mUpdatePending) {
                 return;
             }
 
             if (mPinnedHeadsUpCount != 0) {
                 updateHeadsUpScrim(false);
             }
-
             updateScrim(false /* animate */, mScrimInFront, mCurrentInFrontAlpha);
             updateScrim(false /* animate */, mScrimBehind, mCurrentBehindAlpha);
         }
     }
 
+    private void applyExpansionToAlpha() {
+        if (mState == ScrimState.UNLOCKED) {
+            // Darken scrim as you pull down the shade when unlocked
+            float behindFraction = getInterpolatedFraction();
+            behindFraction = (float) Math.pow(behindFraction, 0.8f);
+            mCurrentBehindAlpha = behindFraction * mScrimBehindAlphaKeyguard;
+            mCurrentInFrontAlpha = 0;
+        } else if (mState == ScrimState.KEYGUARD) {
+            // Either darken of make the scrim transparent when you
+            // pull down the shade
+            float interpolatedFract = getInterpolatedFraction();
+            float alphaBehind = mState.getBehindAlpha(mNotificationDensity);
+            if (mDarkenWhileDragging) {
+                mCurrentBehindAlpha = MathUtils.lerp(mScrimBehindAlphaUnlocking, alphaBehind,
+                        interpolatedFract);
+                mCurrentInFrontAlpha = (1f - interpolatedFract) * SCRIM_IN_FRONT_ALPHA_LOCKED;
+            } else {
+                mCurrentBehindAlpha = MathUtils.lerp(0 /* start */, alphaBehind,
+                        interpolatedFract);
+                mCurrentInFrontAlpha = 0;
+            }
+        }
+    }
+
     /**
      * Keyguard and shade scrim opacity varies according to how many notifications are visible.
      * @param notificationCount Number of visible notifications.
@@ -409,15 +417,14 @@
     public void setNotificationCount(int notificationCount) {
         final float maxNotificationDensity = 3;
         float notificationDensity = Math.min(notificationCount / maxNotificationDensity, 1f);
-        float newAlpha = MathUtils.map(0, 1,
-                GRADIENT_SCRIM_ALPHA, GRADIENT_SCRIM_ALPHA_BUSY,
-                notificationDensity);
-        if (mScrimBehindAlphaKeyguard != newAlpha) {
-            mScrimBehindAlphaKeyguard = newAlpha;
+        if (mNotificationDensity == notificationDensity) {
+            return;
+        }
+        mNotificationDensity = notificationDensity;
 
-            if (mState == ScrimState.KEYGUARD || mState == ScrimState.BOUNCER) {
-                scheduleUpdate();
-            }
+        if (mState == ScrimState.KEYGUARD) {
+            applyExpansionToAlpha();
+            scheduleUpdate();
         }
     }
 
@@ -497,7 +504,7 @@
     }
 
     private float getInterpolatedFraction() {
-        float frac = mFraction;
+        float frac = mExpansionFraction;
         // let's start this 20% of the way down the screen
         frac = frac * 1.2f - 0.2f;
         if (frac <= 0) {
@@ -551,7 +558,7 @@
         return scrim == mScrimInFront ? mCurrentInFrontTint : mCurrentBehindTint;
     }
 
-    private void startScrimAnimation(final View scrim, float current, float target) {
+    private void startScrimAnimation(final View scrim, float current) {
         ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
         final int initialScrimTint = scrim instanceof ScrimView ? ((ScrimView) scrim).getTint() :
                 Color.TRANSPARENT;
@@ -559,7 +566,9 @@
             final float animAmount = (float) animation.getAnimatedValue();
             final int finalScrimTint = scrim == mScrimInFront ?
                     mCurrentInFrontTint : mCurrentBehindTint;
-            float alpha = MathUtils.lerp(current, target, animAmount);
+            float finalScrimAlpha = scrim == mScrimInFront ?
+                    mCurrentInFrontAlpha : mCurrentBehindAlpha;
+            float alpha = MathUtils.lerp(current, finalScrimAlpha, animAmount);
             int tint = ColorUtils.blendARGB(initialScrimTint, finalScrimTint, animAmount);
             updateScrimColor(scrim, alpha, tint);
             dispatchScrimsVisible();
@@ -570,6 +579,12 @@
         anim.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
+                final int finalScrimTint = scrim == mScrimInFront ?
+                        mCurrentInFrontTint : mCurrentBehindTint;
+                float finalScrimAlpha = scrim == mScrimInFront ?
+                        mCurrentInFrontAlpha : mCurrentBehindAlpha;
+                updateScrimColor(scrim, finalScrimAlpha, finalScrimTint);
+
                 if (mKeyguardFadingOutInProgress) {
                     mKeyguardFadeoutAnimation = null;
                     mKeyguardFadingOutInProgress = false;
@@ -577,7 +592,6 @@
                 onFinished();
 
                 scrim.setTag(TAG_KEY_ANIM, null);
-                scrim.setTag(TAG_KEY_ANIM_TARGET, null);
                 dispatchScrimsVisible();
 
                 if (!mDeferFinishedListener && mOnAnimationFinished != null) {
@@ -592,7 +606,6 @@
             mKeyguardFadeoutAnimation = anim;
         }
         scrim.setTag(TAG_KEY_ANIM, anim);
-        scrim.setTag(TAG_KEY_ANIM_TARGET, target);
     }
 
     protected Interpolator getInterpolator() {
@@ -700,7 +713,7 @@
                 if (animate) {
                     mDeferFinishedListener = true;
                 }
-                previousAnimator.cancel();
+                cancelAnimator(previousAnimator);
                 mDeferFinishedListener = false;
             } else {
                 animEndValue = ViewState.getChildTag(scrim, TAG_END_ALPHA);
@@ -709,9 +722,11 @@
 
         if (mPendingFrameCallback != null) {
             // Display is off and we're waiting.
+            cancelAnimator(previousAnimator);
             return;
         } else if (mBlankScreen) {
             // Need to blank the display before continuing.
+            cancelAnimator(previousAnimator);
             blankDisplay();
             return;
         } else if (!mScreenBlankingCallbackCalled) {
@@ -737,7 +752,7 @@
             if (animate) {
                 final float fromAlpha = scrimView == null ? scrim.getAlpha()
                         : scrimView.getViewAlpha();
-                startScrimAnimation(scrim, fromAlpha, alpha);
+                startScrimAnimation(scrim, fromAlpha);
                 scrim.setTag(TAG_START_ALPHA, currentAlpha);
                 scrim.setTag(TAG_END_ALPHA, alpha);
             } else {
@@ -765,6 +780,13 @@
         }
     }
 
+    @VisibleForTesting
+    protected void cancelAnimator(ValueAnimator previousAnimator) {
+        if (previousAnimator != null) {
+            previousAnimator.cancel();
+        }
+    }
+
     private void blankDisplay() {
         updateScrimColor(mScrimInFront, 1, Color.BLACK);
 
@@ -827,7 +849,7 @@
         } else {
             alpha = 1.0f - mTopHeadsUpDragAmount;
         }
-        float expandFactor = (1.0f - mFraction);
+        float expandFactor = (1.0f - mExpansionFraction);
         expandFactor = Math.max(expandFactor, 0.0f);
         return alpha * expandFactor;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index 381e4af..053c5a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -18,6 +18,7 @@
 
 import android.graphics.Color;
 import android.os.Trace;
+import android.util.MathUtils;
 
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.statusbar.ScrimView;
@@ -55,6 +56,13 @@
             mCurrentBehindAlpha = mScrimBehindAlphaKeyguard;
             mCurrentInFrontAlpha = 0;
         }
+
+        @Override
+        public float getBehindAlpha(float busynessFactor) {
+            return MathUtils.map(0 /* start */, 1 /* stop */,
+                   ScrimController.GRADIENT_SCRIM_ALPHA, ScrimController.GRADIENT_SCRIM_ALPHA_BUSY,
+                   busynessFactor);
+        }
     },
 
     /**
@@ -183,7 +191,7 @@
         return mCurrentInFrontAlpha;
     }
 
-    public float getBehindAlpha() {
+    public float getBehindAlpha(float busyness) {
         return mCurrentBehindAlpha;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 24920cb..86e618e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -180,6 +180,7 @@
 import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.stackdivider.WindowManagerProxy;
 import com.android.systemui.statusbar.ActivatableNotificationView;
+import com.android.systemui.statusbar.AppOpsListener;
 import com.android.systemui.statusbar.BackDropView;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.CrossFadeHelper;
@@ -210,7 +211,6 @@
 import com.android.systemui.statusbar.notification.AboveShelfObserver;
 import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
 import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
@@ -240,7 +240,6 @@
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
@@ -407,6 +406,7 @@
     protected NotificationLogger mNotificationLogger;
     protected NotificationEntryManager mEntryManager;
     protected NotificationViewHierarchyManager mViewHierarchyManager;
+    protected AppOpsListener mAppOpsListener;
 
     /**
      * Helper that is responsible for showing the right toast when a disallowed activity operation
@@ -624,6 +624,8 @@
         mMediaManager = Dependency.get(NotificationMediaManager.class);
         mEntryManager = Dependency.get(NotificationEntryManager.class);
         mViewHierarchyManager = Dependency.get(NotificationViewHierarchyManager.class);
+        mAppOpsListener = Dependency.get(AppOpsListener.class);
+        mAppOpsListener.setUpWithPresenter(this, mEntryManager);
 
         mColorExtractor = Dependency.get(SysuiColorExtractor.class);
         mColorExtractor.addOnColorsChangedListener(this);
@@ -815,6 +817,7 @@
 
         mHeadsUpManager = new HeadsUpManagerPhone(context, mStatusBarWindow, mGroupManager, this,
                 mVisualStabilityManager);
+        Dependency.get(ConfigurationController.class).addCallback(mHeadsUpManager);
         mHeadsUpManager.addListener(this);
         mHeadsUpManager.addListener(mNotificationPanel);
         mHeadsUpManager.addListener(mGroupManager);
@@ -1071,7 +1074,6 @@
         // end old BaseStatusBar.onDensityOrFontScaleChanged().
         mScrimController.onDensityOrFontScaleChanged();
         // TODO: Remove this.
-        if (mStatusBarView != null) mStatusBarView.onDensityOrFontScaleChanged();
         if (mBrightnessMirrorController != null) {
             mBrightnessMirrorController.onDensityOrFontScaleChanged();
         }
@@ -2804,6 +2806,7 @@
                     public void setRemoteInputActive(NotificationData.Entry entry,
                             boolean remoteInputActive) {
                         mHeadsUpManager.setRemoteInputActive(entry, remoteInputActive);
+                        entry.row.updateMaxHeights();
                     }
                     public void lockScrollTo(NotificationData.Entry entry) {
                         mStackScroller.lockScrollTo(entry.row);
@@ -3080,6 +3083,9 @@
 
         loadDimens();
 
+        if (mStatusBarView != null) {
+            mStatusBarView.updateResources();
+        }
         if (mNotificationPanel != null) {
             mNotificationPanel.updateResources();
         }
@@ -3294,6 +3300,7 @@
         Dependency.get(ActivityStarterDelegate.class).setActivityStarterImpl(null);
         mDeviceProvisionedController.removeCallback(mUserSetupObserver);
         Dependency.get(ConfigurationController.class).removeCallback(this);
+        mAppOpsListener.destroy();
     }
 
     private boolean mDemoModeAllowed;
@@ -4519,6 +4526,9 @@
             }
             if (isScreenTurningOnOrOn()) {
                 if (DEBUG_CAMERA_LIFT) Slog.d(TAG, "Launching camera");
+                if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
+                    mStatusBarKeyguardViewManager.reset(true /* hide */);
+                }
                 mNotificationPanel.launchCamera(mDeviceInteractive /* animate */, source);
                 updateScrimController();
             } else {
@@ -4723,7 +4733,7 @@
 
         @Override
         public boolean isPowerSaveActive() {
-            return mBatteryController.isPowerSave();
+            return mBatteryController.isAodPowerSave();
         }
 
         @Override
@@ -4981,7 +4991,7 @@
                                     notificationKey)) {
                                 // Show work challenge, do not run PendingIntent and
                                 // remove notification
-                                collapsePanel();
+                                collapseOnMainThread();
                                 return;
                             }
                         }
@@ -5022,11 +5032,7 @@
                     }
                 }
                 if (shouldCollapse()) {
-                    if (Looper.getMainLooper().isCurrentThread()) {
-                        collapsePanel();
-                    } else {
-                        mStackScroller.post(this::collapsePanel);
-                    }
+                    collapseOnMainThread();
                 }
 
                 try {
@@ -5054,6 +5060,14 @@
         }, afterKeyguardGone);
     }
 
+    private void collapseOnMainThread() {
+        if (Looper.getMainLooper().isCurrentThread()) {
+            collapsePanel();
+        } else {
+            mStackScroller.post(this::collapsePanel);
+        }
+    }
+
     private boolean shouldCollapse() {
         return mState != StatusBarState.SHADE || !mActivityLaunchAnimator.isAnimationPending();
     }
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 07610ce..956bebb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -18,6 +18,7 @@
 import static android.app.StatusBarManager.DISABLE_NONE;
 
 import android.content.Context;
+import android.os.Bundle;
 import android.support.annotation.VisibleForTesting;
 import android.text.TextUtils;
 import android.util.ArraySet;
@@ -29,6 +30,7 @@
 import android.widget.LinearLayout.LayoutParams;
 
 import com.android.internal.statusbar.StatusBarIcon;
+import com.android.systemui.DemoMode;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.StatusBarIconView;
@@ -109,6 +111,20 @@
             super.onSetIcon(viewIndex, icon);
             mDarkIconDispatcher.applyDark((ImageView) mGroup.getChildAt(viewIndex));
         }
+
+        @Override
+        protected DemoStatusIcons createDemoStatusIcons() {
+            DemoStatusIcons icons = super.createDemoStatusIcons();
+            mDarkIconDispatcher.addDarkReceiver(icons);
+
+            return icons;
+        }
+
+        @Override
+        protected void exitDemoMode() {
+            mDarkIconDispatcher.removeDarkReceiver(mDemoStatusIcons);
+            super.exitDemoMode();
+        }
     }
 
     public static class TintedIconManager extends IconManager {
@@ -134,15 +150,28 @@
                 }
             }
         }
+
+        @Override
+        protected DemoStatusIcons createDemoStatusIcons() {
+            DemoStatusIcons icons = super.createDemoStatusIcons();
+            icons.setColor(mColor);
+            return icons;
+        }
     }
 
     /**
      * Turns info from StatusBarIconController into ImageViews in a ViewGroup.
      */
-    public static class IconManager {
+    public static class IconManager implements DemoMode {
         protected final ViewGroup mGroup;
         protected final Context mContext;
         protected final int mIconSize;
+        // Whether or not these icons show up in dumpsys
+        protected boolean mShouldLog = false;
+
+        // Enables SystemUI demo mode to take effect in this group
+        protected boolean mDemoable = true;
+        protected DemoStatusIcons mDemoStatusIcons;
 
         public IconManager(ViewGroup group) {
             mGroup = group;
@@ -159,6 +188,22 @@
             }
         }
 
+        public boolean isDemoable() {
+            return mDemoable;
+        }
+
+        public void setIsDemoable(boolean demoable) {
+            mDemoable = demoable;
+        }
+
+        public void setShouldLog(boolean should) {
+            mShouldLog = should;
+        }
+
+        public boolean shouldLog() {
+            return mShouldLog;
+        }
+
         protected void onIconAdded(int index, String slot, boolean blocked,
                 StatusBarIcon icon) {
             addIcon(index, slot, blocked, icon);
@@ -218,5 +263,31 @@
             StatusBarIconView view = (StatusBarIconView) mGroup.getChildAt(viewIndex);
             view.set(icon);
         }
+
+        @Override
+        public void dispatchDemoCommand(String command, Bundle args) {
+            if (!mDemoable) {
+                return;
+            }
+
+            if (mDemoStatusIcons != null && command.equals(COMMAND_EXIT)) {
+                mDemoStatusIcons.dispatchDemoCommand(command, args);
+                exitDemoMode();
+            } else {
+                if (mDemoStatusIcons == null) {
+                    mDemoStatusIcons = createDemoStatusIcons();
+                }
+                mDemoStatusIcons.dispatchDemoCommand(command, args);
+            }
+        }
+
+        protected void exitDemoMode() {
+            mDemoStatusIcons.remove();
+            mDemoStatusIcons = null;
+        }
+
+        protected DemoStatusIcons createDemoStatusIcons() {
+            return new DemoStatusIcons((LinearLayout) mGroup, mIconSize);
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
index 1c3ee75..8f5e705 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
@@ -41,6 +41,8 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 
+import static com.android.systemui.statusbar.phone.CollapsedStatusBarFragment.STATUS_BAR_ICON_MANAGER_TAG;
+
 /**
  * Receives the callbacks from CommandQueue related to icons and tracks the state of
  * all the icons. Dispatches this state to any IconManagers that are currently
@@ -48,6 +50,7 @@
  */
 public class StatusBarIconControllerImpl extends StatusBarIconList implements Tunable,
         ConfigurationListener, Dumpable, CommandQueue.Callbacks, StatusBarIconController {
+    private static final String TAG = "StatusBarIconController";
 
     private final ArrayList<IconManager> mIconGroups = new ArrayList<>();
     private final ArraySet<String> mIconBlacklist = new ArraySet<>();
@@ -55,6 +58,7 @@
 
     private Context mContext;
     private DemoStatusIcons mDemoStatusIcons;
+    private IconManager mStatusBarIconManager;
 
     public StatusBarIconControllerImpl(Context context) {
         super(context.getResources().getStringArray(
@@ -197,26 +201,28 @@
 
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        // TODO: Dump info about all icon groups?
-        ViewGroup statusIcons = mIconGroups.get(0).mGroup;
-        int N = statusIcons.getChildCount();
-        pw.println("  icon views: " + N);
-        for (int i = 0; i < N; i++) {
-            StatusBarIconView ic = (StatusBarIconView) statusIcons.getChildAt(i);
-            pw.println("    [" + i + "] icon=" + ic);
+        pw.println(TAG + " state:");
+        for (IconManager manager : mIconGroups) {
+            if (manager.shouldLog()) {
+                ViewGroup group = manager.mGroup;
+                int N = group.getChildCount();
+                pw.println("  icon views: " + N);
+                for (int i = 0; i < N; i++) {
+                    StatusBarIconView ic = (StatusBarIconView) group.getChildAt(i);
+                    pw.println("    [" + i + "] icon=" + ic);
+                }
+            }
         }
+
         super.dump(pw);
     }
 
     public void dispatchDemoCommand(String command, Bundle args) {
-        if (mDemoStatusIcons == null) {
-            // TODO: Rework how we handle demo mode.
-            int iconSize = mContext.getResources().getDimensionPixelSize(
-                    com.android.internal.R.dimen.status_bar_icon_size);
-            mDemoStatusIcons = new DemoStatusIcons((LinearLayout) mIconGroups.get(0).mGroup,
-                    iconSize);
+        for (IconManager manager : mIconGroups) {
+            if (manager.isDemoable()) {
+                manager.dispatchDemoCommand(command, args);
+            }
         }
-        mDemoStatusIcons.dispatchDemoCommand(command, args);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java
index f600908..1aa3a43 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java
@@ -77,6 +77,7 @@
     }
 
     public void dump(PrintWriter pw) {
+        pw.println("StatusBarIconList state:");
         final int N = mSlots.size();
         pw.println("  icon slots: " + N);
         for (int i=0; i<N; i++) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index c667309..a009d80 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -24,6 +24,7 @@
 import android.content.Context;
 import android.os.Bundle;
 import android.os.SystemClock;
+import android.util.StatsLog;
 import android.view.KeyEvent;
 import android.view.View;
 import android.view.ViewGroup;
@@ -140,6 +141,8 @@
         mShowing = true;
         mStatusBarWindowManager.setKeyguardShowing(true);
         reset(true /* hideBouncerWhenShowing */);
+        StatsLog.write(StatsLog.KEYGUARD_STATE_CHANGED,
+            StatsLog.KEYGUARD_STATE_CHANGED__STATE__SHOWN);
     }
 
     /**
@@ -289,6 +292,8 @@
     public void setOccluded(boolean occluded, boolean animate) {
         mStatusBar.setOccluded(occluded);
         if (occluded && !mOccluded && mShowing) {
+            StatsLog.write(StatsLog.KEYGUARD_STATE_CHANGED,
+                StatsLog.KEYGUARD_STATE_CHANGED__STATE__OCCLUDED);
             if (mStatusBar.isInLaunchTransition()) {
                 mOccluded = true;
                 mStatusBar.fadeKeyguardAfterLaunchTransition(null /* beforeFading */,
@@ -301,6 +306,9 @@
                         });
                 return;
             }
+        } else if (!occluded && mOccluded && mShowing) {
+            StatsLog.write(StatsLog.KEYGUARD_STATE_CHANGED,
+                StatsLog.KEYGUARD_STATE_CHANGED__STATE__SHOWN);
         }
         boolean isOccluding = !mOccluded && occluded;
         mOccluded = occluded;
@@ -398,6 +406,8 @@
             mStatusBarWindowManager.setKeyguardShowing(false);
             mViewMediatorCallback.keyguardGone();
         }
+        StatsLog.write(StatsLog.KEYGUARD_STATE_CHANGED,
+            StatsLog.KEYGUARD_STATE_CHANGED__STATE__HIDDEN);
     }
 
     public void onDensityOrFontScaleChanged() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
index 503a1b4..dba89479 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
@@ -14,12 +14,6 @@
  * limitations under the License.
  */
 
-/**
- * A container for Status bar system icons. Limits the number of system icons and handles overflow
- * similar to NotificationIconController. Can be used to layout nested StatusIconContainers
- *
- * Children are expected to be of type StatusBarIconView.
- */
 package com.android.systemui.statusbar.phone;
 
 import android.annotation.Nullable;
@@ -33,6 +27,12 @@
 import com.android.systemui.statusbar.StatusBarIconView;
 import com.android.systemui.statusbar.stack.ViewState;
 
+/**
+ * A container for Status bar system icons. Limits the number of system icons and handles overflow
+ * similar to NotificationIconController. Can be used to layout nested StatusIconContainers
+ *
+ * Children are expected to be of type StatusBarIconView.
+ */
 public class StatusIconContainer extends AlphaOptimizedLinearLayout {
 
     private static final String TAG = "StatusIconContainer";
@@ -40,6 +40,10 @@
     private static final int MAX_ICONS = 5;
     private static final int MAX_DOTS = 3;
 
+    public StatusIconContainer(Context context) {
+        this(context, null);
+    }
+
     public StatusIconContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java
index 0d21c4e..6ee6cb2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java
@@ -102,8 +102,6 @@
 
     @Override
     public void scanForAccessPoints() {
-        if (DEBUG) Log.d(TAG, "force update APs!");
-        mWifiTracker.forceUpdate();
         fireAcccessPointsCallback(mWifiTracker.getAccessPoints());
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
index 641fe69..6f4026d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -41,6 +41,13 @@
     boolean isPowerSave();
 
     /**
+     * Returns {@code true} if AOD was disabled by power saving policies.
+     */
+    default boolean isAodPowerSave() {
+        return isPowerSave();
+    }
+
+    /**
      * A listener that will be notified whenever a change in battery level or power save mode
      * has occurred.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index e8d5af6..49f880c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -24,8 +24,10 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.PowerManager;
+import android.os.PowerSaveState;
 import android.util.Log;
-import com.android.systemui.DemoMode;
+
+import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -52,13 +54,19 @@
     protected boolean mCharging;
     protected boolean mCharged;
     protected boolean mPowerSave;
+    protected boolean mAodPowerSave;
     private boolean mTestmode = false;
     private boolean mHasReceivedBattery = false;
 
     public BatteryControllerImpl(Context context) {
+        this(context, context.getSystemService(PowerManager.class));
+    }
+
+    @VisibleForTesting
+    BatteryControllerImpl(Context context, PowerManager powerManager) {
         mContext = context;
         mHandler = new Handler();
-        mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+        mPowerManager = powerManager;
 
         registerReceiver();
         updatePowerSave();
@@ -166,6 +174,11 @@
         return mPowerSave;
     }
 
+    @Override
+    public boolean isAodPowerSave() {
+        return mAodPowerSave;
+    }
+
     private void updatePowerSave() {
         setPowerSave(mPowerManager.isPowerSaveMode());
     }
@@ -173,6 +186,11 @@
     private void setPowerSave(boolean powerSave) {
         if (powerSave == mPowerSave) return;
         mPowerSave = powerSave;
+
+        // AOD power saving setting might be different from PowerManager power saving mode.
+        PowerSaveState state = mPowerManager.getPowerSaveState(PowerManager.ServiceType.AOD);
+        mAodPowerSave = state.batterySaverEnabled;
+
         if (DEBUG) Log.d(TAG, "Power save is " + (mPowerSave ? "on" : "off"));
         firePowerSaveChanged();
     }
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 a011952..06a56ff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.policy;
 
 import android.annotation.NonNull;
+import android.content.res.Resources;
 import android.util.ArraySet;
 import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
@@ -111,10 +112,10 @@
     public void updateResources() {
         FrameLayout.LayoutParams lp =
                 (FrameLayout.LayoutParams) mBrightnessMirror.getLayoutParams();
-        lp.width = mBrightnessMirror.getResources().getDimensionPixelSize(
-                R.dimen.qs_panel_width);
-        lp.gravity = mBrightnessMirror.getResources().getInteger(
-                R.integer.notification_panel_layout_gravity);
+        Resources r = mBrightnessMirror.getResources();
+        lp.width = r.getDimensionPixelSize(R.dimen.qs_panel_width);
+        lp.height = r.getDimensionPixelSize(R.dimen.brightness_mirror_height);
+        lp.gravity = r.getInteger(R.integer.notification_panel_layout_gravity);
         mBrightnessMirror.setLayoutParams(lp);
     }
 
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 a2bec98..cc7943b8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java
@@ -26,11 +26,9 @@
 import android.graphics.Paint;
 import android.graphics.PixelFormat;
 import android.graphics.drawable.Drawable;
-import android.os.Handler;
 import android.view.DisplayListCanvas;
 import android.view.RenderNodeAnimator;
 import android.view.View;
-import android.view.ViewConfiguration;
 import android.view.animation.Interpolator;
 
 import com.android.systemui.Interpolators;
@@ -58,17 +56,14 @@
     private float mGlowAlpha = 0f;
     private float mGlowScale = 1f;
     private boolean mPressed;
-    private boolean mVisible;
     private boolean mDrawingHardwareGlow;
     private int mMaxWidth;
     private boolean mLastDark;
     private boolean mDark;
-    private boolean mDelayTouchFeedback;
 
     private final Interpolator mInterpolator = new LogInterpolator();
     private boolean mSupportHardware;
     private final View mTargetView;
-    private final Handler mHandler = new Handler();
 
     private final HashSet<Animator> mRunningAnimations = new HashSet<>();
     private final ArrayList<Animator> mTmpArray = new ArrayList<>();
@@ -82,10 +77,6 @@
         mDark = darkIntensity >= 0.5f;
     }
 
-    public void setDelayTouchFeedback(boolean delay) {
-        mDelayTouchFeedback = delay;
-    }
-
     private Paint getRipplePaint() {
         if (mRipplePaint == null) {
             mRipplePaint = new Paint();
@@ -220,16 +211,7 @@
         }
     }
 
-    /**
-     * Abort the ripple while it is delayed and before shown used only when setShouldDelayStartTouch
-     * is enabled.
-     */
-    public void abortDelayedRipple() {
-        mHandler.removeCallbacksAndMessages(null);
-    }
-
     private void cancelAnimations() {
-        mVisible = false;
         mTmpArray.addAll(mRunningAnimations);
         int size = mTmpArray.size();
         for (int i = 0; i < size; i++) {
@@ -238,21 +220,11 @@
         }
         mTmpArray.clear();
         mRunningAnimations.clear();
-        mHandler.removeCallbacksAndMessages(null);
     }
 
     private void setPressedSoftware(boolean pressed) {
         if (pressed) {
-            if (mDelayTouchFeedback) {
-                if (mRunningAnimations.isEmpty()) {
-                    mHandler.removeCallbacksAndMessages(null);
-                    mHandler.postDelayed(this::enterSoftware, ViewConfiguration.getTapTimeout());
-                } else if (mVisible) {
-                    enterSoftware();
-                }
-            } else {
-                enterSoftware();
-            }
+            enterSoftware();
         } else {
             exitSoftware();
         }
@@ -260,7 +232,6 @@
 
     private void enterSoftware() {
         cancelAnimations();
-        mVisible = true;
         mGlowAlpha = getMaxGlowAlpha();
         ObjectAnimator scaleAnimator = ObjectAnimator.ofFloat(this, "glowScale",
                 0f, GLOW_MAX_SCALE_FACTOR);
@@ -269,12 +240,6 @@
         scaleAnimator.addListener(mAnimatorListener);
         scaleAnimator.start();
         mRunningAnimations.add(scaleAnimator);
-
-        // With the delay, it could eventually animate the enter animation with no pressed state,
-        // then immediately show the exit animation. If this is skipped there will be no ripple.
-        if (mDelayTouchFeedback && !mPressed) {
-            exitSoftware();
-        }
     }
 
     private void exitSoftware() {
@@ -288,16 +253,7 @@
 
     private void setPressedHardware(boolean pressed) {
         if (pressed) {
-            if (mDelayTouchFeedback) {
-                if (mRunningAnimations.isEmpty()) {
-                    mHandler.removeCallbacksAndMessages(null);
-                    mHandler.postDelayed(this::enterHardware, ViewConfiguration.getTapTimeout());
-                } else if (mVisible) {
-                    enterHardware();
-                }
-            } else {
-                enterHardware();
-            }
+            enterHardware();
         } else {
             exitHardware();
         }
@@ -346,7 +302,6 @@
 
     private void enterHardware() {
         cancelAnimations();
-        mVisible = true;
         mDrawingHardwareGlow = true;
         setExtendStart(CanvasProperty.createFloat(getExtendSize() / 2));
         final RenderNodeAnimator startAnim = new RenderNodeAnimator(getExtendStart(),
@@ -388,12 +343,6 @@
         mRunningAnimations.add(endAnim);
 
         invalidateSelf();
-
-        // With the delay, it could eventually animate the enter animation with no pressed state,
-        // then immediately show the exit animation. If this is skipped there will be no ripple.
-        if (mDelayTouchFeedback && !mPressed) {
-            exitHardware();
-        }
     }
 
     private void exitHardware() {
@@ -417,7 +366,6 @@
         public void onAnimationEnd(Animator animation) {
             mRunningAnimations.remove(animation);
             if (mRunningAnimations.isEmpty() && !mPressed) {
-                mVisible = false;
                 mDrawingHardwareGlow = false;
                 invalidateSelf();
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index 98bebec..e7b802d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -67,6 +67,7 @@
     private int mTouchSlop;
     private int mTouchDownX;
     private int mTouchDownY;
+    private boolean mIsPressed;
     private boolean mSupportsLongpress = true;
     private AudioManager mAudioManager;
     private boolean mGestureAborted;
@@ -79,7 +80,7 @@
 
     private final Runnable mCheckLongPress = new Runnable() {
         public void run() {
-            if (isPressed()) {
+            if (mIsPressed) {
                 // Log.d("KeyButtonView", "longpressed: " + this);
                 if (isLongClickable()) {
                     // Just an old-fashioned ImageView
@@ -90,6 +91,12 @@
                     sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
                     mLongClicked = true;
                 }
+
+                // Only when quick step is enabled, ripple will not be shown on touch down, then
+                // show the ripple on touch up or on long press
+                if (mLongClicked && mOverviewProxyService.getProxy() != null) {
+                    setPressed(true);
+                }
             }
         }
     };
@@ -216,7 +223,6 @@
             case MotionEvent.ACTION_DOWN:
                 mDownTime = SystemClock.uptimeMillis();
                 mLongClicked = false;
-                setPressed(true);
                 mTouchDownX = (int) ev.getX();
                 mTouchDownY = (int) ev.getY();
                 if (mCode != 0) {
@@ -225,6 +231,7 @@
                     // Provide the same haptic feedback that the system offers for virtual keys.
                     performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
                 }
+                mIsPressed = true;
                 if (isProxyConnected) {
                     // Provide small vibration for quick step or immediate down feedback
                     AsyncTask.execute(() ->
@@ -232,6 +239,7 @@
                                     .get(VibrationEffect.EFFECT_TICK, false)));
                 } else {
                     playSoundEffect(SoundEffectConstants.CLICK);
+                    setPressed(mIsPressed);
                 }
                 removeCallbacks(mCheckLongPress);
                 postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
@@ -242,7 +250,12 @@
                 boolean exceededTouchSlopX = Math.abs(x - mTouchDownX) > mTouchSlop;
                 boolean exceededTouchSlopY = Math.abs(y - mTouchDownY) > mTouchSlop;
                 if (exceededTouchSlopX || exceededTouchSlopY) {
-                    setPressed(false);
+                    // When quick step is enabled, prevent animating the ripple triggered by
+                    // setPressed and decide to run it on touch up
+                    mIsPressed = false;
+                    if (!isProxyConnected) {
+                        setPressed(mIsPressed);
+                    }
                     removeCallbacks(mCheckLongPress);
                 }
                 break;
@@ -254,10 +267,11 @@
                 removeCallbacks(mCheckLongPress);
                 break;
             case MotionEvent.ACTION_UP:
-                final boolean doIt = isPressed() && !mLongClicked;
-                setPressed(false);
+                final boolean doIt = mIsPressed && !mLongClicked;
                 if (isProxyConnected) {
                     if (doIt) {
+                        // Animate the ripple in on touch up with setPressed and then out later
+                        setPressed(true);
                         performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
                         playSoundEffect(SoundEffectConstants.CLICK);
                     }
@@ -266,6 +280,7 @@
                     // and it feels weird to sometimes get a release haptic and other times not.
                     performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY_RELEASE);
                 }
+                setPressed(false);
                 if (mCode != 0) {
                     if (doIt) {
                         // If there was a pending remote recents animation, then we need to
@@ -295,6 +310,12 @@
         mAudioManager.playSoundEffect(soundConstant, ActivityManager.getCurrentUser());
     }
 
+    @Override
+    public void setPressed(boolean pressed) {
+        mIsPressed = pressed;
+        super.setPressed(pressed);
+    }
+
     public void sendEvent(int action, int flags) {
         sendEvent(action, flags, SystemClock.uptimeMillis());
     }
@@ -317,7 +338,6 @@
     @Override
     public void abortCurrentGesture() {
         setPressed(false);
-        mRipple.abortDelayedRipple();
         mGestureAborted = true;
     }
 
@@ -336,7 +356,6 @@
 
     @Override
     public void setDelayTouchFeedback(boolean shouldDelay) {
-        mRipple.setDelayTouchFeedback(shouldDelay);
     }
 
     @Override
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 baf0ebf..5363742 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -403,54 +403,62 @@
             Log.d(TAG, "onReceive: intent=" + intent);
         }
         final String action = intent.getAction();
-        if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) ||
-                action.equals(ConnectivityManager.INET_CONDITION_ACTION)) {
-            updateConnectivity();
-        } else if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
-            refreshLocale();
-            updateAirplaneMode(false);
-        } else if (action.equals(TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED)) {
-            // We are using different subs now, we might be able to make calls.
-            recalculateEmergency();
-        } else if (action.equals(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) {
-            // Notify every MobileSignalController so they can know whether they are the
-            // data sim or not.
-            for (int i = 0; i < mMobileSignalControllers.size(); i++) {
-                MobileSignalController controller = mMobileSignalControllers.valueAt(i);
-                controller.handleBroadcast(intent);
-            }
-        } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
-            // Might have different subscriptions now.
-            updateMobileControllers();
-        } else if (action.equals(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED)) {
-            mLastServiceState = ServiceState.newFromBundle(intent.getExtras());
-            if (mMobileSignalControllers.size() == 0) {
-                // If none of the subscriptions are active, we might need to recalculate
-                // emergency state.
+        switch (action) {
+            case ConnectivityManager.CONNECTIVITY_ACTION:
+            case ConnectivityManager.INET_CONDITION_ACTION:
+                updateConnectivity();
+                break;
+            case Intent.ACTION_AIRPLANE_MODE_CHANGED:
+                refreshLocale();
+                updateAirplaneMode(false);
+                break;
+            case TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED:
+                // We are using different subs now, we might be able to make calls.
                 recalculateEmergency();
-            }
-        } else if (action.equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
-            mConfig = Config.readConfig(mContext);
-            mReceiverHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    handleConfigurationChanged();
+                break;
+            case TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED:
+                // Notify every MobileSignalController so they can know whether they are the
+                // data sim or not.
+                for (int i = 0; i < mMobileSignalControllers.size(); i++) {
+                    MobileSignalController controller = mMobileSignalControllers.valueAt(i);
+                    controller.handleBroadcast(intent);
                 }
-            });
-        } else {
-            int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
-                    SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-            if (SubscriptionManager.isValidSubscriptionId(subId)) {
-                if (mMobileSignalControllers.indexOfKey(subId) >= 0) {
-                    mMobileSignalControllers.get(subId).handleBroadcast(intent);
+                break;
+            case TelephonyIntents.ACTION_SIM_STATE_CHANGED:
+                // Avoid rebroadcast because SysUI is direct boot aware.
+                if (intent.getBooleanExtra(TelephonyIntents.EXTRA_REBROADCAST_ON_UNLOCK, false)) {
+                    break;
+                }
+                // Might have different subscriptions now.
+                updateMobileControllers();
+                break;
+            case TelephonyIntents.ACTION_SERVICE_STATE_CHANGED:
+                mLastServiceState = ServiceState.newFromBundle(intent.getExtras());
+                if (mMobileSignalControllers.size() == 0) {
+                    // If none of the subscriptions are active, we might need to recalculate
+                    // emergency state.
+                    recalculateEmergency();
+                }
+                break;
+            case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED:
+                mConfig = Config.readConfig(mContext);
+                mReceiverHandler.post(this::handleConfigurationChanged);
+                break;
+            default:
+                int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
+                        SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+                if (SubscriptionManager.isValidSubscriptionId(subId)) {
+                    if (mMobileSignalControllers.indexOfKey(subId) >= 0) {
+                        mMobileSignalControllers.get(subId).handleBroadcast(intent);
+                    } else {
+                        // Can't find this subscription...  We must be out of date.
+                        updateMobileControllers();
+                    }
                 } else {
-                    // Can't find this subscription...  We must be out of date.
-                    updateMobileControllers();
+                    // No sub id, must be for the wifi.
+                    mWifiSignalController.handleBroadcast(intent);
                 }
-            } else {
-                // No sub id, must be for the wifi.
-                mWifiSignalController.handleBroadcast(intent);
-            }
+                break;
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index 179c0d5..a794e19 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -60,6 +60,8 @@
 import com.android.systemui.statusbar.notification.NotificationViewWrapper;
 import com.android.systemui.statusbar.stack.StackStateAnimator;
 
+import java.util.function.Consumer;
+
 /**
  * Host for the remote input.
  */
@@ -90,6 +92,7 @@
 
     private boolean mResetting;
     private NotificationViewWrapper mWrapper;
+    private Consumer<Boolean> mOnVisibilityChangedListener;
 
     public RemoteInputView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -451,6 +454,18 @@
         mWrapper = wrapper;
     }
 
+    public void setOnVisibilityChangedListener(Consumer<Boolean> visibilityChangedListener) {
+        mOnVisibilityChangedListener = visibilityChangedListener;
+    }
+
+    @Override
+    protected void onVisibilityChanged(View changedView, int visibility) {
+        super.onVisibilityChanged(changedView, visibility);
+        if (changedView == this && mOnVisibilityChangedListener != null) {
+            mOnVisibilityChangedListener.accept(visibility == VISIBLE);
+        }
+    }
+
     /**
      * An EditText that changes appearance based on whether it's focusable and becomes
      * un-focusable whenever the user navigates away from it or it becomes invisible.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
index d7a810e..0f637fb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
@@ -220,8 +220,7 @@
     }
 
     public int getInnerHeight() {
-        return Math.max(Math.min(mLayoutHeight, mMaxLayoutHeight) - mTopPadding
-                - mExpandAnimationTopChange, mLayoutMinHeight);
+        return Math.max(Math.min(mLayoutHeight, mMaxLayoutHeight) - mTopPadding, mLayoutMinHeight);
     }
 
     public boolean isShadeExpanded() {
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 4ca33cd..ac2a1e1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
@@ -120,6 +120,7 @@
         super(context, attrs, defStyleAttr, defStyleRes);
         initDimens();
         mHybridGroupManager = new HybridGroupManager(getContext(), this);
+        setClipChildren(false);
     }
 
     private void initDimens() {
@@ -134,7 +135,7 @@
                 R.dimen.notification_children_container_top_padding);
         mHeaderHeight = mNotificationHeaderMargin + mNotificatonTopPadding;
         mCollapsedBottompadding = res.getDimensionPixelSize(
-                com.android.internal.R.dimen.notification_content_margin_bottom);
+                com.android.internal.R.dimen.notification_content_margin);
         mEnableShadowOnChildNotifications =
                 res.getBoolean(R.bool.config_enableShadowOnChildNotifications);
         mShowDividersWhenExpanded =
@@ -533,11 +534,12 @@
 
     /**
      * Update the state of all its children based on a linear layout algorithm.
-     *
-     * @param resultState the state to update
+     *  @param resultState the state to update
      * @param parentState the state of the parent
+     * @param ambientState
      */
-    public void getState(StackScrollState resultState, ExpandableViewState parentState) {
+    public void getState(StackScrollState resultState, ExpandableViewState parentState,
+            AmbientState ambientState) {
         int childCount = mChildren.size();
         int yPosition = mNotificationHeaderMargin;
         boolean firstChild = true;
@@ -553,6 +555,7 @@
 
         boolean childrenExpandedAndNotAnimating = mChildrenExpanded
                 && !mContainingNotification.isGroupExpansionChanging();
+        int launchTransitionCompensation = 0;
         for (int i = 0; i < childCount; i++) {
             ExpandableNotificationRow child = mChildren.get(i);
             if (!firstChild) {
@@ -577,13 +580,13 @@
             ExpandableViewState childState = resultState.getViewStateForView(child);
             int intrinsicHeight = child.getIntrinsicHeight();
             childState.height = intrinsicHeight;
-            childState.yTranslation = yPosition;
+            childState.yTranslation = yPosition + launchTransitionCompensation;
             childState.hidden = false;
             // When the group is expanded, the children cast the shadows rather than the parent
             // so use the parent's elevation here.
             childState.zTranslation =
                     (childrenExpandedAndNotAnimating && mEnableShadowOnChildNotifications)
-                    ? mContainingNotification.getTranslationZ()
+                    ? parentState.zTranslation
                     : 0;
             childState.dimmed = parentState.dimmed;
             childState.dark = parentState.dark;
@@ -600,6 +603,9 @@
             childState.location = parentState.location;
             childState.inShelf = parentState.inShelf;
             yPosition += intrinsicHeight;
+            if (child.isExpandAnimationRunning()) {
+                launchTransitionCompensation = -ambientState.getExpandAnimationTopChange();
+            }
 
         }
         if (mOverflowNumber != null) {
@@ -637,7 +643,7 @@
             }
             mHeaderViewState.initFrom(mNotificationHeader);
             mHeaderViewState.zTranslation = childrenExpandedAndNotAnimating
-                    ? mContainingNotification.getTranslationZ()
+                    ? parentState.zTranslation
                     : 0;
         }
     }
@@ -727,6 +733,9 @@
     }
 
     private void updateChildrenClipping() {
+        if (mContainingNotification.hasExpandingChild()) {
+            return;
+        }
         int childCount = mChildren.size();
         int layoutEnd = mContainingNotification.getActualHeight() - mClipBottomAmount;
         for (int i = 0; i < childCount; i++) {
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 1b55a5b..66fde79 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -1394,6 +1394,7 @@
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
+        mStatusBarHeight = getResources().getDimensionPixelOffset(R.dimen.status_bar_height);
         float densityScale = getResources().getDisplayMetrics().density;
         mSwipeHelper.setDensityScale(densityScale);
         float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
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 d68a7b1..51737a8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -91,17 +91,18 @@
         updateClipping(resultState, algorithmState, ambientState);
         updateSpeedBumpState(resultState, algorithmState, ambientState);
         updateShelfState(resultState, ambientState);
-        getNotificationChildrenStates(resultState, algorithmState);
+        getNotificationChildrenStates(resultState, algorithmState, ambientState);
     }
 
     private void getNotificationChildrenStates(StackScrollState resultState,
-            StackScrollAlgorithmState algorithmState) {
+            StackScrollAlgorithmState algorithmState,
+            AmbientState ambientState) {
         int childCount = algorithmState.visibleChildren.size();
         for (int i = 0; i < childCount; i++) {
             ExpandableView v = algorithmState.visibleChildren.get(i);
             if (v instanceof ExpandableNotificationRow) {
                 ExpandableNotificationRow row = (ExpandableNotificationRow) v;
-                row.getChildrenStates(resultState);
+                row.getChildrenStates(resultState, ambientState);
             }
         }
     }
@@ -323,7 +324,9 @@
         }
         ExpandableNotificationRow expandingNotification = ambientState.getExpandingNotification();
         state.indexOfExpandingNotification = expandingNotification != null
-                ? state.visibleChildren.indexOf(expandingNotification)
+                ? expandingNotification.isChildInGroup()
+                    ? state.visibleChildren.indexOf(expandingNotification.getNotificationParent())
+                    : state.visibleChildren.indexOf(expandingNotification)
                 : -1;
     }
 
@@ -386,7 +389,7 @@
 
         childViewState.location = ExpandableViewState.LOCATION_MAIN_AREA;
         float inset = ambientState.getTopPadding() + ambientState.getStackTranslation();
-        if (i < algorithmState.getIndexOfExpandingNotification()) {
+        if (i <= algorithmState.getIndexOfExpandingNotification()) {
             inset += ambientState.getExpandAnimationTopChange();
         }
         if (child.mustStayOnScreen() && childViewState.yTranslation >= 0) {
@@ -515,7 +518,7 @@
                 - ambientState.getShelf().getIntrinsicHeight();
         childViewState.yTranslation = Math.min(childViewState.yTranslation, shelfStart);
         if (childViewState.yTranslation >= shelfStart) {
-            childViewState.hidden = !child.isExpandAnimationRunning();
+            childViewState.hidden = !child.isExpandAnimationRunning() && !child.hasExpandingChild();
             childViewState.inShelf = true;
             childViewState.headsUpIsVisible = false;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/OutputChooserDialog.java b/packages/SystemUI/src/com/android/systemui/volume/OutputChooserDialog.java
deleted file mode 100644
index 6ed07f8..0000000
--- a/packages/SystemUI/src/com/android/systemui/volume/OutputChooserDialog.java
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 static android.support.v7.media.MediaRouter.RouteInfo.CONNECTION_STATE_CONNECTED;
-import static android.support.v7.media.MediaRouter.RouteInfo.CONNECTION_STATE_CONNECTING;
-import static android.support.v7.media.MediaRouter.UNSELECT_REASON_DISCONNECTED;
-
-import static com.android.settingslib.bluetooth.Utils.getBtClassDrawableWithDescription;
-
-import android.app.Dialog;
-import android.bluetooth.BluetoothClass;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothProfile;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemClock;
-import android.support.v7.media.MediaControlIntent;
-import android.support.v7.media.MediaRouteSelector;
-import android.support.v7.media.MediaRouter;
-import android.telecom.TelecomManager;
-import android.util.Log;
-import android.util.Pair;
-import android.view.Window;
-import android.view.WindowManager;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settingslib.Utils;
-import com.android.settingslib.bluetooth.CachedBluetoothDevice;
-import com.android.systemui.Dependency;
-import com.android.systemui.HardwareUiLayout;
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
-import com.android.systemui.plugins.VolumeDialogController;
-import com.android.systemui.statusbar.policy.BluetoothController;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.List;
-
-public class OutputChooserDialog extends Dialog
-        implements DialogInterface.OnDismissListener, OutputChooserLayout.Callback {
-
-    private static final String TAG = Util.logTag(OutputChooserDialog.class);
-    private static final int MAX_DEVICES = 10;
-
-    private static final long UPDATE_DELAY_MS = 300L;
-    private static final int MSG_UPDATE_ITEMS = 1;
-
-    private final Context mContext;
-    private final BluetoothController mBluetoothController;
-    private WifiManager mWifiManager;
-    private OutputChooserLayout mView;
-    private final MediaRouterWrapper mRouter;
-    private final MediaRouterCallback mRouterCallback;
-    private long mLastUpdateTime;
-    static final boolean INCLUDE_MEDIA_ROUTES = false;
-    private boolean mIsInCall;
-    protected boolean isAttached;
-
-    private final MediaRouteSelector mRouteSelector;
-    private Drawable mDefaultIcon;
-    private Drawable mTvIcon;
-    private Drawable mSpeakerIcon;
-    private Drawable mSpeakerGroupIcon;
-    private HardwareUiLayout mHardwareLayout;
-    private final VolumeDialogController mController;
-
-    public OutputChooserDialog(Context context, MediaRouterWrapper router) {
-        super(context, com.android.systemui.R.style.qs_theme);
-        mContext = context;
-        mBluetoothController = Dependency.get(BluetoothController.class);
-        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
-        TelecomManager tm = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
-        mIsInCall = tm.isInCall();
-        mRouter = router;
-        mRouterCallback = new MediaRouterCallback();
-        mRouteSelector = new MediaRouteSelector.Builder()
-                .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
-                .build();
-
-        final IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
-        context.registerReceiver(mReceiver, filter);
-
-        mController = Dependency.get(VolumeDialogController.class);
-
-        // Window initialization
-        Window window = getWindow();
-        window.requestFeature(Window.FEATURE_NO_TITLE);
-        window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
-        window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND
-                | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
-        window.addFlags(
-                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                        | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
-                        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
-                        | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
-        window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
-    }
-
-    protected void setIsInCall(boolean inCall) {
-        mIsInCall = inCall;
-    }
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.output_chooser);
-        setCanceledOnTouchOutside(true);
-        setOnDismissListener(this::onDismiss);
-
-        mView = findViewById(R.id.output_chooser);
-        mHardwareLayout = HardwareUiLayout.get(mView);
-        mHardwareLayout.setOutsideTouchListener(view -> dismiss());
-        mHardwareLayout.setSwapOrientation(false);
-        mView.setCallback(this);
-
-        if (mIsInCall) {
-            mView.setTitle(R.string.output_calls_title);
-        } else {
-            mView.setTitle(R.string.output_title);
-        }
-
-        mDefaultIcon = mContext.getDrawable(R.drawable.ic_cast);
-        mTvIcon = mContext.getDrawable(R.drawable.ic_tv);
-        mSpeakerIcon = mContext.getDrawable(R.drawable.ic_speaker);
-        mSpeakerGroupIcon = mContext.getDrawable(R.drawable.ic_speaker_group);
-
-        final boolean wifiOff = !mWifiManager.isWifiEnabled();
-        final boolean btOff = !mBluetoothController.isBluetoothEnabled();
-        if (wifiOff && btOff) {
-            mView.setEmptyState(getDisabledServicesMessage(wifiOff, btOff));
-        }
-        // time out after 5 seconds
-        mView.postDelayed(() -> updateItems(true), 5000);
-    }
-
-    protected void cleanUp() {}
-
-
-    @Override
-    protected void onStart() {
-        super.onStart();
-    }
-
-    @Override
-    public void onAttachedToWindow() {
-        super.onAttachedToWindow();
-
-        if (!mIsInCall && INCLUDE_MEDIA_ROUTES) {
-            mRouter.addCallback(mRouteSelector, mRouterCallback,
-                    MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
-        }
-        mBluetoothController.addCallback(mCallback);
-        mController.addCallback(mControllerCallbackH, mHandler);
-        isAttached = true;
-    }
-
-    @Override
-    public void onDetachedFromWindow() {
-        isAttached = false;
-        mRouter.removeCallback(mRouterCallback);
-        mController.removeCallback(mControllerCallbackH);
-        mBluetoothController.removeCallback(mCallback);
-        super.onDetachedFromWindow();
-    }
-
-    @Override
-    public void onDismiss(DialogInterface unused) {
-        mContext.unregisterReceiver(mReceiver);
-        cleanUp();
-    }
-
-    @Override
-    public void show() {
-        super.show();
-        Dependency.get(MetricsLogger.class).visible(MetricsProto.MetricsEvent.OUTPUT_CHOOSER);
-        mHardwareLayout.setTranslationX(getAnimTranslation());
-        mHardwareLayout.setAlpha(0);
-        mHardwareLayout.animate()
-                .alpha(1)
-                .translationX(0)
-                .setDuration(300)
-                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
-                .withEndAction(() -> getWindow().getDecorView().requestAccessibilityFocus())
-                .start();
-    }
-
-    @Override
-    public void dismiss() {
-        Dependency.get(MetricsLogger.class).hidden(MetricsProto.MetricsEvent.OUTPUT_CHOOSER);
-        mHardwareLayout.setTranslationX(0);
-        mHardwareLayout.setAlpha(1);
-        mHardwareLayout.animate()
-                .alpha(0)
-                .translationX(getAnimTranslation())
-                .setDuration(300)
-                .withEndAction(() -> super.dismiss())
-                .setInterpolator(new SystemUIInterpolators.LogAccelerateInterpolator())
-                .start();
-    }
-
-    private float getAnimTranslation() {
-        return getContext().getResources().getDimension(
-                com.android.systemui.R.dimen.output_chooser_panel_width) / 2;
-    }
-
-    @Override
-    public void onDetailItemClick(OutputChooserLayout.Item item) {
-        if (item == null || item.tag == null) return;
-        if (item.deviceType == OutputChooserLayout.Item.DEVICE_TYPE_BT) {
-            final CachedBluetoothDevice device = (CachedBluetoothDevice) item.tag;
-            if (device.getMaxConnectionState() == BluetoothProfile.STATE_DISCONNECTED) {
-                Dependency.get(MetricsLogger.class).action(
-                        MetricsProto.MetricsEvent.ACTION_OUTPUT_CHOOSER_CONNECT);
-                mBluetoothController.connect(device);
-            }
-        } else if (item.deviceType == OutputChooserLayout.Item.DEVICE_TYPE_MEDIA_ROUTER) {
-            final MediaRouter.RouteInfo route = (MediaRouter.RouteInfo) item.tag;
-            if (route.isEnabled()) {
-                Dependency.get(MetricsLogger.class).action(
-                        MetricsProto.MetricsEvent.ACTION_OUTPUT_CHOOSER_CONNECT);
-                route.select();
-            }
-        }
-    }
-
-    @Override
-    public void onDetailItemDisconnect(OutputChooserLayout.Item item) {
-        if (item == null || item.tag == null) return;
-        if (item.deviceType == OutputChooserLayout.Item.DEVICE_TYPE_BT) {
-            final CachedBluetoothDevice device = (CachedBluetoothDevice) item.tag;
-            Dependency.get(MetricsLogger.class).action(
-                    MetricsProto.MetricsEvent.ACTION_OUTPUT_CHOOSER_DISCONNECT);
-            mBluetoothController.disconnect(device);
-        } else if (item.deviceType == OutputChooserLayout.Item.DEVICE_TYPE_MEDIA_ROUTER) {
-            Dependency.get(MetricsLogger.class).action(
-                    MetricsProto.MetricsEvent.ACTION_OUTPUT_CHOOSER_DISCONNECT);
-            mRouter.unselect(UNSELECT_REASON_DISCONNECTED);
-        }
-    }
-
-    private void updateItems(boolean timeout) {
-        if (SystemClock.uptimeMillis() - mLastUpdateTime < UPDATE_DELAY_MS) {
-            mHandler.removeMessages(MSG_UPDATE_ITEMS);
-            mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_UPDATE_ITEMS, timeout),
-                    mLastUpdateTime + UPDATE_DELAY_MS);
-            return;
-        }
-        mLastUpdateTime = SystemClock.uptimeMillis();
-        if (mView == null) return;
-        ArrayList<OutputChooserLayout.Item> items = new ArrayList<>();
-
-        // Add bluetooth devices
-        addBluetoothDevices(items);
-
-        // Add remote displays
-        if (!mIsInCall && INCLUDE_MEDIA_ROUTES) {
-            addRemoteDisplayRoutes(items);
-        }
-
-        items.sort(ItemComparator.sInstance);
-
-        if (items.size() == 0 && timeout) {
-            String emptyMessage = mContext.getString(R.string.output_none_found);
-            final boolean wifiOff = !mWifiManager.isWifiEnabled();
-            final boolean btOff = !mBluetoothController.isBluetoothEnabled();
-            if (wifiOff || btOff) {
-                emptyMessage = getDisabledServicesMessage(wifiOff, btOff);
-            }
-            mView.setEmptyState(emptyMessage);
-        }
-
-        mView.setItems(items.toArray(new OutputChooserLayout.Item[items.size()]));
-    }
-
-    private String getDisabledServicesMessage(boolean wifiOff, boolean btOff) {
-        return mContext.getString(R.string.output_none_found_service_off,
-                wifiOff && btOff ? mContext.getString(R.string.output_service_bt_wifi)
-                        : wifiOff ? mContext.getString(R.string.output_service_wifi)
-                                : mContext.getString(R.string.output_service_bt));
-    }
-
-    private void addBluetoothDevices(List<OutputChooserLayout.Item> items) {
-        final Collection<CachedBluetoothDevice> devices = mBluetoothController.getDevices();
-        if (devices != null) {
-            int connectedDevices = 0;
-            int count = 0;
-            for (CachedBluetoothDevice device : devices) {
-                if (mBluetoothController.getBondState(device) == BluetoothDevice.BOND_NONE) continue;
-                final int majorClass = device.getBtClass().getMajorDeviceClass();
-                if (majorClass != BluetoothClass.Device.Major.AUDIO_VIDEO
-                        && majorClass != BluetoothClass.Device.Major.UNCATEGORIZED) {
-                    continue;
-                }
-                final OutputChooserLayout.Item item = new OutputChooserLayout.Item();
-                item.iconResId = R.drawable.ic_qs_bluetooth_on;
-                item.line1 = device.getName();
-                item.tag = device;
-                item.deviceType = OutputChooserLayout.Item.DEVICE_TYPE_BT;
-                int state = device.getMaxConnectionState();
-                if (state == BluetoothProfile.STATE_CONNECTED) {
-                    item.iconResId = R.drawable.ic_qs_bluetooth_connected;
-                    int batteryLevel = device.getBatteryLevel();
-                    if (batteryLevel != BluetoothDevice.BATTERY_LEVEL_UNKNOWN) {
-                        Pair<Drawable, String> pair =
-                                getBtClassDrawableWithDescription(getContext(), device);
-                        item.icon = pair.first;
-                        item.line2 = mContext.getString(
-                                R.string.quick_settings_connected_battery_level,
-                                Utils.formatPercentage(batteryLevel));
-                    } else {
-                        item.line2 = mContext.getString(R.string.quick_settings_connected);
-                    }
-                    item.canDisconnect = true;
-                    items.add(connectedDevices, item);
-                    connectedDevices++;
-                } else if (state == BluetoothProfile.STATE_CONNECTING) {
-                    item.iconResId = R.drawable.ic_qs_bluetooth_connecting;
-                    item.line2 = mContext.getString(R.string.quick_settings_connecting);
-                    items.add(connectedDevices, item);
-                } else {
-                    items.add(item);
-                }
-                if (++count == MAX_DEVICES) {
-                    break;
-                }
-            }
-        }
-    }
-
-    private void addRemoteDisplayRoutes(List<OutputChooserLayout.Item> items) {
-        List<MediaRouter.RouteInfo> routes = mRouter.getRoutes();
-        for(MediaRouter.RouteInfo route : routes) {
-            if (route.isDefaultOrBluetooth() || !route.isEnabled()
-                    || !route.matchesSelector(mRouteSelector)) {
-                continue;
-            }
-            final OutputChooserLayout.Item item = new OutputChooserLayout.Item();
-            item.icon = getIconDrawable(route);
-            item.line1 = route.getName();
-            item.tag = route;
-            item.deviceType = OutputChooserLayout.Item.DEVICE_TYPE_MEDIA_ROUTER;
-            if (route.getConnectionState() == CONNECTION_STATE_CONNECTING) {
-                mContext.getString(R.string.quick_settings_connecting);
-            } else {
-                item.line2 = route.getDescription();
-            }
-
-            if (route.getConnectionState() == CONNECTION_STATE_CONNECTED) {
-                item.canDisconnect = true;
-            }
-            items.add(item);
-        }
-    }
-
-    private Drawable getIconDrawable(MediaRouter.RouteInfo route) {
-        Uri iconUri = route.getIconUri();
-        if (iconUri != null) {
-            try {
-                InputStream is = getContext().getContentResolver().openInputStream(iconUri);
-                Drawable drawable = Drawable.createFromStream(is, null);
-                if (drawable != null) {
-                    return drawable;
-                }
-            } catch (IOException e) {
-                Log.w(TAG, "Failed to load " + iconUri, e);
-                // Falls back.
-            }
-        }
-        return getDefaultIconDrawable(route);
-    }
-
-    private Drawable getDefaultIconDrawable(MediaRouter.RouteInfo route) {
-        // If the type of the receiver device is specified, use it.
-        switch (route.getDeviceType()) {
-            case  MediaRouter.RouteInfo.DEVICE_TYPE_TV:
-                return mTvIcon;
-            case MediaRouter.RouteInfo.DEVICE_TYPE_SPEAKER:
-                return mSpeakerIcon;
-        }
-
-        // Otherwise, make the best guess based on other route information.
-        if (route instanceof MediaRouter.RouteGroup) {
-            // Only speakers can be grouped for now.
-            return mSpeakerGroupIcon;
-        }
-        return mDefaultIcon;
-    }
-
-    private final class MediaRouterCallback extends MediaRouter.Callback {
-        @Override
-        public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo info) {
-            updateItems(false);
-        }
-
-        @Override
-        public void onRouteRemoved(MediaRouter router, MediaRouter.RouteInfo info) {
-            updateItems(false);
-        }
-
-        @Override
-        public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo info) {
-            updateItems(false);
-        }
-
-        @Override
-        public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo route) {
-            updateItems(false);
-        }
-    }
-
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
-                if (D.BUG) Log.d(TAG, "Received ACTION_CLOSE_SYSTEM_DIALOGS");
-                cancel();
-                cleanUp();
-            }
-        }
-    };
-
-    private final BluetoothController.Callback mCallback = new BluetoothController.Callback() {
-        @Override
-        public void onBluetoothStateChange(boolean enabled) {
-            updateItems(false);
-        }
-
-        @Override
-        public void onBluetoothDevicesChanged() {
-            updateItems(false);
-        }
-    };
-
-    static final class ItemComparator implements Comparator<OutputChooserLayout.Item> {
-        public static final ItemComparator sInstance = new ItemComparator();
-
-        @Override
-        public int compare(OutputChooserLayout.Item lhs, OutputChooserLayout.Item rhs) {
-            // Connected item(s) first
-            if (lhs.canDisconnect != rhs.canDisconnect) {
-                return Boolean.compare(rhs.canDisconnect, lhs.canDisconnect);
-            }
-            // Bluetooth items before media routes
-            if (lhs.deviceType != rhs.deviceType) {
-                return Integer.compare(lhs.deviceType, rhs.deviceType);
-            }
-            // then by name
-            return lhs.line1.toString().compareToIgnoreCase(rhs.line1.toString());
-        }
-    }
-
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message message) {
-            switch (message.what) {
-                case MSG_UPDATE_ITEMS:
-                    updateItems((Boolean) message.obj);
-                    break;
-            }
-        }
-    };
-
-    private final VolumeDialogController.Callbacks mControllerCallbackH
-            = new VolumeDialogController.Callbacks() {
-        @Override
-        public void onShowRequested(int reason) {
-            dismiss();
-        }
-
-        @Override
-        public void onDismissRequested(int reason) {}
-
-        @Override
-        public void onScreenOff() {
-            dismiss();
-        }
-
-        @Override
-        public void onStateChanged(VolumeDialogController.State state) {}
-
-        @Override
-        public void onLayoutDirectionChanged(int layoutDirection) {}
-
-        @Override
-        public void onConfigurationChanged() {}
-
-        @Override
-        public void onShowVibrateHint() {}
-
-        @Override
-        public void onShowSilentHint() {}
-
-        @Override
-        public void onShowSafetyWarning(int flags) {}
-
-        @Override
-        public void onAccessibilityModeChanged(Boolean showA11yStream) {}
-
-        @Override
-        public void onConnectedDeviceChanged(String deviceName) {}
-    };
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/volume/OutputChooserLayout.java b/packages/SystemUI/src/com/android/systemui/volume/OutputChooserLayout.java
deleted file mode 100644
index d4c6f89..0000000
--- a/packages/SystemUI/src/com/android/systemui/volume/OutputChooserLayout.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.content.Context;
-import android.content.res.Configuration;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.android.systemui.FontSizeUtils;
-import com.android.systemui.R;
-import com.android.systemui.qs.AutoSizingList;
-
-/**
- * Limited height list of devices.
- */
-public class OutputChooserLayout extends LinearLayout {
-    private static final String TAG = "OutputChooserLayout";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    private final Context mContext;
-    private final H mHandler = new H();
-    private final Adapter mAdapter = new Adapter();
-
-    private String mTag;
-    private Callback mCallback;
-    private boolean mItemsVisible = true;
-    private AutoSizingList mItemList;
-    private View mEmpty;
-    private TextView mEmptyText;
-    private TextView mTitle;
-
-    private Item[] mItems;
-
-    public OutputChooserLayout(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mContext = context;
-        mTag = TAG;
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        mItemList = findViewById(android.R.id.list);
-        mItemList.setVisibility(GONE);
-        mItemList.setAdapter(mAdapter);
-        mEmpty = findViewById(android.R.id.empty);
-        mEmpty.setVisibility(GONE);
-        mEmptyText = mEmpty.findViewById(R.id.empty_text);
-        mTitle = findViewById(R.id.title);
-    }
-
-    @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        FontSizeUtils.updateFontSize(mEmptyText, R.dimen.qs_detail_empty_text_size);
-        int count = mItemList.getChildCount();
-        for (int i = 0; i < count; i++) {
-            View item = mItemList.getChildAt(i);
-            FontSizeUtils.updateFontSize(item, R.id.empty_text,
-                    R.dimen.qs_detail_item_primary_text_size);
-            FontSizeUtils.updateFontSize(item, android.R.id.summary,
-                    R.dimen.qs_detail_item_secondary_text_size);
-            FontSizeUtils.updateFontSize(item, android.R.id.title,
-                    R.dimen.qs_detail_header_text_size);
-        }
-    }
-
-    public void setTitle(int title) {
-            mTitle.setText(title);
-    }
-
-    public void setEmptyState(String text) {
-        mEmptyText.setText(text);
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        if (DEBUG) Log.d(mTag, "onAttachedToWindow");
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        if (DEBUG) Log.d(mTag, "onDetachedFromWindow");
-        mCallback = null;
-    }
-
-    public void setCallback(Callback callback) {
-        mHandler.removeMessages(H.SET_CALLBACK);
-        mHandler.obtainMessage(H.SET_CALLBACK, callback).sendToTarget();
-    }
-
-    public void setItems(Item[] items) {
-        mHandler.removeMessages(H.SET_ITEMS);
-        mHandler.obtainMessage(H.SET_ITEMS, items).sendToTarget();
-    }
-
-    public void setItemsVisible(boolean visible) {
-        mHandler.removeMessages(H.SET_ITEMS_VISIBLE);
-        mHandler.obtainMessage(H.SET_ITEMS_VISIBLE, visible ? 1 : 0, 0).sendToTarget();
-    }
-
-    private void handleSetCallback(Callback callback) {
-        mCallback = callback;
-    }
-
-    private void handleSetItems(Item[] items) {
-        final int itemCount = items != null ? items.length : 0;
-        mEmpty.setVisibility(itemCount == 0 ? VISIBLE : GONE);
-        mItemList.setVisibility(itemCount == 0 ? GONE : VISIBLE);
-        mItems = items;
-        mAdapter.notifyDataSetChanged();
-    }
-
-    private void handleSetItemsVisible(boolean visible) {
-        if (mItemsVisible == visible) return;
-        mItemsVisible = visible;
-        for (int i = 0; i < mItemList.getChildCount(); i++) {
-            mItemList.getChildAt(i).setVisibility(mItemsVisible ? VISIBLE : INVISIBLE);
-        }
-    }
-
-    private class Adapter extends BaseAdapter {
-
-        @Override
-        public int getCount() {
-            return mItems != null ? mItems.length : 0;
-        }
-
-        @Override
-        public Object getItem(int position) {
-            return mItems[position];
-        }
-
-        @Override
-        public long getItemId(int position) {
-            return 0;
-        }
-
-        @Override
-        public View getView(int position, View view, ViewGroup parent) {
-            final Item item = mItems[position];
-            if (view == null) {
-                view = LayoutInflater.from(mContext).inflate(R.layout.output_chooser_item, parent,
-                        false);
-            }
-            view.setVisibility(mItemsVisible ? VISIBLE : INVISIBLE);
-            final ImageView iv = view.findViewById(android.R.id.icon);
-            if (item.icon != null) {
-                iv.setImageDrawable(item.icon);
-            } else {
-                iv.setImageResource(item.iconResId);
-            }
-            final TextView title = view.findViewById(android.R.id.title);
-            title.setText(item.line1);
-            final TextView summary =  view.findViewById(android.R.id.summary);
-            final boolean twoLines = !TextUtils.isEmpty(item.line2);
-            title.setMaxLines(twoLines ? 1 : 2);
-            summary.setVisibility(twoLines ? VISIBLE : GONE);
-            summary.setText(twoLines ? item.line2 : null);
-            view.setOnClickListener(v -> {
-                if (mCallback != null) {
-                    mCallback.onDetailItemClick(item);
-                }
-            });
-
-            final ImageView icon2 = view.findViewById(android.R.id.icon2);
-            if (item.canDisconnect) {
-                icon2.setImageResource(R.drawable.ic_qs_cancel);
-                icon2.setVisibility(VISIBLE);
-                icon2.setClickable(true);
-                icon2.setOnClickListener(v -> {
-                    if (mCallback != null) {
-                        mCallback.onDetailItemDisconnect(item);
-                    }
-                });
-            } else if (item.icon2 != -1) {
-                icon2.setVisibility(VISIBLE);
-                icon2.setImageResource(item.icon2);
-                icon2.setClickable(false);
-            } else {
-                icon2.setVisibility(GONE);
-            }
-
-            return view;
-        }
-    };
-
-    private class H extends Handler {
-        private static final int SET_ITEMS = 1;
-        private static final int SET_CALLBACK = 2;
-        private static final int SET_ITEMS_VISIBLE = 3;
-
-        public H() {
-            super(Looper.getMainLooper());
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            if (msg.what == SET_ITEMS) {
-                handleSetItems((Item[]) msg.obj);
-            } else if (msg.what == SET_CALLBACK) {
-                handleSetCallback((OutputChooserLayout.Callback) msg.obj);
-            } else if (msg.what == SET_ITEMS_VISIBLE) {
-                handleSetItemsVisible(msg.arg1 != 0);
-            }
-        }
-    }
-
-    public static class Item {
-        public static int DEVICE_TYPE_BT = 1;
-        public static int DEVICE_TYPE_MEDIA_ROUTER = 2;
-        public int iconResId;
-        public Drawable icon;
-        public Drawable overlay;
-        public CharSequence line1;
-        public CharSequence line2;
-        public Object tag;
-        public boolean canDisconnect;
-        public int icon2 = -1;
-        public int deviceType = 0;
-    }
-
-    public interface Callback {
-        void onDetailItemClick(Item item);
-        void onDetailItemDisconnect(Item item);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index 3c29b77..7c71b2a 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -110,11 +110,7 @@
     private boolean mShowA11yStream;
     private boolean mShowVolumeDialog;
     private boolean mShowSafetyWarning;
-    private DeviceCallback mDeviceCallback = new DeviceCallback();
     private final NotificationManager mNotificationManager;
-    @GuardedBy("mLock")
-    private List<AudioDeviceInfo> mConnectedDevices = new ArrayList<>();
-    private Object mLock = new Object();
 
     private boolean mDestroyed;
     private VolumePolicy mVolumePolicy;
@@ -192,7 +188,6 @@
         } catch (SecurityException e) {
             Log.w(TAG, "No access to media sessions", e);
         }
-        mAudio.registerAudioDeviceCallback(mDeviceCallback, mWorker);
     }
 
     public void setVolumePolicy(VolumePolicy policy) {
@@ -218,7 +213,6 @@
         mMediaSessions.destroy();
         mObserver.destroy();
         mReceiver.destroy();
-        mAudio.unregisterAudioDeviceCallback(mDeviceCallback);
         mWorkerThread.quitSafely();
     }
 
@@ -842,18 +836,6 @@
                 });
             }
         }
-
-        @Override
-        public void onConnectedDeviceChanged(String deviceName) {
-            for (final Map.Entry<Callbacks, Handler> entry : mCallbackMap.entrySet()) {
-                entry.getValue().post(new Runnable() {
-                    @Override
-                    public void run() {
-                        entry.getKey().onConnectedDeviceChanged(deviceName);
-                    }
-                });
-            }
-        }
     }
 
 
@@ -1060,33 +1042,6 @@
         }
     }
 
-    protected final class DeviceCallback extends AudioDeviceCallback {
-        public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
-            synchronized (mLock) {
-                for (AudioDeviceInfo info : addedDevices) {
-                    if (info.isSink()
-                            && (info.getType() == AudioDeviceInfo.TYPE_BLUETOOTH_A2DP
-                            || info.getType() == AudioDeviceInfo.TYPE_BLUETOOTH_SCO)) {
-                        mConnectedDevices.add(info);
-                        mCallbacks.onConnectedDeviceChanged(info.getProductName().toString());
-                    }
-                }
-            }
-        }
-
-        public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
-            synchronized (mLock) {
-                for (AudioDeviceInfo info : removedDevices) {
-                    mConnectedDevices.remove(info);
-                }
-
-                if (mConnectedDevices.size() == 0) {
-                    mCallbacks.onConnectedDeviceChanged(null);
-                }
-            }
-        }
-    }
-
     public interface UserActivityListener {
         void onUserActivity();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 1e8e98c..90a9fc8 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -18,22 +18,22 @@
 
 import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
 import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_GENERIC;
+import static android.media.AudioManager.RINGER_MODE_MAX;
+import static android.media.AudioManager.RINGER_MODE_NORMAL;
+import static android.media.AudioManager.RINGER_MODE_SILENT;
+import static android.media.AudioManager.RINGER_MODE_VIBRATE;
 import static android.media.AudioManager.STREAM_ACCESSIBILITY;
 
-import static com.android.systemui.volume.Events.DISMISS_REASON_OUTPUT_CHOOSER;
 import static com.android.systemui.volume.Events.DISMISS_REASON_SETTINGS_CLICKED;
-import static com.android.systemui.volume.Events.DISMISS_REASON_TOUCH_OUTSIDE;
 
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.animation.ObjectAnimator;
-import android.annotation.NonNull;
 import android.annotation.SuppressLint;
 import android.app.Dialog;
 import android.app.KeyguardManager;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.content.pm.PackageManager;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.graphics.Color;
@@ -48,9 +48,7 @@
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.provider.Settings.Global;
-import android.support.v7.media.MediaRouter;
 import android.text.InputFilter;
-import android.text.TextUtils;
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseBooleanArray;
@@ -60,7 +58,6 @@
 import android.view.View;
 import android.view.View.AccessibilityDelegate;
 import android.view.View.OnAttachStateChangeListener;
-import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.view.Window;
 import android.view.WindowManager;
@@ -72,9 +69,11 @@
 import android.widget.SeekBar;
 import android.widget.SeekBar.OnSeekBarChangeListener;
 import android.widget.TextView;
+import android.widget.Toast;
 
 import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
+import com.android.systemui.Prefs;
 import com.android.systemui.R;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.VolumeDialog;
@@ -108,18 +107,16 @@
     private CustomDialog mDialog;
     private ViewGroup mDialogView;
     private ViewGroup mDialogRowsView;
-    private ViewGroup mFooter;
+    private ViewGroup mRinger;
     private ImageButton mRingerIcon;
+    private ImageButton mSettingsIcon;
     private ImageView mZenIcon;
-    private TextView mRingerStatus;
-    private TextView mRingerTitle;
     private final List<VolumeRow> mRows = new ArrayList<>();
     private ConfigurableTexts mConfigurableTexts;
     private final SparseBooleanArray mDynamic = new SparseBooleanArray();
     private final KeyguardManager mKeyguard;
     private final AccessibilityManagerWrapper mAccessibilityMgr;
     private final Object mSafetyWarningLock = new Object();
-    private final Object mOutputChooserLock = new Object();
     private final Accessibility mAccessibility = new Accessibility();
     private final ColorStateList mActiveSliderTint;
     private final ColorStateList mInactiveSliderTint;
@@ -133,7 +130,6 @@
     private boolean mSilentMode = VolumePrefs.DEFAULT_ENABLE_SILENT_MODE;
     private State mState;
     private SafetyWarningDialog mSafetyWarning;
-    private OutputChooserDialog mOutputChooserDialog;
     private boolean mHovering = false;
 
     public VolumeDialogImpl(Context context) {
@@ -215,11 +211,10 @@
         uiLayout.updateRotation();
 
         mDialogRowsView = mDialog.findViewById(R.id.volume_dialog_rows);
-        mFooter = mDialog.findViewById(R.id.footer);
-        mRingerIcon = mFooter.findViewById(R.id.ringer_icon);
-        mRingerStatus = mFooter.findViewById(R.id.ringer_status);
-        mRingerTitle = mFooter.findViewById(R.id.ringer_title);
-        mZenIcon = mFooter.findViewById(R.id.dnd_icon);
+        mRinger = mDialog.findViewById(R.id.ringer);
+        mRingerIcon = mRinger.findViewById(R.id.ringer_icon);
+        mZenIcon = mRinger.findViewById(R.id.dnd_icon);
+        mSettingsIcon = mDialog.findViewById(R.id.settings);
 
         if (mRows.isEmpty()) {
             addRow(AudioManager.STREAM_MUSIC,
@@ -244,6 +239,7 @@
 
         updateRowsH(getActiveRow());
         initRingerH();
+        initSettingsH();
     }
 
     protected ViewGroup getDialogView() {
@@ -358,10 +354,6 @@
         row.slider.setOnSeekBarChangeListener(new VolumeSeekBarChangeListener(row));
         row.anim = null;
 
-        row.outputChooser = row.view.findViewById(R.id.output_chooser);
-        row.outputChooser.setOnClickListener(mClickOutputChooser);
-        row.connectedDevice = row.view.findViewById(R.id.volume_row_connected_device);
-
         row.icon = row.view.findViewById(R.id.volume_row_icon);
         row.icon.setImageResource(iconRes);
         if (row.stream != AudioSystem.STREAM_ACCESSIBILITY) {
@@ -396,6 +388,15 @@
         }
     }
 
+    public void initSettingsH() {
+        mSettingsIcon.setOnClickListener(v -> {
+            Intent intent = new Intent(Settings.ACTION_SOUND_SETTINGS);
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            dismissH(DISMISS_REASON_SETTINGS_CLICKED);
+            Dependency.get(ActivityStarter.class).startActivity(intent, true /* dismissShade */);
+        });
+    }
+
     public void initRingerH() {
         mRingerIcon.setOnClickListener(v -> {
             Events.writeEvent(mContext, Events.EVENT_ICON_CLICK, AudioManager.STREAM_RING,
@@ -406,34 +407,55 @@
             }
             // normal -> vibrate -> silent -> normal (skip vibrate if device doesn't have
             // a vibrator.
+            int newRingerMode;
             final boolean hasVibrator = mController.hasVibrator();
             if (mState.ringerModeInternal == AudioManager.RINGER_MODE_NORMAL) {
                 if (hasVibrator) {
                     mController.vibrate();
-                    mController.setRingerMode(AudioManager.RINGER_MODE_VIBRATE, false);
+                    newRingerMode = AudioManager.RINGER_MODE_VIBRATE;
                 } else {
-                    mController.setRingerMode(AudioManager.RINGER_MODE_SILENT, false);
+                    newRingerMode = AudioManager.RINGER_MODE_SILENT;
                 }
             } else if (mState.ringerModeInternal == AudioManager.RINGER_MODE_VIBRATE) {
-                mController.setRingerMode(AudioManager.RINGER_MODE_SILENT, false);
+                newRingerMode = AudioManager.RINGER_MODE_SILENT;
             } else {
-                mController.setRingerMode(AudioManager.RINGER_MODE_NORMAL, false);
+                newRingerMode = AudioManager.RINGER_MODE_NORMAL;
                 if (ss.level == 0) {
                     mController.setStreamVolume(AudioManager.STREAM_RING, 1);
                 }
             }
             updateRingerH();
-        });
-        mRingerIcon.setOnLongClickListener(v -> {
-            Intent intent = new Intent(Settings.ACTION_SOUND_SETTINGS);
-            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            dismissH(DISMISS_REASON_SETTINGS_CLICKED);
-            Dependency.get(ActivityStarter.class).startActivity(intent, true /* dismissShade */);
-            return true;
+
+            mController.setRingerMode(newRingerMode, false);
+            maybeShowToastH(newRingerMode);
         });
         updateRingerH();
     }
 
+    private void maybeShowToastH(int newRingerMode) {
+        int seenToastCount = Prefs.getInt(mContext, Prefs.Key.SEEN_RINGER_GUIDANCE_COUNT, 0);
+
+        if (seenToastCount > VolumePrefs.SHOW_RINGER_TOAST_COUNT) {
+            return;
+        }
+        int toastText;
+        switch (newRingerMode) {
+            case RINGER_MODE_NORMAL:
+                toastText = R.string.volume_dialog_ringer_guidance_ring;
+                break;
+            case RINGER_MODE_SILENT:
+                toastText = R.string.volume_dialog_ringer_guidance_silent;
+                break;
+            case RINGER_MODE_VIBRATE:
+            default:
+                toastText = R.string.volume_dialog_ringer_guidance_vibrate;
+        }
+
+        Toast.makeText(mContext, toastText, Toast.LENGTH_SHORT).show();
+        seenToastCount++;
+        Prefs.putInt(mContext, Prefs.Key.SEEN_RINGER_GUIDANCE_COUNT, seenToastCount);
+    }
+
     public void show(int reason) {
         mHandler.obtainMessage(H.SHOW, reason, 0).sendToTarget();
     }
@@ -501,15 +523,6 @@
         }
     }
 
-    private boolean isAttached() {
-        return mDialogView != null && mDialogView.isAttachedToWindow();
-    }
-
-    private boolean hasTouchFeature() {
-        final PackageManager pm = mContext.getPackageManager();
-        return pm.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN);
-    }
-
     private boolean shouldBeVisibleH(VolumeRow row, VolumeRow activeRow) {
         boolean isActive = row == activeRow;
         if (row.stream == AudioSystem.STREAM_ACCESSIBILITY) {
@@ -536,20 +549,12 @@
             final boolean isActive = row == activeRow;
             final boolean shouldBeVisible = shouldBeVisibleH(row, activeRow);
             Util.setVisOrGone(row.view, shouldBeVisible);
-            Util.setVisOrGone(row.header, shouldBeVisible);
             if (row.view.isShown()) {
                 updateVolumeRowSliderTintH(row, isActive);
             }
         }
     }
 
-    protected void updateConnectedDeviceH(String deviceName) {
-        for (final VolumeRow row : mRows) {
-            row.connectedDevice.setText(deviceName);
-            Util.setVisOrGone(row.connectedDevice, !TextUtils.isEmpty(deviceName));
-        }
-    }
-
     protected void updateRingerH() {
         if (mState != null) {
             final StreamState ss = mState.states.get(AudioManager.STREAM_RING);
@@ -560,12 +565,10 @@
             enableRingerViewsH(mState.zenMode == Global.ZEN_MODE_OFF || !mState.disallowRinger);
             switch (mState.ringerModeInternal) {
                 case AudioManager.RINGER_MODE_VIBRATE:
-                    mRingerStatus.setText(R.string.volume_ringer_status_vibrate);
                     mRingerIcon.setImageResource(R.drawable.ic_volume_ringer_vibrate);
                     mRingerIcon.setTag(Events.ICON_STATE_VIBRATE);
                     break;
                 case AudioManager.RINGER_MODE_SILENT:
-                    mRingerStatus.setText(R.string.volume_ringer_status_silent);
                     mRingerIcon.setImageResource(R.drawable.ic_volume_ringer_mute);
                     mRingerIcon.setContentDescription(mContext.getString(
                             R.string.volume_stream_content_description_unmute,
@@ -576,14 +579,12 @@
                 default:
                     boolean muted = (mAutomute && ss.level == 0) || ss.muted;
                     if (muted) {
-                        mRingerStatus.setText(R.string.volume_ringer_status_silent);
                         mRingerIcon.setImageResource(R.drawable.ic_volume_ringer_mute);
                         mRingerIcon.setContentDescription(mContext.getString(
                                 R.string.volume_stream_content_description_unmute,
                                 getStreamLabelH(ss)));
                         mRingerIcon.setTag(Events.ICON_STATE_MUTE);
                     } else {
-                        mRingerStatus.setText(R.string.volume_ringer_status_normal);
                         mRingerIcon.setImageResource(R.drawable.ic_volume_ringer);
                         if (mController.hasVibrator()) {
                             mRingerIcon.setContentDescription(mContext.getString(
@@ -603,12 +604,11 @@
     }
 
     /**
-     * Toggles enable state of views in a VolumeRow (not including seekbar, outputChooser or icon)
+     * Toggles enable state of views in a VolumeRow (not including seekbar or icon)
      * Hides/shows zen icon
      * @param enable whether to enable volume row views and hide dnd icon
      */
     private void enableVolumeRowViewsH(VolumeRow row, boolean enable) {
-        row.header.setEnabled(enable);
         row.dndIcon.setVisibility(enable ? View.GONE : View.VISIBLE);
     }
 
@@ -618,8 +618,6 @@
      * @param enable whether to enable ringer views and hide dnd icon
      */
     private void enableRingerViewsH(boolean enable) {
-        mRingerTitle.setEnabled(enable);
-        mRingerStatus.setEnabled(enable);
         mRingerIcon.setEnabled(enable);
         mZenIcon.setVisibility(enable ? View.GONE : View.VISIBLE);
     }
@@ -889,24 +887,6 @@
         rescheduleTimeoutH();
     }
 
-    private void showOutputChooserH() {
-        synchronized (mOutputChooserLock) {
-            if (mOutputChooserDialog != null) {
-                return;
-            }
-            mOutputChooserDialog = new OutputChooserDialog(mContext,
-                    new MediaRouterWrapper(MediaRouter.getInstance(mContext))) {
-                @Override
-                protected void cleanUp() {
-                    synchronized (mOutputChooserLock) {
-                        mOutputChooserDialog = null;
-                    }
-                }
-            };
-            mOutputChooserDialog.show();
-        }
-    }
-
     private String getStreamLabelH(StreamState ss) {
         if (ss.remoteLabel != null) {
             return ss.remoteLabel;
@@ -919,14 +899,6 @@
         }
     }
 
-    private final OnClickListener mClickOutputChooser = new OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            dismissH(DISMISS_REASON_OUTPUT_CHOOSER);
-            showOutputChooserH();
-        }
-    };
-
     private final VolumeDialogController.Callbacks mControllerCallbackH
             = new VolumeDialogController.Callbacks() {
         @Override
@@ -991,11 +963,6 @@
             }
 
         }
-
-        @Override
-        public void onConnectedDeviceChanged(String deviceName) {
-            updateConnectedDeviceH(deviceName);
-        }
     };
 
     private final class H extends Handler {
@@ -1184,8 +1151,6 @@
         private ObjectAnimator anim;  // slider progress animation for non-touch-related updates
         private int animTargetProgress;
         private int lastAudibleLevel = 1;
-        private View outputChooser;
-        private TextView connectedDevice;
         private ImageView dndIcon;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePrefs.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePrefs.java
index 04339eb..173400f 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePrefs.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePrefs.java
@@ -43,6 +43,8 @@
     public static final String PREF_ADJUST_ALARMS = "pref_adjust_alarms";
     public static final String PREF_ADJUST_NOTIFICATION = "pref_adjust_notification";
 
+    public static final int SHOW_RINGER_TOAST_COUNT = 9;
+
     public static final boolean DEFAULT_SHOW_HEADERS = true;
     public static final boolean DEFAULT_ENABLE_AUTOMUTE = true;
     public static final boolean DEFAULT_ENABLE_SILENT_MODE = true;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
new file mode 100644
index 0000000..7686948
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.keyguard;
+
+import android.graphics.Color;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.LayoutInflater;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWithLooper
+@RunWith(AndroidTestingRunner.class)
+public class KeyguardSliceViewTest extends SysuiTestCase {
+    private KeyguardSliceView mKeyguardSliceView;
+
+    @Before
+    public void setUp() throws Exception {
+        mKeyguardSliceView = (KeyguardSliceView) LayoutInflater.from(getContext())
+                .inflate(R.layout.keyguard_status_area, null);
+    }
+
+    @Test
+    public void getTextColor_whiteTextWhenAOD() {
+        // Set text color to red since the default is white and test would always pass
+        mKeyguardSliceView.setTextColor(Color.RED);
+        mKeyguardSliceView.setDark(0);
+        Assert.assertEquals("Should be using regular text color", Color.RED,
+                mKeyguardSliceView.getTextColor());
+        mKeyguardSliceView.setDark(1);
+        Assert.assertEquals("Should be using AOD text color", Color.WHITE,
+                mKeyguardSliceView.getTextColor());
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
new file mode 100644
index 0000000..21483aa
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.keyguard;
+
+import android.content.Intent;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+
+import com.android.internal.telephony.IccCardConstants;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class KeyguardUpdateMonitorTest extends SysuiTestCase {
+
+    private TestableLooper mTestableLooper;
+
+    @Before
+    public void setup() {
+        mTestableLooper = TestableLooper.get(this);
+    }
+
+    @Test
+    public void testIgnoresSimStateCallback_rebroadcast() {
+        Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
+
+        AtomicBoolean simStateChanged = new AtomicBoolean(false);
+        KeyguardUpdateMonitor keyguardUpdateMonitor = new KeyguardUpdateMonitor(getContext()) {
+            @Override
+            protected void handleSimStateChange(int subId, int slotId,
+                    IccCardConstants.State state) {
+                simStateChanged.set(true);
+                super.handleSimStateChange(subId, slotId, state);
+            }
+        };
+
+        keyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext(), intent);
+        mTestableLooper.processAllMessages();
+        Assert.assertTrue("onSimStateChanged not called", simStateChanged.get());
+
+        intent.putExtra(TelephonyIntents.EXTRA_REBROADCAST_ON_UNLOCK, true);
+        simStateChanged.set(false);
+        keyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext(), intent);
+        mTestableLooper.processAllMessages();
+        Assert.assertFalse("onSimStateChanged should have been skipped", simStateChanged.get());
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
index 943020c..18dd3c7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
@@ -16,6 +16,14 @@
 
 package com.android.systemui;
 
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import android.annotation.UserIdInt;
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -24,17 +32,14 @@
 import android.service.notification.StatusBarNotification;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.widget.RemoteViews;
+
 import com.android.internal.messages.nano.SystemMessageProto;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class ForegroundServiceControllerTest extends SysuiTestCase {
@@ -49,7 +54,7 @@
     }
 
     @Test
-    public void testNotificationCRUD() {
+    public void testNotificationCRUD_dungeon() {
         StatusBarNotification sbn_user1_app1_fg = makeMockFgSBN(USERID_ONE, "com.example.app1");
         StatusBarNotification sbn_user2_app2_fg = makeMockFgSBN(USERID_TWO, "com.example.app2");
         StatusBarNotification sbn_user1_app3_fg = makeMockFgSBN(USERID_ONE, "com.example.app3");
@@ -98,6 +103,101 @@
     }
 
     @Test
+    public void testNotificationCRUD_stdLayout() {
+        StatusBarNotification sbn_user1_app1_fg =
+                makeMockFgSBN(USERID_ONE, "com.example.app1", 0, true);
+        StatusBarNotification sbn_user2_app2_fg =
+                makeMockFgSBN(USERID_TWO, "com.example.app2", 1, true);
+        StatusBarNotification sbn_user1_app3_fg =
+                makeMockFgSBN(USERID_ONE, "com.example.app3", 2, true);
+        StatusBarNotification sbn_user1_app1 = makeMockSBN(USERID_ONE, "com.example.app1",
+                5000, "monkeys", Notification.FLAG_AUTO_CANCEL);
+        StatusBarNotification sbn_user2_app1 = makeMockSBN(USERID_TWO, "com.example.app1",
+                5000, "monkeys", Notification.FLAG_AUTO_CANCEL);
+
+        assertFalse(fsc.removeNotification(sbn_user1_app3_fg));
+        assertFalse(fsc.removeNotification(sbn_user2_app2_fg));
+        assertFalse(fsc.removeNotification(sbn_user1_app1_fg));
+        assertFalse(fsc.removeNotification(sbn_user1_app1));
+        assertFalse(fsc.removeNotification(sbn_user2_app1));
+
+        fsc.addNotification(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN);
+        fsc.addNotification(sbn_user2_app2_fg, NotificationManager.IMPORTANCE_MIN);
+        fsc.addNotification(sbn_user1_app3_fg, NotificationManager.IMPORTANCE_MIN);
+        fsc.addNotification(sbn_user1_app1, NotificationManager.IMPORTANCE_MIN);
+        fsc.addNotification(sbn_user2_app1, NotificationManager.IMPORTANCE_MIN);
+
+        // these are never added to the tracker
+        assertFalse(fsc.removeNotification(sbn_user1_app1));
+        assertFalse(fsc.removeNotification(sbn_user2_app1));
+
+        fsc.updateNotification(sbn_user1_app1, NotificationManager.IMPORTANCE_MIN);
+        fsc.updateNotification(sbn_user2_app1, NotificationManager.IMPORTANCE_MIN);
+        // should still not be there
+        assertFalse(fsc.removeNotification(sbn_user1_app1));
+        assertFalse(fsc.removeNotification(sbn_user2_app1));
+
+        fsc.updateNotification(sbn_user2_app2_fg, NotificationManager.IMPORTANCE_MIN);
+        fsc.updateNotification(sbn_user1_app3_fg, NotificationManager.IMPORTANCE_MIN);
+        fsc.updateNotification(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN);
+
+        assertTrue(fsc.removeNotification(sbn_user1_app3_fg));
+        assertFalse(fsc.removeNotification(sbn_user1_app3_fg));
+
+        assertTrue(fsc.removeNotification(sbn_user2_app2_fg));
+        assertFalse(fsc.removeNotification(sbn_user2_app2_fg));
+
+        assertTrue(fsc.removeNotification(sbn_user1_app1_fg));
+        assertFalse(fsc.removeNotification(sbn_user1_app1_fg));
+
+        assertFalse(fsc.removeNotification(sbn_user1_app1));
+        assertFalse(fsc.removeNotification(sbn_user2_app1));
+    }
+
+    @Test
+    public void testAppOpsCRUD() {
+        // no crash on remove that doesn't exist
+        fsc.onAppOpChanged(9, 1000, "pkg1", false);
+        assertNull(fsc.getAppOps(0, "pkg1"));
+
+        // multiuser & multipackage
+        fsc.onAppOpChanged(8, 50, "pkg1", true);
+        fsc.onAppOpChanged(1, 60, "pkg3", true);
+        fsc.onAppOpChanged(7, 500000, "pkg2", true);
+
+        assertEquals(1, fsc.getAppOps(0, "pkg1").size());
+        assertTrue(fsc.getAppOps(0, "pkg1").contains(8));
+
+        assertEquals(1, fsc.getAppOps(UserHandle.getUserId(500000), "pkg2").size());
+        assertTrue(fsc.getAppOps(UserHandle.getUserId(500000), "pkg2").contains(7));
+
+        assertEquals(1, fsc.getAppOps(0, "pkg3").size());
+        assertTrue(fsc.getAppOps(0, "pkg3").contains(1));
+
+        // multiple ops for the same package
+        fsc.onAppOpChanged(9, 50, "pkg1", true);
+        fsc.onAppOpChanged(5, 50, "pkg1", true);
+
+        assertEquals(3, fsc.getAppOps(0, "pkg1").size());
+        assertTrue(fsc.getAppOps(0, "pkg1").contains(8));
+        assertTrue(fsc.getAppOps(0, "pkg1").contains(9));
+        assertTrue(fsc.getAppOps(0, "pkg1").contains(5));
+
+        assertEquals(1, fsc.getAppOps(UserHandle.getUserId(500000), "pkg2").size());
+        assertTrue(fsc.getAppOps(UserHandle.getUserId(500000), "pkg2").contains(7));
+
+        // remove one of the multiples
+        fsc.onAppOpChanged(9, 50, "pkg1", false);
+        assertEquals(2, fsc.getAppOps(0, "pkg1").size());
+        assertTrue(fsc.getAppOps(0, "pkg1").contains(8));
+        assertTrue(fsc.getAppOps(0, "pkg1").contains(5));
+
+        // remove last op
+        fsc.onAppOpChanged(1, 60, "pkg3", false);
+        assertNull(fsc.getAppOps(0, "pkg3"));
+    }
+
+    @Test
     public void testDungeonPredicate() {
         StatusBarNotification sbn_user1_app1 = makeMockSBN(USERID_ONE, "com.example.app1",
                 5000, "monkeys", Notification.FLAG_AUTO_CANCEL);
@@ -252,6 +352,14 @@
         assertFalse(fsc.isDungeonNeededForUser(USERID_TWO));
         assertTrue(fsc.isDungeonNeededForUser(USERID_ONE));
 
+        // importance upgrade
+        fsc.addNotification(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN);
+        assertTrue(fsc.isDungeonNeededForUser(USERID_ONE));
+        assertFalse(fsc.isDungeonNeededForUser(USERID_TWO));
+        sbn_user1_app1.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
+        fsc.updateNotification(sbn_user1_app1_fg,
+                NotificationManager.IMPORTANCE_DEFAULT); // this is now a fg notification
+
         // finally, let's turn off the service
         fsc.addNotification(makeMockDungeon(USERID_ONE, null),
                 NotificationManager.IMPORTANCE_DEFAULT);
@@ -260,12 +368,71 @@
         assertFalse(fsc.isDungeonNeededForUser(USERID_TWO));
     }
 
+    @Test
+    public void testStdLayoutBasic() {
+        final String PKG1 = "com.example.app0";
+
+        StatusBarNotification sbn_user1_app1 = makeMockFgSBN(USERID_ONE, PKG1, 0, true);
+        sbn_user1_app1.getNotification().flags = 0;
+        StatusBarNotification sbn_user1_app1_fg = makeMockFgSBN(USERID_ONE, PKG1, 1, true);
+        fsc.addNotification(sbn_user1_app1, NotificationManager.IMPORTANCE_MIN); // not fg
+        assertTrue(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required!
+        fsc.addNotification(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN);
+        assertFalse(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // app1 has got it covered
+        assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, "otherpkg"));
+        // let's take out the non-fg notification and see what happens.
+        fsc.removeNotification(sbn_user1_app1);
+        // still covered by sbn_user1_app1_fg
+        assertFalse(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1));
+        assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, "anyPkg"));
+
+        // let's attempt to downgrade the notification from FLAG_FOREGROUND and see what we get
+        StatusBarNotification sbn_user1_app1_fg_sneaky = makeMockFgSBN(USERID_ONE, PKG1, 1, true);
+        sbn_user1_app1_fg_sneaky.getNotification().flags = 0;
+        fsc.updateNotification(sbn_user1_app1_fg_sneaky, NotificationManager.IMPORTANCE_MIN);
+        assertTrue(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required!
+        assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, "anything"));
+        // ok, ok, we'll put it back
+        sbn_user1_app1_fg_sneaky.getNotification().flags = Notification.FLAG_FOREGROUND_SERVICE;
+        fsc.updateNotification(sbn_user1_app1_fg, NotificationManager.IMPORTANCE_MIN);
+        assertFalse(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1));
+        assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, "whatever"));
+
+        assertTrue(fsc.removeNotification(sbn_user1_app1_fg_sneaky));
+        assertTrue(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required!
+        assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, "a"));
+
+        // let's try a custom layout
+        sbn_user1_app1_fg_sneaky = makeMockFgSBN(USERID_ONE, PKG1, 1, false);
+        fsc.updateNotification(sbn_user1_app1_fg_sneaky, NotificationManager.IMPORTANCE_MIN);
+        assertTrue(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1)); // should be required!
+        assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, "anything"));
+        // now let's test an upgrade (non fg to fg)
+        fsc.addNotification(sbn_user1_app1, NotificationManager.IMPORTANCE_MIN);
+        assertTrue(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1));
+        assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, "b"));
+        sbn_user1_app1.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
+        fsc.updateNotification(sbn_user1_app1,
+                NotificationManager.IMPORTANCE_MIN); // this is now a fg notification
+
+        assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, PKG1));
+        assertFalse(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1));
+
+        // remove it, make sure we're out of compliance again
+        assertTrue(fsc.removeNotification(sbn_user1_app1)); // was fg, should return true
+        assertFalse(fsc.removeNotification(sbn_user1_app1));
+        assertFalse(fsc.isSystemAlertWarningNeeded(USERID_TWO, PKG1));
+        assertTrue(fsc.isSystemAlertWarningNeeded(USERID_ONE, PKG1));
+    }
+
     private StatusBarNotification makeMockSBN(int userid, String pkg, int id, String tag,
             int flags) {
         final Notification n = mock(Notification.class);
+        n.extras = new Bundle();
         n.flags = flags;
         return makeMockSBN(userid, pkg, id, tag, n);
     }
+
     private StatusBarNotification makeMockSBN(int userid, String pkg, int id, String tag,
             Notification n) {
         final StatusBarNotification sbn = mock(StatusBarNotification.class);
@@ -278,9 +445,25 @@
         when(sbn.getKey()).thenReturn("MOCK:"+userid+"|"+pkg+"|"+id+"|"+tag);
         return sbn;
     }
+
+    private StatusBarNotification makeMockFgSBN(int userid, String pkg, int id,
+            boolean usesStdLayout) {
+        StatusBarNotification sbn =
+                makeMockSBN(userid, pkg, id, "foo", Notification.FLAG_FOREGROUND_SERVICE);
+        if (usesStdLayout) {
+            sbn.getNotification().contentView = null;
+            sbn.getNotification().headsUpContentView = null;
+            sbn.getNotification().bigContentView = null;
+        } else {
+            sbn.getNotification().contentView = mock(RemoteViews.class);
+        }
+        return sbn;
+    }
+
     private StatusBarNotification makeMockFgSBN(int userid, String pkg) {
         return makeMockSBN(userid, pkg, 1000, "foo", Notification.FLAG_FOREGROUND_SERVICE);
     }
+
     private StatusBarNotification makeMockDungeon(int userid, String[] pkgs) {
         final Notification n = mock(Notification.class);
         n.flags = Notification.FLAG_ONGOING_EVENT;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
index cd409d8..b6116e0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
@@ -16,10 +16,17 @@
 
 package com.android.systemui.keyguard;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+
 import androidx.app.slice.Slice;
+
+import android.app.AlarmManager;
+import android.content.ContentResolver;
 import android.content.Intent;
 import android.net.Uri;
-import android.os.Debug;
 import android.os.Handler;
 import android.support.test.filters.SmallTest;
 import android.testing.AndroidTestingRunner;
@@ -32,24 +39,31 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
 
 import androidx.app.slice.SliceItem;
 import androidx.app.slice.SliceProvider;
 import androidx.app.slice.SliceSpecs;
 import androidx.app.slice.core.SliceQuery;
-import androidx.app.slice.widget.SliceLiveData;
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper(setAsMainLooper = true)
 public class KeyguardSliceProviderTest extends SysuiTestCase {
 
+    @Mock
+    private ContentResolver mContentResolver;
+    @Mock
+    private AlarmManager mAlarmManager;
     private TestableKeyguardSliceProvider mProvider;
 
     @Before
     public void setup() {
+        MockitoAnnotations.initMocks(this);
         mProvider = new TestableKeyguardSliceProvider();
         mProvider.attachInfo(getContext(), null);
         SliceProvider.setSpecs(Arrays.asList(SliceSpecs.LIST));
@@ -70,7 +84,7 @@
 
     @Test
     public void returnsValidSlice() {
-        Slice slice = mProvider.onBindSlice(Uri.parse(KeyguardSliceProvider.KEYGUARD_SLICE_URI));
+        Slice slice = mProvider.onBindSlice(mProvider.getUri());
         SliceItem text = SliceQuery.find(slice, android.app.slice.SliceItem.FORMAT_TEXT,
                 android.app.slice.Slice.HINT_TITLE,
                 null /* nonHints */);
@@ -87,21 +101,52 @@
 
     @Test
     public void updatesClock() {
-        mProvider.mUpdateClockInvokations = 0;
         mProvider.mIntentReceiver.onReceive(getContext(), new Intent(Intent.ACTION_TIME_TICK));
         TestableLooper.get(this).processAllMessages();
-        Assert.assertEquals("Clock should have been updated.", 1 /* expected */,
-                mProvider.mUpdateClockInvokations);
+        verify(mContentResolver).notifyChange(eq(mProvider.getUri()), eq(null));
+    }
+
+    @Test
+    public void schedulesAlarm12hBefore() {
+        long in16Hours = System.currentTimeMillis() + TimeUnit.HOURS.toHours(16);
+        AlarmManager.AlarmClockInfo alarmClockInfo = new AlarmManager.AlarmClockInfo(in16Hours, null);
+        mProvider.onNextAlarmChanged(alarmClockInfo);
+
+        long twelveHours = TimeUnit.HOURS.toMillis(KeyguardSliceProvider.ALARM_VISIBILITY_HOURS);
+        long triggerAt = in16Hours - twelveHours;
+        verify(mAlarmManager).setExact(eq(AlarmManager.RTC), eq(triggerAt), anyString(), any(),
+                any());
+    }
+
+    @Test
+    public void updatingNextAlarmInvalidatesSlice() {
+        long in16Hours = System.currentTimeMillis() + TimeUnit.HOURS.toHours(8);
+        AlarmManager.AlarmClockInfo alarmClockInfo = new AlarmManager.AlarmClockInfo(in16Hours, null);
+        mProvider.onNextAlarmChanged(alarmClockInfo);
+
+        verify(mContentResolver).notifyChange(eq(mProvider.getUri()), eq(null));
     }
 
     private class TestableKeyguardSliceProvider extends KeyguardSliceProvider {
         int mCleanDateFormatInvokations;
-        int mUpdateClockInvokations;
+        private int mCounter;
 
         TestableKeyguardSliceProvider() {
             super(new Handler(TestableLooper.get(KeyguardSliceProviderTest.this).getLooper()));
         }
 
+        Uri getUri() {
+            return mSliceUri;
+        }
+
+        @Override
+        public boolean onCreateSliceProvider() {
+            super.onCreateSliceProvider();
+            mAlarmManager = KeyguardSliceProviderTest.this.mAlarmManager;
+            mContentResolver = KeyguardSliceProviderTest.this.mContentResolver;
+            return true;
+        }
+
         @Override
         void cleanDateFormat() {
             super.cleanDateFormat();
@@ -109,9 +154,8 @@
         }
 
         @Override
-        protected void updateClock() {
-            super.updateClock();
-            mUpdateClockInvokations++;
+        protected String getFormattedDate() {
+            return super.getFormattedDate() + mCounter++;
         }
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java
index 11491a75..2040e75 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java
@@ -54,7 +54,7 @@
         // Layout needs to leave space for the tile margins. Three times the margin size is
         // sufficient for any number of columns.
         mLayoutSizeForOneTile =
-                mContext.getResources().getDimensionPixelSize(R.dimen.qs_tile_margin) * 3;
+                mContext.getResources().getDimensionPixelSize(R.dimen.qs_tile_margin_horizontal) * 3;
     }
 
     private QSPanel.TileRecord createTileRecord() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/TouchAnimatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/TouchAnimatorTest.java
index 641cdc7..4cc0e20 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/TouchAnimatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/TouchAnimatorTest.java
@@ -56,6 +56,28 @@
     }
 
     @Test
+    public void testSetValueFloat_threeValues() {
+        TouchAnimator animator = new TouchAnimator.Builder()
+                .addFloat(mTestView, "x", 0, 20, 50)
+                .build();
+
+        animator.setPosition(0);
+        assertEquals(0f, mTestView.getX());
+
+        animator.setPosition(.25f);
+        assertEquals(10f, mTestView.getX());
+
+        animator.setPosition(.5f);
+        assertEquals(20f, mTestView.getX());
+
+        animator.setPosition(.75f);
+        assertEquals(35f, mTestView.getX());
+
+        animator.setPosition(1);
+        assertEquals(50f, mTestView.getX());
+    }
+
+    @Test
     public void testSetValueInt() {
         TouchAnimator animator = new TouchAnimator.Builder()
                 .addInt(mTestView, "top", 0, 50)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
index 1c9c794..6764634 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
@@ -37,6 +37,7 @@
 import android.content.Intent;
 import android.metrics.LogMaker;
 import android.support.test.filters.SmallTest;
+import android.support.test.InstrumentationRegistry;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
@@ -73,6 +74,7 @@
         mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
         mHost = mock(QSTileHost.class);
         when(mHost.indexOf(spec)).thenReturn(POSITION);
+        when(mHost.getContext()).thenReturn(mContext.getBaseContext());
 
         mTile = spy(new TileImpl(mHost));
         mTile.mHandler = mTile.new H(mTestableLooper.getLooper());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AppOpsListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AppOpsListenerTest.java
new file mode 100644
index 0000000..2a48c4b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AppOpsListenerTest.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.AppOpsManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import com.android.systemui.ForegroundServiceController;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class AppOpsListenerTest extends SysuiTestCase {
+    private static final String TEST_PACKAGE_NAME = "test";
+    private static final int TEST_UID = 0;
+
+    @Mock private NotificationPresenter mPresenter;
+    @Mock private AppOpsManager mAppOpsManager;
+
+    // Dependency mocks:
+    @Mock private NotificationEntryManager mEntryManager;
+    @Mock private ForegroundServiceController mFsc;
+
+    private AppOpsListener mListener;
+    private Handler mHandler;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
+        mDependency.injectTestDependency(ForegroundServiceController.class, mFsc);
+        getContext().addMockSystemService(AppOpsManager.class, mAppOpsManager);
+        mHandler = new Handler(Looper.getMainLooper());
+        when(mPresenter.getHandler()).thenReturn(mHandler);
+
+        mListener = new AppOpsListener(mContext);
+    }
+
+    @Test
+    public void testOnlyListenForFewOps() {
+        mListener.setUpWithPresenter(mPresenter, mEntryManager);
+
+        verify(mAppOpsManager, times(1)).startWatchingActive(AppOpsListener.OPS, mListener);
+    }
+
+    @Test
+    public void testStopListening() {
+        mListener.destroy();
+        verify(mAppOpsManager, times(1)).stopWatchingActive(mListener);
+    }
+
+    @Test
+    public void testInformEntryMgrOnAppOpsChange() {
+        mListener.setUpWithPresenter(mPresenter, mEntryManager);
+        mListener.onOpActiveChanged(
+                AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
+        waitForIdleSync(mHandler);
+        verify(mEntryManager, times(1)).updateNotificationsForAppOps(
+                AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
+    }
+
+    @Test
+    public void testInformFscOnAppOpsChange() {
+        mListener.setUpWithPresenter(mPresenter, mEntryManager);
+        mListener.onOpActiveChanged(
+                AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
+        waitForIdleSync(mHandler);
+        verify(mFsc, times(1)).onAppOpChanged(
+                AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
index 544585a..ce629bb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
@@ -19,10 +19,15 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
+import android.app.AppOpsManager;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.util.ArraySet;
+import android.view.NotificationHeaderView;
 import android.view.View;
 
 import com.android.systemui.SysuiTestCase;
@@ -146,4 +151,34 @@
         Assert.assertTrue("Should always play sounds when not trusted.",
                 mGroup.isSoundEffectsEnabled());
     }
+
+    @Test
+    public void testShowAppOpsIcons_noHeader() {
+        // public notification is custom layout - no header
+        mGroup.setSensitive(true, true);
+        mGroup.showAppOpsIcons(new ArraySet<>());
+    }
+
+    @Test
+    public void testShowAppOpsIcons_header() throws Exception {
+        NotificationHeaderView mockHeader = mock(NotificationHeaderView.class);
+
+        NotificationContentView publicLayout = mock(NotificationContentView.class);
+        mGroup.setPublicLayout(publicLayout);
+        NotificationContentView privateLayout = mock(NotificationContentView.class);
+        mGroup.setPrivateLayout(privateLayout);
+        NotificationChildrenContainer mockContainer = mock(NotificationChildrenContainer.class);
+        when(mockContainer.getNotificationChildCount()).thenReturn(1);
+        when(mockContainer.getHeaderView()).thenReturn(mockHeader);
+        mGroup.setChildrenContainer(mockContainer);
+
+        ArraySet<Integer> ops = new ArraySet<>();
+        ops.add(AppOpsManager.OP_ANSWER_PHONE_CALLS);
+        mGroup.showAppOpsIcons(ops);
+
+        verify(mockHeader, times(1)).showAppOpsIcons(ops);
+        verify(privateLayout, times(1)).showAppOpsIcons(ops);
+        verify(publicLayout, times(1)).showAppOpsIcons(ops);
+
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
index 436849c..1fb4c37 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
@@ -16,14 +16,23 @@
 
 package com.android.systemui.statusbar;
 
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
+import android.app.AppOpsManager;
 import android.support.test.annotation.UiThreadTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.util.ArraySet;
+import android.view.NotificationHeaderView;
 import android.view.View;
 
 import com.android.systemui.SysuiTestCase;
@@ -75,4 +84,35 @@
         mView.setHeadsUpAnimatingAway(true);
         Assert.assertFalse(mView.isAnimatingVisibleType());
     }
+
+    @Test
+    @UiThreadTest
+    public void testShowAppOpsIcons() {
+        NotificationHeaderView mockContracted = mock(NotificationHeaderView.class);
+        when(mockContracted.findViewById(com.android.internal.R.id.notification_header))
+                .thenReturn(mockContracted);
+        NotificationHeaderView mockExpanded = mock(NotificationHeaderView.class);
+        when(mockExpanded.findViewById(com.android.internal.R.id.notification_header))
+                .thenReturn(mockExpanded);
+        NotificationHeaderView mockHeadsUp = mock(NotificationHeaderView.class);
+        when(mockHeadsUp.findViewById(com.android.internal.R.id.notification_header))
+                .thenReturn(mockHeadsUp);
+        NotificationHeaderView mockAmbient = mock(NotificationHeaderView.class);
+        when(mockAmbient.findViewById(com.android.internal.R.id.notification_header))
+                .thenReturn(mockAmbient);
+
+        mView.setContractedChild(mockContracted);
+        mView.setExpandedChild(mockExpanded);
+        mView.setHeadsUpChild(mockHeadsUp);
+        mView.setAmbientChild(mockAmbient);
+
+        ArraySet<Integer> ops = new ArraySet<>();
+        ops.add(AppOpsManager.OP_ANSWER_PHONE_CALLS);
+        mView.showAppOpsIcons(ops);
+
+        verify(mockContracted, times(1)).showAppOpsIcons(ops);
+        verify(mockExpanded, times(1)).showAppOpsIcons(ops);
+        verify(mockAmbient, never()).showAppOpsIcons(ops);
+        verify(mockHeadsUp, times(1)).showAppOpsIcons(any());
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java
index 972eddb..b1e1c02 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java
@@ -16,8 +16,16 @@
 
 package com.android.systemui.statusbar;
 
+import static android.app.AppOpsManager.OP_ACCEPT_HANDOVER;
+import static android.app.AppOpsManager.OP_CAMERA;
+
+import static junit.framework.Assert.assertEquals;
+
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -33,7 +41,9 @@
 import android.support.test.annotation.UiThreadTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.util.ArraySet;
 
+import com.android.systemui.ForegroundServiceController;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 
@@ -41,6 +51,8 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -51,6 +63,10 @@
 
     private final StatusBarNotification mMockStatusBarNotification =
             mock(StatusBarNotification.class);
+    @Mock
+    ForegroundServiceController mFsc;
+    @Mock
+    NotificationData.Environment mEnvironment;
 
     private final IPackageManager mMockPackageManager = mock(IPackageManager.class);
     private NotificationData mNotificationData;
@@ -58,6 +74,7 @@
 
     @Before
     public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
         when(mMockStatusBarNotification.getUid()).thenReturn(UID_NORMAL);
 
         when(mMockPackageManager.checkUidPermission(
@@ -69,9 +86,11 @@
                 eq(UID_ALLOW_DURING_SETUP)))
                 .thenReturn(PackageManager.PERMISSION_GRANTED);
 
-        NotificationData.Environment mock = mock(NotificationData.Environment.class);
-        when(mock.getGroupManager()).thenReturn(new NotificationGroupManager());
-        mNotificationData = new TestableNotificationData(mock);
+        mDependency.injectTestDependency(ForegroundServiceController.class, mFsc);
+        when(mEnvironment.getGroupManager()).thenReturn(new NotificationGroupManager());
+        when(mEnvironment.isDeviceProvisioned()).thenReturn(true);
+        when(mEnvironment.isNotificationForCurrentProfiles(any())).thenReturn(true);
+        mNotificationData = new TestableNotificationData(mEnvironment);
         mNotificationData.updateRanking(mock(NotificationListenerService.RankingMap.class));
         mRow = new NotificationTestHelper(getContext()).createRow();
     }
@@ -117,6 +136,117 @@
         Assert.assertTrue(mRow.getEntry().channel != null);
     }
 
+    @Test
+    public void testAdd_appOpsAdded() {
+        ArraySet<Integer> expected = new ArraySet<>();
+        expected.add(3);
+        expected.add(235);
+        expected.add(1);
+        when(mFsc.getAppOps(mRow.getEntry().notification.getUserId(),
+                mRow.getEntry().notification.getPackageName())).thenReturn(expected);
+
+        mNotificationData.add(mRow.getEntry());
+        assertEquals(expected.size(),
+                mNotificationData.get(mRow.getEntry().key).mActiveAppOps.size());
+        for (int op : expected) {
+            assertTrue(" entry missing op " + op,
+                    mNotificationData.get(mRow.getEntry().key).mActiveAppOps.contains(op));
+        }
+    }
+
+    @Test
+    public void testAdd_noExistingAppOps() {
+        when(mFsc.getAppOps(mRow.getEntry().notification.getUserId(),
+                mRow.getEntry().notification.getPackageName())).thenReturn(null);
+
+        mNotificationData.add(mRow.getEntry());
+        assertEquals(0, mNotificationData.get(mRow.getEntry().key).mActiveAppOps.size());
+    }
+
+    @Test
+    public void testAllRelevantNotisTaggedWithAppOps() throws Exception {
+        mNotificationData.add(mRow.getEntry());
+        ExpandableNotificationRow row2 = new NotificationTestHelper(getContext()).createRow();
+        mNotificationData.add(row2.getEntry());
+        ExpandableNotificationRow diffPkg =
+                new NotificationTestHelper(getContext()).createRow("pkg", 4000);
+        mNotificationData.add(diffPkg.getEntry());
+
+        ArraySet<Integer> expectedOps = new ArraySet<>();
+        expectedOps.add(OP_CAMERA);
+        expectedOps.add(OP_ACCEPT_HANDOVER);
+
+        for (int op : expectedOps) {
+            mNotificationData.updateAppOp(op, NotificationTestHelper.UID,
+                    NotificationTestHelper.PKG, true);
+        }
+        for (int op : expectedOps) {
+            assertTrue(mRow.getEntry().key + " doesn't have op " + op,
+                    mNotificationData.get(mRow.getEntry().key).mActiveAppOps.contains(op));
+            assertTrue(row2.getEntry().key + " doesn't have op " + op,
+                    mNotificationData.get(row2.getEntry().key).mActiveAppOps.contains(op));
+            assertFalse(diffPkg.getEntry().key + " has op " + op,
+                    mNotificationData.get(diffPkg.getEntry().key).mActiveAppOps.contains(op));
+        }
+    }
+
+    @Test
+    public void testAppOpsRemoval() throws Exception {
+        mNotificationData.add(mRow.getEntry());
+        ExpandableNotificationRow row2 = new NotificationTestHelper(getContext()).createRow();
+        mNotificationData.add(row2.getEntry());
+
+        ArraySet<Integer> expectedOps = new ArraySet<>();
+        expectedOps.add(OP_CAMERA);
+        expectedOps.add(OP_ACCEPT_HANDOVER);
+
+        for (int op : expectedOps) {
+            mNotificationData.updateAppOp(op, NotificationTestHelper.UID,
+                    NotificationTestHelper.PKG, true);
+        }
+
+        expectedOps.remove(OP_ACCEPT_HANDOVER);
+        mNotificationData.updateAppOp(OP_ACCEPT_HANDOVER, NotificationTestHelper.UID,
+                NotificationTestHelper.PKG, false);
+
+        assertTrue(mRow.getEntry().key + " doesn't have op " + OP_CAMERA,
+                mNotificationData.get(mRow.getEntry().key).mActiveAppOps.contains(OP_CAMERA));
+        assertTrue(row2.getEntry().key + " doesn't have op " + OP_CAMERA,
+                mNotificationData.get(row2.getEntry().key).mActiveAppOps.contains(OP_CAMERA));
+        assertFalse(mRow.getEntry().key + " has op " + OP_ACCEPT_HANDOVER,
+                mNotificationData.get(mRow.getEntry().key)
+                        .mActiveAppOps.contains(OP_ACCEPT_HANDOVER));
+        assertFalse(row2.getEntry().key + " has op " + OP_ACCEPT_HANDOVER,
+                mNotificationData.get(row2.getEntry().key)
+                        .mActiveAppOps.contains(OP_ACCEPT_HANDOVER));
+    }
+
+    @Test
+    public void testSuppressSystemAlertNotification() {
+        when(mFsc.isSystemAlertWarningNeeded(anyInt(), anyString())).thenReturn(false);
+        when(mFsc.isSystemAlertNotification(any())).thenReturn(true);
+
+        assertTrue(mNotificationData.shouldFilterOut(mRow.getEntry().notification));
+    }
+
+    @Test
+    public void testDoNotSuppressSystemAlertNotification() {
+        when(mFsc.isSystemAlertWarningNeeded(anyInt(), anyString())).thenReturn(true);
+        when(mFsc.isSystemAlertNotification(any())).thenReturn(true);
+
+        assertFalse(mNotificationData.shouldFilterOut(mRow.getEntry().notification));
+
+        when(mFsc.isSystemAlertWarningNeeded(anyInt(), anyString())).thenReturn(true);
+        when(mFsc.isSystemAlertNotification(any())).thenReturn(false);
+
+        assertFalse(mNotificationData.shouldFilterOut(mRow.getEntry().notification));
+
+        when(mFsc.isSystemAlertWarningNeeded(anyInt(), anyString())).thenReturn(false);
+        when(mFsc.isSystemAlertNotification(any())).thenReturn(false);
+
+        assertFalse(mNotificationData.shouldFilterOut(mRow.getEntry().notification));
+    }
+
     private void initStatusBarNotification(boolean allowDuringSetup) {
         Bundle bundle = new Bundle();
         bundle.putBoolean(Notification.EXTRA_ALLOW_DURING_SETUP, allowDuringSetup);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryManagerTest.java
index f9ec3f92..37dd939 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryManagerTest.java
@@ -23,14 +23,17 @@
 import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.ActivityManager;
+import android.app.AppOpsManager;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.content.Context;
@@ -274,4 +277,40 @@
 
         assertNull(mEntryManager.getNotificationData().get(mSbn.getKey()));
     }
+
+    @Test
+    public void testUpdateAppOps_foregroundNoti() {
+        com.android.systemui.util.Assert.isNotMainThread();
+
+        when(mForegroundServiceController.getStandardLayoutKey(anyInt(), anyString()))
+                .thenReturn("something");
+        mEntry.row = mRow;
+        mEntryManager.getNotificationData().add(mEntry);
+
+
+        mHandler.post(() -> {
+            mEntryManager.updateNotificationsForAppOps(
+                    AppOpsManager.OP_CAMERA, mEntry.notification.getUid(),
+                    mEntry.notification.getPackageName(), true);
+        });
+        waitForIdleSync(mHandler);
+
+        verify(mPresenter, times(1)).updateNotificationViews();
+        assertTrue(mEntryManager.getNotificationData().get(mEntry.key).mActiveAppOps.contains(
+                AppOpsManager.OP_CAMERA));
+    }
+
+    @Test
+    public void testUpdateAppOps_otherNoti() {
+        com.android.systemui.util.Assert.isNotMainThread();
+
+        when(mForegroundServiceController.getStandardLayoutKey(anyInt(), anyString()))
+                .thenReturn(null);
+        mHandler.post(() -> {
+            mEntryManager.updateNotificationsForAppOps(AppOpsManager.OP_CAMERA, 1000, "pkg", true);
+        });
+        waitForIdleSync(mHandler);
+
+        verify(mPresenter, never()).updateNotificationViews();
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
index f3c1171..2764254 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
@@ -48,6 +48,8 @@
     private ExpandableNotificationRow mRow;
     private InflationException mException;
     private HeadsUpManager mHeadsUpManager;
+    protected static final String PKG = "com.android.systemui";
+    protected static final int UID = 1000;
 
     public NotificationTestHelper(Context context) {
         mContext = context;
@@ -55,7 +57,7 @@
         mHeadsUpManager = new HeadsUpManagerPhone(mContext, null, mGroupManager, null, null);
     }
 
-    public ExpandableNotificationRow createRow() throws Exception {
+    public ExpandableNotificationRow createRow(String pkg, int uid) throws Exception {
         Notification publicVersion = new Notification.Builder(mContext).setSmallIcon(
                 R.drawable.ic_person)
                 .setCustomContentView(new RemoteViews(mContext.getPackageName(),
@@ -67,10 +69,19 @@
                 .setContentText("Text")
                 .setPublicVersion(publicVersion)
                 .build();
-        return createRow(notification);
+        return createRow(notification, pkg, uid);
+    }
+
+    public ExpandableNotificationRow createRow() throws Exception {
+        return createRow(PKG, UID);
     }
 
     public ExpandableNotificationRow createRow(Notification notification) throws Exception {
+        return createRow(notification, PKG, UID);
+    }
+
+    public ExpandableNotificationRow createRow(Notification notification, String pkg, int uid)
+            throws Exception {
         LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
                 mContext.LAYOUT_INFLATER_SERVICE);
         mInstrumentation.runOnMainSync(() -> {
@@ -83,8 +94,7 @@
         row.setHeadsUpManager(mHeadsUpManager);
         row.setAboveShelfChangedListener(aboveShelf -> {});
         UserHandle mUser = UserHandle.of(ActivityManager.getCurrentUser());
-        StatusBarNotification sbn = new StatusBarNotification("com.android.systemui",
-                "com.android.systemui", mId++, null, 1000,
+        StatusBarNotification sbn = new StatusBarNotification(pkg, pkg, mId++, null, uid,
                 2000, notification, mUser, null, System.currentTimeMillis());
         NotificationData.Entry entry = new NotificationData.Entry(sbn);
         entry.row = row;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
index fbe730a..76ed452 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
@@ -19,6 +19,9 @@
 import static junit.framework.Assert.assertTrue;
 
 import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -170,6 +173,19 @@
         assertEquals(View.VISIBLE, entry1.row.getVisibility());
     }
 
+    @Test
+    public void testUpdateNotificationViews_appOps() throws Exception {
+        NotificationData.Entry entry0 = createEntry();
+        entry0.row = spy(entry0.row);
+        when(mNotificationData.getActiveNotifications()).thenReturn(
+                Lists.newArrayList(entry0));
+        mListContainer.addContainerView(entry0.row);
+
+        mViewHierarchyManager.updateNotificationViews();
+
+        verify(entry0.row, times(1)).showAppOpsIcons(any());
+    }
+
     private class FakeListContainer implements NotificationListContainer {
         final LinearLayout mLayout = new LinearLayout(mContext);
         final List<View> mRows = Lists.newArrayList();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
index 2d2db1b..a80b045 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
@@ -18,28 +18,21 @@
 
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
 
-import android.app.AlarmManager.AlarmClockInfo;
-import android.os.Handler;
 import android.support.test.filters.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
 import com.android.internal.app.ColorDisplayController;
 import com.android.systemui.Dependency;
+import com.android.systemui.Prefs;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.qs.AutoAddTracker;
 import com.android.systemui.qs.QSTileHost;
-import com.android.systemui.statusbar.policy.NextAlarmController;
-import com.android.systemui.statusbar.policy.NextAlarmController.NextAlarmChangeCallback;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.Mockito;
 
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
@@ -47,19 +40,16 @@
 public class AutoTileManagerTest extends SysuiTestCase {
 
     @Mock private QSTileHost mQsTileHost;
-    @Mock private AutoAddTracker mAutoAddTracker;
-    @Captor private ArgumentCaptor<NextAlarmChangeCallback> mAlarmCallback;
 
     private AutoTileManager mAutoTileManager;
 
     @Before
     public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        mDependency.injectMockDependency(NextAlarmController.class);
-        mAutoTileManager = new AutoTileManager(mContext, mAutoAddTracker,
-            mQsTileHost, new Handler(TestableLooper.get(this).getLooper()));
-        verify(Dependency.get(NextAlarmController.class))
-            .addCallback(mAlarmCallback.capture());
+        mDependency.injectTestDependency(Dependency.BG_LOOPER,
+                TestableLooper.get(this).getLooper());
+        Prefs.putBoolean(mContext, Prefs.Key.QS_NIGHTDISPLAY_ADDED, false);
+        mQsTileHost = Mockito.mock(QSTileHost.class);
+        mAutoTileManager = new AutoTileManager(mContext, mQsTileHost);
     }
 
     @Test
@@ -109,30 +99,4 @@
                 ColorDisplayController.AUTO_MODE_DISABLED);
         verify(mQsTileHost, never()).addTile("night");
     }
-
-    @Test
-    public void alarmTileAdded_whenAlarmSet() {
-        mAlarmCallback.getValue().onNextAlarmChanged(new AlarmClockInfo(0, null));
-
-        verify(mQsTileHost).addTile("alarm");
-        verify(mAutoAddTracker).setTileAdded("alarm");
-    }
-
-    @Test
-    public void alarmTileNotAdded_whenAlarmNotSet() {
-        mAlarmCallback.getValue().onNextAlarmChanged(null);
-
-        verify(mQsTileHost, never()).addTile("alarm");
-        verify(mAutoAddTracker, never()).setTileAdded("alarm");
-    }
-
-    @Test
-    public void alarmTileNotAdded_whenAlreadyAdded() {
-        when(mAutoAddTracker.isAdded("alarm")).thenReturn(true);
-
-        mAlarmCallback.getValue().onNextAlarmChanged(new AlarmClockInfo(0, null));
-
-        verify(mQsTileHost, never()).addTile("alarm");
-        verify(mAutoAddTracker, never()).setTileAdded("alarm");
-    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 43e16db..168d8d3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -31,6 +31,7 @@
 import static org.mockito.Mockito.when;
 
 import android.animation.Animator;
+import android.animation.ValueAnimator;
 import android.app.AlarmManager;
 import android.graphics.Color;
 import android.os.Handler;
@@ -180,6 +181,7 @@
 
     @Test
     public void transitionToUnlocked() {
+        mScrimController.setPanelExpansion(0f);
         mScrimController.transitionTo(ScrimState.UNLOCKED);
         mScrimController.finishAnimationsImmediately();
         // Front scrim should be transparent
@@ -197,6 +199,7 @@
     public void transitionToUnlockedFromAod() {
         // Simulate unlock with fingerprint
         mScrimController.transitionTo(ScrimState.AOD);
+        mScrimController.setPanelExpansion(0f);
         mScrimController.finishAnimationsImmediately();
         mScrimController.transitionTo(ScrimState.UNLOCKED);
         // Immediately tinted after the transition starts
@@ -324,6 +327,81 @@
         verify(mAlarmManager).cancel(any(AlarmManager.OnAlarmListener.class));
     }
 
+    @Test
+    public void testConservesExpansionOpacityAfterTransition() {
+        mScrimController.transitionTo(ScrimState.UNLOCKED);
+        mScrimController.setPanelExpansion(0.5f);
+        mScrimController.finishAnimationsImmediately();
+
+        final float expandedAlpha = mScrimBehind.getViewAlpha();
+
+        mScrimController.transitionTo(ScrimState.BRIGHTNESS_MIRROR);
+        mScrimController.finishAnimationsImmediately();
+        mScrimController.transitionTo(ScrimState.UNLOCKED);
+        mScrimController.finishAnimationsImmediately();
+
+        Assert.assertEquals("Scrim expansion opacity wasn't conserved when transitioning back",
+                expandedAlpha, mScrimBehind.getViewAlpha(), 0.01f);
+    }
+
+    @Test
+    public void cancelsOldAnimationBeforeBlanking() {
+        mScrimController.transitionTo(ScrimState.AOD);
+        mScrimController.finishAnimationsImmediately();
+        // Consume whatever value we had before
+        mScrimController.wasAnimationJustCancelled();
+
+        mScrimController.transitionTo(ScrimState.KEYGUARD);
+        mScrimController.finishAnimationsImmediately();
+        Assert.assertTrue(mScrimController.wasAnimationJustCancelled());
+    }
+
+    /**
+     * Number of visible notifications affects scrim opacity.
+     */
+    @Test
+    public void testNotificationDensity() {
+        mScrimController.transitionTo(ScrimState.KEYGUARD);
+        mScrimController.finishAnimationsImmediately();
+
+        mScrimController.setNotificationCount(0);
+        mScrimController.finishAnimationsImmediately();
+        Assert.assertEquals("lower density when no notifications",
+                ScrimController.GRADIENT_SCRIM_ALPHA,  mScrimBehind.getViewAlpha(), 0.01f);
+
+        mScrimController.setNotificationCount(3);
+        mScrimController.finishAnimationsImmediately();
+        Assert.assertEquals("stronger density when notifications are visible",
+                ScrimController.GRADIENT_SCRIM_ALPHA_BUSY,  mScrimBehind.getViewAlpha(), 0.01f);
+    }
+
+    /**
+     * Moving from/to states conserves old notification density.
+     */
+    @Test
+    public void testConservesNotificationDensity() {
+        testConservesNotificationDensity(0 /* count */, ScrimController.GRADIENT_SCRIM_ALPHA);
+        testConservesNotificationDensity(3 /* count */, ScrimController.GRADIENT_SCRIM_ALPHA_BUSY);
+    }
+
+    /**
+     * Conserves old notification density after leaving state and coming back.
+     *
+     * @param count How many notification.
+     * @param expectedAlpha Expected alpha.
+     */
+    private void testConservesNotificationDensity(int count, float expectedAlpha) {
+        mScrimController.setNotificationCount(count);
+        mScrimController.transitionTo(ScrimState.UNLOCKED);
+        mScrimController.finishAnimationsImmediately();
+
+        mScrimController.transitionTo(ScrimState.KEYGUARD);
+        mScrimController.finishAnimationsImmediately();
+
+        Assert.assertEquals("Doesn't respect notification busyness after transition",
+                expectedAlpha,  mScrimBehind.getViewAlpha(), 0.01f);
+    }
+
     private void assertScrimTint(ScrimView scrimView, boolean tinted) {
         final boolean viewIsTinted = scrimView.getTint() != Color.TRANSPARENT;
         final String name = scrimView == mScrimInFront ? "front" : "back";
@@ -357,6 +435,7 @@
     private class SynchronousScrimController extends ScrimController {
 
         private FakeHandler mHandler;
+        private boolean mAnimationCancelled;
 
         public SynchronousScrimController(LightBarController lightBarController,
                 ScrimView scrimBehind, ScrimView scrimInFront, View headsUpScrim,
@@ -385,6 +464,12 @@
             }
         }
 
+        public boolean wasAnimationJustCancelled() {
+            final boolean wasCancelled = mAnimationCancelled;
+            mAnimationCancelled = false;
+            return wasCancelled;
+        }
+
         private void endAnimation(ScrimView scrimView, int tag) {
             Animator animator = (Animator) scrimView.getTag(tag);
             if (animator != null) {
@@ -393,6 +478,12 @@
         }
 
         @Override
+        protected void cancelAnimator(ValueAnimator previousAnimator) {
+            super.cancelAnimator(previousAnimator);
+            mAnimationCancelled = true;
+        }
+
+        @Override
         protected Handler getHandler() {
             return mHandler;
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 31442af..ff545f0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -69,6 +69,7 @@
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.statusbar.ActivatableNotificationView;
+import com.android.systemui.statusbar.AppOpsListener;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.KeyguardIndicationController;
 import com.android.systemui.statusbar.NotificationData;
@@ -145,6 +146,7 @@
         mDependency.injectTestDependency(VisualStabilityManager.class, mVisualStabilityManager);
         mDependency.injectTestDependency(NotificationListener.class, mNotificationListener);
         mDependency.injectTestDependency(KeyguardMonitor.class, mock(KeyguardMonitorImpl.class));
+        mDependency.injectTestDependency(AppOpsListener.class, mock(AppOpsListener.class));
 
         mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class));
         mContext.addMockSystemService(FingerprintManager.class, mock(FingerprintManager.class));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
new file mode 100644
index 0000000..d54c295
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 static org.mockito.Mockito.when;
+
+import android.content.Intent;
+import android.os.PowerManager;
+import android.os.PowerSaveState;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class BatteryControllerTest extends SysuiTestCase {
+
+    @Mock
+    private PowerManager mPowerManager;
+    private BatteryControllerImpl mBatteryController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mBatteryController = new BatteryControllerImpl(getContext(), mPowerManager);
+    }
+
+    @Test
+    public void testIndependentAODBatterySaver_true() {
+        PowerSaveState state = new PowerSaveState.Builder()
+                .setBatterySaverEnabled(true)
+                .build();
+        Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
+        when(mPowerManager.getPowerSaveState(PowerManager.ServiceType.AOD)).thenReturn(state);
+        when(mPowerManager.isPowerSaveMode()).thenReturn(true);
+
+        mBatteryController.onReceive(getContext(), intent);
+
+        Assert.assertTrue(mBatteryController.isPowerSave());
+        Assert.assertTrue(mBatteryController.isAodPowerSave());
+    }
+
+    @Test
+    public void testIndependentAODBatterySaver_false() {
+        PowerSaveState state = new PowerSaveState.Builder()
+                .setBatterySaverEnabled(false)
+                .build();
+        Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
+        when(mPowerManager.getPowerSaveState(PowerManager.ServiceType.AOD)).thenReturn(state);
+        when(mPowerManager.isPowerSaveMode()).thenReturn(true);
+
+        mBatteryController.onReceive(getContext(), intent);
+
+        Assert.assertTrue(mBatteryController.isPowerSave());
+        Assert.assertFalse(mBatteryController.isAodPowerSave());
+    }
+
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
index 63920a4..7e1aba5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
@@ -24,6 +24,7 @@
 import android.support.test.filters.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
+import android.view.View;
 import android.widget.EditText;
 import android.widget.ImageButton;
 
@@ -33,6 +34,7 @@
 import com.android.systemui.statusbar.NotificationTestHelper;
 import com.android.systemui.statusbar.RemoteInputController;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -46,7 +48,7 @@
 
     private static final String TEST_RESULT_KEY = "test_result_key";
     private static final String TEST_REPLY = "hello";
-    private static final String TEST_ACTION = "com.android.ACTION";
+    private static final String TEST_ACTION = "com.android.REMOTE_INPUT_VIEW_ACTION";
 
     @Mock private RemoteInputController mController;
     @Mock private ShortcutManager mShortcutManager;
@@ -67,6 +69,11 @@
         mView = RemoteInputView.inflate(mContext, null, row.getEntry(), mController);
     }
 
+    @After
+    public void tearDown() {
+        mContext.unregisterReceiver(mReceiver);
+    }
+
     @Test
     public void testSendRemoteInput_intentContainsResultsAndSource() throws InterruptedException {
         PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0,
@@ -88,4 +95,11 @@
         assertEquals(RemoteInput.SOURCE_FREE_FORM_INPUT,
                 RemoteInput.getResultsSource(resultIntent));
     }
+
+    @Test
+    public void testNoCrashWithoutVisibilityListener() {
+        mView.setOnVisibilityChangedListener(null);
+        mView.setVisibility(View.INVISIBLE);
+        mView.setVisibility(View.VISIBLE);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
index 58abf19..a9b2c96 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
@@ -37,6 +37,7 @@
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -46,7 +47,7 @@
 @SmallTest
 public class SmartReplyViewTest extends SysuiTestCase {
     private static final String TEST_RESULT_KEY = "test_result_key";
-    private static final String TEST_ACTION = "com.android.ACTION";
+    private static final String TEST_ACTION = "com.android.SMART_REPLY_VIEW_ACTION";
 
     private static final String[] TEST_CHOICES = new String[]{"Hello", "What's up?", "I'm here"};
 
@@ -76,6 +77,11 @@
         mSpacing = res.getDimensionPixelSize(R.dimen.smart_reply_button_spacing);
     }
 
+    @After
+    public void tearDown() {
+        mContext.unregisterReceiver(mReceiver);
+    }
+
     @Test
     public void testSendSmartReply_intentContainsResultsAndSource() throws InterruptedException {
         setRepliesFromRemoteInput(TEST_CHOICES);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/OutputChooserDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/OutputChooserDialogTest.java
deleted file mode 100644
index 922bde7..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/OutputChooserDialogTest.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 static com.android.systemui.volume.OutputChooserDialog.INCLUDE_MEDIA_ROUTES;
-
-import static junit.framework.Assert.assertTrue;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.bluetooth.BluetoothProfile;
-import android.net.wifi.WifiManager;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.support.v7.media.MediaRouter;
-import android.telecom.TelecomManager;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.widget.TextView;
-
-import com.android.settingslib.bluetooth.CachedBluetoothDevice;
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.plugins.VolumeDialogController;
-import com.android.systemui.statusbar.policy.BluetoothController;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@Ignore
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class OutputChooserDialogTest extends SysuiTestCase {
-
-    OutputChooserDialog mDialog;
-
-    @Mock
-    private VolumeDialogController mVolumeController;
-    @Mock
-    private BluetoothController mController;
-    @Mock
-    private WifiManager mWifiManager;
-    @Mock
-    private TelecomManager mTelecomManager;
-
-    @Mock
-    private MediaRouterWrapper mRouter;
-
-
-    @Before
-    public void setup() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        mVolumeController = mDependency.injectMockDependency(VolumeDialogController.class);
-        mController = mDependency.injectMockDependency(BluetoothController.class);
-        when(mWifiManager.isWifiEnabled()).thenReturn(true);
-
-        getContext().addMockSystemService(WifiManager.class, mWifiManager);
-        getContext().addMockSystemService(TelecomManager.class, mTelecomManager);
-
-        mDialog = new OutputChooserDialog(getContext(), mRouter);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        TestableLooper.get(this).processAllMessages();
-    }
-/*
-    @Test
-    public void testClickMediaRouterItemConnectsMedia() {
-        mDialog.show();
-
-        OutputChooserLayout.Item item = new OutputChooserLayout.Item();
-        item.deviceType = OutputChooserLayout.Item.DEVICE_TYPE_MEDIA_ROUTER;
-        MediaRouter.RouteInfo info = mock(MediaRouter.RouteInfo.class);
-        when(info.isEnabled()).thenReturn(true);
-        item.tag = info;
-
-        mDialog.onDetailItemClick(item);
-        verify(info, times(1)).select();
-        verify(mController, never()).connect(any());
-        mDialog.dismiss();
-    }
-
-    @Test
-    public void testClickBtItemConnectsBt() {
-        mDialog.show();
-
-        OutputChooserLayout.Item item = new OutputChooserLayout.Item();
-        item.deviceType = OutputChooserLayout.Item.DEVICE_TYPE_BT;
-        CachedBluetoothDevice btDevice = mock(CachedBluetoothDevice.class);
-        when(btDevice.getMaxConnectionState()).thenReturn(BluetoothProfile.STATE_DISCONNECTED);
-        item.tag = btDevice;
-
-        mDialog.onDetailItemClick(item);
-        verify(mController, times(1)).connect(any());
-        mDialog.dismiss();
-    }
-
-    @Test
-    public void testTitleNotInCall() {
-        mDialog.show();
-
-        assertTrue(((TextView) mDialog.findViewById(R.id.title))
-                .getText().toString().contains("Media"));
-        mDialog.dismiss();
-    }
-
-    @Test
-    public void testTitleInCall() {
-        mDialog.setIsInCall(true);
-        mDialog.show();
-
-        assertTrue(((TextView) mDialog.findViewById(R.id.title))
-                .getText().toString().contains("Phone"));
-        mDialog.dismiss();
-    }
-*/
-    @Test
-    public void testNoMediaScanIfInCall() {
-        mDialog.setIsInCall(true);
-        mDialog.onAttachedToWindow();
-
-        verify(mRouter, never()).addCallback(any(), any(), anyInt());
-    }
-
-    @Test
-    public void testRegisterCallbacks() {
-        mDialog.setIsInCall(false);
-        mDialog.onAttachedToWindow();
-
-        if (INCLUDE_MEDIA_ROUTES) {
-            verify(mRouter, times(1)).addCallback(any(), any(), anyInt());
-        }
-        verify(mController, times(1)).addCallback(any());
-        verify(mVolumeController, times(1)).addCallback(any(), any());
-    }
-
-    @Test
-    public void testUnregisterCallbacks() {
-        mDialog.setIsInCall(false);
-        mDialog.onDetachedFromWindow();
-
-        verify(mRouter, times(1)).removeCallback(any());
-        verify(mController, times(1)).removeCallback(any());
-        verify(mVolumeController, times(1)).removeCallback(any());
-    }
-}
diff --git a/packages/VpnDialogs/Android.mk b/packages/VpnDialogs/Android.mk
index 4c80a26..8507646 100644
--- a/packages/VpnDialogs/Android.mk
+++ b/packages/VpnDialogs/Android.mk
@@ -27,5 +27,6 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := VpnDialogs
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 include $(BUILD_PACKAGE)
diff --git a/packages/VpnDialogs/res/values-as/strings.xml b/packages/VpnDialogs/res/values-as/strings.xml
new file mode 100644
index 0000000..4f16c74
--- /dev/null
+++ b/packages/VpnDialogs/res/values-as/strings.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="prompt" msgid="3183836924226407828">"সংযোগৰ অনুৰোধ"</string>
+    <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g>এ নেটৱৰ্ক ট্ৰেফিক নিৰীক্ষণ কৰিবলৈ এটা ভিপিএন সংযোগ ছেট আপ কৰিবলৈ বিচাৰিছে৷ আপুনি কেৱল উৎসটোক বিশ্বাস কৰিলেহে অনুৰোধ স্বীকাৰ কৰিব৷ ভিপিএন সক্ৰিয় থকাৰ সময়ত আপোনাৰ স্ক্ৰীণৰ ওপৰত &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; দৃশ্যমান হয়৷"</string>
+    <string name="legacy_title" msgid="192936250066580964">"ভিপিএন সংযোগ হৈ আছে"</string>
+    <string name="session" msgid="6470628549473641030">"ছেশ্বন:"</string>
+    <string name="duration" msgid="3584782459928719435">"সময়সীমা:"</string>
+    <string name="data_transmitted" msgid="7988167672982199061">"পঠিওৱা হ\'ল:"</string>
+    <string name="data_received" msgid="4062776929376067820">"পোৱা গ\'ল:"</string>
+    <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_1">%2$s</xliff:g> পেকেট / <xliff:g id="NUMBER_0">%1$s</xliff:g> বাইট"</string>
+    <!-- no translation found for always_on_disconnected_title (1906740176262776166) -->
+    <skip />
+    <!-- no translation found for always_on_disconnected_message (555634519845992917) -->
+    <skip />
+    <!-- no translation found for always_on_disconnected_message_lockdown (4232225539869452120) -->
+    <skip />
+    <!-- no translation found for always_on_disconnected_message_separator (3310614409322581371) -->
+    <skip />
+    <!-- no translation found for always_on_disconnected_message_settings_link (6172280302829992412) -->
+    <skip />
+    <string name="configure" msgid="4905518375574791375">"কনফিগাৰ কৰক"</string>
+    <string name="disconnect" msgid="971412338304200056">"সংযোগ বিচ্ছিন্ন কৰক"</string>
+    <!-- no translation found for open_app (3717639178595958667) -->
+    <skip />
+    <!-- no translation found for dismiss (6192859333764711227) -->
+    <skip />
+</resources>
diff --git a/packages/VpnDialogs/res/values-or/strings.xml b/packages/VpnDialogs/res/values-or/strings.xml
new file mode 100644
index 0000000..93f56ba
--- /dev/null
+++ b/packages/VpnDialogs/res/values-or/strings.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="prompt" msgid="3183836924226407828">"ସଂଯୋଗ ଅନୁରୋଧ"</string>
+    <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> ଏକ VPN ସଂଯୋଗ ସେଟ୍ ଅପ୍ କରିବାକୁ ଚାହେଁ, ଯାହା ଏହି ନେଟ୍‌ୱର୍କର ଟ୍ରାଫିକକୁ ମନିଟର୍ କରିବାକୁ ଅନୁମତି ଦିଏ। ଆପଣ ସୋର୍ସ ଉପରେ ବିଶ୍ୱାସ କରିବା ବଦଳରେ କେବଳ ସ୍ୱୀକାର କରନ୍ତୁ। &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; VPN ସକ୍ରିୟ ଥିବାବେଳେ ଏହା ଆପଣଙ୍କ ସ୍କ୍ରୀନ୍‍ର ଉପରେ ଦେଖାଯାଏ।"</string>
+    <string name="legacy_title" msgid="192936250066580964">"VPN ସଂଯୋଗ ହେଲା"</string>
+    <string name="session" msgid="6470628549473641030">"ସେସନ୍‍:"</string>
+    <string name="duration" msgid="3584782459928719435">"ଅବଧି:"</string>
+    <string name="data_transmitted" msgid="7988167672982199061">"ପଠାଯାଇଛି:"</string>
+    <string name="data_received" msgid="4062776929376067820">"ପ୍ରାପ୍ତ ହୋଇଛି:"</string>
+    <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> ବାଇଟ୍ସ <xliff:g id="NUMBER_1">%2$s</xliff:g> ପ୍ୟାକେଟ୍ସ"</string>
+    <!-- no translation found for always_on_disconnected_title (1906740176262776166) -->
+    <skip />
+    <!-- no translation found for always_on_disconnected_message (555634519845992917) -->
+    <skip />
+    <!-- no translation found for always_on_disconnected_message_lockdown (4232225539869452120) -->
+    <skip />
+    <!-- no translation found for always_on_disconnected_message_separator (3310614409322581371) -->
+    <skip />
+    <!-- no translation found for always_on_disconnected_message_settings_link (6172280302829992412) -->
+    <skip />
+    <string name="configure" msgid="4905518375574791375">"କନଫିଗର୍‍ କରନ୍ତୁ"</string>
+    <string name="disconnect" msgid="971412338304200056">"ବିଚ୍ଛିନ୍ନ କରନ୍ତୁ"</string>
+    <!-- no translation found for open_app (3717639178595958667) -->
+    <skip />
+    <!-- no translation found for dismiss (6192859333764711227) -->
+    <skip />
+</resources>
diff --git a/packages/WAPPushManager/Android.mk b/packages/WAPPushManager/Android.mk
index 60f093f..91526dd 100644
--- a/packages/WAPPushManager/Android.mk
+++ b/packages/WAPPushManager/Android.mk
@@ -9,6 +9,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := WAPPushManager
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_JAVA_LIBRARIES += telephony-common
 LOCAL_STATIC_JAVA_LIBRARIES += android-common
diff --git a/packages/WAPPushManager/tests/Android.mk b/packages/WAPPushManager/tests/Android.mk
index bfc85ab..c4c2240f 100644
--- a/packages/WAPPushManager/tests/Android.mk
+++ b/packages/WAPPushManager/tests/Android.mk
@@ -32,6 +32,7 @@
 # automatically get all of its classes loaded into our environment.
 
 LOCAL_PACKAGE_NAME := WAPPushManagerTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_INSTRUMENTATION_FOR := WAPPushManager
 
diff --git a/packages/WallpaperBackup/Android.mk b/packages/WallpaperBackup/Android.mk
index cf04249..a6426a6 100644
--- a/packages/WallpaperBackup/Android.mk
+++ b/packages/WallpaperBackup/Android.mk
@@ -24,6 +24,7 @@
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 
 LOCAL_PACKAGE_NAME := WallpaperBackup
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_CERTIFICATE := platform
 LOCAL_PRIVILEGED_MODULE := false
 
diff --git a/packages/WallpaperCropper/Android.mk b/packages/WallpaperCropper/Android.mk
index 7efe8ab..848f2bd 100644
--- a/packages/WallpaperCropper/Android.mk
+++ b/packages/WallpaperCropper/Android.mk
@@ -6,6 +6,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := WallpaperCropper
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_CERTIFICATE := platform
 LOCAL_PRIVILEGED_MODULE := true
 
diff --git a/packages/overlays/DisplayCutoutEmulationNarrowOverlay/Android.mk b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/Android.mk
index 4f3a8b1..f5afad2 100644
--- a/packages/overlays/DisplayCutoutEmulationNarrowOverlay/Android.mk
+++ b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/Android.mk
@@ -9,5 +9,6 @@
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := DisplayCutoutEmulationNarrowOverlay
+LOCAL_SDK_VERSION := current
 
 include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/config.xml b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/config.xml
index a584a7f..c22b2e7 100644
--- a/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/config.xml
+++ b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/config.xml
@@ -46,7 +46,8 @@
     <bool name="config_fillMainBuiltInDisplayCutout">true</bool>
 
     <!-- Height of the status bar -->
-    <dimen name="status_bar_height">48dp</dimen>
+    <dimen name="status_bar_height_portrait">48dp</dimen>
+    <dimen name="status_bar_height_landscape">28dp</dimen>
     <!-- Height of area above QQS where battery/time go (equal to status bar height if > 48dp) -->
     <dimen name="quick_qs_offset_height">48dp</dimen>
     <!-- Total height of QQS (quick_qs_offset_height + 128) -->
diff --git a/packages/overlays/DisplayCutoutEmulationTallOverlay/Android.mk b/packages/overlays/DisplayCutoutEmulationTallOverlay/Android.mk
index dac3878..f1f8c27 100644
--- a/packages/overlays/DisplayCutoutEmulationTallOverlay/Android.mk
+++ b/packages/overlays/DisplayCutoutEmulationTallOverlay/Android.mk
@@ -9,5 +9,6 @@
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := DisplayCutoutEmulationTallOverlay
+LOCAL_SDK_VERSION := current
 
 include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/config.xml b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/config.xml
index 915e164..401e092 100644
--- a/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/config.xml
+++ b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/config.xml
@@ -46,7 +46,8 @@
     <bool name="config_fillMainBuiltInDisplayCutout">true</bool>
 
     <!-- Height of the status bar -->
-    <dimen name="status_bar_height">48dp</dimen>
+    <dimen name="status_bar_height_portrait">48dp</dimen>
+    <dimen name="status_bar_height_landscape">28dp</dimen>
     <!-- Height of area above QQS where battery/time go (equal to status bar height if > 48dp) -->
     <dimen name="quick_qs_offset_height">48dp</dimen>
     <!-- Total height of QQS (quick_qs_offset_height + 128) -->
diff --git a/packages/overlays/DisplayCutoutEmulationWideOverlay/Android.mk b/packages/overlays/DisplayCutoutEmulationWideOverlay/Android.mk
index f4f250c..d149d8e 100644
--- a/packages/overlays/DisplayCutoutEmulationWideOverlay/Android.mk
+++ b/packages/overlays/DisplayCutoutEmulationWideOverlay/Android.mk
@@ -9,5 +9,6 @@
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := DisplayCutoutEmulationWideOverlay
+LOCAL_SDK_VERSION := current
 
 include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/config.xml b/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/config.xml
index b8e29da..f328b83 100644
--- a/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/config.xml
+++ b/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/config.xml
@@ -46,7 +46,8 @@
     <bool name="config_fillMainBuiltInDisplayCutout">true</bool>
 
     <!-- Height of the status bar -->
-    <dimen name="status_bar_height">48dp</dimen>
+    <dimen name="status_bar_height_portrait">48dp</dimen>
+    <dimen name="status_bar_height_landscape">28dp</dimen>
     <!-- Height of area above QQS where battery/time go (equal to status bar height if > 48dp) -->
     <dimen name="quick_qs_offset_height">48dp</dimen>
     <!-- Total height of QQS (quick_qs_offset_height + 128) -->
diff --git a/packages/overlays/SysuiDarkThemeOverlay/Android.mk b/packages/overlays/SysuiDarkThemeOverlay/Android.mk
index 4b83058..7b277bc 100644
--- a/packages/overlays/SysuiDarkThemeOverlay/Android.mk
+++ b/packages/overlays/SysuiDarkThemeOverlay/Android.mk
@@ -9,5 +9,6 @@
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := SysuiDarkThemeOverlay
+LOCAL_SDK_VERSION := current
 
 include $(BUILD_RRO_PACKAGE)
diff --git a/packages/services/PacProcessor/Android.mk b/packages/services/PacProcessor/Android.mk
index 3c4e951..5be90c0 100644
--- a/packages/services/PacProcessor/Android.mk
+++ b/packages/services/PacProcessor/Android.mk
@@ -23,6 +23,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := PacProcessor
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_CERTIFICATE := platform
 
 LOCAL_JNI_SHARED_LIBRARIES := libjni_pacprocessor
diff --git a/packages/services/Proxy/Android.mk b/packages/services/Proxy/Android.mk
index d5546b2..ce1715f 100644
--- a/packages/services/Proxy/Android.mk
+++ b/packages/services/Proxy/Android.mk
@@ -6,6 +6,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := ProxyHandler
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_CERTIFICATE := platform
 LOCAL_PRIVILEGED_MODULE := true
 
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 7e86ef5..6f31b0a 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -5278,11 +5278,76 @@
     // OS: P
     FIELD_QS_MODE = 1311;
 
+
     // OPEN: Settings->Developer Options->Default USB
     // CATEGORY: SETTINGS
     // OS: P
     USB_DEFAULT = 1312;
 
+    // CATEGORY: The category for all actions related to TextClassifier generateLinks.
+    // OS: P
+    TEXT_CLASSIFIER_GENERATE_LINKS = 1313;
+
+    // FIELD: milliseconds spent generating links.
+    // CATEGORY: TEXT_CLASSIFIER_GENERATE_LINKS
+    // OS: P
+    FIELD_LINKIFY_LATENCY = 1314;
+
+    // FIELD: length of the input text in characters.
+    // CATEGORY: TEXT_CLASSIFIER_GENERATE_LINKS
+    // OS: P
+    FIELD_LINKIFY_TEXT_LENGTH = 1315;
+
+    // FIELD: number of links detected.
+    // CATEGORY: TEXT_CLASSIFIER_GENERATE_LINKS
+    // OS: P
+    FIELD_LINKIFY_NUM_LINKS = 1316;
+
+    // FIELD: length of all links in characters.
+    // CATEGORY: TEXT_CLASSIFIER_GENERATE_LINKS
+    // OS: P
+    FIELD_LINKIFY_LINK_LENGTH = 1317;
+
+    // FIELD: the type of entity the stats are for.
+    // CATEGORY: TEXT_CLASSIFIER_GENERATE_LINKS
+    // OS: P
+    FIELD_LINKIFY_ENTITY_TYPE = 1318;
+
+    // FIELD: a random uid for a single call to generateLinks
+    // CATEGORY: TEXT_CLASSIFIER_GENERATE_LINKS
+    // OS: P
+    FIELD_LINKIFY_CALL_ID = 1319;
+
+    // FIELD: The compiler filter used when when optimizing the package.
+    //        Logged together with app transition events.
+    // OS: P
+    PACKAGE_OPTIMIZATION_COMPILATION_FILTER = 1320;
+
+    // FIELD: The reason for optimizing the package.
+    //        Logged together with app transition events.
+    // OS: P
+    PACKAGE_OPTIMIZATION_COMPILATION_REASON = 1321;
+
+    // FIELD: The camera API level used.
+    // CATEGORY: CAMERA
+    // OS: P
+    FIELD_CAMERA_API_LEVEL = 1322;
+
+    // OPEN: Settings > Battery > Battery tip > Battery tip Dialog
+    // CATEGORY: SETTINGS
+    // OS: P
+    FUELGAUGE_BATTERY_TIP_DIALOG = 1323;
+
+    // OPEN: Settings > Battery > Battery tip
+    // CATEGORY: SETTINGS
+    // OS: P
+    ACTION_BATTERY_TIP_SHOWN = 1324;
+
+    // OPEN: Settings > Security & Location > Location > See all
+    // CATEGORY: SETTINGS
+    // OS: P
+    RECENT_LOCATION_REQUESTS_ALL = 1325;
+
     // ---- End P Constants, all P constants go above this line ----
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto
index c77dcc0..74efec9 100644
--- a/proto/src/wifi.proto
+++ b/proto/src/wifi.proto
@@ -379,6 +379,9 @@
 
   // Number of connectivity single scan requests.
   optional int32 num_connectivity_oneshot_scans = 93;
+
+  // WifiWake statistics
+  optional WifiWakeStats wifi_wake_stats = 94;
 }
 
 // Information that gets logged for every WiFi connection.
@@ -1159,3 +1162,39 @@
   // Amount of time wifi is in tx (ms)
   optional int64 tx_time_ms = 5;
 }
+
+// Metrics for Wifi Wake
+message WifiWakeStats {
+  // An individual session for Wifi Wake
+  message Session {
+    // A Wifi Wake lifecycle event
+    message Event {
+      // Elapsed time in milliseconds since start of session.
+      optional int64 elapsed_time_millis = 1;
+
+      // Number of scans that have occurred since start of session.
+      optional int32 elapsed_scans = 2;
+    }
+
+    // Start time of session in milliseconds.
+    optional int64 start_time_millis = 1;
+
+    // The number of networks the lock was initialized with at start.
+    optional int32 locked_networks_at_start = 2;
+
+    // Event for unlocking the WakeupLock. Does not occur if lock was initialized with 0 networks.
+    optional Event unlock_event = 3;
+
+    // Event for triggering wakeup.
+    optional Event wakeup_event = 4;
+
+    // Event for WifiWake reset event. This event marks the end of a session.
+    optional Event reset_event = 5;
+  }
+
+  // Total number of sessions for Wifi Wake.
+  optional int32 num_sessions = 1;
+
+  // Session information for every Wifi Wake session (up to a maximum of 10).
+  repeated Session sessions = 2;
+}
diff --git a/sax/tests/saxtests/Android.mk b/sax/tests/saxtests/Android.mk
index e0e490c..c4517a9 100644
--- a/sax/tests/saxtests/Android.mk
+++ b/sax/tests/saxtests/Android.mk
@@ -10,6 +10,7 @@
 LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
 LOCAL_STATIC_JAVA_LIBRARIES := junit
 LOCAL_PACKAGE_NAME := FrameworksSaxTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 include $(BUILD_PACKAGE)
 
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index eba9830..b0b9586 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -22,6 +22,7 @@
 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS;
 
 import static com.android.internal.util.FunctionalUtils.ignoreRemoteException;
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
 
 import android.Manifest;
 import android.accessibilityservice.AccessibilityService;
@@ -100,18 +101,20 @@
 import android.view.accessibility.IAccessibilityManagerClient;
 
 import com.android.internal.R;
+import com.android.internal.accessibility.AccessibilityShortcutController;
+import com.android.internal.accessibility.AccessibilityShortcutController.ToggleableFrameworkFeatureInfo;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IntPair;
+import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.LocalServices;
-import com.android.internal.accessibility.AccessibilityShortcutController;
-import com.android.internal.accessibility.AccessibilityShortcutController.ToggleableFrameworkFeatureInfo;
 import com.android.server.wm.WindowManagerInternal;
 
 import libcore.util.EmptyArray;
+
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.FileDescriptor;
@@ -125,9 +128,10 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
-import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.function.Consumer;
+import java.util.function.IntSupplier;
 
 /**
  * This class is instantiated by the system as a system level service and can be
@@ -293,6 +297,12 @@
         return mFingerprintGestureDispatcher;
     }
 
+    private UserState getUserState(int userId) {
+        synchronized (mLock) {
+            return getUserStateLocked(userId);
+        }
+    }
+
     private UserState getUserStateLocked(int userId) {
         UserState state = mUserStates.get(userId);
         if (state == null) {
@@ -540,9 +550,9 @@
                     dispatchEvent = true;
                 }
                 if (mHasInputFilter && mInputFilter != null) {
-                    mMainHandler.obtainMessage(
-                            MainHandler.MSG_SEND_ACCESSIBILITY_EVENT_TO_INPUT_FILTER,
-                            AccessibilityEvent.obtain(event)).sendToTarget();
+                    mMainHandler.sendMessage(obtainMessage(
+                            AccessibilityManagerService::sendAccessibilityEventToInputFilter,
+                            this, AccessibilityEvent.obtain(event)));
                 }
             }
         }
@@ -568,6 +578,15 @@
         }
     }
 
+    private void sendAccessibilityEventToInputFilter(AccessibilityEvent event) {
+        synchronized (mLock) {
+            if (mHasInputFilter && mInputFilter != null) {
+                mInputFilter.notifyAccessibilityEvent(event);
+            }
+        }
+        event.recycle();
+    }
+
     @Override
     public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList(int userId) {
         synchronized (mLock) {
@@ -1024,8 +1043,9 @@
 
             // Disable the local managers for the old user.
             if (oldUserState.mUserClients.getRegisteredCallbackCount() > 0) {
-                mMainHandler.obtainMessage(MainHandler.MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER,
-                        oldUserState.mUserId, 0).sendToTarget();
+                mMainHandler.sendMessage(obtainMessage(
+                        AccessibilityManagerService::sendStateToClients,
+                        this, 0, oldUserState.mUserId));
             }
 
             // Announce user changes only if more that one exist.
@@ -1045,12 +1065,29 @@
 
             if (announceNewUser) {
                 // Schedule announcement of the current user if needed.
-                mMainHandler.sendEmptyMessageDelayed(MainHandler.MSG_ANNOUNCE_NEW_USER_IF_NEEDED,
+                mMainHandler.sendMessageDelayed(
+                        obtainMessage(AccessibilityManagerService::announceNewUserIfNeeded, this),
                         WAIT_FOR_USER_STATE_FULLY_INITIALIZED_MILLIS);
             }
         }
     }
 
+    private void announceNewUserIfNeeded() {
+        synchronized (mLock) {
+            UserState userState = getCurrentUserStateLocked();
+            if (userState.isHandlingAccessibilityEvents()) {
+                UserManager userManager = (UserManager) mContext.getSystemService(
+                        Context.USER_SERVICE);
+                String message = mContext.getString(R.string.user_switched,
+                        userManager.getUserInfo(mCurrentUserId).name);
+                AccessibilityEvent event = AccessibilityEvent.obtain(
+                        AccessibilityEvent.TYPE_ANNOUNCEMENT);
+                event.getText().add(message);
+                sendAccessibilityEventLocked(event, mCurrentUserId);
+            }
+        }
+    }
+
     private void unlockUser(int userId) {
         synchronized (mLock) {
             int parentUserId = mSecurityPolicy.resolveProfileParentLocked(userId);
@@ -1154,8 +1191,8 @@
         }
         if (potentialTargets == 1) {
             if (state.mIsNavBarMagnificationEnabled) {
-                mMainHandler.obtainMessage(
-                        MainHandler.MSG_SEND_ACCESSIBILITY_BUTTON_TO_INPUT_FILTER).sendToTarget();
+                mMainHandler.sendMessage(obtainMessage(
+                        AccessibilityManagerService::sendAccessibilityButtonToInputFilter, this));
                 return;
             } else {
                 for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
@@ -1169,12 +1206,12 @@
         } else {
             if (state.mServiceAssignedToAccessibilityButton == null
                     && !state.mIsNavBarMagnificationAssignedToAccessibilityButton) {
-                mMainHandler.obtainMessage(
-                        MainHandler.MSG_SHOW_ACCESSIBILITY_BUTTON_CHOOSER).sendToTarget();
+                mMainHandler.sendMessage(obtainMessage(
+                        AccessibilityManagerService::showAccessibilityButtonTargetSelection, this));
             } else if (state.mIsNavBarMagnificationEnabled
                     && state.mIsNavBarMagnificationAssignedToAccessibilityButton) {
-                mMainHandler.obtainMessage(
-                        MainHandler.MSG_SEND_ACCESSIBILITY_BUTTON_TO_INPUT_FILTER).sendToTarget();
+                mMainHandler.sendMessage(obtainMessage(
+                        AccessibilityManagerService::sendAccessibilityButtonToInputFilter, this));
                 return;
             } else {
                 for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
@@ -1187,11 +1224,25 @@
                 }
             }
             // The user may have turned off the assigned service or feature
-            mMainHandler.obtainMessage(
-                    MainHandler.MSG_SHOW_ACCESSIBILITY_BUTTON_CHOOSER).sendToTarget();
+            mMainHandler.sendMessage(obtainMessage(
+                    AccessibilityManagerService::showAccessibilityButtonTargetSelection, this));
         }
     }
 
+    private void sendAccessibilityButtonToInputFilter() {
+        synchronized (mLock) {
+            if (mHasInputFilter && mInputFilter != null) {
+                mInputFilter.notifyAccessibilityButtonClicked();
+            }
+        }
+    }
+
+    private void showAccessibilityButtonTargetSelection() {
+        Intent intent = new Intent(AccessibilityManager.ACTION_CHOOSE_ACCESSIBILITY_BUTTON);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        mContext.startActivityAsUser(intent, UserHandle.of(mCurrentUserId));
+    }
+
     private void notifyAccessibilityButtonVisibilityChangedLocked(boolean available) {
         final UserState state = getCurrentUserStateLocked();
         mIsAccessibilityButtonShown = available;
@@ -1555,28 +1606,54 @@
                 && (mGlobalClients.getRegisteredCallbackCount() > 0
                         || userState.mUserClients.getRegisteredCallbackCount() > 0)) {
             userState.mLastSentClientState = clientState;
-            mMainHandler.obtainMessage(MainHandler.MSG_SEND_STATE_TO_CLIENTS,
-                    clientState, userState.mUserId).sendToTarget();
+            mMainHandler.sendMessage(obtainMessage(
+                    AccessibilityManagerService::sendStateToAllClients,
+                    this, clientState, userState.mUserId));
         }
     }
 
-    private void showAccessibilityButtonTargetSelection() {
-        Intent intent = new Intent(AccessibilityManager.ACTION_CHOOSE_ACCESSIBILITY_BUTTON);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
-        mContext.startActivityAsUser(intent, UserHandle.of(mCurrentUserId));
+    private void sendStateToAllClients(int clientState, int userId) {
+        sendStateToClients(clientState, mGlobalClients);
+        sendStateToClients(clientState, userId);
+    }
+
+    private void sendStateToClients(int clientState, int userId) {
+        sendStateToClients(clientState, getUserState(userId).mUserClients);
+    }
+
+    private void sendStateToClients(int clientState,
+            RemoteCallbackList<IAccessibilityManagerClient> clients) {
+        clients.broadcast(ignoreRemoteException(
+                client -> client.setState(clientState)));
     }
 
     private void scheduleNotifyClientsOfServicesStateChange(UserState userState) {
-        mMainHandler.obtainMessage(MainHandler.MSG_SEND_SERVICES_STATE_CHANGED_TO_CLIENTS,
-                userState.mUserId).sendToTarget();
+        mMainHandler.sendMessage(obtainMessage(
+                AccessibilityManagerService::sendServicesStateChanged,
+                this, userState.mUserClients));
+    }
+
+    private void sendServicesStateChanged(
+            RemoteCallbackList<IAccessibilityManagerClient> userClients) {
+        notifyClientsOfServicesStateChange(mGlobalClients);
+        notifyClientsOfServicesStateChange(userClients);
+    }
+
+    private void notifyClientsOfServicesStateChange(
+            RemoteCallbackList<IAccessibilityManagerClient> clients) {
+        clients.broadcast(ignoreRemoteException(
+                client -> client.notifyServicesStateChanged()));
     }
 
     private void scheduleUpdateInputFilter(UserState userState) {
-        mMainHandler.obtainMessage(MainHandler.MSG_UPDATE_INPUT_FILTER, userState).sendToTarget();
+        mMainHandler.sendMessage(obtainMessage(
+                AccessibilityManagerService::updateInputFilter, this, userState));
     }
 
     private void scheduleUpdateFingerprintGestureHandling(UserState userState) {
-        mMainHandler.obtainMessage(MainHandler.MSG_UPDATE_FINGERPRINT, userState).sendToTarget();
+        mMainHandler.sendMessage(obtainMessage(
+                AccessibilityManagerService::updateFingerprintGestureHandling,
+                this, userState));
     }
 
     private void updateInputFilter(UserState userState) {
@@ -1979,7 +2056,7 @@
         }
 
         ComponentName componentName = ComponentName.unflattenFromString(componentId);
-        if (componentName.equals(userState.mServiceAssignedToAccessibilityButton)) {
+        if (Objects.equals(componentName, userState.mServiceAssignedToAccessibilityButton)) {
             return false;
         }
         userState.mServiceAssignedToAccessibilityButton = componentName;
@@ -2039,9 +2116,9 @@
                 return true;
             } else if (mEnableTouchExplorationDialog == null
                     || !mEnableTouchExplorationDialog.isShowing()) {
-                mMainHandler.obtainMessage(
-                        MainHandler.MSG_SHOW_ENABLED_TOUCH_EXPLORATION_DIALOG,
-                        service).sendToTarget();
+                mMainHandler.sendMessage(obtainMessage(
+                        AccessibilityManagerService::showEnableTouchExplorationDialog,
+                        this, service));
             }
         } else {
             // Starting in JB-MR2 we request an accessibility service to declare
@@ -2293,9 +2370,9 @@
     private void sendAccessibilityEventLocked(AccessibilityEvent event, int userId) {
         // Resync to avoid calling out with the lock held
         event.setEventTime(SystemClock.uptimeMillis());
-        mMainHandler.obtainMessage(
-                MainHandler.MSG_SEND_ACCESSIBILITY_EVENT, userId, 0 /* unused */, event)
-                .sendToTarget();
+        mMainHandler.sendMessage(obtainMessage(
+                AccessibilityManagerService::sendAccessibilityEvent,
+                this, event, userId));
     }
 
     /**
@@ -2419,22 +2496,9 @@
         }
     }
 
+    //TODO remove after refactoring KeyEventDispatcherTest
     final class MainHandler extends Handler {
-        public static final int MSG_SEND_ACCESSIBILITY_EVENT_TO_INPUT_FILTER = 1;
-        public static final int MSG_SEND_STATE_TO_CLIENTS = 2;
-        public static final int MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER = 3;
-        public static final int MSG_ANNOUNCE_NEW_USER_IF_NEEDED = 5;
-        public static final int MSG_UPDATE_INPUT_FILTER = 6;
-        public static final int MSG_SHOW_ENABLED_TOUCH_EXPLORATION_DIALOG = 7;
         public static final int MSG_SEND_KEY_EVENT_TO_INPUT_FILTER = 8;
-        public static final int MSG_CLEAR_ACCESSIBILITY_FOCUS = 9;
-        public static final int MSG_SEND_SERVICES_STATE_CHANGED_TO_CLIENTS = 10;
-        public static final int MSG_UPDATE_FINGERPRINT = 11;
-        public static final int MSG_SEND_RELEVANT_EVENTS_CHANGED_TO_CLIENTS = 12;
-        public static final int MSG_SEND_ACCESSIBILITY_BUTTON_TO_INPUT_FILTER = 13;
-        public static final int MSG_SHOW_ACCESSIBILITY_BUTTON_CHOOSER = 14;
-        public static final int MSG_INIT_SERVICE = 15;
-        public static final int MSG_SEND_ACCESSIBILITY_EVENT = 16;
 
         public MainHandler(Looper looper) {
             super(looper);
@@ -2442,143 +2506,25 @@
 
         @Override
         public void handleMessage(Message msg) {
-            final int type = msg.what;
-            switch (type) {
-                case MSG_SEND_ACCESSIBILITY_EVENT_TO_INPUT_FILTER: {
-                    AccessibilityEvent event = (AccessibilityEvent) msg.obj;
-                    synchronized (mLock) {
-                        if (mHasInputFilter && mInputFilter != null) {
-                            mInputFilter.notifyAccessibilityEvent(event);
-                        }
+            if (msg.what == MSG_SEND_KEY_EVENT_TO_INPUT_FILTER) {
+                KeyEvent event = (KeyEvent) msg.obj;
+                final int policyFlags = msg.arg1;
+                synchronized (mLock) {
+                    if (mHasInputFilter && mInputFilter != null) {
+                        mInputFilter.sendInputEvent(event, policyFlags);
                     }
-                    event.recycle();
-                } break;
-
-                case MSG_SEND_KEY_EVENT_TO_INPUT_FILTER: {
-                    KeyEvent event = (KeyEvent) msg.obj;
-                    final int policyFlags = msg.arg1;
-                    synchronized (mLock) {
-                        if (mHasInputFilter && mInputFilter != null) {
-                            mInputFilter.sendInputEvent(event, policyFlags);
-                        }
-                    }
-                    event.recycle();
-                } break;
-
-                case MSG_SEND_STATE_TO_CLIENTS: {
-                    final int clientState = msg.arg1;
-                    final int userId = msg.arg2;
-                    sendStateToClients(clientState, mGlobalClients);
-                    sendStateToClients(clientState, getUserClientsForId(userId));
-                } break;
-
-                case MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER: {
-                    final int userId = msg.arg1;
-                    sendStateToClients(0, getUserClientsForId(userId));
-                } break;
-
-                case MSG_ANNOUNCE_NEW_USER_IF_NEEDED: {
-                    announceNewUserIfNeeded();
-                } break;
-
-                case MSG_UPDATE_INPUT_FILTER: {
-                    UserState userState = (UserState) msg.obj;
-                    updateInputFilter(userState);
-                } break;
-
-                case MSG_SHOW_ENABLED_TOUCH_EXPLORATION_DIALOG: {
-                    AccessibilityServiceConnection service =
-                            (AccessibilityServiceConnection) msg.obj;
-                    showEnableTouchExplorationDialog(service);
-                } break;
-
-                case MSG_CLEAR_ACCESSIBILITY_FOCUS: {
-                    final int windowId = msg.arg1;
-                    getInteractionBridge().clearAccessibilityFocusNotLocked(windowId);
-                } break;
-
-                case MSG_SEND_SERVICES_STATE_CHANGED_TO_CLIENTS: {
-                    final int userId = msg.arg1;
-                    notifyClientsOfServicesStateChange(mGlobalClients);
-                    notifyClientsOfServicesStateChange(getUserClientsForId(userId));
-                } break;
-
-                case MSG_UPDATE_FINGERPRINT: {
-                    updateFingerprintGestureHandling((UserState) msg.obj);
-                } break;
-
-                case MSG_SEND_RELEVANT_EVENTS_CHANGED_TO_CLIENTS: {
-                    final int userId = msg.arg1;
-                    final int relevantEventTypes = msg.arg2;
-                    final UserState userState;
-                    synchronized (mLock) {
-                        userState = getUserStateLocked(userId);
-                    }
-                    broadcastToClients(userState, ignoreRemoteException(
-                            client -> client.mCallback.setRelevantEventTypes(relevantEventTypes)));
-                } break;
-
-               case MSG_SEND_ACCESSIBILITY_BUTTON_TO_INPUT_FILTER: {
-                    synchronized (mLock) {
-                        if (mHasInputFilter && mInputFilter != null) {
-                            mInputFilter.notifyAccessibilityButtonClicked();
-                        }
-                    }
-                } break;
-
-                case MSG_SHOW_ACCESSIBILITY_BUTTON_CHOOSER: {
-                    showAccessibilityButtonTargetSelection();
-                } break;
-
-                case MSG_INIT_SERVICE: {
-                    final AccessibilityServiceConnection service =
-                            (AccessibilityServiceConnection) msg.obj;
-                    service.initializeService();
-                } break;
-
-                case MSG_SEND_ACCESSIBILITY_EVENT: {
-                    final AccessibilityEvent event = (AccessibilityEvent) msg.obj;
-                    final int userId = msg.arg1;
-                    sendAccessibilityEvent(event, userId);
                 }
+                event.recycle();
             }
         }
+    }
 
-        private void announceNewUserIfNeeded() {
-            synchronized (mLock) {
-                UserState userState = getCurrentUserStateLocked();
-                if (userState.isHandlingAccessibilityEvents()) {
-                    UserManager userManager = (UserManager) mContext.getSystemService(
-                            Context.USER_SERVICE);
-                    String message = mContext.getString(R.string.user_switched,
-                            userManager.getUserInfo(mCurrentUserId).name);
-                    AccessibilityEvent event = AccessibilityEvent.obtain(
-                            AccessibilityEvent.TYPE_ANNOUNCEMENT);
-                    event.getText().add(message);
-                    sendAccessibilityEventLocked(event, mCurrentUserId);
-                }
-            }
-        }
+    void clearAccessibilityFocus(IntSupplier windowId) {
+        clearAccessibilityFocus(windowId.getAsInt());
+    }
 
-        private RemoteCallbackList<IAccessibilityManagerClient> getUserClientsForId(int userId) {
-            final UserState userState;
-            synchronized (mLock) {
-                userState = getUserStateLocked(userId);
-            }
-            return userState.mUserClients;
-        }
-
-        private void sendStateToClients(int clientState,
-                RemoteCallbackList<IAccessibilityManagerClient> clients) {
-            clients.broadcast(ignoreRemoteException(
-                    client -> client.setState(clientState)));
-        }
-
-        private void notifyClientsOfServicesStateChange(
-                RemoteCallbackList<IAccessibilityManagerClient> clients) {
-            clients.broadcast(ignoreRemoteException(
-                    client -> client.notifyServicesStateChanged()));
-        }
+    void clearAccessibilityFocus(int windowId) {
+        getInteractionBridge().clearAccessibilityFocusNotLocked(windowId);
     }
 
     private int findWindowIdLocked(IBinder token) {
@@ -2912,7 +2858,7 @@
          * Has no effect if no item has accessibility focus, if the item with accessibility
          * focus does not expose the specified action, or if the action fails.
          *
-         * @param actionId The id of the action to perform.
+         * @param action The action to perform.
          *
          * @return {@code true} if the action was performed. {@code false} if it was not.
          */
@@ -3353,8 +3299,10 @@
                 case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: {
                     synchronized (mLock) {
                         if (mAccessibilityFocusedWindowId != windowId) {
-                            mMainHandler.obtainMessage(MainHandler.MSG_CLEAR_ACCESSIBILITY_FOCUS,
-                                    mAccessibilityFocusedWindowId, 0).sendToTarget();
+                            mMainHandler.sendMessage(obtainMessage(
+                                    AccessibilityManagerService::clearAccessibilityFocus,
+                                    AccessibilityManagerService.this,
+                                    box(mAccessibilityFocusedWindowId)));
                             mSecurityPolicy.setAccessibilityFocusedWindowLocked(windowId);
                             mAccessibilityFocusNodeId = nodeId;
                         }
@@ -3406,12 +3354,17 @@
                 if (oldActiveWindow != mSecurityPolicy.mActiveWindowId
                         && mAccessibilityFocusedWindowId == oldActiveWindow
                         && getCurrentUserStateLocked().mAccessibilityFocusOnlyInActiveWindow) {
-                    mMainHandler.obtainMessage(MainHandler.MSG_CLEAR_ACCESSIBILITY_FOCUS,
-                            oldActiveWindow, 0).sendToTarget();
+                    mMainHandler.sendMessage(obtainMessage(
+                            AccessibilityManagerService::clearAccessibilityFocus,
+                            AccessibilityManagerService.this, box(oldActiveWindow)));
                 }
             }
         }
 
+        private IntSupplier box(int value) {
+            return PooledLambda.obtainSupplier(value).recycleOnUse();
+        }
+
         public int getActiveWindowId() {
             if (mActiveWindowId == INVALID_WINDOW_ID && !mTouchInteractionInProgress) {
                 mActiveWindowId = getFocusedWindowId();
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
index 96b8979..89bf82d 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
@@ -18,6 +18,8 @@
 
 import static android.provider.Settings.Secure.SHOW_MODE_AUTO;
 
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.accessibilityservice.IAccessibilityServiceClient;
 import android.content.ComponentName;
@@ -158,8 +160,8 @@
             mSystemSupport.onClientChange(false);
             // Initialize the service on the main handler after we're done setting up for
             // the new configuration (for example, initializing the input filter).
-            mMainHandler.obtainMessage(
-                    AccessibilityManagerService.MainHandler.MSG_INIT_SERVICE, this).sendToTarget();
+            mMainHandler.sendMessage(obtainMessage(
+                    AccessibilityServiceConnection::initializeService, this));
         }
     }
 
diff --git a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
index 3419b80..84a8d45 100644
--- a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
@@ -21,7 +21,6 @@
 import android.os.Handler;
 import android.util.Slog;
 import android.view.InputDevice;
-import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.MotionEvent.PointerCoords;
 import android.view.MotionEvent.PointerProperties;
@@ -296,7 +295,8 @@
                 // Already handled.
             } break;
             default:
-                throw new IllegalStateException("Illegal state: " + mCurrentState);
+                Slog.e(LOG_TAG, "Illegal state: " + mCurrentState);
+                clear(event, policyFlags);
         }
     }
 
@@ -649,8 +649,10 @@
         }
         switch (event.getActionMasked()) {
             case MotionEvent.ACTION_DOWN: {
-                throw new IllegalStateException("Dragging state can be reached only if two "
+                Slog.e(LOG_TAG, "Dragging state can be reached only if two "
                         + "pointers are already down");
+                clear(event, policyFlags);
+                return;
             }
             case MotionEvent.ACTION_POINTER_DOWN: {
                 // We are in dragging state so we have two pointers and another one
@@ -741,8 +743,10 @@
     private void handleMotionEventStateDelegating(MotionEvent event, int policyFlags) {
         switch (event.getActionMasked()) {
             case MotionEvent.ACTION_DOWN: {
-                throw new IllegalStateException("Delegating state can only be reached if "
+                Slog.e(LOG_TAG, "Delegating state can only be reached if "
                         + "there is at least one pointer down!");
+                clear(event, policyFlags);
+                return;
             }
             case MotionEvent.ACTION_UP: {
                 // Offset the event if we are doing a long press as the
@@ -1093,7 +1097,7 @@
             case STATE_GESTURE_DETECTING:
                 return "STATE_GESTURE_DETECTING";
             default:
-                throw new IllegalArgumentException("Unknown state: " + state);
+                return "Unknown state: " + state;
         }
     }
 
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index db62961..05237af 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -524,6 +524,7 @@
 
     private void addCompatibilityModeRequestsLocked(@NonNull AutofillManagerServiceImpl service
             , int userId) {
+        mAutofillCompatState.reset();
         final ArrayMap<String, Pair<Long, String>> compatPackages =
                 service.getCompatibilityPackagesLocked();
         if (compatPackages == null || compatPackages.isEmpty()) {
@@ -626,6 +627,15 @@
                 }
             }
         }
+
+        void reset() {
+            synchronized (mLock) {
+                if (mUserSpecs != null) {
+                    mUserSpecs.clear();
+                    mUserSpecs = null;
+                }
+            }
+        }
     }
 
     final class AutoFillManagerServiceStub extends IAutoFillManager.Stub {
@@ -1045,6 +1055,9 @@
                     Settings.Secure.AUTOFILL_SERVICE), false, this, UserHandle.USER_ALL);
             resolver.registerContentObserver(Settings.Secure.getUriFor(
                     Settings.Secure.USER_SETUP_COMPLETE), false, this, UserHandle.USER_ALL);
+            resolver.registerContentObserver(Settings.Global.getUriFor(
+                    Settings.Global.AUTOFILL_COMPAT_ALLOWED_PACKAGES), false, this,
+                    UserHandle.USER_ALL);
         }
 
         @Override
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index c201de4..8622dbe 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -41,6 +41,7 @@
 import android.os.AsyncTask;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.RemoteCallbackList;
@@ -76,7 +77,6 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.os.HandlerCaller;
 import com.android.server.LocalServices;
 import com.android.server.autofill.ui.AutoFillUI;
 
@@ -99,8 +99,6 @@
     /** Minimum interval to prune abandoned sessions */
     private static final int MAX_ABANDONED_SESSION_MILLIS = 30000;
 
-    static final int MSG_SERVICE_SAVE = 1;
-
     private final int mUserId;
     private final Context mContext;
     private final Object mLock;
@@ -151,18 +149,7 @@
     @GuardedBy("mLock")
     private boolean mSetupComplete;
 
-    private final HandlerCaller.Callback mHandlerCallback = (msg) -> {
-        switch (msg.what) {
-            case MSG_SERVICE_SAVE:
-                handleSessionSave(msg.arg1);
-                break;
-            default:
-                Slog.w(TAG, "invalid msg on handler: " + msg);
-        }
-    };
-
-    private final HandlerCaller mHandlerCaller = new HandlerCaller(null, Looper.getMainLooper(),
-            mHandlerCallback, true);
+    private final Handler mHandler = new Handler(Looper.getMainLooper(), null, true);
 
     /**
      * Cache of pending {@link Session}s, keyed by sessionId.
@@ -508,7 +495,7 @@
 
         assertCallerLocked(componentName);
 
-        final Session newSession = new Session(this, mUi, mContext, mHandlerCaller, mUserId, mLock,
+        final Session newSession = new Session(this, mUi, mContext, mHandler, mUserId, mLock,
                 sessionId, uid, activityToken, appCallbackToken, hasCallback, mUiLatencyHistory,
                 mWtfHistory, mInfo.getServiceInfo().getComponentName(), componentName, compatMode,
                 flags);
@@ -597,11 +584,10 @@
         mSessions.remove(sessionId);
     }
 
-    private void handleSessionSave(int sessionId) {
+    void handleSessionSave(Session session) {
         synchronized (mLock) {
-            final Session session = mSessions.get(sessionId);
-            if (session == null) {
-                Slog.w(TAG, "handleSessionSave(): already gone: " + sessionId);
+            if (mSessions.get(session.id) == null) {
+                Slog.w(TAG, "handleSessionSave(): already gone: " + session.id);
 
                 return;
             }
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index fe6d4c4..f7a4b73 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -18,6 +18,7 @@
 
 import static android.service.autofill.FillRequest.INVALID_REQUEST_ID;
 
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
 import static com.android.server.autofill.Helper.sDebug;
 import static com.android.server.autofill.Helper.sVerbose;
 
@@ -32,7 +33,6 @@
 import android.os.IBinder;
 import android.os.IBinder.DeathRecipient;
 import android.os.ICancellationSignal;
-import android.os.Message;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
@@ -47,7 +47,6 @@
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.os.HandlerCaller;
 import com.android.server.FgThread;
 
 import java.io.PrintWriter;
@@ -63,13 +62,14 @@
  */
 final class RemoteFillService implements DeathRecipient {
     private static final String LOG_TAG = "RemoteFillService";
-
     // How long after the last interaction with the service we would unbind
     private static final long TIMEOUT_IDLE_BIND_MILLIS = 5 * DateUtils.SECOND_IN_MILLIS;
 
     // How long after we make a remote request to a fill service we timeout
     private static final long TIMEOUT_REMOTE_REQUEST_MILLIS = 5 * DateUtils.SECOND_IN_MILLIS;
 
+    private static final int MSG_UNBIND = 3;
+
     private final Context mContext;
 
     private final ComponentName mComponentName;
@@ -82,7 +82,7 @@
 
     private final ServiceConnection mServiceConnection = new RemoteServiceConnection();
 
-    private final HandlerCaller mHandler;
+    private final Handler mHandler;
 
     private IAutoFillService mAutoFillService;
 
@@ -115,14 +115,16 @@
         mComponentName = componentName;
         mIntent = new Intent(AutofillService.SERVICE_INTERFACE).setComponent(mComponentName);
         mUserId = userId;
-        mHandler = new MyHandler(context);
+        mHandler = new Handler(FgThread.getHandler().getLooper());
     }
 
     public void destroy() {
-        mHandler.obtainMessage(MyHandler.MSG_DESTROY).sendToTarget();
+        mHandler.sendMessage(obtainMessage(
+                RemoteFillService::handleDestroy, this));
     }
 
     private void handleDestroy() {
+        if (checkIfDestroyed()) return;
         if (mPendingRequest != null) {
             mPendingRequest.cancel();
             mPendingRequest = null;
@@ -133,10 +135,12 @@
 
     @Override
     public void binderDied() {
-        mHandler.obtainMessage(MyHandler.MSG_BINDER_DIED).sendToTarget();
+        mHandler.sendMessage(obtainMessage(
+                RemoteFillService::handleBinderDied, this));
     }
 
     private void handleBinderDied() {
+        if (checkIfDestroyed()) return;
         if (mAutoFillService != null) {
             mAutoFillService.asBinder().unlinkToDeath(this, 0);
         }
@@ -174,14 +178,17 @@
 
     public void onFillRequest(@NonNull FillRequest request) {
         cancelScheduledUnbind();
-        final PendingFillRequest pendingRequest = new PendingFillRequest(request, this);
-        mHandler.obtainMessageO(MyHandler.MSG_ON_PENDING_REQUEST, pendingRequest).sendToTarget();
+        scheduleRequest(new PendingFillRequest(request, this));
     }
 
     public void onSaveRequest(@NonNull SaveRequest request) {
         cancelScheduledUnbind();
-        final PendingSaveRequest pendingRequest = new PendingSaveRequest(request, this);
-        mHandler.obtainMessageO(MyHandler.MSG_ON_PENDING_REQUEST, pendingRequest).sendToTarget();
+        scheduleRequest(new PendingSaveRequest(request, this));
+    }
+
+    private void scheduleRequest(PendingRequest pendingRequest) {
+        mHandler.sendMessage(obtainMessage(
+                RemoteFillService::handlePendingRequest, this, pendingRequest));
     }
 
     // Note: we are dumping without a lock held so this is a bit racy but
@@ -204,21 +211,25 @@
     }
 
     private void cancelScheduledUnbind() {
-        mHandler.removeMessages(MyHandler.MSG_UNBIND);
+        mHandler.removeMessages(MSG_UNBIND);
     }
 
     private void scheduleUnbind() {
         cancelScheduledUnbind();
-        Message message = mHandler.obtainMessage(MyHandler.MSG_UNBIND);
-        mHandler.sendMessageDelayed(message, TIMEOUT_IDLE_BIND_MILLIS);
+        mHandler.sendMessageDelayed(
+                obtainMessage(RemoteFillService::handleUnbind, this)
+                        .setWhat(MSG_UNBIND),
+                TIMEOUT_IDLE_BIND_MILLIS);
     }
 
     private void handleUnbind() {
+        if (checkIfDestroyed()) return;
         ensureUnbound();
     }
 
     private void handlePendingRequest(PendingRequest pendingRequest) {
-        if (mDestroyed || mCompleted) {
+        if (checkIfDestroyed()) return;
+        if (mCompleted) {
             return;
         }
         if (!isBound()) {
@@ -283,7 +294,7 @@
 
     private void dispatchOnFillRequestSuccess(PendingRequest pendingRequest, int requestFlags,
             FillResponse response) {
-        mHandler.getHandler().post(() -> {
+        mHandler.post(() -> {
             if (handleResponseCallbackCommon(pendingRequest)) {
                 mCallbacks.onFillRequestSuccess(requestFlags, response,
                         mComponentName.getPackageName());
@@ -293,7 +304,7 @@
 
     private void dispatchOnFillRequestFailure(PendingRequest pendingRequest,
             @Nullable CharSequence message) {
-        mHandler.getHandler().post(() -> {
+        mHandler.post(() -> {
             if (handleResponseCallbackCommon(pendingRequest)) {
                 mCallbacks.onFillRequestFailure(message, mComponentName.getPackageName());
             }
@@ -301,7 +312,7 @@
     }
 
     private void dispatchOnFillTimeout(@NonNull ICancellationSignal cancellationSignal) {
-        mHandler.getHandler().post(() -> {
+        mHandler.post(() -> {
             try {
                 cancellationSignal.cancel();
             } catch (RemoteException e) {
@@ -312,7 +323,7 @@
 
     private void dispatchOnSaveRequestSuccess(PendingRequest pendingRequest,
             IntentSender intentSender) {
-        mHandler.getHandler().post(() -> {
+        mHandler.post(() -> {
             if (handleResponseCallbackCommon(pendingRequest)) {
                 mCallbacks.onSaveRequestSuccess(mComponentName.getPackageName(), intentSender);
             }
@@ -321,7 +332,7 @@
 
     private void dispatchOnSaveRequestFailure(PendingRequest pendingRequest,
             @Nullable CharSequence message) {
-        mHandler.getHandler().post(() -> {
+        mHandler.post(() -> {
             if (handleResponseCallbackCommon(pendingRequest)) {
                 mCallbacks.onSaveRequestFailure(message, mComponentName.getPackageName());
             }
@@ -345,7 +356,8 @@
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
             if (mDestroyed || !mBinding) {
-                mContext.unbindService(mServiceConnection);
+                // This is abnormal. Unbinding the connection has been requested already.
+                Slog.wtf(LOG_TAG, "onServiceConnected was dispatched after unbindService.");
                 return;
             }
             mBinding = false;
@@ -378,44 +390,14 @@
         }
     }
 
-    private final class MyHandler extends HandlerCaller {
-        public static final int MSG_DESTROY = 1;
-        public static final int MSG_BINDER_DIED = 2;
-        public static final int MSG_UNBIND = 3;
-        public static final int MSG_ON_PENDING_REQUEST = 4;
-
-        public MyHandler(Context context) {
-            // Cannot use lambda - doesn't compile
-            super(context, FgThread.getHandler().getLooper(), new Callback() {
-                @Override
-                public void executeMessage(Message message) {
-                    if (mDestroyed) {
-                        if (sVerbose) {
-                            Slog.v(LOG_TAG, "Not handling " + message + " as service for "
-                                    + mComponentName + " is already destroyed");
-                        }
-                        return;
-                    }
-                    switch (message.what) {
-                        case MSG_DESTROY: {
-                            handleDestroy();
-                        } break;
-
-                        case MSG_BINDER_DIED: {
-                            handleBinderDied();
-                        } break;
-
-                        case MSG_UNBIND: {
-                            handleUnbind();
-                        } break;
-
-                        case MSG_ON_PENDING_REQUEST: {
-                            handlePendingRequest((PendingRequest) message.obj);
-                        } break;
-                    }
-                }
-            }, false);
+    private boolean checkIfDestroyed() {
+        if (mDestroyed) {
+            if (sVerbose) {
+                Slog.v(LOG_TAG, "Not handling operation as service for "
+                        + mComponentName + " is already destroyed");
+            }
         }
+        return mDestroyed;
     }
 
     private static abstract class PendingRequest implements Runnable {
@@ -433,7 +415,7 @@
 
         PendingRequest(RemoteFillService service) {
             mWeakService = new WeakReference<>(service);
-            mServiceHandler = service.mHandler.getHandler();
+            mServiceHandler = service.mHandler;
             mTimeoutTrigger = () -> {
                 synchronized (mLock) {
                     if (mCancelled) {
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index ef6ed08..bcfe1b6 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -26,6 +26,7 @@
 import static android.view.autofill.AutofillManager.ACTION_VIEW_ENTERED;
 import static android.view.autofill.AutofillManager.ACTION_VIEW_EXITED;
 
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
 import static com.android.server.autofill.Helper.sDebug;
 import static com.android.server.autofill.Helper.sPartitionMaxCount;
 import static com.android.server.autofill.Helper.sVerbose;
@@ -49,6 +50,7 @@
 import android.metrics.LogMaker;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.IBinder;
 import android.os.Parcelable;
 import android.os.RemoteCallback;
@@ -74,6 +76,7 @@
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.TimeUtils;
+import android.view.KeyEvent;
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillManager;
 import android.view.autofill.AutofillValue;
@@ -117,7 +120,7 @@
     private static final String EXTRA_REQUEST_ID = "android.service.autofill.extra.REQUEST_ID";
 
     private final AutofillManagerServiceImpl mService;
-    private final HandlerCaller mHandlerCaller;
+    private final Handler mHandler;
     private final Object mLock;
     private final AutoFillUI mUi;
 
@@ -485,7 +488,7 @@
     }
 
     Session(@NonNull AutofillManagerServiceImpl service, @NonNull AutoFillUI ui,
-            @NonNull Context context, @NonNull HandlerCaller handlerCaller, int userId,
+            @NonNull Context context, @NonNull Handler handler, int userId,
             @NonNull Object lock, int sessionId, int uid, @NonNull IBinder activityToken,
             @NonNull IBinder client, boolean hasCallback, @NonNull LocalLog uiLatencyHistory,
             @NonNull LocalLog wtfHistory,
@@ -498,7 +501,7 @@
         mService = service;
         mLock = lock;
         mUi = ui;
-        mHandlerCaller = handlerCaller;
+        mHandler = handler;
         mRemoteFillService = new RemoteFillService(context, serviceComponentName, userId, this);
         mActivityToken = activityToken;
         mHasCallback = hasCallback;
@@ -726,8 +729,9 @@
         mService.setAuthenticationSelected(id, mClientState);
 
         final int authenticationId = AutofillManager.makeAuthenticationId(requestId, datasetIndex);
-        mHandlerCaller.getHandler().post(() -> startAuthentication(authenticationId,
-                intent, fillInIntent));
+        mHandler.sendMessage(obtainMessage(
+                Session::startAuthentication,
+                this, authenticationId, intent, fillInIntent));
     }
 
     // FillServiceCallbacks
@@ -746,7 +750,9 @@
                 return;
             }
         }
-        mHandlerCaller.getHandler().post(() -> autoFill(requestId, datasetIndex, dataset, true));
+        mHandler.sendMessage(obtainMessage(
+                Session::autoFill,
+                this, requestId, datasetIndex, dataset, true));
     }
 
     // AutoFillUiCallback
@@ -759,9 +765,9 @@
                 return;
             }
         }
-        mHandlerCaller.getHandler()
-                .obtainMessage(AutofillManagerServiceImpl.MSG_SERVICE_SAVE, id, 0)
-                .sendToTarget();
+        mHandler.sendMessage(obtainMessage(
+                AutofillManagerServiceImpl::handleSessionSave,
+                mService, this));
     }
 
     // AutoFillUiCallback
@@ -776,7 +782,8 @@
                 return;
             }
         }
-        mHandlerCaller.getHandler().post(() -> removeSelf());
+        mHandler.sendMessage(obtainMessage(
+                Session::removeSelf, this));
     }
 
     // AutoFillUiCallback
@@ -806,6 +813,27 @@
         }
     }
 
+    @Override
+    public void dispatchUnhandledKey(AutofillId id, KeyEvent keyEvent) {
+        synchronized (mLock) {
+            if (mDestroyed) {
+                Slog.w(TAG, "Call to Session#dispatchUnhandledKey() rejected - session: "
+                        + id + " destroyed");
+                return;
+            }
+            if (id.equals(mCurrentViewId)) {
+                try {
+                    mClient.dispatchUnhandledKey(this.id, id, keyEvent);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Error requesting to dispatch unhandled key", e);
+                }
+            } else {
+                Slog.w(TAG, "Do not dispatch unhandled key on " + id
+                        + " as it is not the current view (" + mCurrentViewId + ") anymore");
+            }
+        }
+    }
+
     // AutoFillUiCallback
     @Override
     public void requestHideFillUi(AutofillId id) {
@@ -831,15 +859,19 @@
             }
             removeSelfLocked();
         }
-        mHandlerCaller.getHandler().post(() -> {
-            try {
-                synchronized (mLock) {
-                    mClient.startIntentSender(intentSender, null);
-                }
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Error launching auth intent", e);
+        mHandler.sendMessage(obtainMessage(
+                Session::doStartIntentSender,
+                this, intentSender));
+    }
+
+    private void doStartIntentSender(IntentSender intentSender) {
+        try {
+            synchronized (mLock) {
+                mClient.startIntentSender(intentSender, null);
             }
-        });
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Error launching auth intent", e);
+        }
     }
 
     @GuardedBy("mLock")
@@ -960,11 +992,14 @@
      * when necessary.
      */
     public void logContextCommitted() {
-        mHandlerCaller.getHandler().post(() -> {
-            synchronized (mLock) {
-                logContextCommittedLocked();
-            }
-        });
+        mHandler.sendMessage(obtainMessage(
+                Session::doLogContextCommitted, this));
+    }
+
+    private void doLogContextCommitted() {
+        synchronized (mLock) {
+            logContextCommittedLocked();
+        }
     }
 
     @GuardedBy("mLock")
@@ -1486,7 +1521,8 @@
                 }
 
                 // Use handler so logContextCommitted() is logged first
-                mHandlerCaller.getHandler().post(() -> mService.logSaveShown(id, mClientState));
+                mHandler.sendMessage(obtainMessage(
+                        Session::logSaveShown, this));
 
                 final IAutoFillManagerClient client = getClient();
                 mPendingSaveUi = new PendingUi(mActivityToken, id, client);
@@ -1514,6 +1550,10 @@
         return true;
     }
 
+    private void logSaveShown() {
+        mService.logSaveShown(id, mClientState);
+    }
+
     @Nullable
     private ArrayMap<AutofillId, InternalSanitizer> createSanitizers(@Nullable SaveInfo saveInfo) {
         if (saveInfo == null) return null;
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index dc36518..e28a204 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -34,6 +34,7 @@
 import android.service.autofill.ValueFinder;
 import android.text.TextUtils;
 import android.util.Slog;
+import android.view.KeyEvent;
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillManager;
 import android.view.autofill.IAutofillWindowPresenter;
@@ -78,6 +79,7 @@
                 IAutofillWindowPresenter presenter);
         void requestHideFillUi(AutofillId id);
         void startIntentSender(IntentSender intentSender);
+        void dispatchUnhandledKey(AutofillId id, KeyEvent keyEvent);
     }
 
     public AutoFillUI(@NonNull Context context) {
@@ -240,6 +242,13 @@
                         mCallback.startIntentSender(intentSender);
                     }
                 }
+
+                @Override
+                public void dispatchUnhandledKey(KeyEvent keyEvent) {
+                    if (mCallback != null) {
+                        mCallback.dispatchUnhandledKey(focusedId, keyEvent);
+                    }
+                }
             });
         });
     }
diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
index d64244d..dbed242 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -18,6 +18,7 @@
 import static com.android.server.autofill.Helper.sDebug;
 import static com.android.server.autofill.Helper.sVerbose;
 
+import android.annotation.AttrRes;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.PendingIntent;
@@ -31,8 +32,10 @@
 import android.service.autofill.Dataset.DatasetFieldFilter;
 import android.service.autofill.FillResponse;
 import android.text.TextUtils;
+import android.util.AttributeSet;
 import android.util.Slog;
 import android.util.TypedValue;
+import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
@@ -47,6 +50,7 @@
 import android.widget.BaseAdapter;
 import android.widget.Filter;
 import android.widget.Filterable;
+import android.widget.FrameLayout;
 import android.widget.ListView;
 import android.widget.RemoteViews;
 
@@ -69,6 +73,28 @@
 
     private static final TypedValue sTempTypedValue = new TypedValue();
 
+    public static final class AutofillFrameLayout extends FrameLayout {
+
+        OnKeyListener mUnhandledListener;
+
+        public AutofillFrameLayout(Context context, AttributeSet attrs) {
+            super(context, attrs);
+        }
+
+        public AutofillFrameLayout(Context context, AttributeSet attrs, @AttrRes int defStyleAttr) {
+            super(context, attrs, defStyleAttr);
+        }
+
+        @Override
+        public boolean dispatchKeyEvent(KeyEvent event) {
+            boolean handled = super.dispatchKeyEvent(event);
+            if (!handled) {
+                handled = mUnhandledListener.onKey(this, event.getKeyCode(), event);
+            }
+            return handled;
+        }
+    }
+
     interface Callback {
         void onResponsePicked(@NonNull FillResponse response);
         void onDatasetPicked(@NonNull Dataset dataset);
@@ -78,6 +104,7 @@
                 IAutofillWindowPresenter windowPresenter);
         void requestHideFillUi();
         void startIntentSender(IntentSender intentSender);
+        void dispatchUnhandledKey(KeyEvent keyEvent);
     }
 
     private final @NonNull Point mTempPoint = new Point();
@@ -122,6 +149,31 @@
                 mFullScreen ? R.layout.autofill_dataset_picker_fullscreen
                         : R.layout.autofill_dataset_picker, null);
 
+        // if autofill ui is not fullscreen, send unhandled keyevent to app window.
+        if (!mFullScreen) {
+            if (decor instanceof AutofillFrameLayout) {
+                ((AutofillFrameLayout) decor).mUnhandledListener =
+                        (View view, int keyCode, KeyEvent event) -> {
+                            switch (keyCode) {
+                                case KeyEvent.KEYCODE_BACK:
+                                case KeyEvent.KEYCODE_ESCAPE:
+                                case KeyEvent.KEYCODE_ENTER:
+                                case KeyEvent.KEYCODE_DPAD_CENTER:
+                                case KeyEvent.KEYCODE_DPAD_LEFT:
+                                case KeyEvent.KEYCODE_DPAD_UP:
+                                case KeyEvent.KEYCODE_DPAD_RIGHT:
+                                case KeyEvent.KEYCODE_DPAD_DOWN:
+                                    return false;
+                                default:
+                                    mCallback.dispatchUnhandledKey(event);
+                                    return true;
+                            }
+                        };
+            } else {
+                Slog.wtf(TAG, "Unable to send unhandled key");
+            }
+        }
+
         final RemoteViews.OnClickHandler interceptionHandler = new RemoteViews.OnClickHandler() {
             @Override
             public boolean onClickHandler(View view, PendingIntent pendingIntent,
@@ -538,7 +590,7 @@
         }
     }
 
-    final class AnchoredWindow implements View.OnTouchListener {
+    final class AnchoredWindow {
         private final @NonNull OverlayControl mOverlayControl;
         private final WindowManager mWm;
         private final View mContentView;
@@ -571,7 +623,6 @@
                     params.accessibilityTitle = mContentView.getContext()
                             .getString(R.string.autofill_picker_accessibility_title);
                     mWm.addView(mContentView, params);
-                    mContentView.setOnTouchListener(this);
                     mOverlayControl.hideOverlays();
                     mShowing = true;
                 } else {
@@ -595,7 +646,6 @@
         void hide() {
             try {
                 if (mShowing) {
-                    mContentView.setOnTouchListener(null);
                     mWm.removeView(mContentView);
                     mShowing = false;
                 }
@@ -609,16 +659,6 @@
                 mOverlayControl.showOverlays();
             }
         }
-
-        @Override
-        public boolean onTouch(View view, MotionEvent event) {
-            // When the window is touched outside, hide the window.
-            if (view == mContentView && event.getAction() == MotionEvent.ACTION_OUTSIDE) {
-                mCallback.onCanceled();
-                return true;
-            }
-            return false;
-        }
     }
 
     public void dump(PrintWriter pw, String prefix) {
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 83367f3..369df54 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -2357,7 +2357,7 @@
 
         // If the caller does not hold the BACKUP permission, it can only request a
         // wipe of its own backed-up data.
-        HashSet<String> apps;
+        Set<String> apps;
         if ((mContext.checkPermission(android.Manifest.permission.BACKUP, Binder.getCallingPid(),
                 Binder.getCallingUid())) == PackageManager.PERMISSION_DENIED) {
             apps = mBackupParticipants.get(Binder.getCallingUid());
@@ -2365,10 +2365,9 @@
             // a caller with full permission can ask to back up any participating app
             // !!! TODO: allow data-clear of ANY app?
             if (MORE_DEBUG) Slog.v(TAG, "Privileged caller, allowing clear of other apps");
-            apps = SparseArrayUtils.union(mBackupParticipants);
+            apps = mProcessedPackagesJournal.getPackagesCopy();
         }
 
-        // Is the given app an available participant?
         if (apps.contains(packageName)) {
             // found it; fire off the clear request
             if (MORE_DEBUG) Slog.v(TAG, "Found the app - running clear process");
@@ -3556,6 +3555,7 @@
                     + (this.mPendingInits.size() == 0 ? "not " : "") + "pending init");
             pw.println("Auto-restore is " + (mAutoRestore ? "enabled" : "disabled"));
             if (mBackupRunning) pw.println("Backup currently running");
+            pw.println(isBackupOperationInProgress() ? "Backup in progress" : "No backups running");
             pw.println("Last backup pass started: " + mLastBackupPass
                     + " (now = " + System.currentTimeMillis() + ')');
             pw.println("  next scheduled: " + KeyValueBackupJob.nextScheduled());
diff --git a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
index 3cf374f..4443130 100644
--- a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
+++ b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
@@ -23,6 +23,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.ResolveInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.Signature;
@@ -30,6 +31,7 @@
 import android.os.ParcelFileDescriptor;
 import android.util.Slog;
 
+import com.android.server.LocalServices;
 import com.android.server.backup.utils.AppBackupUtils;
 
 import java.io.BufferedInputStream;
@@ -235,7 +237,7 @@
         if (home != null) {
             try {
                 homeInfo = mPackageManager.getPackageInfo(home.getPackageName(),
-                        PackageManager.GET_SIGNATURES);
+                        PackageManager.GET_SIGNING_CERTIFICATES);
                 homeInstaller = mPackageManager.getInstallerPackageName(home.getPackageName());
                 homeVersion = homeInfo.getLongVersionCode();
                 homeSigHashes = BackupUtils.hashSignatureArray(homeInfo.signatures);
@@ -252,10 +254,11 @@
             //    2. the home app [or absence] we now use differs from the prior state,
             // OR 3. it looks like we use the same home app + version as before, but
             //       the signatures don't match so we treat them as different apps.
+            PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
             final boolean needHomeBackup = (homeVersion != mStoredHomeVersion)
                     || !Objects.equals(home, mStoredHomeComponent)
                     || (home != null
-                        && !BackupUtils.signaturesMatch(mStoredHomeSigHashes, homeInfo));
+                        && !BackupUtils.signaturesMatch(mStoredHomeSigHashes, homeInfo, pmi));
             if (needHomeBackup) {
                 if (DEBUG) {
                     Slog.i(TAG, "Home preference changed; backing up new state " + home);
diff --git a/services/backup/java/com/android/server/backup/TransportManager.java b/services/backup/java/com/android/server/backup/TransportManager.java
index 501ff29..c87d298 100644
--- a/services/backup/java/com/android/server/backup/TransportManager.java
+++ b/services/backup/java/com/android/server/backup/TransportManager.java
@@ -19,6 +19,7 @@
 import android.annotation.Nullable;
 import android.annotation.WorkerThread;
 import android.app.backup.BackupManager;
+import android.app.backup.BackupTransport;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -58,8 +59,6 @@
     @VisibleForTesting
     public static final String SERVICE_ACTION_TRANSPORT_HOST = "android.backup.TRANSPORT_HOST";
 
-    private static final String EXTRA_TRANSPORT_REGISTRATION = "transport_registration";
-
     private final Intent mTransportServiceIntent = new Intent(SERVICE_ACTION_TRANSPORT_HOST);
     private final Context mContext;
     private final PackageManager mPackageManager;
@@ -587,7 +586,7 @@
         String callerLogString = "TransportManager.registerTransport()";
 
         Bundle extras = new Bundle();
-        extras.putBoolean(EXTRA_TRANSPORT_REGISTRATION, true);
+        extras.putBoolean(BackupTransport.EXTRA_TRANSPORT_REGISTRATION, true);
 
         TransportClient transportClient = mTransportClientManager.getTransportClient(
             transportComponent, extras, callerLogString);
diff --git a/services/backup/java/com/android/server/backup/internal/BackupHandler.java b/services/backup/java/com/android/server/backup/internal/BackupHandler.java
index 3df6e47..136fada 100644
--- a/services/backup/java/com/android/server/backup/internal/BackupHandler.java
+++ b/services/backup/java/com/android/server/backup/internal/BackupHandler.java
@@ -302,7 +302,7 @@
                     sets = transport.getAvailableRestoreSets();
                     // cache the result in the active session
                     synchronized (params.session) {
-                        params.session.mRestoreSets = sets;
+                        params.session.setRestoreSets(sets);
                     }
                     if (sets == null) {
                         EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
diff --git a/services/backup/java/com/android/server/backup/params/RestoreParams.java b/services/backup/java/com/android/server/backup/params/RestoreParams.java
index e500d6e..5125b0d 100644
--- a/services/backup/java/com/android/server/backup/params/RestoreParams.java
+++ b/services/backup/java/com/android/server/backup/params/RestoreParams.java
@@ -16,6 +16,7 @@
 
 package com.android.server.backup.params;
 
+import android.annotation.Nullable;
 import android.app.backup.IBackupManagerMonitor;
 import android.app.backup.IRestoreObserver;
 import android.content.pm.PackageInfo;
@@ -28,10 +29,10 @@
     public final IRestoreObserver observer;
     public final IBackupManagerMonitor monitor;
     public final long token;
-    public final PackageInfo packageInfo;
+    @Nullable public final PackageInfo packageInfo;
     public final int pmToken; // in post-install restore, the PM's token for this transaction
     public final boolean isSystemRestore;
-    public final String[] filterSet;
+    @Nullable public final String[] filterSet;
     public final OnTaskFinishedListener listener;
 
     /**
@@ -129,10 +130,10 @@
             IRestoreObserver observer,
             IBackupManagerMonitor monitor,
             long token,
-            PackageInfo packageInfo,
+            @Nullable PackageInfo packageInfo,
             int pmToken,
             boolean isSystemRestore,
-            String[] filterSet,
+            @Nullable String[] filterSet,
             OnTaskFinishedListener listener) {
         this.transportClient = transportClient;
         this.observer = observer;
diff --git a/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java b/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java
index 238f7a0..140dded 100644
--- a/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java
+++ b/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java
@@ -22,6 +22,7 @@
 import static com.android.server.backup.internal.BackupHandler.MSG_RUN_GET_RESTORE_SETS;
 import static com.android.server.backup.internal.BackupHandler.MSG_RUN_RESTORE;
 
+import android.annotation.Nullable;
 import android.app.backup.IBackupManagerMonitor;
 import android.app.backup.IRestoreObserver;
 import android.app.backup.IRestoreSession;
@@ -53,13 +54,15 @@
     private final TransportManager mTransportManager;
     private final String mTransportName;
     private final BackupManagerService mBackupManagerService;
-    private final String mPackageName;
+    @Nullable private final String mPackageName;
     public RestoreSet[] mRestoreSets = null;
     boolean mEnded = false;
     boolean mTimedOut = false;
 
-    public ActiveRestoreSession(BackupManagerService backupManagerService,
-            String packageName, String transportName) {
+    public ActiveRestoreSession(
+            BackupManagerService backupManagerService,
+            @Nullable String packageName,
+            String transportName) {
         mBackupManagerService = backupManagerService;
         mPackageName = packageName;
         mTransportManager = backupManagerService.getTransportManager();
@@ -360,6 +363,10 @@
         }
     }
 
+    public void setRestoreSets(RestoreSet[] restoreSets) {
+        mRestoreSets = restoreSets;
+    }
+
     /**
      * Returns 0 if operation sent or -1 otherwise.
      */
diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
index 0ca4f25..c1a1c1d 100644
--- a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
+++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
@@ -36,11 +36,13 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.Signature;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.util.Slog;
 
+import com.android.server.LocalServices;
 import com.android.server.backup.BackupRestoreTask;
 import com.android.server.backup.FileMetadata;
 import com.android.server.backup.KeyValueAdbRestoreEngine;
@@ -207,8 +209,11 @@
                 if (info.path.equals(BACKUP_MANIFEST_FILENAME)) {
                     Signature[] signatures = tarBackupReader.readAppManifestAndReturnSignatures(
                             info);
+                    PackageManagerInternal pmi = LocalServices.getService(
+                            PackageManagerInternal.class);
                     RestorePolicy restorePolicy = tarBackupReader.chooseRestorePolicy(
-                            mBackupManagerService.getPackageManager(), allowApks, info, signatures);
+                            mBackupManagerService.getPackageManager(), allowApks, info, signatures,
+                            pmi);
                     mManifestSignatures.put(info.packageName, signatures);
                     mPackagePolicies.put(pkg, restorePolicy);
                     mPackageInstallers.put(pkg, info.installerPackageName);
diff --git a/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
index e576b3c..dacde0b 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
@@ -40,6 +40,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.Signature;
 import android.os.Environment;
 import android.os.ParcelFileDescriptor;
@@ -47,6 +48,7 @@
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.LocalServices;
 import com.android.server.backup.BackupManagerService;
 import com.android.server.backup.FileMetadata;
 import com.android.server.backup.KeyValueAdbRestoreEngine;
@@ -470,9 +472,11 @@
                 if (info.path.equals(BACKUP_MANIFEST_FILENAME)) {
                     Signature[] signatures = tarBackupReader.readAppManifestAndReturnSignatures(
                             info);
+                    PackageManagerInternal pmi = LocalServices.getService(
+                            PackageManagerInternal.class);
                     RestorePolicy restorePolicy = tarBackupReader.chooseRestorePolicy(
                             mBackupManagerService.getPackageManager(), allowApks,
-                            info, signatures);
+                            info, signatures, pmi);
                     mManifestSignatures.put(info.packageName, signatures);
                     mPackagePolicies.put(pkg, restorePolicy);
                     mPackageInstallers.put(pkg, info.installerPackageName);
diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
index 6eb9619..4b467e5 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
@@ -30,6 +30,7 @@
 import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERATION_TIMEOUT;
 import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_SESSION_TIMEOUT;
 
+import android.annotation.Nullable;
 import android.app.ApplicationThreadConstants;
 import android.app.IBackupAgent;
 import android.app.backup.BackupDataInput;
@@ -42,6 +43,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.Bundle;
 import android.os.Message;
@@ -56,6 +58,7 @@
 import com.android.internal.backup.IBackupTransport;
 import com.android.server.AppWidgetBackupBridge;
 import com.android.server.EventLogTags;
+import com.android.server.LocalServices;
 import com.android.server.backup.BackupRestoreTask;
 import com.android.server.backup.BackupUtils;
 import com.android.server.backup.PackageManagerBackupAgent;
@@ -158,12 +161,18 @@
 
     private final int mEphemeralOpToken;
 
-    // Invariant: mWakelock is already held, and this task is responsible for
-    // releasing it at the end of the restore operation.
-    public PerformUnifiedRestoreTask(BackupManagerService backupManagerService,
-            TransportClient transportClient, IRestoreObserver observer,
-            IBackupManagerMonitor monitor, long restoreSetToken, PackageInfo targetPackage,
-            int pmToken, boolean isFullSystemRestore, String[] filterSet,
+    // This task can assume that the wakelock is properly held for it and doesn't have to worry
+    // about releasing it.
+    public PerformUnifiedRestoreTask(
+            BackupManagerService backupManagerService,
+            TransportClient transportClient,
+            IRestoreObserver observer,
+            IBackupManagerMonitor monitor,
+            long restoreSetToken,
+            @Nullable PackageInfo targetPackage,
+            int pmToken,
+            boolean isFullSystemRestore,
+            @Nullable String[] filterSet,
             OnTaskFinishedListener listener) {
         this.backupManagerService = backupManagerService;
         mTransportManager = backupManagerService.getTransportManager();
@@ -336,7 +345,7 @@
      *
      *   [ state change => FINAL ]
      *
-     * 7. t.finishRestore(), release wakelock, etc.
+     * 7. t.finishRestore(), call listeners, etc.
      *
      *
      */
@@ -497,7 +506,7 @@
 
             try {
                 mCurrentPackage = backupManagerService.getPackageManager().getPackageInfo(
-                        pkgName, PackageManager.GET_SIGNATURES);
+                        pkgName, PackageManager.GET_SIGNING_CERTIFICATES);
             } catch (NameNotFoundException e) {
                 // Whoops, we thought we could restore this package but it
                 // turns out not to be present.  Skip it.
@@ -612,7 +621,8 @@
         }
 
         Metadata metaInfo = mPmAgent.getRestoredMetadata(packageName);
-        if (!BackupUtils.signaturesMatch(metaInfo.sigHashes, mCurrentPackage)) {
+        PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
+        if (!BackupUtils.signaturesMatch(metaInfo.sigHashes, mCurrentPackage, pmi)) {
             Slog.w(TAG, "Signature mismatch restoring " + packageName);
             mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
                     BackupManagerMonitor.LOG_EVENT_ID_SIGNATURE_MISMATCH, mCurrentPackage,
diff --git a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
index 6780563..90c1387 100644
--- a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
@@ -25,6 +25,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.Signature;
 import android.os.Process;
 import android.util.Slog;
@@ -37,6 +38,9 @@
  * Utility methods wrapping operations on ApplicationInfo and PackageInfo.
  */
 public class AppBackupUtils {
+
+    private static final boolean DEBUG = false;
+
     /**
      * Returns whether app is eligible for backup.
      *
@@ -88,7 +92,8 @@
     public static boolean appIsRunningAndEligibleForBackupWithTransport(
             @Nullable TransportClient transportClient, String packageName, PackageManager pm) {
         try {
-            PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
+            PackageInfo packageInfo = pm.getPackageInfo(packageName,
+                    PackageManager.GET_SIGNING_CERTIFICATES);
             ApplicationInfo applicationInfo = packageInfo.applicationInfo;
             if (!appIsEligibleForBackup(applicationInfo, pm)
                     || appIsStopped(applicationInfo)
@@ -165,12 +170,18 @@
      *
      * <ul>
      *   <li>Source and target have at least one signature each
-     *   <li>Target contains all signatures in source
+     *   <li>Target contains all signatures in source, and nothing more
      * </ul>
      *
+     * or if both source and target have exactly one signature, and they don't match, we check
+     * if the app was ever signed with source signature (i.e. app has rotated key)
+     * Note: key rotation is only supported for apps ever signed with one key, and those apps will
+     * not be allowed to be signed by more certificates in the future
+     *
      * Note that if {@param target} is null we return false.
      */
-    public static boolean signaturesMatch(Signature[] storedSigs, PackageInfo target) {
+    public static boolean signaturesMatch(Signature[] storedSigs, PackageInfo target,
+            PackageManagerInternal pmi) {
         if (target == null) {
             return false;
         }
@@ -187,33 +198,52 @@
             return true;
         }
 
-        Signature[] deviceSigs = target.signatures;
-        if (MORE_DEBUG) {
-            Slog.v(TAG, "signaturesMatch(): stored=" + storedSigs + " device=" + deviceSigs);
-        }
-
         // Don't allow unsigned apps on either end
-        if (ArrayUtils.isEmpty(storedSigs) || ArrayUtils.isEmpty(deviceSigs)) {
+        if (ArrayUtils.isEmpty(storedSigs)) {
             return false;
         }
 
-        // Signatures can be added over time, so the target-device apk needs to contain all the
-        // source-device apk signatures, but not necessarily the other way around.
-        int nStored = storedSigs.length;
-        int nDevice = deviceSigs.length;
+        Signature[][] deviceHistorySigs = target.signingCertificateHistory;
+        if (ArrayUtils.isEmpty(deviceHistorySigs)) {
+            Slog.w(TAG, "signingCertificateHistory is empty, app was either unsigned or the flag" +
+                    " PackageManager#GET_SIGNING_CERTIFICATES was not specified");
+            return false;
+        }
 
-        for (int i = 0; i < nStored; i++) {
-            boolean match = false;
-            for (int j = 0; j < nDevice; j++) {
-                if (storedSigs[i].equals(deviceSigs[j])) {
-                    match = true;
-                    break;
+        if (DEBUG) {
+            Slog.v(TAG, "signaturesMatch(): stored=" + storedSigs + " device=" + deviceHistorySigs);
+        }
+
+        final int nStored = storedSigs.length;
+        if (nStored == 1) {
+            // if the app is only signed with one sig, it's possible it has rotated its key
+            // (the checks with signing history are delegated to PackageManager)
+            // TODO: address the case that app has declared restoreAnyVersion and is restoring
+            // from higher version to lower after having rotated the key (i.e. higher version has
+            // different sig than lower version that we want to restore to)
+            return pmi.isDataRestoreSafe(storedSigs[0], target.packageName);
+        } else {
+            // the app couldn't have rotated keys, since it was signed with multiple sigs - do
+            // a comprehensive 1-to-1 signatures check
+            // since app hasn't rotated key, we only need to check with deviceHistorySigs[0]
+            Signature[] deviceSigs = deviceHistorySigs[0];
+            int nDevice = deviceSigs.length;
+
+            // ensure that each stored sig matches an on-device sig
+            for (int i = 0; i < nStored; i++) {
+                boolean match = false;
+                for (int j = 0; j < nDevice; j++) {
+                    if (storedSigs[i].equals(deviceSigs[j])) {
+                        match = true;
+                        break;
+                    }
+                }
+                if (!match) {
+                    return false;
                 }
             }
-            if (!match) {
-                return false;
-            }
+            // we have found a match for all stored sigs
+            return true;
         }
-        return true;
     }
 }
diff --git a/services/backup/java/com/android/server/backup/utils/RestoreUtils.java b/services/backup/java/com/android/server/backup/utils/RestoreUtils.java
index 10f0695..df7e6d4 100644
--- a/services/backup/java/com/android/server/backup/utils/RestoreUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/RestoreUtils.java
@@ -30,6 +30,7 @@
 import android.content.pm.PackageInstaller.Session;
 import android.content.pm.PackageInstaller.SessionParams;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.Signature;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -37,6 +38,7 @@
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.server.LocalServices;
 import com.android.server.backup.FileMetadata;
 import com.android.server.backup.restore.RestoreDeleteObserver;
 import com.android.server.backup.restore.RestorePolicy;
@@ -142,9 +144,8 @@
                     uninstall = true;
                 } else {
                     try {
-                        PackageInfo pkg = packageManager.getPackageInfo(
-                                info.packageName,
-                                PackageManager.GET_SIGNATURES);
+                        PackageInfo pkg = packageManager.getPackageInfo(info.packageName,
+                                PackageManager.GET_SIGNING_CERTIFICATES);
                         if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_BACKUP)
                                 == 0) {
                             Slog.w(TAG, "Restore stream contains apk of package "
@@ -154,7 +155,9 @@
                         } else {
                             // So far so good -- do the signatures match the manifest?
                             Signature[] sigs = manifestSignatures.get(info.packageName);
-                            if (AppBackupUtils.signaturesMatch(sigs, pkg)) {
+                            PackageManagerInternal pmi = LocalServices.getService(
+                                    PackageManagerInternal.class);
+                            if (AppBackupUtils.signaturesMatch(sigs, pkg, pmi)) {
                                 // If this is a system-uid app without a declared backup agent,
                                 // don't restore any of the file data.
                                 if ((pkg.applicationInfo.uid < Process.FIRST_APPLICATION_UID)
diff --git a/services/backup/java/com/android/server/backup/utils/TarBackupReader.java b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
index cc26ff8..6dd5284 100644
--- a/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
+++ b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
@@ -50,6 +50,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.Signature;
 import android.os.Bundle;
 import android.os.Process;
@@ -385,7 +386,8 @@
      * @return a restore policy constant.
      */
     public RestorePolicy chooseRestorePolicy(PackageManager packageManager,
-            boolean allowApks, FileMetadata info, Signature[] signatures) {
+            boolean allowApks, FileMetadata info, Signature[] signatures,
+            PackageManagerInternal pmi) {
         if (signatures == null) {
             return RestorePolicy.IGNORE;
         }
@@ -395,7 +397,7 @@
         // Okay, got the manifest info we need...
         try {
             PackageInfo pkgInfo = packageManager.getPackageInfo(
-                    info.packageName, PackageManager.GET_SIGNATURES);
+                    info.packageName, PackageManager.GET_SIGNING_CERTIFICATES);
             // Fall through to IGNORE if the app explicitly disallows backup
             final int flags = pkgInfo.applicationInfo.flags;
             if ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0) {
@@ -411,7 +413,7 @@
                     // such packages are signed with the platform cert instead of
                     // the app developer's cert, so they're different on every
                     // device.
-                    if (AppBackupUtils.signaturesMatch(signatures, pkgInfo)) {
+                    if (AppBackupUtils.signaturesMatch(signatures, pkgInfo, pmi)) {
                         if ((pkgInfo.applicationInfo.flags
                                 & ApplicationInfo.FLAG_RESTORE_ANY_VERSION) != 0) {
                             Slog.i(TAG, "Package has restoreAnyVersion; taking data");
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 9cd3621..d17ca7f 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -66,6 +66,7 @@
 import android.system.Os;
 import android.text.TextUtils;
 import android.text.format.DateFormat;
+import android.text.format.DateUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.KeyValueListParser;
@@ -268,6 +269,7 @@
         // Key names stored in the settings value.
         private static final String KEY_MIN_FUTURITY = "min_futurity";
         private static final String KEY_MIN_INTERVAL = "min_interval";
+        private static final String KEY_MAX_INTERVAL = "max_interval";
         private static final String KEY_ALLOW_WHILE_IDLE_SHORT_TIME = "allow_while_idle_short_time";
         private static final String KEY_ALLOW_WHILE_IDLE_LONG_TIME = "allow_while_idle_long_time";
         private static final String KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION
@@ -285,6 +287,7 @@
 
         private static final long DEFAULT_MIN_FUTURITY = 5 * 1000;
         private static final long DEFAULT_MIN_INTERVAL = 60 * 1000;
+        private static final long DEFAULT_MAX_INTERVAL = 365 * DateUtils.DAY_IN_MILLIS;
         private static final long DEFAULT_ALLOW_WHILE_IDLE_SHORT_TIME = DEFAULT_MIN_FUTURITY;
         private static final long DEFAULT_ALLOW_WHILE_IDLE_LONG_TIME = 9*60*1000;
         private static final long DEFAULT_ALLOW_WHILE_IDLE_WHITELIST_DURATION = 10*1000;
@@ -303,6 +306,9 @@
         // Minimum alarm recurrence interval
         public long MIN_INTERVAL = DEFAULT_MIN_INTERVAL;
 
+        // Maximum alarm recurrence interval
+        public long MAX_INTERVAL = DEFAULT_MAX_INTERVAL;
+
         // Minimum time between ALLOW_WHILE_IDLE alarms when system is not idle.
         public long ALLOW_WHILE_IDLE_SHORT_TIME = DEFAULT_ALLOW_WHILE_IDLE_SHORT_TIME;
 
@@ -361,6 +367,7 @@
 
                 MIN_FUTURITY = mParser.getLong(KEY_MIN_FUTURITY, DEFAULT_MIN_FUTURITY);
                 MIN_INTERVAL = mParser.getLong(KEY_MIN_INTERVAL, DEFAULT_MIN_INTERVAL);
+                MAX_INTERVAL = mParser.getLong(KEY_MAX_INTERVAL, DEFAULT_MAX_INTERVAL);
                 ALLOW_WHILE_IDLE_SHORT_TIME = mParser.getLong(KEY_ALLOW_WHILE_IDLE_SHORT_TIME,
                         DEFAULT_ALLOW_WHILE_IDLE_SHORT_TIME);
                 ALLOW_WHILE_IDLE_LONG_TIME = mParser.getLong(KEY_ALLOW_WHILE_IDLE_LONG_TIME,
@@ -391,6 +398,10 @@
             TimeUtils.formatDuration(MIN_INTERVAL, pw);
             pw.println();
 
+            pw.print("    "); pw.print(KEY_MAX_INTERVAL); pw.print("=");
+            TimeUtils.formatDuration(MAX_INTERVAL, pw);
+            pw.println();
+
             pw.print("    "); pw.print(KEY_LISTENER_TIMEOUT); pw.print("=");
             TimeUtils.formatDuration(LISTENER_TIMEOUT, pw);
             pw.println();
@@ -419,6 +430,7 @@
 
             proto.write(ConstantsProto.MIN_FUTURITY_DURATION_MS, MIN_FUTURITY);
             proto.write(ConstantsProto.MIN_INTERVAL_DURATION_MS, MIN_INTERVAL);
+            proto.write(ConstantsProto.MAX_INTERVAL_DURATION_MS, MAX_INTERVAL);
             proto.write(ConstantsProto.LISTENER_TIMEOUT_DURATION_MS, LISTENER_TIMEOUT);
             proto.write(ConstantsProto.ALLOW_WHILE_IDLE_SHORT_DURATION_MS,
                     ALLOW_WHILE_IDLE_SHORT_TIME);
@@ -481,7 +493,7 @@
 
         Batch(Alarm seed) {
             start = seed.whenElapsed;
-            end = seed.maxWhenElapsed;
+            end = clampPositive(seed.maxWhenElapsed);
             flags = seed.flags;
             alarms.add(seed);
             if (seed.operation == mTimeTickSender) {
@@ -737,7 +749,7 @@
         if (futurity < MIN_FUZZABLE_INTERVAL) {
             futurity = 0;
         }
-        return triggerAtTime + (long)(.75 * futurity);
+        return clampPositive(triggerAtTime + (long)(.75 * futurity));
     }
 
     // returns true if the batch was added at the head
@@ -913,7 +925,7 @@
             // the window based on the alarm's new futurity.  Note that this
             // reflects a policy of preferring timely to deferred delivery.
             maxElapsed = (a.windowLength > 0)
-                    ? (whenElapsed + a.windowLength)
+                    ? clampPositive(whenElapsed + a.windowLength)
                     : maxTriggerTime(nowElapsed, whenElapsed, a.repeatInterval);
         }
         a.whenElapsed = whenElapsed;
@@ -921,6 +933,10 @@
         setImplLocked(a, true, doValidate);
     }
 
+    static long clampPositive(long val) {
+        return (val >= 0) ? val : Long.MAX_VALUE;
+    }
+
     /**
      * Sends alarms that were blocked due to user applied background restrictions - either because
      * the user lifted those or the uid came to foreground.
@@ -1421,13 +1437,18 @@
         }
 
         // Sanity check the recurrence interval.  This will catch people who supply
-        // seconds when the API expects milliseconds.
+        // seconds when the API expects milliseconds, or apps trying shenanigans
+        // around intentional period overflow, etc.
         final long minInterval = mConstants.MIN_INTERVAL;
         if (interval > 0 && interval < minInterval) {
             Slog.w(TAG, "Suspiciously short interval " + interval
                     + " millis; expanding to " + (minInterval/1000)
                     + " seconds");
             interval = minInterval;
+        } else if (interval > mConstants.MAX_INTERVAL) {
+            Slog.w(TAG, "Suspiciously long interval " + interval
+                    + " millis; clamping");
+            interval = mConstants.MAX_INTERVAL;
         }
 
         if (type < RTC_WAKEUP || type > ELAPSED_REALTIME) {
@@ -2170,42 +2191,42 @@
         synchronized (mLock) {
             final long nowRTC = System.currentTimeMillis();
             final long nowElapsed = SystemClock.elapsedRealtime();
-            proto.write(AlarmManagerServiceProto.CURRENT_TIME, nowRTC);
-            proto.write(AlarmManagerServiceProto.ELAPSED_REALTIME, nowElapsed);
-            proto.write(AlarmManagerServiceProto.LAST_TIME_CHANGE_CLOCK_TIME,
+            proto.write(AlarmManagerServiceDumpProto.CURRENT_TIME, nowRTC);
+            proto.write(AlarmManagerServiceDumpProto.ELAPSED_REALTIME, nowElapsed);
+            proto.write(AlarmManagerServiceDumpProto.LAST_TIME_CHANGE_CLOCK_TIME,
                     mLastTimeChangeClockTime);
-            proto.write(AlarmManagerServiceProto.LAST_TIME_CHANGE_REALTIME,
+            proto.write(AlarmManagerServiceDumpProto.LAST_TIME_CHANGE_REALTIME,
                     mLastTimeChangeRealtime);
 
-            mConstants.dumpProto(proto, AlarmManagerServiceProto.SETTINGS);
+            mConstants.dumpProto(proto, AlarmManagerServiceDumpProto.SETTINGS);
 
             if (mAppStateTracker != null) {
                 mAppStateTracker.dumpProto(proto,
-                        AlarmManagerServiceProto.FORCE_APP_STANDBY_TRACKER);
+                        AlarmManagerServiceDumpProto.FORCE_APP_STANDBY_TRACKER);
             }
 
-            proto.write(AlarmManagerServiceProto.IS_INTERACTIVE, mInteractive);
+            proto.write(AlarmManagerServiceDumpProto.IS_INTERACTIVE, mInteractive);
             if (!mInteractive) {
                 // Durations
-                proto.write(AlarmManagerServiceProto.TIME_SINCE_NON_INTERACTIVE_MS,
+                proto.write(AlarmManagerServiceDumpProto.TIME_SINCE_NON_INTERACTIVE_MS,
                         nowElapsed - mNonInteractiveStartTime);
-                proto.write(AlarmManagerServiceProto.MAX_WAKEUP_DELAY_MS,
+                proto.write(AlarmManagerServiceDumpProto.MAX_WAKEUP_DELAY_MS,
                         currentNonWakeupFuzzLocked(nowElapsed));
-                proto.write(AlarmManagerServiceProto.TIME_SINCE_LAST_DISPATCH_MS,
+                proto.write(AlarmManagerServiceDumpProto.TIME_SINCE_LAST_DISPATCH_MS,
                         nowElapsed - mLastAlarmDeliveryTime);
-                proto.write(AlarmManagerServiceProto.TIME_UNTIL_NEXT_NON_WAKEUP_DELIVERY_MS,
+                proto.write(AlarmManagerServiceDumpProto.TIME_UNTIL_NEXT_NON_WAKEUP_DELIVERY_MS,
                         nowElapsed - mNextNonWakeupDeliveryTime);
             }
 
-            proto.write(AlarmManagerServiceProto.TIME_UNTIL_NEXT_NON_WAKEUP_ALARM_MS,
+            proto.write(AlarmManagerServiceDumpProto.TIME_UNTIL_NEXT_NON_WAKEUP_ALARM_MS,
                     mNextNonWakeup - nowElapsed);
-            proto.write(AlarmManagerServiceProto.TIME_UNTIL_NEXT_WAKEUP_MS,
+            proto.write(AlarmManagerServiceDumpProto.TIME_UNTIL_NEXT_WAKEUP_MS,
                     mNextWakeup - nowElapsed);
-            proto.write(AlarmManagerServiceProto.TIME_SINCE_LAST_WAKEUP_MS,
+            proto.write(AlarmManagerServiceDumpProto.TIME_SINCE_LAST_WAKEUP_MS,
                     nowElapsed - mLastWakeup);
-            proto.write(AlarmManagerServiceProto.TIME_SINCE_LAST_WAKEUP_SET_MS,
+            proto.write(AlarmManagerServiceDumpProto.TIME_SINCE_LAST_WAKEUP_SET_MS,
                     nowElapsed - mLastWakeupSet);
-            proto.write(AlarmManagerServiceProto.TIME_CHANGE_EVENT_COUNT, mNumTimeChanged);
+            proto.write(AlarmManagerServiceDumpProto.TIME_CHANGE_EVENT_COUNT, mNumTimeChanged);
 
             final TreeSet<Integer> users = new TreeSet<>();
             final int nextAlarmClockForUserSize = mNextAlarmClockForUser.size();
@@ -2221,14 +2242,14 @@
                 final AlarmManager.AlarmClockInfo next = mNextAlarmClockForUser.get(user);
                 final long time = next != null ? next.getTriggerTime() : 0;
                 final boolean pendingSend = mPendingSendNextAlarmClockChangedForUser.get(user);
-                final long aToken = proto.start(AlarmManagerServiceProto.NEXT_ALARM_CLOCK_METADATA);
+                final long aToken = proto.start(AlarmManagerServiceDumpProto.NEXT_ALARM_CLOCK_METADATA);
                 proto.write(AlarmClockMetadataProto.USER, user);
                 proto.write(AlarmClockMetadataProto.IS_PENDING_SEND, pendingSend);
                 proto.write(AlarmClockMetadataProto.TRIGGER_TIME_MS, time);
                 proto.end(aToken);
             }
             for (Batch b : mAlarmBatches) {
-                b.writeToProto(proto, AlarmManagerServiceProto.PENDING_ALARM_BATCHES,
+                b.writeToProto(proto, AlarmManagerServiceDumpProto.PENDING_ALARM_BATCHES,
                         nowElapsed, nowRTC);
             }
             for (int i = 0; i < mPendingBackgroundAlarms.size(); i++) {
@@ -2236,66 +2257,66 @@
                 if (blockedAlarms != null) {
                     for (Alarm a : blockedAlarms) {
                         a.writeToProto(proto,
-                                AlarmManagerServiceProto.PENDING_USER_BLOCKED_BACKGROUND_ALARMS,
+                                AlarmManagerServiceDumpProto.PENDING_USER_BLOCKED_BACKGROUND_ALARMS,
                                 nowElapsed, nowRTC);
                     }
                 }
             }
             if (mPendingIdleUntil != null) {
                 mPendingIdleUntil.writeToProto(
-                        proto, AlarmManagerServiceProto.PENDING_IDLE_UNTIL, nowElapsed, nowRTC);
+                        proto, AlarmManagerServiceDumpProto.PENDING_IDLE_UNTIL, nowElapsed, nowRTC);
             }
             for (Alarm a : mPendingWhileIdleAlarms) {
-                a.writeToProto(proto, AlarmManagerServiceProto.PENDING_WHILE_IDLE_ALARMS,
+                a.writeToProto(proto, AlarmManagerServiceDumpProto.PENDING_WHILE_IDLE_ALARMS,
                         nowElapsed, nowRTC);
             }
             if (mNextWakeFromIdle != null) {
-                mNextWakeFromIdle.writeToProto(proto, AlarmManagerServiceProto.NEXT_WAKE_FROM_IDLE,
+                mNextWakeFromIdle.writeToProto(proto, AlarmManagerServiceDumpProto.NEXT_WAKE_FROM_IDLE,
                         nowElapsed, nowRTC);
             }
 
             for (Alarm a : mPendingNonWakeupAlarms) {
-                a.writeToProto(proto, AlarmManagerServiceProto.PAST_DUE_NON_WAKEUP_ALARMS,
+                a.writeToProto(proto, AlarmManagerServiceDumpProto.PAST_DUE_NON_WAKEUP_ALARMS,
                         nowElapsed, nowRTC);
             }
 
-            proto.write(AlarmManagerServiceProto.DELAYED_ALARM_COUNT, mNumDelayedAlarms);
-            proto.write(AlarmManagerServiceProto.TOTAL_DELAY_TIME_MS, mTotalDelayTime);
-            proto.write(AlarmManagerServiceProto.MAX_DELAY_DURATION_MS, mMaxDelayTime);
-            proto.write(AlarmManagerServiceProto.MAX_NON_INTERACTIVE_DURATION_MS,
+            proto.write(AlarmManagerServiceDumpProto.DELAYED_ALARM_COUNT, mNumDelayedAlarms);
+            proto.write(AlarmManagerServiceDumpProto.TOTAL_DELAY_TIME_MS, mTotalDelayTime);
+            proto.write(AlarmManagerServiceDumpProto.MAX_DELAY_DURATION_MS, mMaxDelayTime);
+            proto.write(AlarmManagerServiceDumpProto.MAX_NON_INTERACTIVE_DURATION_MS,
                     mNonInteractiveTime);
 
-            proto.write(AlarmManagerServiceProto.BROADCAST_REF_COUNT, mBroadcastRefCount);
-            proto.write(AlarmManagerServiceProto.PENDING_INTENT_SEND_COUNT, mSendCount);
-            proto.write(AlarmManagerServiceProto.PENDING_INTENT_FINISH_COUNT, mSendFinishCount);
-            proto.write(AlarmManagerServiceProto.LISTENER_SEND_COUNT, mListenerCount);
-            proto.write(AlarmManagerServiceProto.LISTENER_FINISH_COUNT, mListenerFinishCount);
+            proto.write(AlarmManagerServiceDumpProto.BROADCAST_REF_COUNT, mBroadcastRefCount);
+            proto.write(AlarmManagerServiceDumpProto.PENDING_INTENT_SEND_COUNT, mSendCount);
+            proto.write(AlarmManagerServiceDumpProto.PENDING_INTENT_FINISH_COUNT, mSendFinishCount);
+            proto.write(AlarmManagerServiceDumpProto.LISTENER_SEND_COUNT, mListenerCount);
+            proto.write(AlarmManagerServiceDumpProto.LISTENER_FINISH_COUNT, mListenerFinishCount);
 
             for (InFlight f : mInFlight) {
-                f.writeToProto(proto, AlarmManagerServiceProto.OUTSTANDING_DELIVERIES);
+                f.writeToProto(proto, AlarmManagerServiceDumpProto.OUTSTANDING_DELIVERIES);
             }
 
             for (int i = 0; i < mLastAllowWhileIdleDispatch.size(); ++i) {
                 final long token = proto.start(
-                        AlarmManagerServiceProto.LAST_ALLOW_WHILE_IDLE_DISPATCH_TIMES);
+                        AlarmManagerServiceDumpProto.LAST_ALLOW_WHILE_IDLE_DISPATCH_TIMES);
                 final int uid = mLastAllowWhileIdleDispatch.keyAt(i);
                 final long lastTime = mLastAllowWhileIdleDispatch.valueAt(i);
 
-                proto.write(AlarmManagerServiceProto.LastAllowWhileIdleDispatch.UID, uid);
-                proto.write(AlarmManagerServiceProto.LastAllowWhileIdleDispatch.TIME_MS, lastTime);
-                proto.write(AlarmManagerServiceProto.LastAllowWhileIdleDispatch.NEXT_ALLOWED_MS,
+                proto.write(AlarmManagerServiceDumpProto.LastAllowWhileIdleDispatch.UID, uid);
+                proto.write(AlarmManagerServiceDumpProto.LastAllowWhileIdleDispatch.TIME_MS, lastTime);
+                proto.write(AlarmManagerServiceDumpProto.LastAllowWhileIdleDispatch.NEXT_ALLOWED_MS,
                         lastTime + getWhileIdleMinIntervalLocked(uid));
                 proto.end(token);
             }
 
             for (int i = 0; i < mUseAllowWhileIdleShortTime.size(); i++) {
                 if (mUseAllowWhileIdleShortTime.valueAt(i)) {
-                    proto.write(AlarmManagerServiceProto.USE_ALLOW_WHILE_IDLE_SHORT_TIME,
+                    proto.write(AlarmManagerServiceDumpProto.USE_ALLOW_WHILE_IDLE_SHORT_TIME,
                             mUseAllowWhileIdleShortTime.keyAt(i));
                 }
             }
 
-            mLog.writeToProto(proto, AlarmManagerServiceProto.RECENT_PROBLEMS);
+            mLog.writeToProto(proto, AlarmManagerServiceDumpProto.RECENT_PROBLEMS);
 
             final FilterStats[] topFilters = new FilterStats[10];
             final Comparator<FilterStats> comparator = new Comparator<FilterStats>() {
@@ -2336,13 +2357,13 @@
                 }
             }
             for (int i = 0; i < len; ++i) {
-                final long token = proto.start(AlarmManagerServiceProto.TOP_ALARMS);
+                final long token = proto.start(AlarmManagerServiceDumpProto.TOP_ALARMS);
                 FilterStats fs = topFilters[i];
 
-                proto.write(AlarmManagerServiceProto.TopAlarm.UID, fs.mBroadcastStats.mUid);
-                proto.write(AlarmManagerServiceProto.TopAlarm.PACKAGE_NAME,
+                proto.write(AlarmManagerServiceDumpProto.TopAlarm.UID, fs.mBroadcastStats.mUid);
+                proto.write(AlarmManagerServiceDumpProto.TopAlarm.PACKAGE_NAME,
                         fs.mBroadcastStats.mPackageName);
-                fs.writeToProto(proto, AlarmManagerServiceProto.TopAlarm.FILTER);
+                fs.writeToProto(proto, AlarmManagerServiceDumpProto.TopAlarm.FILTER);
 
                 proto.end(token);
             }
@@ -2351,10 +2372,10 @@
             for (int iu = 0; iu < mBroadcastStats.size(); ++iu) {
                 ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu);
                 for (int ip = 0; ip < uidStats.size(); ++ip) {
-                    final long token = proto.start(AlarmManagerServiceProto.ALARM_STATS);
+                    final long token = proto.start(AlarmManagerServiceDumpProto.ALARM_STATS);
 
                     BroadcastStats bs = uidStats.valueAt(ip);
-                    bs.writeToProto(proto, AlarmManagerServiceProto.AlarmStat.BROADCAST);
+                    bs.writeToProto(proto, AlarmManagerServiceDumpProto.AlarmStat.BROADCAST);
 
                     // uidStats is an ArrayMap, which we can't sort.
                     tmpFilters.clear();
@@ -2363,7 +2384,7 @@
                     }
                     Collections.sort(tmpFilters, comparator);
                     for (FilterStats fs : tmpFilters) {
-                        fs.writeToProto(proto, AlarmManagerServiceProto.AlarmStat.FILTERS);
+                        fs.writeToProto(proto, AlarmManagerServiceDumpProto.AlarmStat.FILTERS);
                     }
 
                     proto.end(token);
@@ -2374,7 +2395,7 @@
                 for (int i = 0; i < mAllowWhileIdleDispatches.size(); i++) {
                     IdleDispatchEntry ent = mAllowWhileIdleDispatches.get(i);
                     final long token = proto.start(
-                            AlarmManagerServiceProto.ALLOW_WHILE_IDLE_DISPATCHES);
+                            AlarmManagerServiceDumpProto.ALLOW_WHILE_IDLE_DISPATCHES);
 
                     proto.write(IdleDispatchEntryProto.UID, ent.uid);
                     proto.write(IdleDispatchEntryProto.PKG, ent.pkg);
@@ -2390,7 +2411,7 @@
 
             if (WAKEUP_STATS) {
                 for (WakeupEvent event : mRecentWakeups) {
-                    final long token = proto.start(AlarmManagerServiceProto.RECENT_WAKEUP_HISTORY);
+                    final long token = proto.start(AlarmManagerServiceDumpProto.RECENT_WAKEUP_HISTORY);
                     proto.write(WakeupEventProto.UID, event.uid);
                     proto.write(WakeupEventProto.ACTION, event.action);
                     proto.write(WakeupEventProto.WHEN, event.when);
@@ -3175,8 +3196,7 @@
             whenElapsed = _whenElapsed;
             expectedWhenElapsed = _whenElapsed;
             windowLength = _windowLength;
-            maxWhenElapsed = _maxWhen;
-            expectedMaxWhenElapsed = _maxWhen;
+            maxWhenElapsed = expectedMaxWhenElapsed = clampPositive(_maxWhen);
             repeatInterval = _interval;
             operation = _op;
             listener = _rec;
@@ -3860,7 +3880,7 @@
     final class AppStandbyTracker extends UsageStatsManagerInternal.AppIdleStateChangeListener {
         @Override
         public void onAppIdleStateChanged(final String packageName, final @UserIdInt int userId,
-                boolean idle, int bucket) {
+                boolean idle, int bucket, int reason) {
             if (DEBUG_STANDBY) {
                 Slog.d(TAG, "Package " + packageName + " for user " + userId + " now in bucket " +
                         bucket);
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index ca67a34..53c9ecb 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -211,9 +211,11 @@
 
     public final class ActiveCallback implements DeathRecipient {
         final IAppOpsActiveCallback mCallback;
+        final int mUid;
 
-        public ActiveCallback(IAppOpsActiveCallback callback) {
+        public ActiveCallback(IAppOpsActiveCallback callback, int uid) {
             mCallback = callback;
+            mUid = uid;
             try {
                 mCallback.asBinder().linkToDeath(this, 0);
             } catch (RemoteException e) {
@@ -230,24 +232,22 @@
         }
     }
 
-    final ArrayMap<IBinder, ClientState> mClients = new ArrayMap<IBinder, ClientState>();
+    final ArrayMap<IBinder, ClientState> mClients = new ArrayMap<>();
 
     public final class ClientState extends Binder implements DeathRecipient {
+        final ArrayList<Op> mStartedOps = new ArrayList<>();
         final IBinder mAppToken;
         final int mPid;
-        final ArrayList<Op> mStartedOps;
 
         public ClientState(IBinder appToken) {
             mAppToken = appToken;
             mPid = Binder.getCallingPid();
-            if (appToken instanceof Binder) {
-                // For local clients, there is no reason to track them.
-                mStartedOps = null;
-            } else {
-                mStartedOps = new ArrayList<Op>();
+            // Watch only for remote processes dying
+            if (!(appToken instanceof Binder)) {
                 try {
                     mAppToken.linkToDeath(this, 0);
                 } catch (RemoteException e) {
+                    /* do nothing */
                 }
             }
         }
@@ -256,7 +256,7 @@
         public String toString() {
             return "ClientState{" +
                     "mAppToken=" + mAppToken +
-                    ", " + (mStartedOps != null ? ("pid=" + mPid) : "local") +
+                    ", " + "pid=" + mPid +
                     '}';
         }
 
@@ -264,7 +264,7 @@
         public void binderDied() {
             synchronized (AppOpsService.this) {
                 for (int i=mStartedOps.size()-1; i>=0; i--) {
-                    finishOperationLocked(mStartedOps.get(i));
+                    finishOperationLocked(mStartedOps.get(i), /*finishNested*/ true);
                 }
                 mClients.remove(mAppToken);
             }
@@ -397,6 +397,27 @@
                 mUidStates.remove(uid);
             }
 
+            // Finish ops other packages started on behalf of the package.
+            final int clientCount = mClients.size();
+            for (int i = 0; i < clientCount; i++) {
+                final ClientState client = mClients.valueAt(i);
+                if (client.mStartedOps == null) {
+                    continue;
+                }
+                final int opCount = client.mStartedOps.size();
+                for (int j = opCount - 1; j >= 0; j--) {
+                    final Op op = client.mStartedOps.get(j);
+                    if (uid == op.uid && packageName.equals(op.packageName)) {
+                        finishOperationLocked(op, /*finishNested*/ true);
+                        client.mStartedOps.remove(j);
+                        if (op.nesting <= 0) {
+                            scheduleOpActiveChangedIfNeededLocked(op.op,
+                                    uid, packageName, false);
+                        }
+                    }
+                }
+            }
+
             if (ops != null) {
                 scheduleFastWriteLocked();
 
@@ -1195,8 +1216,11 @@
 
     @Override
     public void startWatchingActive(int[] ops, IAppOpsActiveCallback callback) {
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.WATCH_APPOPS,
-                "startWatchingActive");
+        int watchedUid = -1;
+        if (mContext.checkCallingOrSelfPermission(Manifest.permission.WATCH_APPOPS)
+                != PackageManager.PERMISSION_GRANTED) {
+            watchedUid = Binder.getCallingUid();
+        }
         if (ops != null) {
             Preconditions.checkArrayElementsInRange(ops, 0,
                     AppOpsManager._NUM_OP - 1, "Invalid op code in: " + Arrays.toString(ops));
@@ -1210,7 +1234,7 @@
                 callbacks = new SparseArray<>();
                 mActiveWatchers.put(callback.asBinder(), callbacks);
             }
-            final ActiveCallback activeCallback = new ActiveCallback(callback);
+            final ActiveCallback activeCallback = new ActiveCallback(callback, watchedUid);
             for (int op : ops) {
                 callbacks.put(op, activeCallback);
             }
@@ -1239,7 +1263,8 @@
     }
 
     @Override
-    public int startOperation(IBinder token, int code, int uid, String packageName) {
+    public int startOperation(IBinder token, int code, int uid, String packageName,
+            boolean startIfModeDefault) {
         verifyIncomingUid(uid);
         verifyIncomingOp(code);
         String resolvedPackageName = resolvePackageName(uid, packageName);
@@ -1265,7 +1290,8 @@
             // non-default) it takes over, otherwise use the per package policy.
             if (uidState.opModes != null && uidState.opModes.indexOfKey(switchCode) >= 0) {
                 final int uidMode = uidState.opModes.get(switchCode);
-                if (uidMode != AppOpsManager.MODE_ALLOWED) {
+                if (uidMode != AppOpsManager.MODE_ALLOWED
+                        && (!startIfModeDefault || uidMode != AppOpsManager.MODE_DEFAULT)) {
                     if (DEBUG) Slog.d(TAG, "noteOperation: reject #" + op.mode + " for code "
                             + switchCode + " (" + code + ") uid " + uid + " package "
                             + resolvedPackageName);
@@ -1274,7 +1300,8 @@
                 }
             } else {
                 final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op;
-                if (switchOp.mode != AppOpsManager.MODE_ALLOWED) {
+                if (switchOp.mode != AppOpsManager.MODE_ALLOWED
+                        && (!startIfModeDefault || switchOp.mode != AppOpsManager.MODE_DEFAULT)) {
                     if (DEBUG) Slog.d(TAG, "startOperation: reject #" + op.mode + " for code "
                             + switchCode + " (" + code + ") uid " + uid + " package "
                             + resolvedPackageName);
@@ -1316,13 +1343,11 @@
             if (op == null) {
                 return;
             }
-            if (client.mStartedOps != null) {
-                if (!client.mStartedOps.remove(op)) {
-                    throw new IllegalStateException("Operation not started: uid" + op.uid
-                            + " pkg=" + op.packageName + " op=" + op.op);
-                }
+            if (!client.mStartedOps.remove(op)) {
+                throw new IllegalStateException("Operation not started: uid" + op.uid
+                        + " pkg=" + op.packageName + " op=" + op.op);
             }
-            finishOperationLocked(op);
+            finishOperationLocked(op, /*finishNested*/ false);
             if (op.nesting <= 0) {
                 scheduleOpActiveChangedIfNeededLocked(code, uid, packageName, false);
             }
@@ -1337,6 +1362,9 @@
             final SparseArray<ActiveCallback> callbacks = mActiveWatchers.valueAt(i);
             ActiveCallback callback = callbacks.get(code);
             if (callback != null) {
+                if (callback.mUid >= 0 && callback.mUid != uid) {
+                    continue;
+                }
                 if (dispatchedCallbacks == null) {
                     dispatchedCallbacks = new ArraySet<>();
                 }
@@ -1380,9 +1408,9 @@
         return AppOpsManager.permissionToOpCode(permission);
     }
 
-    void finishOperationLocked(Op op) {
-        if (op.nesting <= 1) {
-            if (op.nesting == 1) {
+    void finishOperationLocked(Op op, boolean finishNested) {
+        if (op.nesting <= 1 || finishNested) {
+            if (op.nesting == 1 || finishNested) {
                 op.duration = (int)(System.currentTimeMillis() - op.time);
                 op.time += op.duration;
             } else {
@@ -2420,7 +2448,7 @@
                     pw.print("    "); pw.print(mClients.keyAt(i)); pw.println(":");
                     ClientState cs = mClients.valueAt(i);
                     pw.print("      "); pw.println(cs);
-                    if (cs.mStartedOps != null && cs.mStartedOps.size() > 0) {
+                    if (cs.mStartedOps.size() > 0) {
                         pw.println("      Started ops:");
                         for (int j=0; j<cs.mStartedOps.size(); j++) {
                             Op op = cs.mStartedOps.get(j);
@@ -2651,8 +2679,12 @@
 
     @Override
     public boolean isOperationActive(int code, int uid, String packageName) {
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.WATCH_APPOPS,
-                "isOperationActive");
+        if (Binder.getCallingUid() != uid) {
+            if (mContext.checkCallingOrSelfPermission(Manifest.permission.WATCH_APPOPS)
+                    != PackageManager.PERMISSION_GRANTED) {
+                return false;
+            }
+        }
         verifyIncomingOp(code);
         final String resolvedPackageName = resolvePackageName(uid, packageName);
         if (resolvedPackageName == null) {
@@ -2661,8 +2693,6 @@
         synchronized (AppOpsService.this) {
             for (int i = mClients.size() - 1; i >= 0; i--) {
                 final ClientState client = mClients.valueAt(i);
-                if (client.mStartedOps == null) continue;
-
                 for (int j = client.mStartedOps.size() - 1; j >= 0; j--) {
                     final Op op = client.mStartedOps.get(j);
                     if (op.op == code && op.uid == uid) return true;
diff --git a/services/core/java/com/android/server/AppStateTracker.java b/services/core/java/com/android/server/AppStateTracker.java
index 9b29b32..a6b71b7 100644
--- a/services/core/java/com/android/server/AppStateTracker.java
+++ b/services/core/java/com/android/server/AppStateTracker.java
@@ -53,6 +53,7 @@
 import com.android.internal.app.IAppOpsCallback;
 import com.android.internal.app.IAppOpsService;
 import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
 import com.android.server.ForceAppStandbyTrackerProto.ExemptedPackage;
 import com.android.server.ForceAppStandbyTrackerProto.RunAnyInBackgroundRestrictedPackages;
@@ -677,7 +678,7 @@
     final class StandbyTracker extends AppIdleStateChangeListener {
         @Override
         public void onAppIdleStateChanged(String packageName, int userId, boolean idle,
-                int bucket) {
+                int bucket, int reason) {
             if (DEBUG) {
                 Slog.d(TAG,"onAppIdleStateChanged: " + packageName + " u" + userId
                         + (idle ? " idle" : " active") + " " + bucket);
@@ -1182,72 +1183,67 @@
         }
     }
 
-    public void dump(PrintWriter pw, String indent) {
+    @Deprecated
+    public void dump(PrintWriter pw, String prefix) {
+        dump(new IndentingPrintWriter(pw, "  ").setIndent(prefix));
+    }
+
+    public void dump(IndentingPrintWriter pw) {
         synchronized (mLock) {
-            pw.print(indent);
             pw.println("Forced App Standby Feature enabled: " + mForcedAppStandbyEnabled);
 
-            pw.print(indent);
             pw.print("Force all apps standby: ");
             pw.println(isForceAllAppsStandbyEnabled());
 
-            pw.print(indent);
             pw.print("Small Battery Device: ");
             pw.println(isSmallBatteryDevice());
 
-            pw.print(indent);
             pw.print("Force all apps standby for small battery device: ");
             pw.println(mForceAllAppStandbyForSmallBattery);
 
-            pw.print(indent);
             pw.print("Plugged In: ");
             pw.println(mIsPluggedIn);
 
-            pw.print(indent);
             pw.print("Active uids: ");
             dumpUids(pw, mActiveUids);
 
-            pw.print(indent);
             pw.print("Foreground uids: ");
             dumpUids(pw, mForegroundUids);
 
-            pw.print(indent);
             pw.print("Whitelist appids: ");
             pw.println(Arrays.toString(mPowerWhitelistedAllAppIds));
 
-            pw.print(indent);
             pw.print("Temp whitelist appids: ");
             pw.println(Arrays.toString(mTempWhitelistedAppIds));
 
-            pw.print(indent);
             pw.println("Exempted packages:");
+            pw.increaseIndent();
             for (int i = 0; i < mExemptedPackages.size(); i++) {
-                pw.print(indent);
-                pw.print("  User ");
+                pw.print("User ");
                 pw.print(mExemptedPackages.keyAt(i));
                 pw.println();
 
+                pw.increaseIndent();
                 for (int j = 0; j < mExemptedPackages.sizeAt(i); j++) {
-                    pw.print(indent);
-                    pw.print("    ");
                     pw.print(mExemptedPackages.valueAt(i, j));
                     pw.println();
                 }
+                pw.decreaseIndent();
             }
+            pw.decreaseIndent();
             pw.println();
 
-            pw.print(indent);
             pw.println("Restricted packages:");
+            pw.increaseIndent();
             for (Pair<Integer, String> uidAndPackage : mRunAnyRestrictedPackages) {
-                pw.print(indent);
-                pw.print("  ");
                 pw.print(UserHandle.formatUid(uidAndPackage.first));
                 pw.print(" ");
                 pw.print(uidAndPackage.second);
                 pw.println();
             }
+            pw.decreaseIndent();
 
-            mStatLogger.dump(pw, indent);
+            mStatLogger.dump(pw);
         }
     }
 
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 1d5e47a..c570005 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -1706,6 +1706,13 @@
             if (cs != null) {
                 clearClientSessionLocked(cs);
                 if (mCurClient == cs) {
+                    if (mBoundToMethod) {
+                        mBoundToMethod = false;
+                        if (mCurMethod != null) {
+                            executeOrSendMessage(mCurMethod, mCaller.obtainMessageO(
+                                    MSG_UNBIND_INPUT, mCurMethod));
+                        }
+                    }
                     mCurClient = null;
                 }
                 if (mCurFocusedWindowClient == cs) {
diff --git a/services/core/java/com/android/server/NativeDaemonConnector.java b/services/core/java/com/android/server/NativeDaemonConnector.java
index b5a8332..ad02aad 100644
--- a/services/core/java/com/android/server/NativeDaemonConnector.java
+++ b/services/core/java/com/android/server/NativeDaemonConnector.java
@@ -134,21 +134,23 @@
         mCallbackHandler = new Handler(mLooper, this);
 
         while (true) {
+            if (isShuttingDown()) break;
             try {
                 listenToSocket();
             } catch (Exception e) {
                 loge("Error in NativeDaemonConnector: " + e);
-                String shutdownAct = SystemProperties.get(
-                        ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
-                if (shutdownAct != null && shutdownAct.length() > 0) {
-                    // The device is in middle of shutdown.
-                    break;
-                }
+                if (isShuttingDown()) break;
                 SystemClock.sleep(5000);
             }
         }
     }
 
+    private static boolean isShuttingDown() {
+        String shutdownAct = SystemProperties.get(
+            ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
+        return shutdownAct != null && shutdownAct.length() > 0;
+    }
+
     @Override
     public boolean handleMessage(Message msg) {
         final String event = (String) msg.obj;
diff --git a/services/core/java/com/android/server/StatLogger.java b/services/core/java/com/android/server/StatLogger.java
index 0e6f5e2..d85810d 100644
--- a/services/core/java/com/android/server/StatLogger.java
+++ b/services/core/java/com/android/server/StatLogger.java
@@ -21,6 +21,7 @@
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.StatLoggerProto.Event;
 
 import java.io.PrintWriter;
@@ -78,19 +79,23 @@
         }
     }
 
+    @Deprecated
     public void dump(PrintWriter pw, String prefix) {
+        dump(new IndentingPrintWriter(pw, "  ").setIndent(prefix));
+    }
+
+    public void dump(IndentingPrintWriter pw) {
         synchronized (mLock) {
-            pw.print(prefix);
             pw.println("Stats:");
+            pw.increaseIndent();
             for (int i = 0; i < SIZE; i++) {
-                pw.print(prefix);
-                pw.print("  ");
                 final int count = mCountStats[i];
                 final double durationMs = mDurationStats[i] / 1000.0;
                 pw.println(String.format("%s: count=%d, total=%.1fms, avg=%.3fms",
                         mLabels[i], count, durationMs,
                         (count == 0 ? 0 : ((double) durationMs) / count)));
             }
+            pw.decreaseIndent();
         }
     }
 
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 5e5eacb..e202618 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -35,7 +35,9 @@
 import android.telephony.CellInfo;
 import android.telephony.CellLocation;
 import android.telephony.DisconnectCause;
+import android.telephony.LocationAccessPolicy;
 import android.telephony.PhoneStateListener;
+import android.telephony.PhysicalChannelConfig;
 import android.telephony.PreciseCallState;
 import android.telephony.PreciseDataConnectionState;
 import android.telephony.PreciseDisconnectCause;
@@ -55,6 +57,7 @@
 import com.android.internal.telephony.PhoneConstantConversions;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.TelephonyPermissions;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.am.BatteryStatsService;
@@ -96,7 +99,8 @@
         IPhoneStateListener callback;
         IOnSubscriptionsChangedListener onSubscriptionsChangedListenerCallback;
 
-        int callerUserId;
+        int callerUid;
+        int callerPid;
 
         int events;
 
@@ -120,7 +124,7 @@
                     + " callback=" + callback
                     + " onSubscriptionsChangedListenererCallback="
                                             + onSubscriptionsChangedListenerCallback
-                    + " callerUserId=" + callerUserId + " subId=" + subId + " phoneId=" + phoneId
+                    + " callerUid=" + callerUid + " subId=" + subId + " phoneId=" + phoneId
                     + " events=" + Integer.toHexString(events)
                     + " canReadPhoneState=" + canReadPhoneState + "}";
         }
@@ -176,6 +180,8 @@
 
     private ArrayList<List<CellInfo>> mCellInfo = null;
 
+    private ArrayList<List<PhysicalChannelConfig>> mPhysicalChannelConfigs;
+
     private VoLteServiceState mVoLteServiceState = new VoLteServiceState();
 
     private int mDefaultSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -332,6 +338,7 @@
         mDataConnectionLinkProperties = new LinkProperties[numPhones];
         mDataConnectionNetworkCapabilities = new NetworkCapabilities[numPhones];
         mCellInfo = new ArrayList<List<CellInfo>>();
+        mPhysicalChannelConfigs = new ArrayList<List<PhysicalChannelConfig>>();
         for (int i = 0; i < numPhones; i++) {
             mCallState[i] =  TelephonyManager.CALL_STATE_IDLE;
             mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE;
@@ -346,6 +353,7 @@
             mCallForwarding[i] =  false;
             mCellLocation[i] = new Bundle();
             mCellInfo.add(i, null);
+            mPhysicalChannelConfigs.add(i, null);
             mConnectedApns[i] = new ArrayList<String>();
         }
 
@@ -374,26 +382,17 @@
     public void addOnSubscriptionsChangedListener(String callingPackage,
             IOnSubscriptionsChangedListener callback) {
         int callerUserId = UserHandle.getCallingUserId();
+        mContext.getSystemService(AppOpsManager.class)
+                .checkPackage(Binder.getCallingUid(), callingPackage);
         if (VDBG) {
             log("listen oscl: E pkg=" + callingPackage + " myUserId=" + UserHandle.myUserId()
                 + " callerUserId="  + callerUserId + " callback=" + callback
                 + " callback.asBinder=" + callback.asBinder());
         }
 
-        try {
-            mContext.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
-                    "addOnSubscriptionsChangedListener");
-            // SKIP checking for run-time permission since caller or self has PRIVILEGED permission
-        } catch (SecurityException e) {
-            mContext.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.READ_PHONE_STATE,
-                    "addOnSubscriptionsChangedListener");
-
-            if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
-                    callingPackage) != AppOpsManager.MODE_ALLOWED) {
-                return;
-            }
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mContext, callingPackage, "addOnSubscriptionsChangedListener")) {
+            return;
         }
 
 
@@ -408,7 +407,8 @@
 
             r.onSubscriptionsChangedListenerCallback = callback;
             r.callingPackage = callingPackage;
-            r.callerUserId = callerUserId;
+            r.callerUid = Binder.getCallingUid();
+            r.callerPid = Binder.getCallingPid();
             r.events = 0;
             r.canReadPhoneState = true; // permission has been enforced above
             if (DBG) {
@@ -479,6 +479,8 @@
     private void listen(String callingPackage, IPhoneStateListener callback, int events,
             boolean notifyNow, int subId) {
         int callerUserId = UserHandle.getCallingUserId();
+        mContext.getSystemService(AppOpsManager.class)
+                .checkPackage(Binder.getCallingUid(), callingPackage);
         if (VDBG) {
             log("listen: E pkg=" + callingPackage + " events=0x" + Integer.toHexString(events)
                 + " notifyNow=" + notifyNow + " subId=" + subId + " myUserId="
@@ -486,23 +488,14 @@
         }
 
         if (events != PhoneStateListener.LISTEN_NONE) {
-            /* Checks permission and throws Security exception */
-            checkListenerPermission(events);
-
-            if ((events & ENFORCE_PHONE_STATE_PERMISSION_MASK) != 0) {
-                try {
-                    mContext.enforceCallingOrSelfPermission(
-                            android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null);
-                    // SKIP checking for run-time permission since caller or self has PRIVILEGED
-                    // permission
-                } catch (SecurityException e) {
-                    if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
-                            callingPackage) != AppOpsManager.MODE_ALLOWED) {
-                        return;
-                    }
-                }
+            // Checks permission and throws SecurityException for disallowed operations. For pre-M
+            // apps whose runtime permission has been revoked, we return immediately to skip sending
+            // events to the app without crashing it.
+            if (!checkListenerPermission(events, callingPackage, "listen")) {
+                return;
             }
 
+            int phoneId = SubscriptionManager.getPhoneId(subId);
             synchronized (mRecords) {
                 // register
                 IBinder b = callback.asBinder();
@@ -514,10 +507,12 @@
 
                 r.callback = callback;
                 r.callingPackage = callingPackage;
-                r.callerUserId = callerUserId;
+                r.callerUid = Binder.getCallingUid();
+                r.callerPid = Binder.getCallingPid();
                 boolean isPhoneStateEvent = (events & (CHECK_PHONE_STATE_PERMISSION_MASK
                         | ENFORCE_PHONE_STATE_PERMISSION_MASK)) != 0;
-                r.canReadPhoneState = isPhoneStateEvent && canReadPhoneState(callingPackage);
+                r.canReadPhoneState =
+                        isPhoneStateEvent && canReadPhoneState(callingPackage, "listen");
                 // Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID,
                 // force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID
                 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
@@ -525,9 +520,7 @@
                  } else {//APP specify subID
                     r.subId = subId;
                 }
-                r.phoneId = SubscriptionManager.getPhoneId(r.subId);
-
-                int phoneId = r.phoneId;
+                r.phoneId = phoneId;
                 r.events = events;
                 if (DBG) {
                     log("listen:  Register r=" + r + " r.subId=" + r.subId + " phoneId=" + phoneId);
@@ -572,8 +565,10 @@
                         try {
                             if (DBG_LOC) log("listen: mCellLocation = "
                                     + mCellLocation[phoneId]);
-                            r.callback.onCellLocationChanged(
-                                    new Bundle(mCellLocation[phoneId]));
+                            if (checkLocationAccess(r)) {
+                                r.callback.onCellLocationChanged(
+                                        new Bundle(mCellLocation[phoneId]));
+                            }
                         } catch (RemoteException ex) {
                             remove(r.binder);
                         }
@@ -619,7 +614,9 @@
                         try {
                             if (DBG_LOC) log("listen: mCellInfo[" + phoneId + "] = "
                                     + mCellInfo.get(phoneId));
-                            r.callback.onCellInfoChanged(mCellInfo.get(phoneId));
+                            if (checkLocationAccess(r)) {
+                                r.callback.onCellInfoChanged(mCellInfo.get(phoneId));
+                            }
                         } catch (RemoteException ex) {
                             remove(r.binder);
                         }
@@ -667,6 +664,14 @@
                             remove(r.binder);
                         }
                     }
+                    if ((events & PhoneStateListener.LISTEN_PHYSICAL_CHANNEL_CONFIGURATION) != 0) {
+                        try {
+                            r.callback.onPhysicalChannelConfigurationChanged(
+                                    mPhysicalChannelConfigs.get(phoneId));
+                        } catch (RemoteException ex) {
+                            remove(r.binder);
+                        }
+                    }
                 }
             }
         } else {
@@ -675,21 +680,13 @@
         }
     }
 
-    private boolean canReadPhoneState(String callingPackage) {
-        if (mContext.checkCallingOrSelfPermission(
-                android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) ==
-                PackageManager.PERMISSION_GRANTED) {
-            // SKIP checking for run-time permission since caller or self has PRIVILEGED permission
-            return true;
-        }
-        boolean canReadPhoneState = mContext.checkCallingOrSelfPermission(
-                android.Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED;
-        if (canReadPhoneState &&
-                mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
-                        callingPackage) != AppOpsManager.MODE_ALLOWED) {
+    private boolean canReadPhoneState(String callingPackage, String message) {
+        try {
+            return TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                    mContext, callingPackage, message);
+        } catch (SecurityException e) {
             return false;
         }
-        return canReadPhoneState;
     }
 
     private String getCallIncomingNumber(Record record, int phoneId) {
@@ -1013,14 +1010,14 @@
             log("notifyCellInfoForSubscriber: subId=" + subId
                 + " cellInfo=" + cellInfo);
         }
-
+        int phoneId = SubscriptionManager.getPhoneId(subId);
         synchronized (mRecords) {
-            int phoneId = SubscriptionManager.getPhoneId(subId);
             if (validatePhoneId(phoneId)) {
                 mCellInfo.set(phoneId, cellInfo);
                 for (Record r : mRecords) {
                     if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO) &&
-                            idMatch(r.subId, subId, phoneId)) {
+                            idMatch(r.subId, subId, phoneId) &&
+                            checkLocationAccess(r)) {
                         try {
                             if (DBG_LOC) {
                                 log("notifyCellInfo: mCellInfo=" + cellInfo + " r=" + r);
@@ -1036,6 +1033,45 @@
         }
     }
 
+    public void notifyPhysicalChannelConfiguration(List<PhysicalChannelConfig> configs) {
+        notifyPhysicalChannelConfigurationForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+                configs);
+    }
+
+    public void notifyPhysicalChannelConfigurationForSubscriber(int subId,
+            List<PhysicalChannelConfig> configs) {
+        if (!checkNotifyPermission("notifyPhysicalChannelConfiguration()")) {
+            return;
+        }
+
+        if (VDBG) {
+            log("notifyPhysicalChannelConfiguration: subId=" + subId + " configs=" + configs);
+        }
+
+        synchronized (mRecords) {
+            int phoneId = SubscriptionManager.getPhoneId(subId);
+            if (validatePhoneId(phoneId)) {
+                mPhysicalChannelConfigs.set(phoneId, configs);
+                for (Record r : mRecords) {
+                    if (r.matchPhoneStateListenerEvent(
+                            PhoneStateListener.LISTEN_PHYSICAL_CHANNEL_CONFIGURATION)
+                            && idMatch(r.subId, subId, phoneId)) {
+                        try {
+                            if (DBG_LOC) {
+                                log("notifyPhysicalChannelConfiguration: mPhysicalChannelConfigs="
+                                        + configs + " r=" + r);
+                            }
+                            r.callback.onPhysicalChannelConfigurationChanged(configs);
+                        } catch (RemoteException ex) {
+                            mRemoveList.add(r.binder);
+                        }
+                    }
+                }
+            }
+            handleRemoveListLocked();
+        }
+    }
+
     @Override
     public void notifyMessageWaitingChangedForPhoneId(int phoneId, int subId, boolean mwi) {
         if (!checkNotifyPermission("notifyMessageWaitingChanged()")) {
@@ -1103,8 +1139,8 @@
             log("notifyCallForwardingChangedForSubscriber: subId=" + subId
                 + " cfi=" + cfi);
         }
+        int phoneId = SubscriptionManager.getPhoneId(subId);
         synchronized (mRecords) {
-            int phoneId = SubscriptionManager.getPhoneId(subId);
             if (validatePhoneId(phoneId)) {
                 mCallForwarding[phoneId] = cfi;
                 for (Record r : mRecords) {
@@ -1131,8 +1167,8 @@
         if (!checkNotifyPermission("notifyDataActivity()" )) {
             return;
         }
+        int phoneId = SubscriptionManager.getPhoneId(subId);
         synchronized (mRecords) {
-            int phoneId = SubscriptionManager.getPhoneId(subId);
             if (validatePhoneId(phoneId)) {
                 mDataActivity[phoneId] = state;
                 for (Record r : mRecords) {
@@ -1173,8 +1209,8 @@
                 + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType
                 + " mRecords.size()=" + mRecords.size());
         }
+        int phoneId = SubscriptionManager.getPhoneId(subId);
         synchronized (mRecords) {
-            int phoneId = SubscriptionManager.getPhoneId(subId);
             if (validatePhoneId(phoneId)) {
                 boolean modified = false;
                 if (state == TelephonyManager.DATA_CONNECTED) {
@@ -1297,13 +1333,14 @@
             log("notifyCellLocationForSubscriber: subId=" + subId
                 + " cellLocation=" + cellLocation);
         }
+        int phoneId = SubscriptionManager.getPhoneId(subId);
         synchronized (mRecords) {
-            int phoneId = SubscriptionManager.getPhoneId(subId);
             if (validatePhoneId(phoneId)) {
                 mCellLocation[phoneId] = cellLocation;
                 for (Record r : mRecords) {
                     if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION) &&
-                            idMatch(r.subId, subId, phoneId)) {
+                            idMatch(r.subId, subId, phoneId) &&
+                            checkLocationAccess(r)) {
                         try {
                             if (DBG_LOC) {
                                 log("notifyCellLocation: cellLocation=" + cellLocation
@@ -1660,11 +1697,12 @@
     }
 
     private void enforceNotifyPermissionOrCarrierPrivilege(String method) {
-        if  (checkNotifyPermission()) {
+        if (checkNotifyPermission()) {
             return;
         }
 
-        enforceCarrierPrivilege();
+        TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
+                SubscriptionManager.getDefaultSubscriptionId(), method);
     }
 
     private boolean checkNotifyPermission(String method) {
@@ -1682,23 +1720,7 @@
                 == PackageManager.PERMISSION_GRANTED;
     }
 
-    private void enforceCarrierPrivilege() {
-        TelephonyManager tm = TelephonyManager.getDefault();
-        String[] pkgs = mContext.getPackageManager().getPackagesForUid(Binder.getCallingUid());
-        for (String pkg : pkgs) {
-            if (tm.checkCarrierPrivilegesForPackage(pkg) ==
-                    TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
-                return;
-            }
-        }
-
-        String msg = "Carrier Privilege Permission Denial: from pid=" + Binder.getCallingPid()
-                + ", uid=" + Binder.getCallingUid();
-        if (DBG) log(msg);
-        throw new SecurityException(msg);
-    }
-
-    private void checkListenerPermission(int events) {
+    private boolean checkListenerPermission(int events, String callingPackage, String message) {
         if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
             mContext.enforceCallingOrSelfPermission(
                     android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
@@ -1712,22 +1734,18 @@
         }
 
         if ((events & ENFORCE_PHONE_STATE_PERMISSION_MASK) != 0) {
-            try {
-                mContext.enforceCallingOrSelfPermission(
-                        android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null);
-                // SKIP checking for run-time permission since caller or self has PRIVILEGED
-                // permission
-            } catch (SecurityException e) {
-                mContext.enforceCallingOrSelfPermission(
-                        android.Manifest.permission.READ_PHONE_STATE, null);
+            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                    mContext, callingPackage, message)) {
+                return false;
             }
         }
 
         if ((events & PRECISE_PHONE_STATE_PERMISSION_MASK) != 0) {
             mContext.enforceCallingOrSelfPermission(
                     android.Manifest.permission.READ_PRECISE_PHONE_STATE, null);
-
         }
+
+        return true;
     }
 
     private void handleRemoveListLocked() {
@@ -1747,10 +1765,11 @@
         boolean valid = false;
         try {
             foregroundUser = ActivityManager.getCurrentUser();
-            valid = r.callerUserId ==  foregroundUser && r.matchPhoneStateListenerEvent(events);
+            valid = UserHandle.getUserId(r.callerUid) == foregroundUser
+                    && r.matchPhoneStateListenerEvent(events);
             if (DBG | DBG_LOC) {
                 log("validateEventsAndUserLocked: valid=" + valid
-                        + " r.callerUserId=" + r.callerUserId + " foregroundUser=" + foregroundUser
+                        + " r.callerUid=" + r.callerUid + " foregroundUser=" + foregroundUser
                         + " r.events=" + r.events + " events=" + events);
             }
         } finally {
@@ -1782,6 +1801,16 @@
         }
     }
 
+    private boolean checkLocationAccess(Record r) {
+        long token = Binder.clearCallingIdentity();
+        try {
+            return LocationAccessPolicy.canAccessCellLocation(mContext,
+                    r.callingPackage, r.callerUid, r.callerPid);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
     private void checkPossibleMissNotify(Record r, int phoneId) {
         int events = r.events;
 
@@ -1829,7 +1858,9 @@
                     log("checkPossibleMissNotify: onCellInfoChanged[" + phoneId + "] = "
                             + mCellInfo.get(phoneId));
                 }
-                r.callback.onCellInfoChanged(mCellInfo.get(phoneId));
+                if (checkLocationAccess(r)) {
+                    r.callback.onCellInfoChanged(mCellInfo.get(phoneId));
+                }
             } catch (RemoteException ex) {
                 mRemoveList.add(r.binder);
             }
@@ -1877,7 +1908,9 @@
             try {
                 if (DBG_LOC) log("checkPossibleMissNotify: onCellLocationChanged mCellLocation = "
                         + mCellLocation[phoneId]);
-                r.callback.onCellLocationChanged(new Bundle(mCellLocation[phoneId]));
+                if (checkLocationAccess(r)) {
+                    r.callback.onCellLocationChanged(new Bundle(mCellLocation[phoneId]));
+                }
             } catch (RemoteException ex) {
                 mRemoveList.add(r.binder);
             }
diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java
index 39fc019..965714d 100644
--- a/services/core/java/com/android/server/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/TextServicesManagerService.java
@@ -236,7 +236,7 @@
                     pw.println("        " + "mTsListener=" + req.mTsListener);
                     pw.println("        " + "mScListener=" + req.mScListener);
                     pw.println(
-                            "        " + "mScLocale=" + req.mLocale + " mUid=" + req.mUserId);
+                            "        " + "mScLocale=" + req.mLocale + " mUid=" + req.mUid);
                 }
                 final int numOnGoingSessionRequests = grp.mOnGoingSessionRequests.size();
                 for (int j = 0; j < numOnGoingSessionRequests; j++) {
@@ -246,7 +246,7 @@
                     pw.println("        " + "mTsListener=" + req.mTsListener);
                     pw.println("        " + "mScListener=" + req.mScListener);
                     pw.println(
-                            "        " + "mScLocale=" + req.mLocale + " mUid=" + req.mUserId);
+                            "        " + "mScLocale=" + req.mLocale + " mUid=" + req.mUid);
                 }
                 final int N = grp.mListeners.getRegisteredCallbackCount();
                 for (int j = 0; j < N; j++) {
@@ -738,8 +738,7 @@
     }
 
     private static final class SessionRequest {
-        @UserIdInt
-        public final int mUserId;
+        public final int mUid;
         @Nullable
         public final String mLocale;
         @NonNull
@@ -749,10 +748,10 @@
         @Nullable
         public final Bundle mBundle;
 
-        SessionRequest(@UserIdInt final int userId, @Nullable String locale,
+        SessionRequest(int uid, @Nullable String locale,
                 @NonNull ITextServicesSessionListener tsListener,
                 @NonNull ISpellCheckerSessionListener scListener, @Nullable Bundle bundle) {
-            mUserId = userId;
+            mUid = uid;
             mLocale = locale;
             mTsListener = tsListener;
             mScListener = scListener;
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 14c99b2..752c44a 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -98,7 +98,7 @@
 
     private final Context mContext;
     private final PowerManager.WakeLock mWakeLock;
-    private final IAppOpsService mAppOpsService;
+    private final AppOpsManager mAppOps;
     private final IBatteryStats mBatteryStatsService;
     private PowerManagerInternal mPowerManagerInternal;
     private InputManager mIm;
@@ -265,8 +265,7 @@
         mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*vibrator*");
         mWakeLock.setReferenceCounted(true);
 
-        mAppOpsService =
-            IAppOpsService.Stub.asInterface(ServiceManager.getService(Context.APP_OPS_SERVICE));
+        mAppOps = mContext.getSystemService(AppOpsManager.class);
         mBatteryStatsService = IBatteryStats.Stub.asInterface(ServiceManager.getService(
                 BatteryStats.SERVICE_NAME));
 
@@ -721,17 +720,10 @@
     }
 
     private int getAppOpMode(Vibration vib) {
-        int mode;
-        try {
-            mode = mAppOpsService.checkAudioOperation(AppOpsManager.OP_VIBRATE,
-                    vib.usageHint, vib.uid, vib.opPkg);
-            if (mode == AppOpsManager.MODE_ALLOWED) {
-                mode = mAppOpsService.startOperation(AppOpsManager.getToken(mAppOpsService),
-                    AppOpsManager.OP_VIBRATE, vib.uid, vib.opPkg);
-            }
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Failed to get appop mode for vibration!", e);
-            mode = AppOpsManager.MODE_IGNORED;
+        int mode = mAppOps.checkAudioOpNoThrow(AppOpsManager.OP_VIBRATE,
+                vib.usageHint, vib.uid, vib.opPkg);
+        if (mode == AppOpsManager.MODE_ALLOWED) {
+            mode = mAppOps.startOpNoThrow(AppOpsManager.OP_VIBRATE, vib.uid, vib.opPkg);
         }
         return mode;
     }
@@ -741,11 +733,8 @@
         Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "reportFinishVibrationLocked");
         try {
             if (mCurrentVibration != null) {
-                try {
-                    mAppOpsService.finishOperation(AppOpsManager.getToken(mAppOpsService),
-                            AppOpsManager.OP_VIBRATE, mCurrentVibration.uid,
-                            mCurrentVibration.opPkg);
-                } catch (RemoteException e) { }
+                mAppOps.finishOp(AppOpsManager.OP_VIBRATE, mCurrentVibration.uid,
+                        mCurrentVibration.opPkg);
                 unlinkVibration(mCurrentVibration);
                 mCurrentVibration = null;
             }
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 5fc4373..0c6746e 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -3861,8 +3861,9 @@
         return new ServiceDumper(fd, pw, args, opti, dumpAll, dumpPackage);
     }
 
-    protected void writeToProto(ProtoOutputStream proto) {
+    protected void writeToProto(ProtoOutputStream proto, long fieldId) {
         synchronized (mAm) {
+            final long outterToken = proto.start(fieldId);
             int[] users = mAm.mUserController.getUsers();
             for (int user : users) {
                 ServiceMap smap = mServiceMap.get(user);
@@ -3878,6 +3879,7 @@
                 }
                 proto.end(token);
             }
+            proto.end(outterToken);
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java
index 56ed6c8..bac81e7 100644
--- a/services/core/java/com/android/server/am/ActivityDisplay.java
+++ b/services/core/java/com/android/server/am/ActivityDisplay.java
@@ -158,6 +158,8 @@
     }
 
     private void positionChildAt(ActivityStack stack, int position) {
+        // TODO: Keep in sync with WindowContainer.positionChildAt(), once we change that to adjust
+        //       the position internally, also update the logic here
         mStacks.remove(stack);
         final int insertPosition = getTopInsertPosition(stack, position);
         mStacks.add(insertPosition, stack);
@@ -750,7 +752,15 @@
             return;
         }
 
-        positionChildAt(mHomeStack, Math.max(0, mStacks.indexOf(behindStack) - 1));
+        // Note that positionChildAt will first remove the given stack before inserting into the
+        // list, so we need to adjust the insertion index to account for the removed index
+        // TODO: Remove this logic when WindowContainer.positionChildAt() is updated to adjust the
+        //       position internally
+        final int homeStackIndex = mStacks.indexOf(mHomeStack);
+        final int behindStackIndex = mStacks.indexOf(behindStack);
+        final int insertIndex = homeStackIndex <= behindStackIndex
+                ? behindStackIndex - 1 : behindStackIndex;
+        positionChildAt(mHomeStack, Math.max(0, insertIndex));
     }
 
     boolean isSleeping() {
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 0d6d2bd..6550d06 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -85,7 +85,7 @@
     private static final int DEFAULT_POWER_CHECK_MAX_CPU_3 = 10;
     private static final int DEFAULT_POWER_CHECK_MAX_CPU_4 = 2;
     private static final long DEFAULT_SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
-    private static final long DEFAULT_USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
+    private static final long DEFAULT_USAGE_STATS_INTERACTION_INTERVAL = 2*60*60*1000L;
     private static final long DEFAULT_SERVICE_RESTART_DURATION = 1*1000;
     private static final long DEFAULT_SERVICE_RESET_RUN_DURATION = 60*1000;
     private static final int DEFAULT_SERVICE_RESTART_DURATION_FACTOR = 4;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e8f0113..28a79bd 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -440,15 +440,17 @@
 import com.android.server.am.ActivityStack.ActivityState;
 import com.android.server.am.MemoryStatUtil.MemoryStat;
 import com.android.server.am.proto.ActivityManagerServiceProto;
-import com.android.server.am.proto.BroadcastProto;
+import com.android.server.am.proto.ActivityManagerServiceDumpActivitiesProto;
+import com.android.server.am.proto.ActivityManagerServiceDumpBroadcastsProto;
+import com.android.server.am.proto.ActivityManagerServiceDumpProcessesProto;
+import com.android.server.am.proto.ActivityManagerServiceDumpProcessesProto.UidObserverRegistrationProto;
+import com.android.server.am.proto.ActivityManagerServiceDumpServicesProto;
 import com.android.server.am.proto.GrantUriProto;
 import com.android.server.am.proto.ImportanceTokenProto;
-import com.android.server.am.proto.MemInfoProto;
+import com.android.server.am.proto.MemInfoDumpProto;
 import com.android.server.am.proto.NeededUriGrantsProto;
 import com.android.server.am.proto.ProcessOomProto;
 import com.android.server.am.proto.ProcessToGcProto;
-import com.android.server.am.proto.ProcessesProto;
-import com.android.server.am.proto.ProcessesProto.UidObserverRegistrationProto;
 import com.android.server.am.proto.StickyBroadcastProto;
 import com.android.server.firewall.IntentFirewall;
 import com.android.server.job.JobSchedulerInternal;
@@ -1376,9 +1378,9 @@
 
         void writeToProto(ProtoOutputStream proto, long fieldId) {
             final long token = proto.start(fieldId);
-            proto.write(ProcessesProto.PendingTempWhitelist.TARGET_UID, targetUid);
-            proto.write(ProcessesProto.PendingTempWhitelist.DURATION_MS, duration);
-            proto.write(ProcessesProto.PendingTempWhitelist.TAG, tag);
+            proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TARGET_UID, targetUid);
+            proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.DURATION_MS, duration);
+            proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TAG, tag);
             proto.end(token);
         }
     }
@@ -5451,24 +5453,6 @@
         }
     }
 
-    @Override
-    public final void requestActivityRelaunch(IBinder token) {
-        synchronized(this) {
-            ActivityRecord r = ActivityRecord.isInStackLocked(token);
-            if (r == null) {
-                return;
-            }
-            final long origId = Binder.clearCallingIdentity();
-            try {
-                r.forceNewConfig = true;
-                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
-                        true /* preserveWindow */);
-            } finally {
-                Binder.restoreCallingIdentity(origId);
-            }
-        }
-    }
-
     /**
      * This is the internal entry point for handling Activity.finish().
      *
@@ -5707,8 +5691,7 @@
 
             final long origId = Binder.clearCallingIdentity();
 
-            if (self.state == ActivityState.RESUMED
-                    || self.state == ActivityState.PAUSING) {
+            if (self.isState(ActivityState.RESUMED, ActivityState.PAUSING)) {
                 mWindowManager.overridePendingAppTransition(packageName,
                         enterAnim, exitAnim, null);
             }
@@ -6509,22 +6492,27 @@
 
         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
+        final int[] userIds = mUserController.expandUserId(userId);
+
         long callingId = Binder.clearCallingIdentity();
         try {
             IPackageManager pm = AppGlobals.getPackageManager();
-            synchronized(this) {
+            for (int targetUserId : userIds) {
                 int appId = -1;
                 try {
                     appId = UserHandle.getAppId(
-                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
+                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
+                                    targetUserId));
                 } catch (RemoteException e) {
                 }
                 if (appId == -1) {
                     Slog.w(TAG, "Invalid packageName: " + packageName);
                     return;
                 }
-                killPackageProcessesLocked(packageName, appId, userId,
-                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
+                synchronized (this) {
+                    killPackageProcessesLocked(packageName, appId, targetUserId,
+                            ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
+                }
             }
         } finally {
             Binder.restoreCallingIdentity(callingId);
@@ -9428,6 +9416,25 @@
                     allowed = false;
                 }
             }
+            if (pi.pathPermissions != null) {
+                final int N = pi.pathPermissions.length;
+                for (int i=0; i<N; i++) {
+                    if (pi.pathPermissions[i] != null
+                            && pi.pathPermissions[i].match(grantUri.uri.getPath())) {
+                        if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
+                            if (pi.pathPermissions[i].getReadPermission() != null) {
+                                allowed = false;
+                            }
+                        }
+                        if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
+                            if (pi.pathPermissions[i].getWritePermission() != null) {
+                                allowed = false;
+                            }
+                        }
+                        break;
+                    }
+                }
+            }
             if (allowed) {
                 return -1;
             }
@@ -12874,6 +12881,25 @@
     }
 
     @Override
+    public boolean isBackgroundRestricted(String packageName) {
+        final int callingUid = Binder.getCallingUid();
+        final IPackageManager pm = AppGlobals.getPackageManager();
+        try {
+            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
+                    UserHandle.getUserId(callingUid));
+            if (packageUid != callingUid) {
+                throw new IllegalArgumentException("Uid " + callingUid
+                        + " cannot query restriction state for package " + packageName);
+            }
+        } catch (RemoteException exc) {
+            // Ignore.
+        }
+        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND,
+                callingUid, packageName);
+        return (mode != AppOpsManager.MODE_ALLOWED);
+    }
+
+    @Override
     public void backgroundWhitelistUid(final int uid) {
         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
             throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
@@ -15749,12 +15775,12 @@
             opti++;
 
             if ("activities".equals(cmd) || "a".equals(cmd)) {
-                // output proto is ActivityStackSupervisorProto
+                // output proto is ActivityManagerServiceDumpActivitiesProto
                 synchronized (this) {
                     writeActivitiesToProtoLocked(proto);
                 }
             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
-                // output proto is BroadcastProto
+                // output proto is ActivityManagerServiceDumpBroadcastsProto
                 synchronized (this) {
                     writeBroadcastsToProtoLocked(proto);
                 }
@@ -15776,7 +15802,8 @@
                     pw.println("Use -h for help.");
                 }
             } else if ("service".equals(cmd)) {
-                mServices.writeToProto(proto);
+                // output proto is ActivityManagerServiceDumpServicesProto
+                mServices.writeToProto(proto, ActivityManagerServiceDumpServicesProto.ACTIVE_SERVICES);
             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
                 if (opti < args.length) {
                     dumpPackage = args[opti];
@@ -15798,7 +15825,7 @@
                     proto.end(broadcastToken);
 
                     long serviceToken = proto.start(ActivityManagerServiceProto.SERVICES);
-                    mServices.writeToProto(proto);
+                    mServices.writeToProto(proto, ActivityManagerServiceDumpServicesProto.ACTIVE_SERVICES);
                     proto.end(serviceToken);
 
                     long processToken = proto.start(ActivityManagerServiceProto.PROCESSES);
@@ -16161,8 +16188,8 @@
     }
 
     private void writeActivitiesToProtoLocked(ProtoOutputStream proto) {
-        // The output proto of "activity --proto activities" is ActivityStackSupervisorProto
-        mStackSupervisor.writeToProto(proto);
+        // The output proto of "activity --proto activities" is ActivityManagerServiceDumpActivitiesProto
+        mStackSupervisor.writeToProto(proto, ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR);
     }
 
     private void dumpLastANRLocked(PrintWriter pw) {
@@ -16859,7 +16886,7 @@
                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
                     continue;
                 }
-                r.writeToProto(proto, ProcessesProto.PROCS);
+                r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PROCS);
                 if (r.persistent) {
                     numPers++;
                 }
@@ -16871,7 +16898,7 @@
             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
                 continue;
             }
-            r.writeToProto(proto, ProcessesProto.ISOLATED_PROCS);
+            r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ISOLATED_PROCS);
         }
 
         for (int i=0; i<mActiveInstrumentation.size(); i++) {
@@ -16880,7 +16907,7 @@
                     && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
                 continue;
             }
-            ai.writeToProto(proto, ProcessesProto.ACTIVE_INSTRUMENTATIONS);
+            ai.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ACTIVE_INSTRUMENTATIONS);
         }
 
         int whichAppId = getAppId(dumpPackage);
@@ -16889,7 +16916,7 @@
             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
                 continue;
             }
-            uidRec.writeToProto(proto, ProcessesProto.ACTIVE_UIDS);
+            uidRec.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ACTIVE_UIDS);
         }
 
         for (int i=0; i<mValidateUids.size(); i++) {
@@ -16897,16 +16924,16 @@
             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
                 continue;
             }
-            uidRec.writeToProto(proto, ProcessesProto.VALIDATE_UIDS);
+            uidRec.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VALIDATE_UIDS);
         }
 
         if (mLruProcesses.size() > 0) {
-            long lruToken = proto.start(ProcessesProto.LRU_PROCS);
+            long lruToken = proto.start(ActivityManagerServiceDumpProcessesProto.LRU_PROCS);
             int total = mLruProcesses.size();
-            proto.write(ProcessesProto.LruProcesses.SIZE, total);
-            proto.write(ProcessesProto.LruProcesses.NON_ACT_AT, total-mLruProcessActivityStart);
-            proto.write(ProcessesProto.LruProcesses.NON_SVC_AT, total-mLruProcessServiceStart);
-            writeProcessOomListToProto(proto, ProcessesProto.LruProcesses.LIST, this,
+            proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.SIZE, total);
+            proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_ACT_AT, total-mLruProcessActivityStart);
+            proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_SVC_AT, total-mLruProcessServiceStart);
+            writeProcessOomListToProto(proto, ActivityManagerServiceDumpProcessesProto.LruProcesses.LIST, this,
                     mLruProcesses,false, dumpPackage);
             proto.end(lruToken);
         }
@@ -16918,7 +16945,7 @@
                     if (!r.pkgList.containsKey(dumpPackage)) {
                         continue;
                     }
-                    r.writeToProto(proto, ProcessesProto.PIDS_SELF_LOCKED);
+                    r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PIDS_SELF_LOCKED);
                 }
             }
         }
@@ -16932,7 +16959,7 @@
                             || !r.pkgList.containsKey(dumpPackage))) {
                         continue;
                     }
-                    it.writeToProto(proto, ProcessesProto.IMPORTANT_PROCS);
+                    it.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.IMPORTANT_PROCS);
                 }
             }
         }
@@ -16942,7 +16969,7 @@
             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
                 continue;
             }
-            r.writeToProto(proto, ProcessesProto.PERSISTENT_STARTING_PROCS);
+            r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PERSISTENT_STARTING_PROCS);
         }
 
         for (int i=0; i<mRemovedProcesses.size(); i++) {
@@ -16950,7 +16977,7 @@
             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
                 continue;
             }
-            r.writeToProto(proto, ProcessesProto.REMOVED_PROCS);
+            r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.REMOVED_PROCS);
         }
 
         for (int i=0; i<mProcessesOnHold.size(); i++) {
@@ -16958,41 +16985,41 @@
             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
                 continue;
             }
-            r.writeToProto(proto, ProcessesProto.ON_HOLD_PROCS);
+            r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ON_HOLD_PROCS);
         }
 
-        writeProcessesToGcToProto(proto, ProcessesProto.GC_PROCS, dumpPackage);
-        mAppErrors.writeToProto(proto, ProcessesProto.APP_ERRORS, dumpPackage);
+        writeProcessesToGcToProto(proto, ActivityManagerServiceDumpProcessesProto.GC_PROCS, dumpPackage);
+        mAppErrors.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.APP_ERRORS, dumpPackage);
 
         if (dumpPackage == null) {
-            mUserController.writeToProto(proto, ProcessesProto.USER_CONTROLLER);
-            getGlobalConfiguration().writeToProto(proto, ProcessesProto.GLOBAL_CONFIGURATION);
-            proto.write(ProcessesProto.CONFIG_WILL_CHANGE, getFocusedStack().mConfigWillChange);
+            mUserController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.USER_CONTROLLER);
+            getGlobalConfiguration().writeToProto(proto, ActivityManagerServiceDumpProcessesProto.GLOBAL_CONFIGURATION);
+            proto.write(ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE, getFocusedStack().mConfigWillChange);
         }
 
         if (mHomeProcess != null && (dumpPackage == null
                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
-            mHomeProcess.writeToProto(proto, ProcessesProto.HOME_PROC);
+            mHomeProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HOME_PROC);
         }
 
         if (mPreviousProcess != null && (dumpPackage == null
                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
-            mPreviousProcess.writeToProto(proto, ProcessesProto.PREVIOUS_PROC);
-            proto.write(ProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
+            mPreviousProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC);
+            proto.write(ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
         }
 
         if (mHeavyWeightProcess != null && (dumpPackage == null
                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
-            mHeavyWeightProcess.writeToProto(proto, ProcessesProto.HEAVY_WEIGHT_PROC);
+            mHeavyWeightProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HEAVY_WEIGHT_PROC);
         }
 
         for (Map.Entry<String, Integer> entry : mCompatModePackages.getPackages().entrySet()) {
             String pkg = entry.getKey();
             int mode = entry.getValue();
             if (dumpPackage == null || dumpPackage.equals(pkg)) {
-                long compatToken = proto.start(ProcessesProto.SCREEN_COMPAT_PACKAGES);
-                proto.write(ProcessesProto.ScreenCompatPackage.PACKAGE, pkg);
-                proto.write(ProcessesProto.ScreenCompatPackage.MODE, mode);
+                long compatToken = proto.start(ActivityManagerServiceDumpProcessesProto.SCREEN_COMPAT_PACKAGES);
+                proto.write(ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.PACKAGE, pkg);
+                proto.write(ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.MODE, mode);
                 proto.end(compatToken);
             }
         }
@@ -17002,89 +17029,89 @@
             final UidObserverRegistration reg = (UidObserverRegistration)
                     mUidObservers.getRegisteredCallbackCookie(i);
             if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
-                reg.writeToProto(proto, ProcessesProto.UID_OBSERVERS);
+                reg.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.UID_OBSERVERS);
             }
         }
 
         for (int v : mDeviceIdleWhitelist) {
-            proto.write(ProcessesProto.DEVICE_IDLE_WHITELIST, v);
+            proto.write(ActivityManagerServiceDumpProcessesProto.DEVICE_IDLE_WHITELIST, v);
         }
 
         for (int v : mDeviceIdleTempWhitelist) {
-            proto.write(ProcessesProto.DEVICE_IDLE_TEMP_WHITELIST, v);
+            proto.write(ActivityManagerServiceDumpProcessesProto.DEVICE_IDLE_TEMP_WHITELIST, v);
         }
 
         if (mPendingTempWhitelist.size() > 0) {
             for (int i=0; i < mPendingTempWhitelist.size(); i++) {
                 mPendingTempWhitelist.valueAt(i).writeToProto(proto,
-                        ProcessesProto.PENDING_TEMP_WHITELIST);
+                        ActivityManagerServiceDumpProcessesProto.PENDING_TEMP_WHITELIST);
             }
         }
 
         if (dumpPackage == null) {
-            final long sleepToken = proto.start(ProcessesProto.SLEEP_STATUS);
-            proto.write(ProcessesProto.SleepStatus.WAKEFULNESS,
+            final long sleepToken = proto.start(ActivityManagerServiceDumpProcessesProto.SLEEP_STATUS);
+            proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.WAKEFULNESS,
                     PowerManagerInternal.wakefulnessToProtoEnum(mWakefulness));
             for (SleepToken st : mStackSupervisor.mSleepTokens) {
-                proto.write(ProcessesProto.SleepStatus.SLEEP_TOKENS, st.toString());
+                proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS, st.toString());
             }
-            proto.write(ProcessesProto.SleepStatus.SLEEPING, mSleeping);
-            proto.write(ProcessesProto.SleepStatus.SHUTTING_DOWN, mShuttingDown);
-            proto.write(ProcessesProto.SleepStatus.TEST_PSS_MODE, mTestPssMode);
+            proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
+            proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN, mShuttingDown);
+            proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.TEST_PSS_MODE, mTestPssMode);
             proto.end(sleepToken);
 
             if (mRunningVoice != null) {
-                final long vrToken = proto.start(ProcessesProto.RUNNING_VOICE);
-                proto.write(ProcessesProto.VoiceProto.SESSION, mRunningVoice.toString());
-                mVoiceWakeLock.writeToProto(proto, ProcessesProto.VoiceProto.WAKELOCK);
+                final long vrToken = proto.start(ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
+                proto.write(ActivityManagerServiceDumpProcessesProto.VoiceProto.SESSION, mRunningVoice.toString());
+                mVoiceWakeLock.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VoiceProto.WAKELOCK);
                 proto.end(vrToken);
             }
 
-            mVrController.writeToProto(proto, ProcessesProto.VR_CONTROLLER);
+            mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
         }
 
         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
                 || mOrigWaitForDebugger) {
             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
                     || dumpPackage.equals(mOrigDebugApp)) {
-                final long debugAppToken = proto.start(ProcessesProto.DEBUG);
-                proto.write(ProcessesProto.DebugApp.DEBUG_APP, mDebugApp);
-                proto.write(ProcessesProto.DebugApp.ORIG_DEBUG_APP, mOrigDebugApp);
-                proto.write(ProcessesProto.DebugApp.DEBUG_TRANSIENT, mDebugTransient);
-                proto.write(ProcessesProto.DebugApp.ORIG_WAIT_FOR_DEBUGGER, mOrigWaitForDebugger);
+                final long debugAppToken = proto.start(ActivityManagerServiceDumpProcessesProto.DEBUG);
+                proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.DEBUG_APP, mDebugApp);
+                proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.ORIG_DEBUG_APP, mOrigDebugApp);
+                proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.DEBUG_TRANSIENT, mDebugTransient);
+                proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.ORIG_WAIT_FOR_DEBUGGER, mOrigWaitForDebugger);
                 proto.end(debugAppToken);
             }
         }
 
         if (mCurAppTimeTracker != null) {
-            mCurAppTimeTracker.writeToProto(proto, ProcessesProto.CURRENT_TRACKER, true);
+            mCurAppTimeTracker.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.CURRENT_TRACKER, true);
         }
 
         if (mMemWatchProcesses.getMap().size() > 0) {
-            final long token = proto.start(ProcessesProto.MEM_WATCH_PROCESSES);
+            final long token = proto.start(ActivityManagerServiceDumpProcessesProto.MEM_WATCH_PROCESSES);
             ArrayMap<String, SparseArray<Pair<Long, String>>> procs = mMemWatchProcesses.getMap();
             for (int i=0; i<procs.size(); i++) {
                 final String proc = procs.keyAt(i);
                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
-                final long ptoken = proto.start(ProcessesProto.MemWatchProcess.PROCS);
-                proto.write(ProcessesProto.MemWatchProcess.Process.NAME, proc);
+                final long ptoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.PROCS);
+                proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.NAME, proc);
                 for (int j=0; j<uids.size(); j++) {
-                    final long utoken = proto.start(ProcessesProto.MemWatchProcess.Process.MEM_STATS);
+                    final long utoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MEM_STATS);
                     Pair<Long, String> val = uids.valueAt(j);
-                    proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.UID, uids.keyAt(j));
-                    proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.SIZE,
+                    proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.UID, uids.keyAt(j));
+                    proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.SIZE,
                             DebugUtils.sizeValueToString(val.first, new StringBuilder()));
-                    proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.REPORT_TO, val.second);
+                    proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.REPORT_TO, val.second);
                     proto.end(utoken);
                 }
                 proto.end(ptoken);
             }
 
-            final long dtoken = proto.start(ProcessesProto.MemWatchProcess.DUMP);
-            proto.write(ProcessesProto.MemWatchProcess.Dump.PROC_NAME, mMemWatchDumpProcName);
-            proto.write(ProcessesProto.MemWatchProcess.Dump.FILE, mMemWatchDumpFile);
-            proto.write(ProcessesProto.MemWatchProcess.Dump.PID, mMemWatchDumpPid);
-            proto.write(ProcessesProto.MemWatchProcess.Dump.UID, mMemWatchDumpUid);
+            final long dtoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.DUMP);
+            proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PROC_NAME, mMemWatchDumpProcName);
+            proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.FILE, mMemWatchDumpFile);
+            proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PID, mMemWatchDumpPid);
+            proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.UID, mMemWatchDumpUid);
             proto.end(dtoken);
 
             proto.end(token);
@@ -17092,58 +17119,58 @@
 
         if (mTrackAllocationApp != null) {
             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
-                proto.write(ProcessesProto.TRACK_ALLOCATION_APP, mTrackAllocationApp);
+                proto.write(ActivityManagerServiceDumpProcessesProto.TRACK_ALLOCATION_APP, mTrackAllocationApp);
             }
         }
 
         if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
                 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
-                final long token = proto.start(ProcessesProto.PROFILE);
-                proto.write(ProcessesProto.Profile.APP_NAME, mProfileApp);
-                mProfileProc.writeToProto(proto,ProcessesProto.Profile.PROC);
+                final long token = proto.start(ActivityManagerServiceDumpProcessesProto.PROFILE);
+                proto.write(ActivityManagerServiceDumpProcessesProto.Profile.APP_NAME, mProfileApp);
+                mProfileProc.writeToProto(proto,ActivityManagerServiceDumpProcessesProto.Profile.PROC);
                 if (mProfilerInfo != null) {
-                    mProfilerInfo.writeToProto(proto, ProcessesProto.Profile.INFO);
-                    proto.write(ProcessesProto.Profile.TYPE, mProfileType);
+                    mProfilerInfo.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.Profile.INFO);
+                    proto.write(ActivityManagerServiceDumpProcessesProto.Profile.TYPE, mProfileType);
                 }
                 proto.end(token);
             }
         }
 
         if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
-            proto.write(ProcessesProto.NATIVE_DEBUGGING_APP, mNativeDebuggingApp);
+            proto.write(ActivityManagerServiceDumpProcessesProto.NATIVE_DEBUGGING_APP, mNativeDebuggingApp);
         }
 
         if (dumpPackage == null) {
-            proto.write(ProcessesProto.ALWAYS_FINISH_ACTIVITIES, mAlwaysFinishActivities);
+            proto.write(ActivityManagerServiceDumpProcessesProto.ALWAYS_FINISH_ACTIVITIES, mAlwaysFinishActivities);
             if (mController != null) {
-                final long token = proto.start(ProcessesProto.CONTROLLER);
-                proto.write(ProcessesProto.Controller.CONTROLLER, mController.toString());
-                proto.write(ProcessesProto.Controller.IS_A_MONKEY, mControllerIsAMonkey);
+                final long token = proto.start(ActivityManagerServiceDumpProcessesProto.CONTROLLER);
+                proto.write(ActivityManagerServiceDumpProcessesProto.Controller.CONTROLLER, mController.toString());
+                proto.write(ActivityManagerServiceDumpProcessesProto.Controller.IS_A_MONKEY, mControllerIsAMonkey);
                 proto.end(token);
             }
-            proto.write(ProcessesProto.TOTAL_PERSISTENT_PROCS, numPers);
-            proto.write(ProcessesProto.PROCESSES_READY, mProcessesReady);
-            proto.write(ProcessesProto.SYSTEM_READY, mSystemReady);
-            proto.write(ProcessesProto.BOOTED, mBooted);
-            proto.write(ProcessesProto.FACTORY_TEST, mFactoryTest);
-            proto.write(ProcessesProto.BOOTING, mBooting);
-            proto.write(ProcessesProto.CALL_FINISH_BOOTING, mCallFinishBooting);
-            proto.write(ProcessesProto.BOOT_ANIMATION_COMPLETE, mBootAnimationComplete);
-            proto.write(ProcessesProto.LAST_POWER_CHECK_UPTIME_MS, mLastPowerCheckUptime);
-            mStackSupervisor.mGoingToSleep.writeToProto(proto, ProcessesProto.GOING_TO_SLEEP);
-            mStackSupervisor.mLaunchingActivity.writeToProto(proto, ProcessesProto.LAUNCHING_ACTIVITY);
-            proto.write(ProcessesProto.ADJ_SEQ, mAdjSeq);
-            proto.write(ProcessesProto.LRU_SEQ, mLruSeq);
-            proto.write(ProcessesProto.NUM_NON_CACHED_PROCS, mNumNonCachedProcs);
-            proto.write(ProcessesProto.NUM_SERVICE_PROCS, mNumServiceProcs);
-            proto.write(ProcessesProto.NEW_NUM_SERVICE_PROCS, mNewNumServiceProcs);
-            proto.write(ProcessesProto.ALLOW_LOWER_MEM_LEVEL, mAllowLowerMemLevel);
-            proto.write(ProcessesProto.LAST_MEMORY_LEVEL, mLastMemoryLevel);
-            proto.write(ProcessesProto.LAST_NUM_PROCESSES, mLastNumProcesses);
+            proto.write(ActivityManagerServiceDumpProcessesProto.TOTAL_PERSISTENT_PROCS, numPers);
+            proto.write(ActivityManagerServiceDumpProcessesProto.PROCESSES_READY, mProcessesReady);
+            proto.write(ActivityManagerServiceDumpProcessesProto.SYSTEM_READY, mSystemReady);
+            proto.write(ActivityManagerServiceDumpProcessesProto.BOOTED, mBooted);
+            proto.write(ActivityManagerServiceDumpProcessesProto.FACTORY_TEST, mFactoryTest);
+            proto.write(ActivityManagerServiceDumpProcessesProto.BOOTING, mBooting);
+            proto.write(ActivityManagerServiceDumpProcessesProto.CALL_FINISH_BOOTING, mCallFinishBooting);
+            proto.write(ActivityManagerServiceDumpProcessesProto.BOOT_ANIMATION_COMPLETE, mBootAnimationComplete);
+            proto.write(ActivityManagerServiceDumpProcessesProto.LAST_POWER_CHECK_UPTIME_MS, mLastPowerCheckUptime);
+            mStackSupervisor.mGoingToSleep.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.GOING_TO_SLEEP);
+            mStackSupervisor.mLaunchingActivity.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.LAUNCHING_ACTIVITY);
+            proto.write(ActivityManagerServiceDumpProcessesProto.ADJ_SEQ, mAdjSeq);
+            proto.write(ActivityManagerServiceDumpProcessesProto.LRU_SEQ, mLruSeq);
+            proto.write(ActivityManagerServiceDumpProcessesProto.NUM_NON_CACHED_PROCS, mNumNonCachedProcs);
+            proto.write(ActivityManagerServiceDumpProcessesProto.NUM_SERVICE_PROCS, mNumServiceProcs);
+            proto.write(ActivityManagerServiceDumpProcessesProto.NEW_NUM_SERVICE_PROCS, mNewNumServiceProcs);
+            proto.write(ActivityManagerServiceDumpProcessesProto.ALLOW_LOWER_MEM_LEVEL, mAllowLowerMemLevel);
+            proto.write(ActivityManagerServiceDumpProcessesProto.LAST_MEMORY_LEVEL, mLastMemoryLevel);
+            proto.write(ActivityManagerServiceDumpProcessesProto.LAST_NUM_PROCESSES, mLastNumProcesses);
             long now = SystemClock.uptimeMillis();
-            ProtoUtils.toDuration(proto, ProcessesProto.LAST_IDLE_TIME, mLastIdleTime, now);
-            proto.write(ProcessesProto.LOW_RAM_SINCE_LAST_IDLE_MS, getLowRamTimeSinceIdle(now));
+            ProtoUtils.toDuration(proto, ActivityManagerServiceDumpProcessesProto.LAST_IDLE_TIME, mLastIdleTime, now);
+            proto.write(ActivityManagerServiceDumpProcessesProto.LOW_RAM_SINCE_LAST_IDLE_MS, getLowRamTimeSinceIdle(now));
         }
 
     }
@@ -17453,15 +17480,15 @@
             Iterator it = mRegisteredReceivers.values().iterator();
             while (it.hasNext()) {
                 ReceiverList r = (ReceiverList)it.next();
-                r.writeToProto(proto, BroadcastProto.RECEIVER_LIST);
+                r.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.RECEIVER_LIST);
             }
         }
-        mReceiverResolver.writeToProto(proto, BroadcastProto.RECEIVER_RESOLVER);
+        mReceiverResolver.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.RECEIVER_RESOLVER);
         for (BroadcastQueue q : mBroadcastQueues) {
-            q.writeToProto(proto, BroadcastProto.BROADCAST_QUEUE);
+            q.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.BROADCAST_QUEUE);
         }
         for (int user=0; user<mStickyBroadcasts.size(); user++) {
-            long token = proto.start(BroadcastProto.STICKY_BROADCASTS);
+            long token = proto.start(ActivityManagerServiceDumpBroadcastsProto.STICKY_BROADCASTS);
             proto.write(StickyBroadcastProto.USER, mStickyBroadcasts.keyAt(user));
             for (Map.Entry<String, ArrayList<Intent>> ent
                     : mStickyBroadcasts.valueAt(user).entrySet()) {
@@ -17476,9 +17503,10 @@
             proto.end(token);
         }
 
-        long handlerToken = proto.start(BroadcastProto.HANDLER);
-        proto.write(BroadcastProto.MainHandler.HANDLER, mHandler.toString());
-        mHandler.getLooper().writeToProto(proto, BroadcastProto.MainHandler.LOOPER);
+        long handlerToken = proto.start(ActivityManagerServiceDumpBroadcastsProto.HANDLER);
+        proto.write(ActivityManagerServiceDumpBroadcastsProto.MainHandler.HANDLER, mHandler.toString());
+        mHandler.getLooper().writeToProto(proto,
+            ActivityManagerServiceDumpBroadcastsProto.MainHandler.LOOPER);
         proto.end(handlerToken);
     }
 
@@ -18240,17 +18268,17 @@
             MemItem mi = items.get(i);
             final long token = proto.start(fieldId);
 
-            proto.write(MemInfoProto.MemItem.TAG, tag);
-            proto.write(MemInfoProto.MemItem.LABEL, mi.shortLabel);
-            proto.write(MemInfoProto.MemItem.IS_PROC, mi.isProc);
-            proto.write(MemInfoProto.MemItem.ID, mi.id);
-            proto.write(MemInfoProto.MemItem.HAS_ACTIVITIES, mi.hasActivities);
-            proto.write(MemInfoProto.MemItem.PSS_KB, mi.pss);
+            proto.write(MemInfoDumpProto.MemItem.TAG, tag);
+            proto.write(MemInfoDumpProto.MemItem.LABEL, mi.shortLabel);
+            proto.write(MemInfoDumpProto.MemItem.IS_PROC, mi.isProc);
+            proto.write(MemInfoDumpProto.MemItem.ID, mi.id);
+            proto.write(MemInfoDumpProto.MemItem.HAS_ACTIVITIES, mi.hasActivities);
+            proto.write(MemInfoDumpProto.MemItem.PSS_KB, mi.pss);
             if (dumpSwapPss) {
-                proto.write(MemInfoProto.MemItem.SWAP_PSS_KB, mi.swapPss);
+                proto.write(MemInfoDumpProto.MemItem.SWAP_PSS_KB, mi.swapPss);
             }
             if (mi.subitems != null) {
-                dumpMemItems(proto, MemInfoProto.MemItem.SUB_ITEMS, mi.shortLabel, mi.subitems,
+                dumpMemItems(proto, MemInfoDumpProto.MemItem.SUB_ITEMS, mi.shortLabel, mi.subitems,
                         true, dumpSwapPss);
             }
             proto.end(token);
@@ -19004,16 +19032,16 @@
                     if (nativeProcs.size() > 0) {
                         ProtoOutputStream proto = new ProtoOutputStream(fd);
 
-                        proto.write(MemInfoProto.UPTIME_DURATION_MS, uptimeMs);
-                        proto.write(MemInfoProto.ELAPSED_REALTIME_MS, realtimeMs);
+                        proto.write(MemInfoDumpProto.UPTIME_DURATION_MS, uptimeMs);
+                        proto.write(MemInfoDumpProto.ELAPSED_REALTIME_MS, realtimeMs);
                         Debug.MemoryInfo mi = null;
                         for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
                             final ProcessCpuTracker.Stats r = nativeProcs.get(i);
                             final int pid = r.pid;
-                            final long nToken = proto.start(MemInfoProto.NATIVE_PROCESSES);
+                            final long nToken = proto.start(MemInfoDumpProto.NATIVE_PROCESSES);
 
-                            proto.write(MemInfoProto.ProcessMemory.PID, pid);
-                            proto.write(MemInfoProto.ProcessMemory.PROCESS_NAME, r.baseName);
+                            proto.write(MemInfoDumpProto.ProcessMemory.PID, pid);
+                            proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, r.baseName);
 
                             if (mi == null) {
                                 mi = new Debug.MemoryInfo();
@@ -19045,8 +19073,8 @@
 
         ProtoOutputStream proto = new ProtoOutputStream(fd);
 
-        proto.write(MemInfoProto.UPTIME_DURATION_MS, uptimeMs);
-        proto.write(MemInfoProto.ELAPSED_REALTIME_MS, realtimeMs);
+        proto.write(MemInfoDumpProto.UPTIME_DURATION_MS, uptimeMs);
+        proto.write(MemInfoDumpProto.ELAPSED_REALTIME_MS, realtimeMs);
 
         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
@@ -19111,10 +19139,10 @@
             }
             if (opts.dumpDetails) {
                 if (opts.localOnly) {
-                    final long aToken = proto.start(MemInfoProto.APP_PROCESSES);
-                    final long mToken = proto.start(MemInfoProto.AppData.PROCESS_MEMORY);
-                    proto.write(MemInfoProto.ProcessMemory.PID, pid);
-                    proto.write(MemInfoProto.ProcessMemory.PROCESS_NAME, r.processName);
+                    final long aToken = proto.start(MemInfoDumpProto.APP_PROCESSES);
+                    final long mToken = proto.start(MemInfoDumpProto.AppData.PROCESS_MEMORY);
+                    proto.write(MemInfoDumpProto.ProcessMemory.PID, pid);
+                    proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, r.processName);
                     ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
                             opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
                     proto.end(mToken);
@@ -19126,7 +19154,7 @@
                             thread.dumpMemInfoProto(tp.getWriteFd(),
                                 mi, opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
                                 opts.dumpUnreachable, innerArgs);
-                            proto.write(MemInfoProto.APP_PROCESSES, tp.get());
+                            proto.write(MemInfoDumpProto.APP_PROCESSES, tp.get());
                         } finally {
                             tp.kill();
                         }
@@ -19314,13 +19342,13 @@
 
             opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
             if (!opts.oomOnly) {
-                dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_PROCESS, "proc",
+                dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_PROCESS, "proc",
                         procMems, true, opts.dumpSwapPss);
             }
-            dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_OOM_ADJUSTMENT, "oom",
+            dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_OOM_ADJUSTMENT, "oom",
                     oomMems, false, opts.dumpSwapPss);
             if (!brief && !opts.oomOnly) {
-                dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_CATEGORY, "cat",
+                dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_CATEGORY, "cat",
                         catMems, true, opts.dumpSwapPss);
             }
             MemInfoReader memInfo = new MemInfoReader();
@@ -19338,40 +19366,40 @@
                 }
             }
             if (!brief) {
-                proto.write(MemInfoProto.TOTAL_RAM_KB, memInfo.getTotalSizeKb());
-                proto.write(MemInfoProto.STATUS, mLastMemoryLevel);
-                proto.write(MemInfoProto.CACHED_PSS_KB, cachedPss);
-                proto.write(MemInfoProto.CACHED_KERNEL_KB, memInfo.getCachedSizeKb());
-                proto.write(MemInfoProto.FREE_KB, memInfo.getFreeSizeKb());
+                proto.write(MemInfoDumpProto.TOTAL_RAM_KB, memInfo.getTotalSizeKb());
+                proto.write(MemInfoDumpProto.STATUS, mLastMemoryLevel);
+                proto.write(MemInfoDumpProto.CACHED_PSS_KB, cachedPss);
+                proto.write(MemInfoDumpProto.CACHED_KERNEL_KB, memInfo.getCachedSizeKb());
+                proto.write(MemInfoDumpProto.FREE_KB, memInfo.getFreeSizeKb());
             }
             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
-            proto.write(MemInfoProto.USED_PSS_KB, totalPss - cachedPss);
-            proto.write(MemInfoProto.USED_KERNEL_KB, memInfo.getKernelUsedSizeKb());
-            proto.write(MemInfoProto.LOST_RAM_KB, lostRAM);
+            proto.write(MemInfoDumpProto.USED_PSS_KB, totalPss - cachedPss);
+            proto.write(MemInfoDumpProto.USED_KERNEL_KB, memInfo.getKernelUsedSizeKb());
+            proto.write(MemInfoDumpProto.LOST_RAM_KB, lostRAM);
             if (!brief) {
                 if (memInfo.getZramTotalSizeKb() != 0) {
-                    proto.write(MemInfoProto.TOTAL_ZRAM_KB, memInfo.getZramTotalSizeKb());
-                    proto.write(MemInfoProto.ZRAM_PHYSICAL_USED_IN_SWAP_KB,
+                    proto.write(MemInfoDumpProto.TOTAL_ZRAM_KB, memInfo.getZramTotalSizeKb());
+                    proto.write(MemInfoDumpProto.ZRAM_PHYSICAL_USED_IN_SWAP_KB,
                             memInfo.getSwapTotalSizeKb() - memInfo.getSwapFreeSizeKb());
-                    proto.write(MemInfoProto.TOTAL_ZRAM_SWAP_KB, memInfo.getSwapTotalSizeKb());
+                    proto.write(MemInfoDumpProto.TOTAL_ZRAM_SWAP_KB, memInfo.getSwapTotalSizeKb());
                 }
                 final long[] ksm = getKsmInfo();
-                proto.write(MemInfoProto.KSM_SHARING_KB, ksm[KSM_SHARING]);
-                proto.write(MemInfoProto.KSM_SHARED_KB, ksm[KSM_SHARED]);
-                proto.write(MemInfoProto.KSM_UNSHARED_KB, ksm[KSM_UNSHARED]);
-                proto.write(MemInfoProto.KSM_VOLATILE_KB, ksm[KSM_VOLATILE]);
+                proto.write(MemInfoDumpProto.KSM_SHARING_KB, ksm[KSM_SHARING]);
+                proto.write(MemInfoDumpProto.KSM_SHARED_KB, ksm[KSM_SHARED]);
+                proto.write(MemInfoDumpProto.KSM_UNSHARED_KB, ksm[KSM_UNSHARED]);
+                proto.write(MemInfoDumpProto.KSM_VOLATILE_KB, ksm[KSM_VOLATILE]);
 
-                proto.write(MemInfoProto.TUNING_MB, ActivityManager.staticGetMemoryClass());
-                proto.write(MemInfoProto.TUNING_LARGE_MB, ActivityManager.staticGetLargeMemoryClass());
-                proto.write(MemInfoProto.OOM_KB,
+                proto.write(MemInfoDumpProto.TUNING_MB, ActivityManager.staticGetMemoryClass());
+                proto.write(MemInfoDumpProto.TUNING_LARGE_MB, ActivityManager.staticGetLargeMemoryClass());
+                proto.write(MemInfoDumpProto.OOM_KB,
                         mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024);
-                proto.write(MemInfoProto.RESTORE_LIMIT_KB,
+                proto.write(MemInfoDumpProto.RESTORE_LIMIT_KB,
                         mProcessList.getCachedRestoreThresholdKb());
 
-                proto.write(MemInfoProto.IS_LOW_RAM_DEVICE, ActivityManager.isLowRamDeviceStatic());
-                proto.write(MemInfoProto.IS_HIGH_END_GFX, ActivityManager.isHighEndGfx());
+                proto.write(MemInfoDumpProto.IS_LOW_RAM_DEVICE, ActivityManager.isLowRamDeviceStatic());
+                proto.write(MemInfoDumpProto.IS_HIGH_END_GFX, ActivityManager.isHighEndGfx());
             }
         }
 
@@ -22374,7 +22402,7 @@
         // Update the configuration with WM first and check if any of the stacks need to be resized
         // due to the configuration change. If so, resize the stacks now and do any relaunches if
         // necessary. This way we don't need to relaunch again afterwards in
-        // ensureActivityConfigurationLocked().
+        // ensureActivityConfiguration().
         if (mWindowManager != null) {
             final int[] resizedStacks =
                     mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
@@ -22402,7 +22430,7 @@
             }
 
             if (starting != null) {
-                kept = starting.ensureActivityConfigurationLocked(changes,
+                kept = starting.ensureActivityConfiguration(changes,
                         false /* preserveWindow */);
                 // And we need to make sure at this point that all other activities
                 // are made visible with the correct configuration.
@@ -22792,7 +22820,7 @@
                         }
                     }
                     break;
-                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
+                } else if (r.isState(ActivityState.PAUSING, ActivityState.PAUSED)) {
                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
                         app.adjType = "pause-activity";
@@ -22807,7 +22835,7 @@
                     app.cached = false;
                     app.empty = false;
                     foregroundActivities = true;
-                } else if (r.state == ActivityState.STOPPING) {
+                } else if (r.isState(ActivityState.STOPPING)) {
                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
                         app.adjType = "stop-activity";
@@ -23201,9 +23229,8 @@
                     }
                     final ActivityRecord a = cr.activity;
                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
-                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
-                            (a.visible || a.state == ActivityState.RESUMED ||
-                             a.state == ActivityState.PAUSING)) {
+                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && (a.visible
+                                || a.isState(ActivityState.RESUMED, ActivityState.PAUSING))) {
                             adj = ProcessList.FOREGROUND_APP_ADJ;
                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
@@ -25749,7 +25776,6 @@
         public void notifyAppTransitionFinished() {
             synchronized (ActivityManagerService.this) {
                 mStackSupervisor.notifyAppTransitionDone();
-                mKeyguardController.notifyAppTransitionDone();
             }
         }
 
@@ -26138,6 +26164,10 @@
             return getRecentTasks().isCallerRecents(callingUid);
         }
 
+        public boolean isRecentsComponentHomeActivity(int userId) {
+            return getRecentTasks().isRecentsComponentHomeActivity(userId);
+        }
+
         @Override
         public boolean isUidActive(int uid) {
             synchronized (ActivityManagerService.this) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index fa0df56..81dae39 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -23,24 +23,35 @@
 import android.app.IActivityManager;
 import android.app.IStopUserCallback;
 import android.app.IUidObserver;
+import android.app.KeyguardManager;
 import android.app.ProfilerInfo;
 import android.app.WaitResult;
+import android.app.usage.AppStandbyInfo;
 import android.app.usage.ConfigurationStats;
 import android.app.usage.IUsageStatsManager;
 import android.app.usage.UsageStatsManager;
 import android.content.ComponentCallbacks2;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.DeviceConfigurationProto;
+import android.content.GlobalConfigurationProto;
 import android.content.IIntentReceiver;
 import android.content.Intent;
+import android.content.pm.ConfigurationInfo;
+import android.content.pm.FeatureInfo;
 import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.ResolveInfo;
+import android.content.pm.SharedLibraryInfo;
 import android.content.pm.UserInfo;
 import android.content.res.AssetManager;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.graphics.Point;
 import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
+import android.opengl.GLES10;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
@@ -52,12 +63,16 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.DebugUtils;
 import android.util.DisplayMetrics;
+import android.util.proto.ProtoOutputStream;
+import android.view.Display;
 
 import com.android.internal.util.HexDump;
+import com.android.internal.util.MemInfoReader;
 import com.android.internal.util.Preconditions;
 
 import java.io.BufferedReader;
@@ -68,11 +83,18 @@
 import java.io.PrintWriter;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
+import java.util.Set;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.egl.EGLSurface;
 
 import static android.app.ActivityManager.RESIZE_MODE_SYSTEM;
 import static android.app.ActivityManager.RESIZE_MODE_USER;
@@ -442,12 +464,11 @@
                     options.setTaskOverlay(true, true /* canResume */);
                 }
             }
-            android.util.Log.d("bfranz", "I was here: " + mIsLockTask);
             if (mIsLockTask) {
                 if (options == null) {
                     options = ActivityOptions.makeBasic();
                 }
-                options.setLockTaskMode(true);
+                options.setLockTaskEnabled(true);
             }
             if (mWaitOption) {
                 result = mInterface.startActivityAndWait(null, null, intent, mimeType,
@@ -1621,6 +1642,11 @@
     }
 
     int runSwitchUser(PrintWriter pw) throws RemoteException {
+        UserManager userManager = mInternal.mContext.getSystemService(UserManager.class);
+        if (!userManager.canSwitchUsers()) {
+            getErrPrintWriter().println("Error: disallowed switching user");
+            return -1;
+        }
         String user = getNextArgRequired();
         mInterface.switchUser(Integer.parseInt(user));
         return 0;
@@ -1835,17 +1861,251 @@
         }
     }
 
-    int runGetConfig(PrintWriter pw) throws RemoteException {
-        int days = 14;
-        String option = getNextOption();
-        if (option != null) {
-            if (!option.equals("--days")) {
-                throw new IllegalArgumentException("unrecognized option " + option);
+    /**
+     * Adds all supported GL extensions for a provided EGLConfig to a set by creating an EGLContext
+     * and EGLSurface and querying extensions.
+     *
+     * @param egl An EGL API object
+     * @param display An EGLDisplay to create a context and surface with
+     * @param config The EGLConfig to get the extensions for
+     * @param surfaceSize eglCreatePbufferSurface generic parameters
+     * @param contextAttribs eglCreateContext generic parameters
+     * @param glExtensions A Set<String> to add GL extensions to
+     */
+    private static void addExtensionsForConfig(
+            EGL10 egl,
+            EGLDisplay display,
+            EGLConfig config,
+            int[] surfaceSize,
+            int[] contextAttribs,
+            Set<String> glExtensions) {
+        // Create a context.
+        EGLContext context =
+                egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, contextAttribs);
+        // No-op if we can't create a context.
+        if (context == EGL10.EGL_NO_CONTEXT) {
+            return;
+        }
+
+        // Create a surface.
+        EGLSurface surface = egl.eglCreatePbufferSurface(display, config, surfaceSize);
+        if (surface == EGL10.EGL_NO_SURFACE) {
+            egl.eglDestroyContext(display, context);
+            return;
+        }
+
+        // Update the current surface and context.
+        egl.eglMakeCurrent(display, surface, surface, context);
+
+        // Get the list of extensions.
+        String extensionList = GLES10.glGetString(GLES10.GL_EXTENSIONS);
+        if (!TextUtils.isEmpty(extensionList)) {
+            // The list of extensions comes from the driver separated by spaces.
+            // Split them apart and add them into a Set for deduping purposes.
+            for (String extension : extensionList.split(" ")) {
+                glExtensions.add(extension);
+            }
+        }
+
+        // Tear down the context and surface for this config.
+        egl.eglMakeCurrent(display, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
+        egl.eglDestroySurface(display, surface);
+        egl.eglDestroyContext(display, context);
+    }
+
+
+    Set<String> getGlExtensionsFromDriver() {
+        Set<String> glExtensions = new HashSet<>();
+
+        // Get the EGL implementation.
+        EGL10 egl = (EGL10) EGLContext.getEGL();
+        if (egl == null) {
+            getErrPrintWriter().println("Warning: couldn't get EGL");
+            return glExtensions;
+        }
+
+        // Get the default display and initialize it.
+        EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
+        int[] version = new int[2];
+        egl.eglInitialize(display, version);
+
+        // Call getConfigs() in order to find out how many there are.
+        int[] numConfigs = new int[1];
+        if (!egl.eglGetConfigs(display, null, 0, numConfigs)) {
+            getErrPrintWriter().println("Warning: couldn't get EGL config count");
+            return glExtensions;
+        }
+
+        // Allocate space for all configs and ask again.
+        EGLConfig[] configs = new EGLConfig[numConfigs[0]];
+        if (!egl.eglGetConfigs(display, configs, numConfigs[0], numConfigs)) {
+            getErrPrintWriter().println("Warning: couldn't get EGL configs");
+            return glExtensions;
+        }
+
+        // Allocate surface size parameters outside of the main loop to cut down
+        // on GC thrashing.  1x1 is enough since we are only using it to get at
+        // the list of extensions.
+        int[] surfaceSize =
+                new int[] {
+                        EGL10.EGL_WIDTH, 1,
+                        EGL10.EGL_HEIGHT, 1,
+                        EGL10.EGL_NONE
+                };
+
+        // For when we need to create a GLES2.0 context.
+        final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
+        int[] gles2 = new int[] {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE};
+
+        // For getting return values from eglGetConfigAttrib
+        int[] attrib = new int[1];
+
+        for (int i = 0; i < numConfigs[0]; i++) {
+            // Get caveat for this config in order to skip slow (i.e. software) configs.
+            egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_CONFIG_CAVEAT, attrib);
+            if (attrib[0] == EGL10.EGL_SLOW_CONFIG) {
+                continue;
             }
 
-            days = Integer.parseInt(getNextArgRequired());
-            if (days <= 0) {
-                throw new IllegalArgumentException("--days must be a positive integer");
+            // If the config does not support pbuffers we cannot do an eglMakeCurrent
+            // on it in addExtensionsForConfig(), so skip it here. Attempting to make
+            // it current with a pbuffer will result in an EGL_BAD_MATCH error
+            egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_SURFACE_TYPE, attrib);
+            if ((attrib[0] & EGL10.EGL_PBUFFER_BIT) == 0) {
+                continue;
+            }
+
+            final int EGL_OPENGL_ES_BIT = 0x0001;
+            final int EGL_OPENGL_ES2_BIT = 0x0004;
+            egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_RENDERABLE_TYPE, attrib);
+            if ((attrib[0] & EGL_OPENGL_ES_BIT) != 0) {
+                addExtensionsForConfig(egl, display, configs[i], surfaceSize, null, glExtensions);
+            }
+            if ((attrib[0] & EGL_OPENGL_ES2_BIT) != 0) {
+                addExtensionsForConfig(egl, display, configs[i], surfaceSize, gles2, glExtensions);
+            }
+        }
+
+        // Release all EGL resources.
+        egl.eglTerminate(display);
+
+        return glExtensions;
+    }
+
+    private void writeDeviceConfig(ProtoOutputStream protoOutputStream, long fieldId,
+            PrintWriter pw, Configuration config, DisplayManager dm) {
+        Point stableSize = dm.getStableDisplaySize();
+        long token = -1;
+        if (protoOutputStream != null) {
+            token = protoOutputStream.start(fieldId);
+            protoOutputStream.write(DeviceConfigurationProto.STABLE_SCREEN_WIDTH_PX, stableSize.x);
+            protoOutputStream.write(DeviceConfigurationProto.STABLE_SCREEN_HEIGHT_PX, stableSize.y);
+            protoOutputStream.write(DeviceConfigurationProto.STABLE_DENSITY_DPI,
+                    DisplayMetrics.DENSITY_DEVICE_STABLE);
+        }
+        if (pw != null) {
+            pw.print("stable-width-px: "); pw.println(stableSize.x);
+            pw.print("stable-height-px: "); pw.println(stableSize.y);
+            pw.print("stable-density-dpi: "); pw.println(DisplayMetrics.DENSITY_DEVICE_STABLE);
+        }
+
+        MemInfoReader memreader = new MemInfoReader();
+        memreader.readMemInfo();
+        KeyguardManager kgm = mInternal.mContext.getSystemService(KeyguardManager.class);
+        if (protoOutputStream != null) {
+            protoOutputStream.write(DeviceConfigurationProto.TOTAL_RAM, memreader.getTotalSize());
+            protoOutputStream.write(DeviceConfigurationProto.LOW_RAM,
+                    ActivityManager.isLowRamDeviceStatic());
+            protoOutputStream.write(DeviceConfigurationProto.MAX_CORES,
+                    Runtime.getRuntime().availableProcessors());
+            protoOutputStream.write(DeviceConfigurationProto.HAS_SECURE_SCREEN_LOCK,
+                    kgm.isDeviceSecure());
+        }
+        if (pw != null) {
+            pw.print("total-ram: "); pw.println(memreader.getTotalSize());
+            pw.print("low-ram: "); pw.println(ActivityManager.isLowRamDeviceStatic());
+            pw.print("max-cores: "); pw.println(Runtime.getRuntime().availableProcessors());
+            pw.print("has-secure-screen-lock: "); pw.println(kgm.isDeviceSecure());
+        }
+
+        ConfigurationInfo configInfo = mInternal.getDeviceConfigurationInfo();
+        if (configInfo.reqGlEsVersion != ConfigurationInfo.GL_ES_VERSION_UNDEFINED) {
+            if (protoOutputStream != null) {
+                protoOutputStream.write(DeviceConfigurationProto.OPENGL_VERSION,
+                        configInfo.reqGlEsVersion);
+            }
+            if (pw != null) {
+                pw.print("opengl-version: 0x");
+                pw.println(Integer.toHexString(configInfo.reqGlEsVersion));
+            }
+        }
+
+        Set<String> glExtensionsSet = getGlExtensionsFromDriver();
+        String[] glExtensions = new String[glExtensionsSet.size()];
+        glExtensions = glExtensionsSet.toArray(glExtensions);
+        Arrays.sort(glExtensions);
+        for (int i = 0; i < glExtensions.length; i++) {
+            if (protoOutputStream != null) {
+                protoOutputStream.write(DeviceConfigurationProto.OPENGL_EXTENSIONS,
+                        glExtensions[i]);
+            }
+            if (pw != null) {
+                pw.print("opengl-extensions: "); pw.println(glExtensions[i]);
+            }
+
+        }
+
+        PackageManager pm = mInternal.mContext.getPackageManager();
+        List<SharedLibraryInfo> slibs = pm.getSharedLibraries(0);
+        Collections.sort(slibs, Comparator.comparing(SharedLibraryInfo::getName));
+        for (int i = 0; i < slibs.size(); i++) {
+            if (protoOutputStream != null) {
+                protoOutputStream.write(DeviceConfigurationProto.SHARED_LIBRARIES,
+                        slibs.get(i).getName());
+            }
+            if (pw != null) {
+                pw.print("shared-libraries: "); pw.println(slibs.get(i).getName());
+            }
+        }
+
+        FeatureInfo[] features = pm.getSystemAvailableFeatures();
+        Arrays.sort(features, (o1, o2) ->
+                (o1.name == o2.name ? 0 : (o1.name == null ? -1 : o1.name.compareTo(o2.name))));
+        for (int i = 0; i < features.length; i++) {
+            if (features[i].name != null) {
+                if (protoOutputStream != null) {
+                    protoOutputStream.write(DeviceConfigurationProto.FEATURES, features[i].name);
+                }
+                if (pw != null) {
+                    pw.print("features: "); pw.println(features[i].name);
+                }
+            }
+        }
+
+        if (protoOutputStream != null) {
+            protoOutputStream.end(token);
+        }
+    }
+
+    int runGetConfig(PrintWriter pw) throws RemoteException {
+        int days = -1;
+        boolean asProto = false;
+        boolean inclDevice = false;
+
+        String opt;
+        while ((opt=getNextOption()) != null) {
+            if (opt.equals("--days")) {
+                days = Integer.parseInt(getNextArgRequired());
+                if (days <= 0) {
+                    throw new IllegalArgumentException("--days must be a positive integer");
+                }
+            } else if (opt.equals("--proto")) {
+                asProto = true;
+            } else if (opt.equals("--device")) {
+                inclDevice = true;
+            } else {
+                getErrPrintWriter().println("Error: Unknown option: " + opt);
+                return -1;
             }
         }
 
@@ -1855,18 +2115,38 @@
             return -1;
         }
 
-        pw.println("config: " + Configuration.resourceQualifierString(config));
-        pw.println("abi: " + TextUtils.join(",", Build.SUPPORTED_ABIS));
+        DisplayManager dm = mInternal.mContext.getSystemService(DisplayManager.class);
+        Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
+        DisplayMetrics metrics = new DisplayMetrics();
+        display.getMetrics(metrics);
 
-        final List<Configuration> recentConfigs = getRecentConfigurations(days);
-        final int recentConfigSize = recentConfigs.size();
-        if (recentConfigSize > 0) {
-            pw.println("recentConfigs:");
-        }
+        if (asProto) {
+            final ProtoOutputStream proto = new ProtoOutputStream(getOutFileDescriptor());
+            config.writeResConfigToProto(proto, GlobalConfigurationProto.RESOURCES, metrics);
+            if (inclDevice) {
+                writeDeviceConfig(proto, GlobalConfigurationProto.DEVICE, null, config, dm);
+            }
+            proto.flush();
 
-        for (int i = 0; i < recentConfigSize; i++) {
-            pw.println("  config: " + Configuration.resourceQualifierString(
-                    recentConfigs.get(i)));
+        } else {
+            pw.println("config: " + Configuration.resourceQualifierString(config, metrics));
+            pw.println("abi: " + TextUtils.join(",", Build.SUPPORTED_ABIS));
+            if (inclDevice) {
+                writeDeviceConfig(null, -1, pw, config, dm);
+            }
+
+            if (days >= 0) {
+                final List<Configuration> recentConfigs = getRecentConfigurations(days);
+                final int recentConfigSize = recentConfigs.size();
+                if (recentConfigSize > 0) {
+                    pw.println("recentConfigs:");
+                    for (int i = 0; i < recentConfigSize; i++) {
+                        pw.println("  config: " + Configuration.resourceQualifierString(
+                                recentConfigs.get(i)));
+                    }
+                }
+            }
+
         }
         return 0;
     }
@@ -1945,15 +2225,16 @@
         if (!multiple) {
             usm.setAppStandbyBucket(packageName, bucketNameToBucketValue(value), userId);
         } else {
-            HashMap<String, Integer> buckets = new HashMap<>();
-            buckets.put(packageName, bucket);
+            ArrayList<AppStandbyInfo> bucketInfoList = new ArrayList<>();
+            bucketInfoList.add(new AppStandbyInfo(packageName, bucket));
             while ((packageName = getNextArg()) != null) {
                 value = getNextArgRequired();
                 bucket = bucketNameToBucketValue(value);
                 if (bucket < 0) continue;
-                buckets.put(packageName, bucket);
+                bucketInfoList.add(new AppStandbyInfo(packageName, bucket));
             }
-            usm.setAppStandbyBuckets(buckets, userId);
+            ParceledListSlice<AppStandbyInfo> slice = new ParceledListSlice<>(bucketInfoList);
+            usm.setAppStandbyBuckets(slice, userId);
         }
         return 0;
     }
@@ -1978,11 +2259,11 @@
             int bucket = usm.getAppStandbyBucket(packageName, null, userId);
             pw.println(bucket);
         } else {
-            Map<String, Integer> buckets = (Map<String, Integer>) usm.getAppStandbyBuckets(
+            ParceledListSlice<AppStandbyInfo> buckets = usm.getAppStandbyBuckets(
                     SHELL_PACKAGE_NAME, userId);
-            for (Map.Entry<String, Integer> entry: buckets.entrySet()) {
-                pw.print(entry.getKey()); pw.print(": ");
-                pw.println(entry.getValue());
+            for (AppStandbyInfo bucketInfo : buckets.getList()) {
+                pw.print(bucketInfo.mPackageName); pw.print(": ");
+                pw.println(bucketInfo.mStandbyBucket);
             }
         }
         return 0;
@@ -2672,7 +2953,7 @@
             pw.println("  crash [--user <USER_ID>] <PACKAGE|PID>");
             pw.println("      Induce a VM crash in the specified package or process");
             pw.println("  kill [--user <USER_ID> | all | current] <PACKAGE>");
-            pw.println("      Kill all processes associated with the given application.");
+            pw.println("      Kill all background processes associated with the given application.");
             pw.println("  kill-all");
             pw.println("      Kill all processes that are safe to kill (cached, etc).");
             pw.println("  make-uid-idle [--user <USER_ID> | all | current] <PACKAGE>");
@@ -2728,8 +3009,11 @@
             pw.println("      Gets the process state of an app given its <UID>.");
             pw.println("  attach-agent <PROCESS> <FILE>");
             pw.println("    Attach an agent to the specified <PROCESS>, which may be either a process name or a PID.");
-            pw.println("  get-config");
-            pw.println("      Rtrieve the configuration and any recent configurations of the device.");
+            pw.println("  get-config [--days N] [--device] [--proto]");
+            pw.println("      Retrieve the configuration and any recent configurations of the device.");
+            pw.println("      --days: also return last N days of configurations that have been seen.");
+            pw.println("      --device: also output global device configuration info.");
+            pw.println("      --proto: return result as a proto; does not include --days info.");
             pw.println("  supports-multiwindow");
             pw.println("      Returns true if the device supports multiwindow.");
             pw.println("  supports-split-screen-multi-window");
diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
index db86f1a..5d5ed55 100644
--- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
@@ -23,6 +23,8 @@
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_WINDOWS_DRAWN_DELAY_MS;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CLASS_NAME;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_INSTANT_APP_LAUNCH_TOKEN;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PACKAGE_OPTIMIZATION_COMPILATION_REASON;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PACKAGE_OPTIMIZATION_COMPILATION_FILTER;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_COLD_LAUNCH;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_HOT_LAUNCH;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_REPORTED_DRAWN_NO_BUNDLE;
@@ -35,6 +37,9 @@
 import static com.android.server.am.MemoryStatUtil.readMemoryStatFromMemcg;
 
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.dex.ArtManagerInternal;
+import android.content.pm.dex.PackageOptimizationInfo;
 import android.metrics.LogMaker;
 import android.os.Handler;
 import android.os.Looper;
@@ -46,7 +51,9 @@
 import android.util.StatsLog;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.os.BackgroundThread;
 import com.android.internal.os.SomeArgs;
+import com.android.server.LocalServices;
 
 import java.util.ArrayList;
 
@@ -68,7 +75,6 @@
     private static final long INVALID_START_TIME = -1;
 
     private static final int MSG_CHECK_VISIBILITY = 0;
-    private static final int MSG_LOG_APP_START_MEMORY_STATE_CAPTURE = 1;
 
     // Preallocated strings we are sending to tron, so we don't have to allocate a new one every
     // time we log.
@@ -93,6 +99,9 @@
     private final SparseArray<WindowingModeTransitionInfo> mLastWindowingModeTransitionInfo =
             new SparseArray<>();
     private final H mHandler;
+
+    private ArtManagerInternal mArtManagerInternal;
+
     private final class H extends Handler {
 
         public H(Looper looper) {
@@ -106,12 +115,9 @@
                     final SomeArgs args = (SomeArgs) msg.obj;
                     checkVisibility((TaskRecord) args.arg1, (ActivityRecord) args.arg2);
                     break;
-                case MSG_LOG_APP_START_MEMORY_STATE_CAPTURE:
-                    logAppStartMemoryStateCapture((WindowingModeTransitionInfo) msg.obj);
-                    break;
             }
         }
-    };
+    }
 
     private final class WindowingModeTransitionInfo {
         private ActivityRecord launchedActivity;
@@ -125,6 +131,40 @@
         private boolean loggedStartingWindowDrawn;
     }
 
+    private final class WindowingModeTransitionInfoSnapshot {
+        final private ApplicationInfo applicationInfo;
+        final private ProcessRecord processRecord;
+        final private String packageName;
+        final private String launchedActivityName;
+        final private String launchedActivityLaunchedFromPackage;
+        final private String launchedActivityLaunchToken;
+        final private String launchedActivityAppRecordRequiredAbi;
+        final private String processName;
+        final private int reason;
+        final private int startingWindowDelayMs;
+        final private int bindApplicationDelayMs;
+        final private int windowsDrawnDelayMs;
+        final private int type;
+
+        private WindowingModeTransitionInfoSnapshot(WindowingModeTransitionInfo info) {
+            applicationInfo = info.launchedActivity.appInfo;
+            packageName = info.launchedActivity.packageName;
+            launchedActivityName = info.launchedActivity.info.name;
+            launchedActivityLaunchedFromPackage = info.launchedActivity.launchedFromPackage;
+            launchedActivityLaunchToken = info.launchedActivity.info.launchToken;
+            launchedActivityAppRecordRequiredAbi = info.launchedActivity.app == null
+                    ? null
+                    : info.launchedActivity.app.requiredAbi;
+            reason = info.reason;
+            startingWindowDelayMs = info.startingWindowDelayMs;
+            bindApplicationDelayMs = info.bindApplicationDelayMs;
+            windowsDrawnDelayMs = info.windowsDrawnDelayMs;
+            type = getTransitionType(info);
+            processRecord = findProcessForActivity(info.launchedActivity);
+            processName = info.launchedActivity.processName;
+        }
+    }
+
     ActivityMetricsLogger(ActivityStackSupervisor supervisor, Context context, Looper looper) {
         mLastLogTimeSecs = SystemClock.elapsedRealtime() / 1000;
         mSupervisor = supervisor;
@@ -456,54 +496,82 @@
             if (type == -1) {
                 return;
             }
-            final LogMaker builder = new LogMaker(APP_TRANSITION);
-            builder.setPackageName(info.launchedActivity.packageName);
-            builder.setType(type);
-            builder.addTaggedData(FIELD_CLASS_NAME, info.launchedActivity.info.name);
-            final boolean isInstantApp = info.launchedActivity.info.applicationInfo.isInstantApp();
-            if (info.launchedActivity.launchedFromPackage != null) {
-                builder.addTaggedData(APP_TRANSITION_CALLING_PACKAGE_NAME,
-                        info.launchedActivity.launchedFromPackage);
-            }
-            String launchToken = info.launchedActivity.info.launchToken;
-            if (launchToken != null) {
-                builder.addTaggedData(FIELD_INSTANT_APP_LAUNCH_TOKEN, launchToken);
-                info.launchedActivity.info.launchToken = null;
-            }
-            builder.addTaggedData(APP_TRANSITION_IS_EPHEMERAL, isInstantApp ? 1 : 0);
-            builder.addTaggedData(APP_TRANSITION_DEVICE_UPTIME_SECONDS,
-                    mCurrentTransitionDeviceUptime);
-            builder.addTaggedData(APP_TRANSITION_DELAY_MS, mCurrentTransitionDelayMs);
-            builder.setSubtype(info.reason);
-            if (info.startingWindowDelayMs != -1) {
-                builder.addTaggedData(APP_TRANSITION_STARTING_WINDOW_DELAY_MS,
-                        info.startingWindowDelayMs);
-            }
-            if (info.bindApplicationDelayMs != -1) {
-                builder.addTaggedData(APP_TRANSITION_BIND_APPLICATION_DELAY_MS,
-                        info.bindApplicationDelayMs);
-            }
-            builder.addTaggedData(APP_TRANSITION_WINDOWS_DRAWN_DELAY_MS, info.windowsDrawnDelayMs);
-            mMetricsLogger.write(builder);
-            StatsLog.write(
-                    StatsLog.APP_START_CHANGED,
-                    info.launchedActivity.appInfo.uid,
-                    info.launchedActivity.packageName,
-                    convertAppStartTransitionType(type),
-                    info.launchedActivity.info.name,
-                    info.launchedActivity.launchedFromPackage,
-                    isInstantApp,
-                    mCurrentTransitionDeviceUptime * 1000,
-                    info.reason,
-                    mCurrentTransitionDelayMs,
-                    info.startingWindowDelayMs,
-                    info.bindApplicationDelayMs,
-                    info.windowsDrawnDelayMs,
-                    launchToken);
-            mHandler.obtainMessage(MSG_LOG_APP_START_MEMORY_STATE_CAPTURE, info).sendToTarget();
+
+            // Take a snapshot of the transition info before sending it to the handler for logging.
+            // This will avoid any races with other operations that modify the ActivityRecord.
+            final WindowingModeTransitionInfoSnapshot infoSnapshot =
+                    new WindowingModeTransitionInfoSnapshot(info);
+            final int currentTransitionDeviceUptime = mCurrentTransitionDeviceUptime;
+            final int currentTransitionDelayMs = mCurrentTransitionDelayMs;
+            BackgroundThread.getHandler().post(() -> logAppTransition(
+                    currentTransitionDeviceUptime, currentTransitionDelayMs, infoSnapshot));
+
+            info.launchedActivity.info.launchToken = null;
         }
     }
 
+    // This gets called on a background thread without holding the activity manager lock.
+    private void logAppTransition(int currentTransitionDeviceUptime, int currentTransitionDelayMs,
+            WindowingModeTransitionInfoSnapshot info) {
+        final LogMaker builder = new LogMaker(APP_TRANSITION);
+        builder.setPackageName(info.packageName);
+        builder.setType(info.type);
+        builder.addTaggedData(FIELD_CLASS_NAME, info.launchedActivityName);
+        final boolean isInstantApp = info.applicationInfo.isInstantApp();
+        if (info.launchedActivityLaunchedFromPackage != null) {
+            builder.addTaggedData(APP_TRANSITION_CALLING_PACKAGE_NAME,
+                    info.launchedActivityLaunchedFromPackage);
+        }
+        String launchToken = info.launchedActivityLaunchToken;
+        if (launchToken != null) {
+            builder.addTaggedData(FIELD_INSTANT_APP_LAUNCH_TOKEN, launchToken);
+        }
+        builder.addTaggedData(APP_TRANSITION_IS_EPHEMERAL, isInstantApp ? 1 : 0);
+        builder.addTaggedData(APP_TRANSITION_DEVICE_UPTIME_SECONDS,
+                currentTransitionDeviceUptime);
+        builder.addTaggedData(APP_TRANSITION_DELAY_MS, currentTransitionDelayMs);
+        builder.setSubtype(info.reason);
+        if (info.startingWindowDelayMs != -1) {
+            builder.addTaggedData(APP_TRANSITION_STARTING_WINDOW_DELAY_MS,
+                    info.startingWindowDelayMs);
+        }
+        if (info.bindApplicationDelayMs != -1) {
+            builder.addTaggedData(APP_TRANSITION_BIND_APPLICATION_DELAY_MS,
+                    info.bindApplicationDelayMs);
+        }
+        builder.addTaggedData(APP_TRANSITION_WINDOWS_DRAWN_DELAY_MS, info.windowsDrawnDelayMs);
+        final ArtManagerInternal artManagerInternal = getArtManagerInternal();
+        final PackageOptimizationInfo packageOptimizationInfo =
+                (artManagerInternal == null) || (info.launchedActivityAppRecordRequiredAbi == null)
+                ? PackageOptimizationInfo.createWithNoInfo()
+                : artManagerInternal.getPackageOptimizationInfo(
+                        info.applicationInfo,
+                        info.launchedActivityAppRecordRequiredAbi);
+        builder.addTaggedData(PACKAGE_OPTIMIZATION_COMPILATION_REASON,
+                packageOptimizationInfo.getCompilationReason());
+        builder.addTaggedData(PACKAGE_OPTIMIZATION_COMPILATION_FILTER,
+                packageOptimizationInfo.getCompilationFilter());
+        mMetricsLogger.write(builder);
+        StatsLog.write(
+                StatsLog.APP_START_CHANGED,
+                info.applicationInfo.uid,
+                info.packageName,
+                convertAppStartTransitionType(info.type),
+                info.launchedActivityName,
+                info.launchedActivityLaunchedFromPackage,
+                isInstantApp,
+                currentTransitionDeviceUptime * 1000,
+                info.reason,
+                currentTransitionDelayMs,
+                info.startingWindowDelayMs,
+                info.bindApplicationDelayMs,
+                info.windowsDrawnDelayMs,
+                launchToken,
+                packageOptimizationInfo.getCompilationReason(),
+                packageOptimizationInfo.getCompilationFilter());
+        logAppStartMemoryStateCapture(info);
+    }
+
     private int convertAppStartTransitionType(int tronType) {
         if (tronType == TYPE_TRANSITION_COLD_LAUNCH) {
             return StatsLog.APP_START_CHANGED__TYPE__COLD;
@@ -559,15 +627,14 @@
         return -1;
     }
 
-    private void logAppStartMemoryStateCapture(WindowingModeTransitionInfo info) {
-        final ProcessRecord processRecord = findProcessForActivity(info.launchedActivity);
-        if (processRecord == null) {
+    private void logAppStartMemoryStateCapture(WindowingModeTransitionInfoSnapshot info) {
+        if (info.processRecord == null) {
             if (DEBUG_METRICS) Slog.i(TAG, "logAppStartMemoryStateCapture processRecord null");
             return;
         }
 
-        final int pid = processRecord.pid;
-        final int uid = info.launchedActivity.appInfo.uid;
+        final int pid = info.processRecord.pid;
+        final int uid = info.applicationInfo.uid;
         final MemoryStat memoryStat = readMemoryStatFromMemcg(uid, pid);
         if (memoryStat == null) {
             if (DEBUG_METRICS) Slog.i(TAG, "logAppStartMemoryStateCapture memoryStat null");
@@ -577,8 +644,8 @@
         StatsLog.write(
                 StatsLog.APP_START_MEMORY_STATE_CAPTURED,
                 uid,
-                info.launchedActivity.processName,
-                info.launchedActivity.info.name,
+                info.processName,
+                info.launchedActivityName,
                 memoryStat.pgfault,
                 memoryStat.pgmajfault,
                 memoryStat.rssInBytes,
@@ -592,4 +659,14 @@
                         launchedActivity.appInfo.uid)
                 : null;
     }
+
+    private ArtManagerInternal getArtManagerInternal() {
+        if (mArtManagerInternal == null) {
+            // Note that this may be null.
+            // ArtManagerInternal is registered during PackageManagerService
+            // initialization which happens after ActivityManagerService.
+            mArtManagerInternal = LocalServices.getService(ArtManagerInternal.class);
+        }
+        return mArtManagerInternal;
+    }
 }
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 4e60924..ae98ca0 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -230,6 +230,8 @@
     private static final String ATTR_COMPONENTSPECIFIED = "component_specified";
     static final String ACTIVITY_ICON_SUFFIX = "_activity_icon_";
 
+    private static final int MAX_STORED_STATE_TRANSITIONS = 5;
+
     final ActivityManagerService service; // owner
     final IApplicationToken.Stub appToken; // window manager token
     AppWindowContainerController mWindowContainerController;
@@ -288,7 +290,7 @@
     HashSet<ConnectionRecord> connections; // All ConnectionRecord we hold
     UriPermissionOwner uriPermissions; // current special URI access perms.
     ProcessRecord app;      // if non-null, hosting application
-    ActivityState state;    // current state we are in
+    private ActivityState mState;    // current state we are in
     Bundle  icicle;         // last saved activity state
     PersistableBundle persistentState; // last persistently saved activity state
     // TODO: See if this is still needed.
@@ -361,11 +363,33 @@
     private boolean mTurnScreenOn;
 
     /**
-     * Temp configs used in {@link #ensureActivityConfigurationLocked(int, boolean)}
+     * Temp configs used in {@link #ensureActivityConfiguration(int, boolean)}
      */
     private final Configuration mTmpConfig = new Configuration();
     private final Rect mTmpBounds = new Rect();
 
+    private final ArrayList<StateTransition> mRecentTransitions = new ArrayList<>();
+
+    // TODO(b/71506345): Remove once issue has been resolved.
+    private static class StateTransition {
+        final long time;
+        final ActivityState prev;
+        final ActivityState state;
+        final String reason;
+
+        StateTransition(ActivityState prev, ActivityState state, String reason) {
+            time = System.currentTimeMillis();
+            this.prev = prev;
+            this.state = state;
+            this.reason = reason;
+        }
+
+        @Override
+        public String toString() {
+            return "[" + prev + "->" + state + ":" + reason + "@" + time + "]";
+        }
+    }
+
     private static String startingWindowStateToString(int state) {
         switch (state) {
             case STARTING_WINDOW_NOT_SHOWN:
@@ -380,9 +404,18 @@
     }
 
     String getLifecycleDescription(String reason) {
+        StringBuilder transitionBuilder = new StringBuilder();
+
+        for (int i = 0, size = mRecentTransitions.size(); i < size; ++i) {
+            transitionBuilder.append(mRecentTransitions.get(i));
+            if (i + 1 < size) {
+                transitionBuilder.append(",");
+            }
+        }
+
         return "name= " + this + ", component=" + intent.getComponent().flattenToShortString()
-                + ", package=" + packageName + ", state=" + state + ", reason=" + reason + ", time="
-                + System.currentTimeMillis();
+                + ", package=" + packageName + ", state=" + mState + ", reason=" + reason
+                + ", time=" + System.currentTimeMillis() + " transitions=" + transitionBuilder;
     }
 
     void dump(PrintWriter pw, String prefix) {
@@ -503,7 +536,7 @@
                 pw.println();
         pw.print(prefix); pw.print("haveState="); pw.print(haveState);
                 pw.print(" icicle="); pw.println(icicle);
-        pw.print(prefix); pw.print("state="); pw.print(state);
+        pw.print(prefix); pw.print("state="); pw.print(mState);
                 pw.print(" stopped="); pw.print(stopped);
                 pw.print(" delayedResume="); pw.print(delayedResume);
                 pw.print(" finishing="); pw.println(finishing);
@@ -841,7 +874,7 @@
         resultTo = _resultTo;
         resultWho = _resultWho;
         requestCode = _reqCode;
-        state = INITIALIZING;
+        setState(INITIALIZING, "ActivityRecord ctor");
         frontOfTask = false;
         launchFailed = false;
         stopped = false;
@@ -1000,6 +1033,11 @@
     }
 
     void removeWindowContainer() {
+        // Do not try to remove a window container if we have already removed it.
+        if (mWindowContainerController == null) {
+            return;
+        }
+
         // Resume key dispatching if it is currently paused before we remove the container.
         resumeKeyDispatchingLocked();
 
@@ -1259,7 +1297,7 @@
             return false;
         }
 
-        switch (state) {
+        switch (mState) {
             case RESUMED:
                 // When visible, allow entering PiP if the app is not locked.  If it is over the
                 // keyguard, then we will prompt to unlock in the caller before entering PiP.
@@ -1385,13 +1423,13 @@
         // - It is currently resumed or paused. i.e. it is currently visible to the user and we want
         //   the user to see the visual effects caused by the intent delivery now.
         // - The device is sleeping and it is the top activity behind the lock screen (b/6700897).
-        if ((state == RESUMED || state == PAUSED
+        if ((mState == RESUMED || mState == PAUSED
                 || isTopActivityWhileSleeping) && app != null && app.thread != null) {
             try {
                 ArrayList<ReferrerIntent> ar = new ArrayList<>(1);
                 ar.add(rintent);
                 service.mLifecycleManager.scheduleTransaction(app.thread, appToken,
-                        NewIntentItem.obtain(ar, state == PAUSED));
+                        NewIntentItem.obtain(ar, mState == PAUSED));
                 unsent = false;
             } catch (RemoteException e) {
                 Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
@@ -1573,6 +1611,54 @@
         mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
     }
 
+    void setState(ActivityState state, String reason) {
+        if (DEBUG_STATES) Slog.v(TAG_STATES, "State movement: " + this + " from:" + getState()
+                        + " to:" + state + " reason:" + reason);
+        final ActivityState prev = mState;
+        mState = state;
+
+        if (mState != prev) {
+            if (mRecentTransitions.size() == MAX_STORED_STATE_TRANSITIONS) {
+                mRecentTransitions.remove(0);
+            }
+
+            mRecentTransitions.add(new StateTransition(prev, state, reason));
+        }
+    }
+
+    ActivityState getState() {
+        return mState;
+    }
+
+    /**
+     * Returns {@code true} if the Activity is in the specified state.
+     */
+    boolean isState(ActivityState state) {
+        return state == mState;
+    }
+
+    /**
+     * Returns {@code true} if the Activity is in one of the specified states.
+     */
+    boolean isState(ActivityState state1, ActivityState state2) {
+        return state1 == mState || state2 == mState;
+    }
+
+    /**
+     * Returns {@code true} if the Activity is in one of the specified states.
+     */
+    boolean isState(ActivityState state1, ActivityState state2, ActivityState state3) {
+        return state1 == mState || state2 == mState || state3 == mState;
+    }
+
+    /**
+     * Returns {@code true} if the Activity is in one of the specified states.
+     */
+    boolean isState(ActivityState state1, ActivityState state2, ActivityState state3,
+            ActivityState state4) {
+        return state1 == mState || state2 == mState || state3 == mState || state4 == mState;
+    }
+
     void notifyAppResumed(boolean wasStopped) {
         mWindowContainerController.notifyAppResumed(wasStopped);
     }
@@ -1602,9 +1688,9 @@
 
     void makeVisibleIfNeeded(ActivityRecord starting) {
         // This activity is not currently visible, but is running. Tell it to become visible.
-        if (state == RESUMED || this == starting) {
+        if (mState == RESUMED || this == starting) {
             if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY,
-                    "Not making visible, r=" + this + " state=" + state + " starting=" + starting);
+                    "Not making visible, r=" + this + " state=" + mState + " starting=" + starting);
             return;
         }
 
@@ -1625,6 +1711,20 @@
             // The activity may be waiting for stop, but that is no longer appropriate for it.
             mStackSupervisor.mStoppingActivities.remove(this);
             mStackSupervisor.mGoingToSleepActivities.remove(this);
+
+            // If the activity is stopped or stopping, cycle to the paused state.
+            if (isState(STOPPED, STOPPING)) {
+                // Capture reason before state change
+                final String reason = getLifecycleDescription("makeVisibleIfNeeded");
+
+                // An activity must be in the {@link PAUSING} state for the system to validate
+                // the move to {@link PAUSED}.
+                setState(PAUSING, "makeVisibleIfNeeded");
+                service.mLifecycleManager.scheduleTransaction(app.thread, appToken,
+                        PauseActivityItem.obtain(finishing, false /* userLeaving */,
+                                configChangeFlags, false /* dontReport */)
+                                .setDescription(reason));
+            }
         } catch (Exception e) {
             // Just skip on any failure; we'll make it visible when it next restarts.
             Slog.w(TAG, "Exception thrown making visibile: " + intent.getComponent(), e);
@@ -1640,7 +1740,7 @@
             }
         } catch(RemoteException e) {
         }
-        return state == RESUMED;
+        return mState == RESUMED;
     }
 
     static void activityResumedLocked(IBinder token) {
@@ -1714,7 +1814,7 @@
     final void activityStoppedLocked(Bundle newIcicle, PersistableBundle newPersistentState,
             CharSequence description) {
         final ActivityStack stack = getStack();
-        if (state != STOPPING) {
+        if (mState != STOPPING) {
             Slog.i(TAG, "Activity reported stop, but no longer stopping: " + this);
             stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
             return;
@@ -1737,7 +1837,7 @@
             if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to STOPPED: " + this + " (stop complete)");
             stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
             stopped = true;
-            state = STOPPED;
+            setState(STOPPED, "activityStoppedLocked");
 
             mWindowContainerController.notifyAppStopped();
 
@@ -2007,8 +2107,7 @@
      * currently pausing, or is resumed.
      */
     public boolean isInterestingToUserLocked() {
-        return visible || nowVisible || state == PAUSING ||
-                state == RESUMED;
+        return visible || nowVisible || mState == PAUSING || mState == RESUMED;
     }
 
     void setSleeping(boolean _sleeping) {
@@ -2070,8 +2169,7 @@
     }
 
     final boolean isDestroyable() {
-        if (finishing || app == null || state == DESTROYING
-                || state == DESTROYED) {
+        if (finishing || app == null) {
             // This would be redundant.
             return false;
         }
@@ -2137,7 +2235,7 @@
                 compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
                 prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(),
                 allowTaskSnapshot(),
-                state.ordinal() >= RESUMED.ordinal() && state.ordinal() <= STOPPED.ordinal(),
+                mState.ordinal() >= RESUMED.ordinal() && mState.ordinal() <= STOPPED.ordinal(),
                 fromRecents);
         if (shown) {
             mStartingWindowState = STARTING_WINDOW_SHOWN;
@@ -2291,13 +2389,27 @@
         outBounds.offsetTo(left, 0 /* top */);
     }
 
+    boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow) {
+        return ensureActivityConfiguration(globalChanges, preserveWindow,
+                false /* ignoreStopState */);
+    }
+
     /**
-     * Make sure the given activity matches the current configuration. Returns false if the activity
-     * had to be destroyed.  Returns true if the configuration is the same, or the activity will
-     * remain running as-is for whatever reason. Ensures the HistoryRecord is updated with the
-     * correct configuration and all other bookkeeping is handled.
+     * Make sure the given activity matches the current configuration. Ensures the HistoryRecord
+     * is updated with the correct configuration and all other bookkeeping is handled.
+     *
+     * @param globalChanges The changes to the global configuration.
+     * @param preserveWindow If the activity window should be preserved on screen if the activity
+     *                       is relaunched.
+     * @param ignoreStopState If we should try to relaunch the activity even if it is in the stopped
+     *                        state. This is useful for the case where we know the activity will be
+     *                        visible soon and we want to ensure its configuration before we make it
+     *                        visible.
+     * @return True if the activity was relaunched and false if it wasn't relaunched because we
+     *         can't or the app handles the specific configuration that is changing.
      */
-    boolean ensureActivityConfigurationLocked(int globalChanges, boolean preserveWindow) {
+    boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow,
+            boolean ignoreStopState) {
         final ActivityStack stack = getStack();
         if (stack.mConfigWillChange) {
             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
@@ -2313,8 +2425,7 @@
             return true;
         }
 
-        // Skip updating configuration for activity that are stopping or stopped.
-        if (state == STOPPING || state == STOPPED) {
+        if (!ignoreStopState && (mState == STOPPING || mState == STOPPED)) {
             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                     "Skipping config check stopped or stopping: " + this);
             return true;
@@ -2364,7 +2475,7 @@
 
         setLastReportedConfiguration(service.getGlobalConfiguration(), newMergedOverrideConfig);
 
-        if (state == INITIALIZING) {
+        if (mState == INITIALIZING) {
             // No need to relaunch or schedule new config for activity that hasn't been launched
             // yet. We do, however, return after applying the config to activity record, so that
             // it will use it for launch transaction.
@@ -2417,7 +2528,7 @@
                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                         "Config is destroying non-running " + this);
                 stack.destroyActivityLocked(this, true, "config");
-            } else if (state == PAUSING) {
+            } else if (mState == PAUSING) {
                 // A little annoying: we are waiting for this activity to finish pausing. Let's not
                 // do anything now, but just flag that it needs to be restarted when done pausing.
                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
@@ -2425,7 +2536,7 @@
                 deferRelaunchUntilPaused = true;
                 preserveWindowOnDeferredRelaunch = preserveWindow;
                 return true;
-            } else if (state == RESUMED) {
+            } else if (mState == RESUMED) {
                 // Try to optimize this case: the configuration is changing and we need to restart
                 // the top, resumed activity. Instead of doing the normal handshaking, just say
                 // "restart!".
@@ -2595,7 +2706,7 @@
             service.showAskCompatModeDialogLocked(this);
         } else {
             service.mHandler.removeMessages(PAUSE_TIMEOUT_MSG, this);
-            state = PAUSED;
+            setState(PAUSED, "relaunchActivityLocked");
             // if the app is relaunched when it's stopped, and we're not resuming,
             // put it back into stopped state.
             if (stopped) {
@@ -2839,7 +2950,7 @@
         final long token = proto.start(fieldId);
         super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */);
         writeIdentifierToProto(proto, IDENTIFIER);
-        proto.write(STATE, state.toString());
+        proto.write(STATE, mState.toString());
         proto.write(VISIBLE, visible);
         proto.write(FRONT_OF_TASK, frontOfTask);
         if (app != null) {
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index fe10670..728c07d 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -70,7 +70,12 @@
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
 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.ActivityStack.ActivityState.DESTROYED;
+import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
+import static com.android.server.am.ActivityStack.ActivityState.FINISHING;
 import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
+import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
+import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
 import static com.android.server.am.ActivityStack.ActivityState.STOPPED;
 import static com.android.server.am.ActivityStack.ActivityState.STOPPING;
 import static com.android.server.am.ActivityStackSupervisor.FindTaskResult;
@@ -104,6 +109,7 @@
 import android.app.WindowConfiguration.ActivityType;
 import android.app.WindowConfiguration.WindowingMode;
 import android.app.servertransaction.ActivityResultItem;
+import android.app.servertransaction.ClientTransaction;
 import android.app.servertransaction.NewIntentItem;
 import android.app.servertransaction.WindowVisibilityItem;
 import android.app.servertransaction.DestroyActivityItem;
@@ -118,7 +124,6 @@
 import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Binder;
-import android.os.Bundle;
 import android.os.Debug;
 import android.os.Handler;
 import android.os.IBinder;
@@ -599,6 +604,8 @@
                 // the one where the home stack is visible since recents isn't visible yet, but the
                 // divider will be off. I think we should just make the initial bounds that of home
                 // so that the divider matches and remove this logic.
+                // TODO: This is currently only called when entering split-screen while in another
+                // task, and from the tests
                 final ActivityStack recentStack = display.getOrCreateStack(
                         WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_RECENTS,
                         true /* onTop */);
@@ -1353,8 +1360,7 @@
             final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
                 final ActivityRecord r = activities.get(activityNdx);
-                if (r.state == STOPPING || r.state == STOPPED
-                        || r.state == ActivityState.PAUSED || r.state == ActivityState.PAUSING) {
+                if (r.isState(STOPPING, STOPPED, PAUSED, PAUSING)) {
                     r.setSleeping(true);
                 }
             }
@@ -1401,7 +1407,7 @@
             ActivityRecord resuming, boolean pauseImmediately) {
         if (mPausingActivity != null) {
             Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
-                    + " state=" + mPausingActivity.state);
+                    + " state=" + mPausingActivity.getState());
             if (!shouldSleepActivities()) {
                 // Avoid recursion among check for sleep and complete pause during sleeping.
                 // Because activity will be paused immediately after resume, just let pause
@@ -1431,7 +1437,7 @@
         mLastPausedActivity = prev;
         mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
                 || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
-        prev.state = ActivityState.PAUSING;
+        prev.setState(PAUSING, "startPausingLocked");
         prev.getTask().touchActiveTime();
         clearLaunchTime(prev);
         final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
@@ -1525,8 +1531,8 @@
                         r.userId, System.identityHashCode(r), r.shortComponentName,
                         mPausingActivity != null
                             ? mPausingActivity.shortComponentName : "(none)");
-                if (r.state == ActivityState.PAUSING) {
-                    r.state = ActivityState.PAUSED;
+                if (r.isState(PAUSING)) {
+                    r.setState(PAUSED, "activityPausedLocked");
                     if (r.finishing) {
                         if (DEBUG_PAUSE) Slog.v(TAG,
                                 "Executing finish of failed to pause activity: " + r);
@@ -1544,8 +1550,8 @@
         if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);
 
         if (prev != null) {
-            final boolean wasStopping = prev.state == STOPPING;
-            prev.state = ActivityState.PAUSED;
+            final boolean wasStopping = prev.isState(STOPPING);
+            prev.setState(PAUSED, "completePausedLocked");
             if (prev.finishing) {
                 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
                 prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false,
@@ -1566,7 +1572,7 @@
                     // We are also stopping, the stop request must have gone soon after the pause.
                     // We can't clobber it, because the stop confirmation will not be handled.
                     // We don't need to schedule another stop, we only need to let it happen.
-                    prev.state = STOPPING;
+                    prev.setState(STOPPING, "completePausedLocked");
                 } else if (!prev.visible || shouldSleepOrShutDownActivities()) {
                     // Clear out any deferred client hide we might currently have.
                     prev.setDeferHidingClient(false);
@@ -1843,11 +1849,14 @@
                     }
                     if (reallyVisible) {
                         if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make visible? " + r
-                                + " finishing=" + r.finishing + " state=" + r.state);
+                                + " finishing=" + r.finishing + " state=" + r.getState());
                         // First: if this is not the current activity being started, make
                         // sure it matches the current configuration.
                         if (r != starting) {
-                            r.ensureActivityConfigurationLocked(0 /* globalChanges */, preserveWindows);
+                            // Ensure activity configuration ignoring stop state since we are
+                            // becoming visible.
+                            r.ensureActivityConfiguration(0 /* globalChanges */, preserveWindows,
+                                    true /* ignoreStopState */);
                         }
 
                         if (r.app == null || r.app.thread == null) {
@@ -1875,7 +1884,7 @@
                         configChanges |= r.configChangeFlags;
                     } else {
                         if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r
-                                + " finishing=" + r.finishing + " state=" + r.state
+                                + " finishing=" + r.finishing + " state=" + r.getState()
                                 + " stackShouldBeVisible=" + stackShouldBeVisible
                                 + " behindFullscreenActivity=" + behindFullscreenActivity
                                 + " mLaunchTaskBehind=" + r.mLaunchTaskBehind);
@@ -2059,7 +2068,7 @@
         }
         // Now for any activities that aren't visible to the user, make sure they no longer are
         // keeping the screen frozen.
-        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Making invisible: " + r + " " + r.state);
+        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Making invisible: " + r + " " + r.getState());
         try {
             final boolean canEnterPictureInPicture = r.checkEnterPictureInPictureState(
                     "makeInvisible", true /* beforeStopping */);
@@ -2071,11 +2080,11 @@
             // the current contract for "auto-Pip" is that the app should enter it before onPause
             // returns. Just need to confirm this reasoning makes sense.
             final boolean deferHidingClient = canEnterPictureInPicture
-                    && r.state != STOPPING && r.state != STOPPED && r.state != PAUSED;
+                    && !r.isState(STOPPING, STOPPED, PAUSED);
             r.setDeferHidingClient(deferHidingClient);
             r.setVisible(false);
 
-            switch (r.state) {
+            switch (r.getState()) {
                 case STOPPING:
                 case STOPPED:
                     if (r.app != null && r.app.thread != null) {
@@ -2255,7 +2264,7 @@
         // TODO: move mResumedActivity to stack supervisor,
         // there should only be 1 global copy of resumed activity.
         mResumedActivity = r;
-        r.state = ActivityState.RESUMED;
+        r.setState(RESUMED, "setResumedActivityLocked");
         mService.setResumedActivityUncheckLocked(r, reason);
         mStackSupervisor.mRecentTasks.add(r.getTask());
     }
@@ -2294,8 +2303,8 @@
         next.delayedResume = false;
 
         // If the top activity is the resumed one, nothing to do.
-        if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
-                    mStackSupervisor.allResumedActivitiesComplete()) {
+        if (mResumedActivity == next && next.isState(RESUMED)
+                && mStackSupervisor.allResumedActivitiesComplete()) {
             // Make sure we have executed any pending transitions, since there
             // should be nothing left to do at this point.
             executeAppTransition(options);
@@ -2389,8 +2398,8 @@
             }
             if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
             return true;
-        } else if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
-                mStackSupervisor.allResumedActivitiesComplete()) {
+        } else if (mResumedActivity == next && next.isState(RESUMED)
+                && mStackSupervisor.allResumedActivitiesComplete()) {
             // It is possible for the activity to be resumed when we paused back stacks above if the
             // next activity doesn't have to wait for pause to complete.
             // So, nothing else to-do except:
@@ -2539,7 +2548,7 @@
 
                 ActivityRecord lastResumedActivity =
                         lastStack == null ? null :lastStack.mResumedActivity;
-                ActivityState lastState = next.state;
+                final ActivityState lastState = next.getState();
 
                 mService.updateCpuStats();
 
@@ -2601,6 +2610,8 @@
                 }
 
                 try {
+                    final ClientTransaction transaction = ClientTransaction.obtain(next.app.thread,
+                            next.appToken);
                     // Deliver all pending results.
                     ArrayList<ResultInfo> a = next.results;
                     if (a != null) {
@@ -2608,15 +2619,13 @@
                         if (!next.finishing && N > 0) {
                             if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
                                     "Delivering results to " + next + ": " + a);
-                            mService.mLifecycleManager.scheduleTransaction(next.app.thread,
-                                    next.appToken, ActivityResultItem.obtain(a));
+                            transaction.addCallback(ActivityResultItem.obtain(a));
                         }
                     }
 
                     if (next.newIntents != null) {
-                        mService.mLifecycleManager.scheduleTransaction(next.app.thread,
-                                next.appToken, NewIntentItem.obtain(next.newIntents,
-                                        false /* andPause */));
+                        transaction.addCallback(NewIntentItem.obtain(next.newIntents,
+                                false /* andPause */));
                     }
 
                     // Well the app will no longer be stopped.
@@ -2633,11 +2642,13 @@
                     next.app.pendingUiClean = true;
                     next.app.forceProcessStateUpTo(mService.mTopProcessState);
                     next.clearOptionsLocked();
-                    mService.mLifecycleManager.scheduleTransaction(next.app.thread, next.appToken,
+
+                    transaction.setLifecycleStateRequest(
                             ResumeActivityItem.obtain(next.app.repProcState,
                                     mService.isNextTransitionForward())
                                     .setDescription(next.getLifecycleDescription(
                                             "resumeTopActivityInnerLocked")));
+                    mService.mLifecycleManager.scheduleTransaction(transaction);
 
                     if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed "
                             + next);
@@ -2645,7 +2656,7 @@
                     // Whoops, need to restart this activity!
                     if (DEBUG_STATES) Slog.v(TAG_STATES, "Resume failed; resetting state to "
                             + lastState + ": " + next);
-                    next.state = lastState;
+                    next.setState(lastState, "resumeTopActivityInnerLocked");
                     if (lastStack != null) {
                         lastStack.mResumedActivity = lastResumedActivity;
                     }
@@ -3408,7 +3419,7 @@
                 r.stopped = false;
                 if (DEBUG_STATES) Slog.v(TAG_STATES,
                         "Moving to STOPPING: " + r + " (stop requested)");
-                r.state = STOPPING;
+                r.setState(STOPPING, "stopActivityLocked");
                 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
                         "Stopping visible=" + r.visible + " for " + r);
                 if (!r.visible) {
@@ -3432,7 +3443,7 @@
                 // Just in case, assume it to be stopped.
                 r.stopped = true;
                 if (DEBUG_STATES) Slog.v(TAG_STATES, "Stop failed; moving to STOPPED: " + r);
-                r.state = STOPPED;
+                r.setState(STOPPED, "stopActivityLocked");
                 if (r.deferRelaunchUntilPaused) {
                     destroyActivityLocked(r, true, "stop-except");
                 }
@@ -3505,9 +3516,7 @@
         }
         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.isState(RESUMED, PAUSING, PAUSED)) {
                 if (!r.isActivityTypeHome() || mService.mHomeProcess != r.app) {
                     Slog.w(TAG, "  Force finishing activity "
                             + r.intent.getComponent().flattenToShortString());
@@ -3671,7 +3680,7 @@
                 if (endTask) {
                     mService.mLockTaskController.clearLockedTask(task);
                 }
-            } else if (r.state != ActivityState.PAUSING) {
+            } else if (!r.isState(PAUSING)) {
                 // If the activity is PAUSING, we will complete the finish once
                 // it is done pausing; else we can just directly finish it here.
                 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + r);
@@ -3738,7 +3747,7 @@
             }
             if (DEBUG_STATES) Slog.v(TAG_STATES,
                     "Moving to STOPPING: "+ r + " (finish requested)");
-            r.state = STOPPING;
+            r.setState(STOPPING, "finishCurrentActivityLocked");
             if (oomAdj) {
                 mService.updateOomAdjLocked();
             }
@@ -3752,15 +3761,15 @@
         if (mResumedActivity == r) {
             mResumedActivity = null;
         }
-        final ActivityState prevState = r.state;
+        final ActivityState prevState = r.getState();
         if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to FINISHING: " + r);
-        r.state = ActivityState.FINISHING;
+        r.setState(FINISHING, "finishCurrentActivityLocked");
         final boolean finishingActivityInNonFocusedStack
                 = r.getStack() != mStackSupervisor.getFocusedStack()
-                && prevState == ActivityState.PAUSED && mode == FINISH_AFTER_VISIBLE;
+                && prevState == PAUSED && mode == FINISH_AFTER_VISIBLE;
 
         if (mode == FINISH_IMMEDIATELY
-                || (prevState == ActivityState.PAUSED
+                || (prevState == PAUSED
                     && (mode == FINISH_AFTER_PAUSE || inPinnedWindowingMode()))
                 || finishingActivityInNonFocusedStack
                 || prevState == STOPPING
@@ -3981,7 +3990,7 @@
 
         if (setState) {
             if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYED: " + r + " (cleaning up)");
-            r.state = ActivityState.DESTROYED;
+            r.setState(DESTROYED, "cleanupActivityLocked");
             if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during cleanUp for activity " + r);
             r.app = null;
         }
@@ -4030,7 +4039,7 @@
         removeTimeoutsForActivityLocked(r);
         if (DEBUG_STATES) Slog.v(TAG_STATES,
                 "Moving to DESTROYED: " + r + " (removed from history)");
-        r.state = ActivityState.DESTROYED;
+        r.setState(DESTROYED, "removeActivityFromHistoryLocked");
         if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during remove for activity " + r);
         r.app = null;
         r.removeWindowContainer();
@@ -4114,7 +4123,8 @@
                     continue;
                 }
                 if (r.isDestroyable()) {
-                    if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Destroying " + r + " in state " + r.state
+                    if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Destroying " + r
+                            + " in state " + r.getState()
                             + " resumed=" + mResumedActivity
                             + " pausing=" + mPausingActivity + " for reason " + reason);
                     if (destroyActivityLocked(r, true, reason)) {
@@ -4131,7 +4141,7 @@
     final boolean safelyDestroyActivityLocked(ActivityRecord r, String reason) {
         if (r.isDestroyable()) {
             if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
-                    "Destroying " + r + " in state " + r.state + " resumed=" + mResumedActivity
+                    "Destroying " + r + " in state " + r.getState() + " resumed=" + mResumedActivity
                     + " pausing=" + mPausingActivity + " for reason " + reason);
             return destroyActivityLocked(r, true, reason);
         }
@@ -4159,7 +4169,7 @@
                 final ActivityRecord activity = activities.get(actNdx);
                 if (activity.app == app && activity.isDestroyable()) {
                     if (DEBUG_RELEASE) Slog.v(TAG_RELEASE, "Destroying " + activity
-                            + " in state " + activity.state + " resumed=" + mResumedActivity
+                            + " in state " + activity.getState() + " resumed=" + mResumedActivity
                             + " pausing=" + mPausingActivity + " for reason " + reason);
                     destroyActivityLocked(activity, true, reason);
                     if (activities.get(actNdx) != activity) {
@@ -4253,13 +4263,15 @@
             if (r.finishing && !skipDestroy) {
                 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYING: " + r
                         + " (destroy requested)");
-                r.state = ActivityState.DESTROYING;
+                r.setState(DESTROYING,
+                        "destroyActivityLocked. finishing and not skipping destroy");
                 Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG, r);
                 mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT);
             } else {
                 if (DEBUG_STATES) Slog.v(TAG_STATES,
                         "Moving to DESTROYED: " + r + " (destroy skipped)");
-                r.state = ActivityState.DESTROYED;
+                r.setState(DESTROYED,
+                        "destroyActivityLocked. not finishing or skipping destroy");
                 if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during destroy for activity " + r);
                 r.app = null;
             }
@@ -4270,7 +4282,7 @@
                 removedFromHistory = true;
             } else {
                 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYED: " + r + " (no app)");
-                r.state = ActivityState.DESTROYED;
+                r.setState(DESTROYED, "destroyActivityLocked. not finishing and had no app");
                 if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during destroy for activity " + r);
                 r.app = null;
             }
@@ -4288,24 +4300,29 @@
     final void activityDestroyedLocked(IBinder token, String reason) {
         final long origId = Binder.clearCallingIdentity();
         try {
-            ActivityRecord r = ActivityRecord.forTokenLocked(token);
-            if (r != null) {
-                mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
-            }
-            if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "activityDestroyedLocked: r=" + r);
-
-            if (isInStackLocked(r) != null) {
-                if (r.state == ActivityState.DESTROYING) {
-                    cleanUpActivityLocked(r, true, false);
-                    removeActivityFromHistoryLocked(r, reason);
-                }
-            }
-            mStackSupervisor.resumeFocusedStackTopActivityLocked();
+            activityDestroyedLocked(ActivityRecord.forTokenLocked(token), reason);
         } finally {
             Binder.restoreCallingIdentity(origId);
         }
     }
 
+    final void activityDestroyedLocked(ActivityRecord record, String reason) {
+        if (record != null) {
+            mHandler.removeMessages(DESTROY_TIMEOUT_MSG, record);
+        }
+
+        if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "activityDestroyedLocked: r=" + record);
+
+        if (isInStackLocked(record) != null) {
+            if (record.isState(DESTROYING, DESTROYED)) {
+                cleanUpActivityLocked(record, true, false);
+                removeActivityFromHistoryLocked(record, reason);
+            }
+        }
+
+        mStackSupervisor.resumeFocusedStackTopActivityLocked();
+    }
+
     private void removeHistoryRecordsForAppLocked(ArrayList<ActivityRecord> list,
             ProcessRecord app, String listName) {
         int i = list.size();
@@ -4374,14 +4391,14 @@
                                 + ": haveState=" + r.haveState
                                 + " stateNotNeeded=" + r.stateNotNeeded
                                 + " finishing=" + r.finishing
-                                + " state=" + r.state + " callers=" + Debug.getCallers(5));
+                                + " state=" + r.getState() + " callers=" + Debug.getCallers(5));
                         if (!r.finishing) {
                             Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
                             EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
                                     r.userId, System.identityHashCode(r),
                                     r.getTask().taskId, r.shortComponentName,
                                     "proc died without state saved");
-                            if (r.state == ActivityState.RESUMED) {
+                            if (r.getState() == RESUMED) {
                                 mService.updateUsageStats(r, false);
                             }
                         }
@@ -4417,7 +4434,7 @@
     private void updateTransitLocked(int transit, ActivityOptions options) {
         if (options != null) {
             ActivityRecord r = topRunningActivityLocked();
-            if (r != null && r.state != ActivityState.RESUMED) {
+            if (r != null && !r.isState(RESUMED)) {
                 r.updateOptionsLocked(options);
             } else {
                 ActivityOptions.abort(options);
@@ -4617,7 +4634,7 @@
                     (start.getTask() == task) ? activities.indexOf(start) : activities.size() - 1;
             for (; activityIndex >= 0; --activityIndex) {
                 final ActivityRecord r = activities.get(activityIndex);
-                updatedConfig |= r.ensureActivityConfigurationLocked(0 /* globalChanges */,
+                updatedConfig |= r.ensureActivityConfiguration(0 /* globalChanges */,
                         preserveWindow);
                 if (r.fullscreen) {
                     behindFullscreen = true;
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 9a3b102..26ffe95 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -93,6 +93,7 @@
 import static com.android.server.am.proto.ActivityStackSupervisorProto.CONFIGURATION_CONTAINER;
 import static com.android.server.am.proto.ActivityStackSupervisorProto.DISPLAYS;
 import static com.android.server.am.proto.ActivityStackSupervisorProto.FOCUSED_STACK_ID;
+import static com.android.server.am.proto.ActivityStackSupervisorProto.IS_HOME_RECENTS_COMPONENT;
 import static com.android.server.am.proto.ActivityStackSupervisorProto.KEYGUARD_CONTROLLER;
 import static com.android.server.am.proto.ActivityStackSupervisorProto.RESUMED_ACTIVITY;
 import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;
@@ -164,7 +165,6 @@
 import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
 import android.view.Display;
-import android.view.RemoteAnimationAdapter;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -1005,7 +1005,7 @@
                 final ActivityStack stack = display.getChildAt(stackNdx);
                 if (isFocusedStack(stack)) {
                     final ActivityRecord r = stack.mResumedActivity;
-                    if (r != null && r.state != RESUMED) {
+                    if (r != null && !r.isState(RESUMED)) {
                         return false;
                     }
                 }
@@ -1069,10 +1069,10 @@
             for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
                 final ActivityStack stack = display.getChildAt(stackNdx);
                 final ActivityRecord r = stack.mPausingActivity;
-                if (r != null && r.state != PAUSED && r.state != STOPPED && r.state != STOPPING) {
+                if (r != null && !r.isState(PAUSED, STOPPED, STOPPING)) {
                     if (DEBUG_STATES) {
                         Slog.d(TAG_STATES,
-                                "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
+                                "allPausedActivitiesComplete: r=" + r + " state=" + r.getState());
                         pausing = false;
                     } else {
                         return false;
@@ -1522,7 +1522,7 @@
             // current icicle and other state.
             if (DEBUG_STATES) Slog.v(TAG_STATES,
                     "Moving to PAUSED: " + r + " (starting in paused state)");
-            r.state = PAUSED;
+            r.setState(PAUSED, "realStartActivityLocked");
         }
 
         // Launch the new version setup screen if needed.  We do this -after-
@@ -2099,9 +2099,9 @@
         }
 
         final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
-        if (r == null || r.state != RESUMED) {
+        if (r == null || !r.isState(RESUMED)) {
             mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
-        } else if (r.state == RESUMED) {
+        } else if (r.isState(RESUMED)) {
             // Kick off any lingering app transitions form the MoveTaskToFront operation.
             mFocusedStack.executeAppTransition(targetOptions);
         }
@@ -2540,6 +2540,11 @@
         }
     }
 
+    void deferUpdateRecentsHomeStackBounds() {
+        deferUpdateBounds(ACTIVITY_TYPE_RECENTS);
+        deferUpdateBounds(ACTIVITY_TYPE_HOME);
+    }
+
     void deferUpdateBounds(int activityType) {
         final ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType);
         if (stack != null) {
@@ -2547,6 +2552,11 @@
         }
     }
 
+    void continueUpdateRecentsHomeStackBounds() {
+        continueUpdateBounds(ACTIVITY_TYPE_RECENTS);
+        continueUpdateBounds(ACTIVITY_TYPE_HOME);
+    }
+
     void continueUpdateBounds(int activityType) {
         final ActivityStack stack = getStack(WINDOWING_MODE_UNDEFINED, activityType);
         if (stack != null) {
@@ -2555,7 +2565,7 @@
     }
 
     void notifyAppTransitionDone() {
-        continueUpdateBounds(ACTIVITY_TYPE_RECENTS);
+        continueUpdateRecentsHomeStackBounds();
         for (int i = mResizingTasksDuringAnimation.size() - 1; i >= 0; i--) {
             final int taskId = mResizingTasksDuringAnimation.valueAt(i);
             final TaskRecord task = anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_ONLY);
@@ -3540,14 +3550,14 @@
             // First, if we find an activity that is in the process of being destroyed,
             // then we just aren't going to do anything for now; we want things to settle
             // down before we try to prune more activities.
-            if (r.finishing || r.state == DESTROYING || r.state == DESTROYED) {
+            if (r.finishing || r.isState(DESTROYING, DESTROYED)) {
                 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r);
                 return;
             }
             // Don't consider any activies that are currently not in a state where they
             // can be destroyed.
-            if (r.visible || !r.stopped || !r.haveState || r.state == RESUMED || r.state == PAUSING
-                    || r.state == PAUSED || r.state == STOPPING) {
+            if (r.visible || !r.stopped || !r.haveState
+                    || r.isState(RESUMED, PAUSING, PAUSED, STOPPING)) {
                 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r);
                 continue;
             }
@@ -3683,7 +3693,7 @@
                         ? stack.shouldSleepOrShutDownActivities()
                         : mService.isSleepingOrShuttingDownLocked();
                 if (!waitingVisible || shouldSleepOrShutDown) {
-                    if (!processPausingActivities && s.state == PAUSING) {
+                    if (!processPausingActivities && s.isState(PAUSING)) {
                         // Defer processing pausing activities in this iteration and reschedule
                         // a delayed idle to reprocess it again
                         removeTimeoutsForActivityLocked(idleActivity);
@@ -3710,7 +3720,7 @@
             for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
                 final ActivityStack stack = display.getChildAt(stackNdx);
                 final ActivityRecord r = stack.topRunningActivityLocked();
-                final ActivityState state = r == null ? DESTROYED : r.state;
+                final ActivityState state = r == null ? DESTROYED : r.getState();
                 if (isFocusedStack(stack)) {
                     if (r == null) Slog.e(TAG,
                             "validateTop...: null top activity, stack=" + stack);
@@ -3760,12 +3770,15 @@
                 pw.print(prefix); pw.print(prefix); mWaitingForActivityVisible.get(i).dump(pw, prefix);
             }
         }
+        pw.print(prefix); pw.print("isHomeRecentsComponent=");
+        pw.print(mRecentTasks.isRecentsComponentHomeActivity(mCurrentUser));
 
         mKeyguardController.dump(pw, prefix);
         mService.mLockTaskController.dump(pw, prefix);
     }
 
-    public void writeToProto(ProtoOutputStream proto) {
+    public void writeToProto(ProtoOutputStream proto, long fieldId) {
+        final long token = proto.start(fieldId);
         super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */);
         for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
             ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
@@ -3781,6 +3794,9 @@
         } else {
             proto.write(FOCUSED_STACK_ID, INVALID_STACK_ID);
         }
+        proto.write(IS_HOME_RECENTS_COMPONENT,
+                mRecentTasks.isRecentsComponentHomeActivity(mCurrentUser));
+        proto.end(token);
     }
 
     /**
@@ -4546,14 +4562,14 @@
                 // Defer updating the stack in which recents is until the app transition is done, to
                 // not run into issues where we still need to draw the task in recents but the
                 // docked stack is already created.
-                deferUpdateBounds(ACTIVITY_TYPE_RECENTS);
+                deferUpdateRecentsHomeStackBounds();
                 mWindowManager.prepareAppTransition(TRANSIT_DOCK_TASK_FROM_RECENTS, false);
             }
 
             task = anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE,
                     activityOptions, ON_TOP);
             if (task == null) {
-                continueUpdateBounds(ACTIVITY_TYPE_RECENTS);
+                continueUpdateRecentsHomeStackBounds();
                 mWindowManager.executeAppTransition();
                 throw new IllegalArgumentException(
                         "startActivityFromRecents: Task " + taskId + " not found.");
@@ -4611,6 +4627,11 @@
                     // window manager can correctly calculate the focus window that can receive
                     // input keys.
                     moveHomeStackToFront("startActivityFromRecents: homeVisibleInSplitScreen");
+
+                    // Immediately update the minimized docked stack mode, the upcoming animation
+                    // for the docked activity (WMS.overridePendingAppTransitionMultiThumbFuture)
+                    // will do the animation to the target bounds
+                    mWindowManager.checkSplitScreenMinimizedChanged(false /* animate */);
                 }
             }
             mWindowManager.continueSurfaceLayout();
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 8205265..fcdf3d2 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -1107,7 +1107,7 @@
                     case START_TASK_TO_FRONT: {
                         // ActivityRecord may represent a different activity, but it should not be
                         // in the resumed state.
-                        if (r.nowVisible && r.state == RESUMED) {
+                        if (r.nowVisible && r.isState(RESUMED)) {
                             outResult.timeout = false;
                             outResult.who = r.realActivity;
                             outResult.totalTime = 0;
@@ -1516,7 +1516,7 @@
                     final TaskRecord task = mSupervisor.anyTaskForIdLocked(
                             mOptions.getLaunchTaskId());
                     final ActivityRecord top = task != null ? task.getTopActivity() : null;
-                    if (top != null && top.state != RESUMED) {
+                    if (top != null && !top.isState(RESUMED)) {
 
                         // The caller specifies that we'd like to be avoided to be moved to the
                         // front, so be it!
diff --git a/services/core/java/com/android/server/am/CompatModePackages.java b/services/core/java/com/android/server/am/CompatModePackages.java
index d84f487..c6947ab 100644
--- a/services/core/java/com/android/server/am/CompatModePackages.java
+++ b/services/core/java/com/android/server/am/CompatModePackages.java
@@ -369,7 +369,7 @@
             }
 
             if (starting != null) {
-                starting.ensureActivityConfigurationLocked(0 /* globalChanges */,
+                starting.ensureActivityConfiguration(0 /* globalChanges */,
                         false /* preserveWindow */);
                 // And we need to make sure at this point that all other activities
                 // are made visible with the correct configuration.
diff --git a/services/core/java/com/android/server/am/EventLogTags.logtags b/services/core/java/com/android/server/am/EventLogTags.logtags
index cb2957d..9caef4a 100644
--- a/services/core/java/com/android/server/am/EventLogTags.logtags
+++ b/services/core/java/com/android/server/am/EventLogTags.logtags
@@ -125,3 +125,12 @@
 30055 am_uid_idle (UID|1|5)
 # Note when a service is being forcibly stopped because its app went idle.
 30056 am_stop_idle_service (UID|1|5),(Component Name|3)
+
+# The activity's onCreate has been called.
+30057 am_on_create_called (User|1|5),(Component Name|3),(Reason|3)
+# The activity's onRestart has been called.
+30058 am_on_restart_called (User|1|5),(Component Name|3),(Reason|3)
+# The activity's onStart has been called.
+30059 am_on_start_called (User|1|5),(Component Name|3),(Reason|3)
+# The activity's onDestroy has been called.
+30060 am_on_destroy_called (User|1|5),(Component Name|3),(Reason|3)
\ No newline at end of file
diff --git a/services/core/java/com/android/server/am/GlobalSettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/GlobalSettingsToPropertiesMapper.java
index 71fd71b8..d7d18a9 100644
--- a/services/core/java/com/android/server/am/GlobalSettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/GlobalSettingsToPropertiesMapper.java
@@ -42,6 +42,7 @@
         {Settings.Global.SYS_VDSO, "sys.vdso"},
         {Settings.Global.FPS_DEVISOR, ThreadedRenderer.DEBUG_FPS_DIVISOR},
         {Settings.Global.DISPLAY_PANEL_LPM, "sys.display_panel_lpm"},
+        {Settings.Global.SYS_UIDCPUPOWER, "sys.uidcpupower"},
     };
 
 
diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java
index e361a70..6b8b380 100644
--- a/services/core/java/com/android/server/am/KeyguardController.java
+++ b/services/core/java/com/android/server/am/KeyguardController.java
@@ -117,14 +117,11 @@
         mSecondaryDisplayShowing = secondaryDisplayShowing;
         if (showingChanged) {
             dismissDockedStackIfNeeded();
+            setKeyguardGoingAway(false);
             if (showing) {
-                setKeyguardGoingAway(false);
                 mDismissalRequested = false;
             }
         }
-        if (!showing) {
-            mStackSupervisor.resumeFocusedStackTopActivityLocked();
-        }
         mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
         updateKeyguardSleepToken();
     }
@@ -149,6 +146,7 @@
             updateKeyguardSleepToken();
 
             // Some stack visibility might change (e.g. docked stack)
+            mStackSupervisor.resumeFocusedStackTopActivityLocked();
             mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
             mStackSupervisor.addStartingWindowsForVisibleActivities(true /* taskSwitch */);
             mWindowManager.executeAppTransition();
@@ -395,8 +393,4 @@
         proto.write(KEYGUARD_OCCLUDED, mOccluded);
         proto.end(token);
     }
-
-    public void notifyAppTransitionDone() {
-        setKeyguardGoingAway(false);
-    }
 }
diff --git a/services/core/java/com/android/server/am/LockTaskController.java b/services/core/java/com/android/server/am/LockTaskController.java
index e5762d2..af99111 100644
--- a/services/core/java/com/android/server/am/LockTaskController.java
+++ b/services/core/java/com/android/server/am/LockTaskController.java
@@ -38,7 +38,6 @@
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED;
 
-import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.Activity;
@@ -114,7 +113,7 @@
         STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_HOME,
                 new Pair<>(StatusBarManager.DISABLE_HOME, StatusBarManager.DISABLE2_NONE));
 
-        STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_RECENTS,
+        STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW,
                 new Pair<>(StatusBarManager.DISABLE_RECENT, StatusBarManager.DISABLE2_NONE));
 
         STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS,
@@ -308,7 +307,7 @@
 
     private boolean isRecentsAllowed(int userId) {
         return (getLockTaskFeaturesForUser(userId)
-                & DevicePolicyManager.LOCK_TASK_FEATURE_RECENTS) != 0;
+                & DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW) != 0;
     }
 
     private boolean isKeyguardAllowed(int userId) {
diff --git a/services/core/java/com/android/server/am/RecentTasks.java b/services/core/java/com/android/server/am/RecentTasks.java
index 2de84ab..5fd300c 100644
--- a/services/core/java/com/android/server/am/RecentTasks.java
+++ b/services/core/java/com/android/server/am/RecentTasks.java
@@ -279,6 +279,16 @@
     }
 
     /**
+     * @return whether the home app is also the active handler of recent tasks.
+     */
+    boolean isRecentsComponentHomeActivity(int userId) {
+        final ComponentName defaultHomeActivity = mService.getPackageManagerInternalLocked()
+                .getDefaultHomeActivity(userId);
+        return defaultHomeActivity != null &&
+                defaultHomeActivity.getPackageName().equals(mRecentsComponent.getPackageName());
+    }
+
+    /**
      * @return the recents component.
      */
     ComponentName getRecentsComponent() {
diff --git a/services/core/java/com/android/server/am/RecentsAnimation.java b/services/core/java/com/android/server/am/RecentsAnimation.java
index 6dcf041..4b1594c 100644
--- a/services/core/java/com/android/server/am/RecentsAnimation.java
+++ b/services/core/java/com/android/server/am/RecentsAnimation.java
@@ -134,6 +134,7 @@
 
             // Fetch all the surface controls and pass them to the client to get the animation
             // started
+            mWindowManager.cancelRecentsAnimation();
             mWindowManager.initializeRecentsAnimation(recentsAnimationRunner, this,
                     display.mDisplayId);
 
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index d679439..6f6e0d9 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -537,7 +537,7 @@
             if (updatedConfig) {
                 final ActivityRecord r = topRunningActivityLocked();
                 if (r != null && !deferResume) {
-                    kept = r.ensureActivityConfigurationLocked(0 /* globalChanges */,
+                    kept = r.ensureActivityConfiguration(0 /* globalChanges */,
                             preserveWindow);
                     mService.mStackSupervisor.ensureActivitiesVisibleLocked(r, 0,
                             !PRESERVE_WINDOWS);
@@ -1103,7 +1103,7 @@
             // Increment the total number of non-finishing activities
             reportOut.numActivities++;
 
-            if (reportOut.top == null || (reportOut.top.state == ActivityState.INITIALIZING)) {
+            if (reportOut.top == null || (reportOut.top.isState(ActivityState.INITIALIZING))) {
                 reportOut.top = r;
                 // Reset the number of running activities until we hit the first non-initializing
                 // activity
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 6134d05..af1ab83 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -1735,6 +1735,20 @@
         return mInjector.getUserManager().getUserIds();
     }
 
+    /**
+     * If {@code userId} is {@link UserHandle#USER_ALL}, then return an array with all running user
+     * IDs. Otherwise return an array whose only element is the given user id.
+     *
+     * It doesn't handle other special user IDs such as {@link UserHandle#USER_CURRENT}.
+     */
+    int[] expandUserId(int userId) {
+        if (userId != UserHandle.USER_ALL) {
+            return new int[] {userId};
+        } else {
+            return getUsers();
+        }
+    }
+
     boolean exists(int userId) {
         return mInjector.getUserManager().exists(userId);
     }
diff --git a/services/core/java/com/android/server/am/VrController.java b/services/core/java/com/android/server/am/VrController.java
index d32db7e..9d34a80 100644
--- a/services/core/java/com/android/server/am/VrController.java
+++ b/services/core/java/com/android/server/am/VrController.java
@@ -24,7 +24,7 @@
 import android.util.proto.ProtoUtils;
 
 import com.android.server.LocalServices;
-import com.android.server.am.proto.ProcessesProto.VrControllerProto;
+import com.android.server.am.proto.ActivityManagerServiceDumpProcessesProto.VrControllerProto;
 import com.android.server.vr.VrManagerInternal;
 
 /**
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 0ce4dc5..8eb8058 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1538,17 +1538,6 @@
         if (adjustVolume && (direction != AudioManager.ADJUST_SAME)) {
             mAudioHandler.removeMessages(MSG_UNMUTE_STREAM);
 
-            // Check if volume update should be send to AVRCP
-            if (streamTypeAlias == AudioSystem.STREAM_MUSIC &&
-                (device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 &&
-                (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
-                synchronized (mA2dpAvrcpLock) {
-                    if (mA2dp != null && mAvrcpAbsVolSupported) {
-                        mA2dp.adjustAvrcpAbsoluteVolume(direction);
-                    }
-                }
-            }
-
             if (isMuteAdjust) {
                 boolean state;
                 if (direction == AudioManager.ADJUST_TOGGLE_MUTE) {
@@ -1597,8 +1586,20 @@
                         0);
             }
 
-            // Check if volume update should be sent to Hdmi system audio.
             int newIndex = mStreamStates[streamType].getIndex(device);
+
+            // Check if volume update should be send to AVRCP
+            if (streamTypeAlias == AudioSystem.STREAM_MUSIC &&
+                (device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 &&
+                (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
+                synchronized (mA2dpAvrcpLock) {
+                    if (mA2dp != null && mAvrcpAbsVolSupported) {
+                        mA2dp.setAvrcpAbsoluteVolume(newIndex / 10);
+                    }
+                }
+            }
+
+            // Check if volume update should be sent to Hdmi system audio.
             if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
                 setSystemAudioVolume(oldIndex, newIndex, getStreamMaxVolume(streamType), flags);
             }
@@ -4221,6 +4222,11 @@
         }
     }
 
+    @Override
+    public void setHearingAidDeviceConnectionState(BluetoothDevice device, int state)
+    {
+    }
+
     public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state, int profile)
     {
         return setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
@@ -7033,26 +7039,75 @@
         // TODO implement clearing mix attribute matching info in native audio policy
     }
 
-    public int setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb) {
-        if (DEBUG_AP) Log.d(TAG, "setFocusPropertiesForPolicy() duck behavior=" + duckingBehavior
-                + " policy " +  pcb.asBinder());
-        // error handling
-        boolean hasPermissionForPolicy =
+    /**
+     * Checks whether caller has MODIFY_AUDIO_ROUTING permission, and the policy is registered.
+     * @param errorMsg log warning if permission check failed.
+     * @return null if the operation on the audio mixes should be cancelled.
+     */
+    @GuardedBy("mAudioPolicies")
+    private AudioPolicyProxy checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg) {
+        // permission check
+        final boolean hasPermissionForPolicy =
                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
         if (!hasPermissionForPolicy) {
-            Slog.w(TAG, "Cannot change audio policy ducking handling for pid " +
+            Slog.w(TAG, errorMsg + " for pid " +
                     + Binder.getCallingPid() + " / uid "
                     + Binder.getCallingUid() + ", need MODIFY_AUDIO_ROUTING");
-            return AudioManager.ERROR;
+            return null;
         }
+        // policy registered?
+        final AudioPolicyProxy app = mAudioPolicies.get(pcb.asBinder());
+        if (app == null) {
+            Slog.w(TAG, errorMsg + " for pid " +
+                    + Binder.getCallingPid() + " / uid "
+                    + Binder.getCallingUid() + ", unregistered policy");
+            return null;
+        }
+        return app;
+    }
 
+    public int addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) {
+        if (DEBUG_AP) { Log.d(TAG, "addMixForPolicy for " + pcb.asBinder()
+                + " with config:" + policyConfig); }
         synchronized (mAudioPolicies) {
+            final AudioPolicyProxy app =
+                    checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy");
+            if (app == null){
+                return AudioManager.ERROR;
+            }
+            app.addMixes(policyConfig.getMixes());
+        }
+        return AudioManager.SUCCESS;
+    }
+
+    public int removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) {
+        if (DEBUG_AP) { Log.d(TAG, "removeMixForPolicy for " + pcb.asBinder()
+                + " with config:" + policyConfig); }
+        synchronized (mAudioPolicies) {
+            final AudioPolicyProxy app =
+                    checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy");
+            if (app == null) {
+                return AudioManager.ERROR;
+            }
+            app.removeMixes(policyConfig.getMixes());
+        }
+        return AudioManager.SUCCESS;
+    }
+
+    public int setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb) {
+        if (DEBUG_AP) Log.d(TAG, "setFocusPropertiesForPolicy() duck behavior=" + duckingBehavior
+                + " policy " +  pcb.asBinder());
+        synchronized (mAudioPolicies) {
+            final AudioPolicyProxy app =
+                    checkUpdateForPolicy(pcb, "Cannot change audio policy focus properties");
+            if (app == null){
+                return AudioManager.ERROR;
+            }
             if (!mAudioPolicies.containsKey(pcb.asBinder())) {
                 Slog.e(TAG, "Cannot change audio policy focus properties, unregistered policy");
                 return AudioManager.ERROR;
             }
-            final AudioPolicyProxy app = mAudioPolicies.get(pcb.asBinder());
             if (duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) {
                 // is there already one policy managing ducking?
                 for (AudioPolicyProxy policy : mAudioPolicies.values()) {
@@ -7284,6 +7339,24 @@
             Binder.restoreCallingIdentity(identity);
         }
 
+        void addMixes(@NonNull ArrayList<AudioMix> mixes) {
+            // TODO optimize to not have to unregister the mixes already in place
+            synchronized (mMixes) {
+                AudioSystem.registerPolicyMixes(mMixes, false);
+                this.add(mixes);
+                AudioSystem.registerPolicyMixes(mMixes, true);
+            }
+        }
+
+        void removeMixes(@NonNull ArrayList<AudioMix> mixes) {
+            // TODO optimize to not have to unregister the mixes already in place
+            synchronized (mMixes) {
+                AudioSystem.registerPolicyMixes(mMixes, false);
+                this.remove(mixes);
+                AudioSystem.registerPolicyMixes(mMixes, true);
+            }
+        }
+
         void connectMixes() {
             final long identity = Binder.clearCallingIdentity();
             AudioSystem.registerPolicyMixes(mMixes, true);
@@ -7401,7 +7474,8 @@
     //======================
     // misc
     //======================
-    private HashMap<IBinder, AudioPolicyProxy> mAudioPolicies =
+    private final HashMap<IBinder, AudioPolicyProxy> mAudioPolicies =
             new HashMap<IBinder, AudioPolicyProxy>();
-    private int mAudioPolicyCounter = 0; // always accessed synchronized on mAudioPolicies
+    @GuardedBy("mAudioPolicies")
+    private int mAudioPolicyCounter = 0;
 }
diff --git a/services/core/java/com/android/server/backup/BackupUtils.java b/services/core/java/com/android/server/backup/BackupUtils.java
index e5d564d..f44afe4 100644
--- a/services/core/java/com/android/server/backup/BackupUtils.java
+++ b/services/core/java/com/android/server/backup/BackupUtils.java
@@ -18,9 +18,12 @@
 
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.Signature;
 import android.util.Slog;
 
+import com.android.internal.util.ArrayUtils;
+
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
@@ -30,9 +33,10 @@
 public class BackupUtils {
     private static final String TAG = "BackupUtils";
 
-    private static final boolean DEBUG = false; // STOPSHIP if true
+    private static final boolean DEBUG = false;
 
-    public static boolean signaturesMatch(ArrayList<byte[]> storedSigHashes, PackageInfo target) {
+    public static boolean signaturesMatch(ArrayList<byte[]> storedSigHashes, PackageInfo target,
+            PackageManagerInternal pmi) {
         if (target == null) {
             return false;
         }
@@ -47,48 +51,54 @@
             return true;
         }
 
-        // Allow unsigned apps, but not signed on one device and unsigned on the other
-        // !!! TODO: is this the right policy?
-        Signature[] deviceSigs = target.signatures;
-        if (DEBUG) Slog.v(TAG, "signaturesMatch(): stored=" + storedSigHashes
-                + " device=" + deviceSigs);
-        if ((storedSigHashes == null || storedSigHashes.size() == 0)
-                && (deviceSigs == null || deviceSigs.length == 0)) {
-            return true;
-        }
-        if (storedSigHashes == null || deviceSigs == null) {
+        // Don't allow unsigned apps on either end
+        if (ArrayUtils.isEmpty(storedSigHashes)) {
             return false;
         }
 
-        // !!! TODO: this demands that every stored signature match one
-        // that is present on device, and does not demand the converse.
-        // Is this this right policy?
-        final int nStored = storedSigHashes.size();
-        final int nDevice = deviceSigs.length;
-
-        // hash each on-device signature
-        ArrayList<byte[]> deviceHashes = new ArrayList<byte[]>(nDevice);
-        for (int i = 0; i < nDevice; i++) {
-            deviceHashes.add(hashSignature(deviceSigs[i]));
+        Signature[][] deviceHistorySigs = target.signingCertificateHistory;
+        if (ArrayUtils.isEmpty(deviceHistorySigs)) {
+            Slog.w(TAG, "signingCertificateHistory is empty, app was either unsigned or the flag" +
+                    " PackageManager#GET_SIGNING_CERTIFICATES was not specified");
+            return false;
         }
 
-        // now ensure that each stored sig (hash) matches an on-device sig (hash)
-        for (int n = 0; n < nStored; n++) {
-            boolean match = false;
-            final byte[] storedHash = storedSigHashes.get(n);
-            for (int i = 0; i < nDevice; i++) {
-                if (Arrays.equals(storedHash, deviceHashes.get(i))) {
-                    match = true;
-                    break;
+        if (DEBUG) {
+            Slog.v(TAG, "signaturesMatch(): stored=" + storedSigHashes
+                    + " device=" + deviceHistorySigs);
+        }
+
+        final int nStored = storedSigHashes.size();
+        if (nStored == 1) {
+            // if the app is only signed with one sig, it's possible it has rotated its key
+            // the checks with signing history are delegated to PackageManager
+            // TODO: address the case that app has declared restoreAnyVersion and is restoring
+            // from higher version to lower after having rotated the key (i.e. higher version has
+            // different sig than lower version that we want to restore to)
+            return pmi.isDataRestoreSafe(storedSigHashes.get(0), target.packageName);
+        } else {
+            // the app couldn't have rotated keys, since it was signed with multiple sigs - do
+            // a comprehensive 1-to-1 signatures check
+            // since app hasn't rotated key, we only need to check with deviceHistorySigs[0]
+            ArrayList<byte[]> deviceHashes = hashSignatureArray(deviceHistorySigs[0]);
+            int nDevice = deviceHashes.size();
+
+            // ensure that each stored sig matches an on-device sig
+            for (int i = 0; i < nStored; i++) {
+                boolean match = false;
+                for (int j = 0; j < nDevice; j++) {
+                    if (Arrays.equals(storedSigHashes.get(i), deviceHashes.get(j))) {
+                        match = true;
+                        break;
+                    }
+                }
+                if (!match) {
+                    return false;
                 }
             }
-            // match is false when no on-device sig matched one of the stored ones
-            if (!match) {
-                return false;
-            }
+            // we have found a match for all stored sigs
+            return true;
         }
-
-        return true;
     }
 
     public static byte[] hashSignature(byte[] signature) {
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index 3133a51..ca8823f 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -103,13 +103,15 @@
     private static class CameraUsageEvent {
         public final int mCameraFacing;
         public final String mClientName;
+        public final int mAPILevel;
 
         private boolean mCompleted;
         private long mDurationOrStartTimeMs;  // Either start time, or duration once completed
 
-        public CameraUsageEvent(int facing, String clientName) {
+        public CameraUsageEvent(int facing, String clientName, int apiLevel) {
             mCameraFacing = facing;
             mClientName = clientName;
+            mAPILevel = apiLevel;
             mDurationOrStartTimeMs = SystemClock.elapsedRealtime();
             mCompleted = false;
         }
@@ -168,13 +170,13 @@
 
         @Override
         public void notifyCameraState(String cameraId, int newCameraState, int facing,
-                String clientName) {
+                String clientName, int apiLevel) {
             String state = cameraStateToString(newCameraState);
             String facingStr = cameraFacingToString(facing);
             if (DEBUG) Slog.v(TAG, "Camera " + cameraId + " facing " + facingStr + " state now " +
-                    state + " for client " + clientName);
+                    state + " for client " + clientName + " API Level " + apiLevel);
 
-            updateActivityCount(cameraId, newCameraState, facing, clientName);
+            updateActivityCount(cameraId, newCameraState, facing, clientName, apiLevel);
         }
     };
 
@@ -293,6 +295,7 @@
                         .setType(MetricsEvent.TYPE_ACTION)
                         .setSubtype(subtype)
                         .setLatency(e.getDuration())
+                        .addTaggedData(MetricsEvent.FIELD_CAMERA_API_LEVEL, e.mAPILevel)
                         .setPackageName(e.mClientName);
                 mLogger.write(l);
             }
@@ -368,7 +371,8 @@
         return true;
     }
 
-    private void updateActivityCount(String cameraId, int newCameraState, int facing, String clientName) {
+    private void updateActivityCount(String cameraId, int newCameraState, int facing,
+            String clientName, int apiLevel) {
         synchronized(mLock) {
             // Update active camera list and notify NFC if necessary
             boolean wasEmpty = mActiveCameraUsage.isEmpty();
@@ -376,7 +380,7 @@
                 case ICameraServiceProxy.CAMERA_STATE_OPEN:
                     break;
                 case ICameraServiceProxy.CAMERA_STATE_ACTIVE:
-                    CameraUsageEvent newEvent = new CameraUsageEvent(facing, clientName);
+                    CameraUsageEvent newEvent = new CameraUsageEvent(facing, clientName, apiLevel);
                     CameraUsageEvent oldEvent = mActiveCameraUsage.put(cameraId, newEvent);
                     if (oldEvent != null) {
                         Slog.w(TAG, "Camera " + cameraId + " was already marked as active");
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index 0c9d70a..776e93d 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -16,6 +16,7 @@
 
 package com.android.server.clipboard;
 
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
@@ -24,9 +25,9 @@
 import android.content.ClipData;
 import android.content.ClipDescription;
 import android.content.ContentProvider;
+import android.content.Context;
 import android.content.IClipboard;
 import android.content.IOnPrimaryClipChangedListener;
-import android.content.Context;
 import android.content.Intent;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
@@ -37,7 +38,6 @@
 import android.os.IBinder;
 import android.os.IUserManager;
 import android.os.Parcel;
-import android.os.Process;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -49,14 +49,10 @@
 
 import com.android.server.SystemService;
 
-import java.util.HashSet;
-import java.util.List;
-
-import java.lang.Thread;
-import java.lang.Runnable;
-import java.lang.InterruptedException;
 import java.io.IOException;
 import java.io.RandomAccessFile;
+import java.util.HashSet;
+import java.util.List;
 
 // The following class is Android Emulator specific. It is used to read and
 // write contents of the host system's clipboard.
@@ -182,7 +178,8 @@
                                          new String[]{"text/plain"},
                                          new ClipData.Item(contents));
                         synchronized(mClipboards) {
-                            setPrimaryClipInternal(getClipboard(0), clip);
+                            setPrimaryClipInternal(getClipboard(0), clip,
+                                    android.os.Process.SYSTEM_UID);
                         }
                     }
                 });
@@ -218,7 +215,10 @@
         final RemoteCallbackList<IOnPrimaryClipChangedListener> primaryClipListeners
                 = new RemoteCallbackList<IOnPrimaryClipChangedListener>();
 
+        /** Current primary clip. */
         ClipData primaryClip;
+        /** UID that set {@link #primaryClip}. */
+        int primaryClipUid = android.os.Process.NOBODY_UID;
 
         final HashSet<String> activePermissionOwners
                 = new HashSet<String>();
@@ -246,58 +246,28 @@
         @Override
         public void setPrimaryClip(ClipData clip, String callingPackage) {
             synchronized (this) {
-                if (clip != null && clip.getItemCount() <= 0) {
+                if (clip == null || clip.getItemCount() <= 0) {
                     throw new IllegalArgumentException("No items");
                 }
-                if (clip.getItemAt(0).getText() != null &&
-                    mHostClipboardMonitor != null) {
-                    mHostClipboardMonitor.setHostClipboard(
-                        clip.getItemAt(0).getText().toString());
-                }
                 final int callingUid = Binder.getCallingUid();
                 if (!clipboardAccessAllowed(AppOpsManager.OP_WRITE_CLIPBOARD, callingPackage,
                             callingUid)) {
                     return;
                 }
                 checkDataOwnerLocked(clip, callingUid);
-                final int userId = UserHandle.getUserId(callingUid);
-                PerUserClipboard clipboard = getClipboard(userId);
-                revokeUris(clipboard);
-                setPrimaryClipInternal(clipboard, clip);
-                List<UserInfo> related = getRelatedProfiles(userId);
-                if (related != null) {
-                    int size = related.size();
-                    if (size > 1) { // Related profiles list include the current profile.
-                        boolean canCopy = false;
-                        try {
-                            canCopy = !mUm.getUserRestrictions(userId).getBoolean(
-                                    UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE);
-                        } catch (RemoteException e) {
-                            Slog.e(TAG, "Remote Exception calling UserManager: " + e);
-                        }
-                        // Copy clip data to related users if allowed. If disallowed, then remove
-                        // primary clip in related users to prevent pasting stale content.
-                        if (!canCopy) {
-                            clip = null;
-                        } else {
-                            // We want to fix the uris of the related user's clip without changing the
-                            // uris of the current user's clip.
-                            // So, copy the ClipData, and then copy all the items, so that nothing
-                            // is shared in memmory.
-                            clip = new ClipData(clip);
-                            for (int i = clip.getItemCount() - 1; i >= 0; i--) {
-                                clip.setItemAt(i, new ClipData.Item(clip.getItemAt(i)));
-                            }
-                            clip.fixUrisLight(userId);
-                        }
-                        for (int i = 0; i < size; i++) {
-                            int id = related.get(i).id;
-                            if (id != userId) {
-                                setPrimaryClipInternal(getClipboard(id), clip);
-                            }
-                        }
-                    }
+                setPrimaryClipInternal(clip, callingUid);
+            }
+        }
+
+        @Override
+        public void clearPrimaryClip(String callingPackage) {
+            synchronized (this) {
+                final int callingUid = Binder.getCallingUid();
+                if (!clipboardAccessAllowed(AppOpsManager.OP_WRITE_CLIPBOARD, callingPackage,
+                        callingUid)) {
+                    return;
                 }
+                setPrimaryClipInternal(null, callingUid);
             }
         }
 
@@ -398,13 +368,75 @@
         return related;
     }
 
-    void setPrimaryClipInternal(PerUserClipboard clipboard, ClipData clip) {
+    void setPrimaryClipInternal(@Nullable ClipData clip, int callingUid) {
+        // Push clipboard to host, if any
+        if (mHostClipboardMonitor != null) {
+            if (clip == null) {
+                // Someone really wants the clipboard cleared, so push empty
+                mHostClipboardMonitor.setHostClipboard("");
+            } else if (clip.getItemCount() > 0) {
+                final CharSequence text = clip.getItemAt(0).getText();
+                if (text != null) {
+                    mHostClipboardMonitor.setHostClipboard(text.toString());
+                }
+            }
+        }
+
+        // Update this user
+        final int userId = UserHandle.getUserId(callingUid);
+        setPrimaryClipInternal(getClipboard(userId), clip, callingUid);
+
+        // Update related users
+        List<UserInfo> related = getRelatedProfiles(userId);
+        if (related != null) {
+            int size = related.size();
+            if (size > 1) { // Related profiles list include the current profile.
+                boolean canCopy = false;
+                try {
+                    canCopy = !mUm.getUserRestrictions(userId).getBoolean(
+                            UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Remote Exception calling UserManager: " + e);
+                }
+                // Copy clip data to related users if allowed. If disallowed, then remove
+                // primary clip in related users to prevent pasting stale content.
+                if (!canCopy) {
+                    clip = null;
+                } else {
+                    // We want to fix the uris of the related user's clip without changing the
+                    // uris of the current user's clip.
+                    // So, copy the ClipData, and then copy all the items, so that nothing
+                    // is shared in memmory.
+                    clip = new ClipData(clip);
+                    for (int i = clip.getItemCount() - 1; i >= 0; i--) {
+                        clip.setItemAt(i, new ClipData.Item(clip.getItemAt(i)));
+                    }
+                    clip.fixUrisLight(userId);
+                }
+                for (int i = 0; i < size; i++) {
+                    int id = related.get(i).id;
+                    if (id != userId) {
+                        setPrimaryClipInternal(getClipboard(id), clip, callingUid);
+                    }
+                }
+            }
+        }
+    }
+
+    void setPrimaryClipInternal(PerUserClipboard clipboard, @Nullable ClipData clip,
+            int callingUid) {
+        revokeUris(clipboard);
         clipboard.activePermissionOwners.clear();
         if (clip == null && clipboard.primaryClip == null) {
             return;
         }
         clipboard.primaryClip = clip;
         if (clip != null) {
+            clipboard.primaryClipUid = callingUid;
+        } else {
+            clipboard.primaryClipUid = android.os.Process.NOBODY_UID;
+        }
+        if (clip != null) {
             final ClipDescription description = clip.getDescription();
             if (description != null) {
                 description.setTimestamp(System.currentTimeMillis());
@@ -479,12 +511,12 @@
         }
     }
 
-    private final void grantUriLocked(Uri uri, String pkg, int userId) {
+    private final void grantUriLocked(Uri uri, int primaryClipUid, String pkg, int userId) {
         long ident = Binder.clearCallingIdentity();
         try {
             int sourceUserId = ContentProvider.getUserIdFromUri(uri, userId);
             uri = ContentProvider.getUriWithoutUserId(uri);
-            mAm.grantUriPermissionFromOwner(mPermissionOwner, Process.myUid(), pkg,
+            mAm.grantUriPermissionFromOwner(mPermissionOwner, primaryClipUid, pkg,
                     uri, Intent.FLAG_GRANT_READ_URI_PERMISSION, sourceUserId, userId);
         } catch (RemoteException e) {
         } finally {
@@ -492,13 +524,14 @@
         }
     }
 
-    private final void grantItemLocked(ClipData.Item item, String pkg, int userId) {
+    private final void grantItemLocked(ClipData.Item item, int primaryClipUid, String pkg,
+            int userId) {
         if (item.getUri() != null) {
-            grantUriLocked(item.getUri(), pkg, userId);
+            grantUriLocked(item.getUri(), primaryClipUid, pkg, userId);
         }
         Intent intent = item.getIntent();
         if (intent != null && intent.getData() != null) {
-            grantUriLocked(intent.getData(), pkg, userId);
+            grantUriLocked(intent.getData(), primaryClipUid, pkg, userId);
         }
     }
 
@@ -524,7 +557,8 @@
         if (clipboard.primaryClip != null && !clipboard.activePermissionOwners.contains(pkg)) {
             final int N = clipboard.primaryClip.getItemCount();
             for (int i=0; i<N; i++) {
-                grantItemLocked(clipboard.primaryClip.getItemAt(i), pkg, UserHandle.getUserId(uid));
+                grantItemLocked(clipboard.primaryClip.getItemAt(i), clipboard.primaryClipUid, pkg,
+                        UserHandle.getUserId(uid));
             }
             clipboard.activePermissionOwners.add(pkg);
         }
diff --git a/services/core/java/com/android/server/MultipathPolicyTracker.java b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
similarity index 85%
rename from services/core/java/com/android/server/MultipathPolicyTracker.java
rename to services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
index 9e0a230..296b9ac 100644
--- a/services/core/java/com/android/server/MultipathPolicyTracker.java
+++ b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
@@ -16,11 +16,17 @@
 
 package com.android.server.connectivity;
 
+import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_HANDOVER;
+import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_RELIABILITY;
+import static android.net.ConnectivityManager.TYPE_MOBILE;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+
+import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH;
+
 import android.app.usage.NetworkStatsManager;
 import android.app.usage.NetworkStatsManager.UsageCallback;
 import android.content.Context;
-import android.net.INetworkStatsService;
-import android.net.INetworkPolicyManager;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
 import android.net.Network;
@@ -31,29 +37,17 @@
 import android.net.NetworkTemplate;
 import android.net.StringNetworkSpecifier;
 import android.os.Handler;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.telephony.TelephonyManager;
 import android.util.DebugUtils;
 import android.util.Slog;
 
-import java.util.Calendar;
-import java.util.concurrent.ConcurrentHashMap;
-
-import com.android.internal.R;
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.LocalServices;
 import com.android.server.net.NetworkPolicyManagerInternal;
+import com.android.server.net.NetworkStatsManagerInternal;
 
-import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_HANDOVER;
-import static android.net.ConnectivityManager.MULTIPATH_PREFERENCE_RELIABILITY;
-import static android.net.ConnectivityManager.TYPE_MOBILE;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
-import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import static android.provider.Settings.Global.NETWORK_AVOID_BAD_WIFI;
-import static android.provider.Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE;
-import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH;
+import java.util.Calendar;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * Manages multipath data budgets.
@@ -76,10 +70,8 @@
     private final Handler mHandler;
 
     private ConnectivityManager mCM;
-    private NetworkStatsManager mStatsManager;
     private NetworkPolicyManager mNPM;
-    private TelephonyManager mTelephonyManager;
-    private INetworkStatsService mStatsService;
+    private NetworkStatsManager mStatsManager;
 
     private NetworkCallback mMobileNetworkCallback;
     private NetworkPolicyManager.Listener mPolicyListener;
@@ -87,8 +79,6 @@
     // STOPSHIP: replace this with a configurable mechanism.
     private static final long DEFAULT_DAILY_MULTIPATH_QUOTA = 2_500_000;
 
-    private volatile int mMeteredMultipathPreference;
-
     public MultipathPolicyTracker(Context ctx, Handler handler) {
         mContext = ctx;
         mHandler = handler;
@@ -97,12 +87,9 @@
     }
 
     public void start() {
-        mCM = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
-        mNPM = (NetworkPolicyManager) mContext.getSystemService(Context.NETWORK_POLICY_SERVICE);
-        mStatsManager = (NetworkStatsManager) mContext.getSystemService(
-                Context.NETWORK_STATS_SERVICE);
-        mStatsService = INetworkStatsService.Stub.asInterface(
-                ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
+        mCM = mContext.getSystemService(ConnectivityManager.class);
+        mNPM = mContext.getSystemService(NetworkPolicyManager.class);
+        mStatsManager = mContext.getSystemService(NetworkStatsManager.class);
 
         registerTrackMobileCallback();
         registerNetworkPolicyListener();
@@ -119,6 +106,9 @@
 
     // Called on an arbitrary binder thread.
     public Integer getMultipathPreference(Network network) {
+        if (network == null) {
+            return null;
+        }
         MultipathTracker t = mMultipathTrackers.get(network);
         if (t != null) {
             return t.getMultipathPreference();
@@ -149,8 +139,7 @@
                         network, nc, e.getMessage()));
             }
 
-            TelephonyManager tele = (TelephonyManager) mContext.getSystemService(
-                    Context.TELEPHONY_SERVICE);
+            TelephonyManager tele = mContext.getSystemService(TelephonyManager.class);
             if (tele == null) {
                 throw new IllegalStateException(String.format("Missing TelephonyManager"));
             }
@@ -162,7 +151,7 @@
 
             subscriberId = tele.getSubscriberId();
             mNetworkTemplate = new NetworkTemplate(
-                    NetworkTemplate.MATCH_MOBILE_ALL, subscriberId, new String[] { subscriberId },
+                    NetworkTemplate.MATCH_MOBILE, subscriberId, new String[] { subscriberId },
                     null, NetworkStats.METERED_ALL, NetworkStats.ROAMING_ALL,
                     NetworkStats.DEFAULT_NETWORK_NO);
             mUsageCallback = new UsageCallback() {
@@ -185,26 +174,21 @@
             start.set(Calendar.SECOND, 0);
             start.set(Calendar.MILLISECOND, 0);
 
-            long bytes;
             try {
-                // TODO: Consider using NetworkStatsManager.getSummaryForDevice instead.
-                bytes = mStatsService.getNetworkTotalBytes(mNetworkTemplate,
-                        start.getTimeInMillis(), end.getTimeInMillis());
-                if (DBG) Slog.w(TAG, "Non-default data usage: " + bytes);
-            } catch (RemoteException e) {
-                Slog.w(TAG, "Can't fetch daily data usage: " + e);
-                bytes = -1;
-            } catch (IllegalStateException e) {
-                // Bandwidth control disabled?
-                bytes = -1;
+                final long bytes = LocalServices.getService(NetworkStatsManagerInternal.class)
+                        .getNetworkTotalBytes(mNetworkTemplate, start.getTimeInMillis(),
+                                end.getTimeInMillis());
+                if (DBG) Slog.d(TAG, "Non-default data usage: " + bytes);
+                return bytes;
+            } catch (RuntimeException e) {
+                Slog.w(TAG, "Failed to get data usage: " + e);
+                return -1;
             }
-            return bytes;
         }
 
         void updateMultipathBudget() {
-            NetworkPolicyManagerInternal npms = LocalServices.getService(
-                    NetworkPolicyManagerInternal.class);
-            long quota = npms.getSubscriptionOpportunisticQuota(this.network, QUOTA_TYPE_MULTIPATH);
+            long quota = LocalServices.getService(NetworkPolicyManagerInternal.class)
+                    .getSubscriptionOpportunisticQuota(this.network, QUOTA_TYPE_MULTIPATH);
             if (DBG) Slog.d(TAG, "Opportunistic quota from data plan: " + quota + " bytes");
 
             if (quota == 0) {
@@ -223,8 +207,10 @@
             }
             mQuota = quota;
 
-            long usage = getDailyNonDefaultDataUsage();
-            long budget = Math.max(0, quota - usage);
+            // If we can't get current usage, assume the worst and don't give
+            // ourselves any budget to work with.
+            final long usage = getDailyNonDefaultDataUsage();
+            final long budget = (usage == -1) ? 0 : Math.max(0, quota - usage);
             if (budget > 0) {
                 if (DBG) Slog.d(TAG, "Setting callback for " + budget +
                         " bytes on network " + network);
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 9a9cdbd..eee830f 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -19,6 +19,7 @@
 import static android.hardware.usb.UsbManager.USB_CONFIGURED;
 import static android.hardware.usb.UsbManager.USB_CONNECTED;
 import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
@@ -103,6 +104,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.net.Inet4Address;
+import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -1359,19 +1361,16 @@
 
         protected void setUpstreamNetwork(NetworkState ns) {
             String iface = null;
-            if (ns != null && ns.linkProperties != null) {
+            if (ns != null) {
                 // Find the interface with the default IPv4 route. It may be the
                 // interface described by linkProperties, or one of the interfaces
                 // stacked on top of it.
-                mLog.i("Finding IPv4 upstream interface on: " + ns.linkProperties);
-                RouteInfo ipv4Default = RouteInfo.selectBestRoute(
-                    ns.linkProperties.getAllRoutes(), Inet4Address.ANY);
-                if (ipv4Default != null) {
-                    iface = ipv4Default.getInterface();
-                    mLog.i("Found interface " + ipv4Default.getInterface());
-                } else {
-                    mLog.i("No IPv4 upstream interface, giving up.");
-                }
+                mLog.i("Looking for default routes on: " + ns.linkProperties);
+                final String iface4 = getIPv4DefaultRouteInterface(ns);
+                final String iface6 = getIPv6DefaultRouteInterface(ns);
+                mLog.i("IPv4/IPv6 upstream interface(s): " + iface4 + "/" + iface6);
+
+                iface = (iface4 != null) ? iface4 : null /* TODO: iface6 */;
             }
 
             if (iface != null) {
@@ -2014,6 +2013,31 @@
         mTetherStates.remove(iface);
     }
 
+    private static String getIPv4DefaultRouteInterface(NetworkState ns) {
+        if (ns == null) return null;
+        return getInterfaceForDestination(ns.linkProperties, Inet4Address.ANY);
+    }
+
+    private static String getIPv6DefaultRouteInterface(NetworkState ns) {
+        if (ns == null) return null;
+        // An upstream network's IPv6 capability is currently only useful if it
+        // can be 64share'd downstream (RFC 7278). For now, that means mobile
+        // upstream networks only.
+        if (ns.networkCapabilities == null ||
+                !ns.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
+            return null;
+        }
+
+        return getInterfaceForDestination(ns.linkProperties, Inet6Address.ANY);
+    }
+
+    private static String getInterfaceForDestination(LinkProperties lp, InetAddress dst) {
+        final RouteInfo ri = (lp != null)
+                ? RouteInfo.selectBestRoute(lp.getAllRoutes(), dst)
+                : null;
+        return (ri != null) ? ri.getInterface() : null;
+    }
+
     private static String[] copy(String[] strarray) {
         return Arrays.copyOf(strarray, strarray.length);
     }
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index e2aee88..cb53521 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -67,7 +67,7 @@
 
     private static final int MSG_UPDATE_AMBIENT_LUX = 1;
     private static final int MSG_BRIGHTNESS_ADJUSTMENT_SAMPLE = 2;
-    private static final int MSG_RESET_SHORT_TERM_MODEL = 3;
+    private static final int MSG_INVALIDATE_SHORT_TERM_MODEL = 3;
 
     // Length of the ambient light horizon used to calculate the long term estimate of ambient
     // light.
@@ -158,9 +158,6 @@
     // A ring buffer containing all of the recent ambient light sensor readings.
     private AmbientLightRingBuffer mAmbientLightRingBuffer;
 
-    // A ring buffer containing the light sensor readings for the initial horizon period.
-    private AmbientLightRingBuffer mInitialHorizonAmbientLightRingBuffer;
-
     // The handler
     private AutomaticBrightnessHandler mHandler;
 
@@ -194,6 +191,14 @@
     private int mBrightnessAdjustmentSampleOldBrightness;
     private float mBrightnessAdjustmentSampleOldGamma;
 
+    // When the short term model is invalidated, we don't necessarily reset it (i.e. clear the
+    // user's adjustment) immediately, but wait for a drastic enough change in the ambient light.
+    // The anchor determines what were the light levels when the user has set her preference, and
+    // we use a relative threshold to determine when to revert to the OEM curve.
+    private boolean mShortTermModelValid;
+    private float mShortTermModelAnchor;
+    private float SHORT_TERM_MODEL_THRESHOLD_RATIO = 0.6f;
+
     public AutomaticBrightnessController(Callbacks callbacks, Looper looper,
             SensorManager sensorManager, BrightnessMappingStrategy mapper, int lightSensorWarmUpTime,
             int brightnessMin, int brightnessMax, float dozeScaleFactor,
@@ -218,12 +223,12 @@
         mWeightingIntercept = ambientLightHorizon;
         mScreenAutoBrightnessAdjustmentMaxGamma = autoBrightnessAdjustmentMaxGamma;
         mDynamicHysteresis = dynamicHysteresis;
+        mShortTermModelValid = true;
+        mShortTermModelAnchor = -1;
 
         mHandler = new AutomaticBrightnessHandler(looper);
         mAmbientLightRingBuffer =
             new AmbientLightRingBuffer(mNormalLightSensorRate, mAmbientLightHorizon);
-        mInitialHorizonAmbientLightRingBuffer =
-            new AmbientLightRingBuffer(mNormalLightSensorRate, mAmbientLightHorizon);
 
         if (!DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) {
             mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
@@ -284,13 +289,13 @@
         final int oldPolicy = mDisplayPolicy;
         mDisplayPolicy = policy;
         if (DEBUG) {
-            Slog.d(TAG, "Display policy transitioning from " + mDisplayPolicy + " to " + policy);
+            Slog.d(TAG, "Display policy transitioning from " + oldPolicy + " to " + policy);
         }
         if (!isInteractivePolicy(policy) && isInteractivePolicy(oldPolicy)) {
-            mHandler.sendEmptyMessageDelayed(MSG_RESET_SHORT_TERM_MODEL,
+            mHandler.sendEmptyMessageDelayed(MSG_INVALIDATE_SHORT_TERM_MODEL,
                     SHORT_TERM_MODEL_TIMEOUT_MILLIS);
         } else if (isInteractivePolicy(policy) && !isInteractivePolicy(oldPolicy)) {
-            mHandler.removeMessages(MSG_RESET_SHORT_TERM_MODEL);
+            mHandler.removeMessages(MSG_INVALIDATE_SHORT_TERM_MODEL);
         }
         return true;
     }
@@ -308,6 +313,11 @@
             return false;
         }
         mBrightnessMapper.addUserDataPoint(mAmbientLux, brightness);
+        mShortTermModelValid = true;
+        mShortTermModelAnchor = mAmbientLux;
+        if (DEBUG) {
+            Slog.d(TAG, "ShortTermModel: anchor=" + mShortTermModelAnchor);
+        }
         // Reset the brightness adjustment so that the next time we're queried for brightness we
         // return the value the user set.
         mScreenAutoBrightnessAdjustment = 0.0f;
@@ -316,6 +326,15 @@
 
     private void resetShortTermModel() {
         mBrightnessMapper.clearUserDataPoints();
+        mShortTermModelValid = true;
+        mShortTermModelAnchor = -1;
+    }
+
+    private void invalidateShortTermModel() {
+        if (DEBUG) {
+            Slog.d(TAG, "ShortTermModel: invalidate user data");
+        }
+        mShortTermModelValid = false;
     }
 
     public boolean setBrightnessConfiguration(BrightnessConfiguration configuration) {
@@ -345,14 +364,13 @@
         pw.println("  mLastObservedLuxTime=" + TimeUtils.formatUptime(mLastObservedLuxTime));
         pw.println("  mRecentLightSamples=" + mRecentLightSamples);
         pw.println("  mAmbientLightRingBuffer=" + mAmbientLightRingBuffer);
-        pw.println("  mInitialHorizonAmbientLightRingBuffer=" +
-                mInitialHorizonAmbientLightRingBuffer);
         pw.println("  mScreenAutoBrightness=" + mScreenAutoBrightness);
         pw.println("  mScreenAutoBrightnessAdjustment=" + mScreenAutoBrightnessAdjustment);
         pw.println("  mScreenAutoBrightnessAdjustmentMaxGamma="
                 + mScreenAutoBrightnessAdjustmentMaxGamma);
         pw.println("  mLastScreenAutoBrightnessGamma=" + mLastScreenAutoBrightnessGamma);
         pw.println("  mDisplayPolicy=" + mDisplayPolicy);
+        pw.println("  mShortTermModelAnchor=" + mShortTermModelAnchor);
 
         pw.println();
         mBrightnessMapper.dump(pw);
@@ -368,17 +386,14 @@
                         mCurrentLightSensorRate * 1000, mHandler);
                 return true;
             }
-        } else {
-            if (mLightSensorEnabled) {
-                mLightSensorEnabled = false;
-                mAmbientLuxValid = !mResetAmbientLuxAfterWarmUpConfig;
-                mRecentLightSamples = 0;
-                mAmbientLightRingBuffer.clear();
-                mInitialHorizonAmbientLightRingBuffer.clear();
-                mCurrentLightSensorRate = -1;
-                mHandler.removeMessages(MSG_UPDATE_AMBIENT_LUX);
-                mSensorManager.unregisterListener(mLightSensorListener);
-            }
+        } else if (mLightSensorEnabled) {
+            mLightSensorEnabled = false;
+            mAmbientLuxValid = !mResetAmbientLuxAfterWarmUpConfig;
+            mRecentLightSamples = 0;
+            mAmbientLightRingBuffer.clear();
+            mCurrentLightSensorRate = -1;
+            mHandler.removeMessages(MSG_UPDATE_AMBIENT_LUX);
+            mSensorManager.unregisterListener(mLightSensorListener);
         }
         return false;
     }
@@ -397,11 +412,6 @@
 
     private void applyLightSensorMeasurement(long time, float lux) {
         mRecentLightSamples++;
-        // Store all of the light measurements for the intial horizon period. This is to help
-        // diagnose dim wake ups and slow responses in b/27951906.
-        if (time <= mLightSensorEnableTime + mAmbientLightHorizon) {
-            mInitialHorizonAmbientLightRingBuffer.push(time, lux);
-        }
         mAmbientLightRingBuffer.prune(time - mAmbientLightHorizon);
         mAmbientLightRingBuffer.push(time, lux);
 
@@ -414,8 +424,9 @@
         // if the light sensor rate changed, update the sensor listener
         if (lightSensorRate != mCurrentLightSensorRate) {
             if (DEBUG) {
-                Slog.d(TAG, "adjustLightSensorRate: previousRate=" + mCurrentLightSensorRate
-                    + ", currentRate=" + lightSensorRate);
+                Slog.d(TAG, "adjustLightSensorRate: " +
+                       "previousRate=" + mCurrentLightSensorRate + ", " +
+                       "currentRate=" + lightSensorRate);
             }
             mCurrentLightSensorRate = lightSensorRate;
             mSensorManager.unregisterListener(mLightSensorListener);
@@ -437,12 +448,29 @@
             Slog.d(TAG, "setAmbientLux(" + lux + ")");
         }
         if (lux < 0) {
-            Slog.w(TAG, "Ambient lux was negative, ignoring and setting to 0.");
+            Slog.w(TAG, "Ambient lux was negative, ignoring and setting to 0");
             lux = 0;
         }
         mAmbientLux = lux;
         mBrighteningLuxThreshold = mDynamicHysteresis.getBrighteningThreshold(lux);
         mDarkeningLuxThreshold = mDynamicHysteresis.getDarkeningThreshold(lux);
+
+        // If the short term model was invalidated and the change is drastic enough, reset it.
+        if (!mShortTermModelValid && mShortTermModelAnchor != -1) {
+            final float minAmbientLux =
+                mShortTermModelAnchor - mShortTermModelAnchor * SHORT_TERM_MODEL_THRESHOLD_RATIO;
+            final float maxAmbientLux =
+                mShortTermModelAnchor + mShortTermModelAnchor * SHORT_TERM_MODEL_THRESHOLD_RATIO;
+            if (minAmbientLux < mAmbientLux && mAmbientLux < maxAmbientLux) {
+                Slog.d(TAG, "ShortTermModel: re-validate user data, ambient lux is " +
+                       minAmbientLux + " < " + mAmbientLux + " < " + maxAmbientLux);
+                mShortTermModelValid = true;
+            } else {
+                Slog.d(TAG, "ShortTermModel: reset data, ambient lux is " + mAmbientLux +
+                       "(" + minAmbientLux + ", " + maxAmbientLux + ")");
+                resetShortTermModel();
+            }
+        }
     }
 
     private float calculateAmbientLux(long now, long horizon) {
@@ -467,9 +495,8 @@
         }
         if (DEBUG) {
             Slog.d(TAG, "calculateAmbientLux: selected endIndex=" + endIndex + ", point=("
-                    + mAmbientLightRingBuffer.getTime(endIndex) + ", "
-                    + mAmbientLightRingBuffer.getLux(endIndex)
-                    + ")");
+                   + mAmbientLightRingBuffer.getTime(endIndex) + ", "
+                   + mAmbientLightRingBuffer.getLux(endIndex) + ")");
         }
         float sum = 0;
         float totalWeight = 0;
@@ -485,17 +512,18 @@
             float weight = calculateWeight(startTime, endTime);
             float lux = mAmbientLightRingBuffer.getLux(i);
             if (DEBUG) {
-                Slog.d(TAG, "calculateAmbientLux: [" +
-                        (startTime) + ", " +
-                        (endTime) + "]: lux=" + lux + ", weight=" + weight);
+                Slog.d(TAG, "calculateAmbientLux: [" + startTime + ", " + endTime + "]: " +
+                       "lux=" + lux + ", " +
+                       "weight=" + weight);
             }
             totalWeight += weight;
-            sum += mAmbientLightRingBuffer.getLux(i) * weight;
+            sum += lux * weight;
             endTime = startTime;
         }
         if (DEBUG) {
-            Slog.d(TAG, "calculateAmbientLux: totalWeight=" + totalWeight +
-                    ", newAmbientLux=" + (sum / totalWeight));
+            Slog.d(TAG, "calculateAmbientLux: " +
+                   "totalWeight=" + totalWeight + ", " +
+                   "newAmbientLux=" + (sum / totalWeight));
         }
         return sum / totalWeight;
     }
@@ -548,9 +576,9 @@
                 mLightSensorWarmUpTimeConfig + mLightSensorEnableTime;
             if (time < timeWhenSensorWarmedUp) {
                 if (DEBUG) {
-                    Slog.d(TAG, "updateAmbientLux: Sensor not  ready yet: "
-                            + "time=" + time
-                            + ", timeWhenSensorWarmedUp=" + timeWhenSensorWarmedUp);
+                    Slog.d(TAG, "updateAmbientLux: Sensor not  ready yet: " +
+                           "time=" + time + ", " +
+                           "timeWhenSensorWarmedUp=" + timeWhenSensorWarmedUp);
                 }
                 mHandler.sendEmptyMessageAtTime(MSG_UPDATE_AMBIENT_LUX,
                         timeWhenSensorWarmedUp);
@@ -559,9 +587,9 @@
             setAmbientLux(calculateAmbientLux(time, AMBIENT_LIGHT_SHORT_HORIZON_MILLIS));
             mAmbientLuxValid = true;
             if (DEBUG) {
-                Slog.d(TAG, "updateAmbientLux: Initializing: "
-                        + "mAmbientLightRingBuffer=" + mAmbientLightRingBuffer
-                        + ", mAmbientLux=" + mAmbientLux);
+                Slog.d(TAG, "updateAmbientLux: Initializing: " +
+                        "mAmbientLightRingBuffer=" + mAmbientLightRingBuffer + ", " +
+                        "mAmbientLux=" + mAmbientLux);
             }
             updateAutoBrightness(true);
         }
@@ -579,17 +607,20 @@
         float slowAmbientLux = calculateAmbientLux(time, AMBIENT_LIGHT_LONG_HORIZON_MILLIS);
         float fastAmbientLux = calculateAmbientLux(time, AMBIENT_LIGHT_SHORT_HORIZON_MILLIS);
 
-        if (slowAmbientLux >= mBrighteningLuxThreshold &&
-                fastAmbientLux >= mBrighteningLuxThreshold && nextBrightenTransition <= time
-                || slowAmbientLux <= mDarkeningLuxThreshold
-                && fastAmbientLux <= mDarkeningLuxThreshold && nextDarkenTransition <= time) {
+        if ((slowAmbientLux >= mBrighteningLuxThreshold &&
+             fastAmbientLux >= mBrighteningLuxThreshold &&
+             nextBrightenTransition <= time)
+             ||
+            (slowAmbientLux <= mDarkeningLuxThreshold &&
+             fastAmbientLux <= mDarkeningLuxThreshold &&
+             nextDarkenTransition <= time)) {
             setAmbientLux(fastAmbientLux);
             if (DEBUG) {
-                Slog.d(TAG, "updateAmbientLux: "
-                        + ((fastAmbientLux > mAmbientLux) ? "Brightened" : "Darkened") + ": "
-                        + "mBrighteningLuxThreshold=" + mBrighteningLuxThreshold
-                        + ", mAmbientLightRingBuffer=" + mAmbientLightRingBuffer
-                        + ", mAmbientLux=" + mAmbientLux);
+                Slog.d(TAG, "updateAmbientLux: " +
+                       ((fastAmbientLux > mAmbientLux) ? "Brightened" : "Darkened") + ": " +
+                       "mBrighteningLuxThreshold=" + mBrighteningLuxThreshold + ", " +
+                       "mAmbientLightRingBuffer=" + mAmbientLightRingBuffer + ", " +
+                       "mAmbientLux=" + mAmbientLux);
             }
             updateAutoBrightness(true);
             nextBrightenTransition = nextAmbientLightBrighteningTransition(time);
@@ -605,8 +636,8 @@
         nextTransitionTime =
                 nextTransitionTime > time ? nextTransitionTime : time + mNormalLightSensorRate;
         if (DEBUG) {
-            Slog.d(TAG, "updateAmbientLux: Scheduling ambient lux update for "
-                    + nextTransitionTime + TimeUtils.formatUptime(nextTransitionTime));
+            Slog.d(TAG, "updateAmbientLux: Scheduling ambient lux update for " +
+                   nextTransitionTime + TimeUtils.formatUptime(nextTransitionTime));
         }
         mHandler.sendEmptyMessageAtTime(MSG_UPDATE_AMBIENT_LUX, nextTransitionTime);
     }
@@ -633,8 +664,10 @@
             final float in = value;
             value = MathUtils.pow(value, gamma);
             if (DEBUG) {
-                Slog.d(TAG, "updateAutoBrightness: gamma=" + gamma
-                        + ", in=" + in + ", out=" + value);
+                Slog.d(TAG, "updateAutoBrightness: " +
+                       "gamma=" + gamma + ", " +
+                       "in=" + in + ", " +
+                       "out=" + value);
             }
         }
 
@@ -642,9 +675,9 @@
                 clampScreenBrightness(Math.round(value * PowerManager.BRIGHTNESS_ON));
         if (mScreenAutoBrightness != newScreenAutoBrightness) {
             if (DEBUG) {
-                Slog.d(TAG, "updateAutoBrightness: mScreenAutoBrightness="
-                        + mScreenAutoBrightness + ", newScreenAutoBrightness="
-                        + newScreenAutoBrightness);
+                Slog.d(TAG, "updateAutoBrightness: " +
+                       "mScreenAutoBrightness=" + mScreenAutoBrightness + ", " +
+                       "newScreenAutoBrightness=" + newScreenAutoBrightness);
             }
 
             mScreenAutoBrightness = newScreenAutoBrightness;
@@ -687,12 +720,12 @@
             mBrightnessAdjustmentSamplePending = false;
             if (mAmbientLuxValid && mScreenAutoBrightness >= 0) {
                 if (DEBUG) {
-                    Slog.d(TAG, "Auto-brightness adjustment changed by user: "
-                            + "adj=" + mScreenAutoBrightnessAdjustment
-                            + ", lux=" + mAmbientLux
-                            + ", brightness=" + mScreenAutoBrightness
-                            + ", gamma=" + mLastScreenAutoBrightnessGamma
-                            + ", ring=" + mAmbientLightRingBuffer);
+                    Slog.d(TAG, "Auto-brightness adjustment changed by user: " +
+                           "adj=" + mScreenAutoBrightnessAdjustment + ", " +
+                           "lux=" + mAmbientLux + ", " +
+                           "brightness=" + mScreenAutoBrightness + ", " +
+                           "gamma=" + mLastScreenAutoBrightnessGamma + ", " +
+                           "ring=" + mAmbientLightRingBuffer);
                 }
 
                 EventLog.writeEvent(EventLogTags.AUTO_BRIGHTNESS_ADJ,
@@ -724,8 +757,8 @@
                     collectBrightnessAdjustmentSample();
                     break;
 
-                case MSG_RESET_SHORT_TERM_MODEL:
-                    resetShortTermModel();
+                case MSG_INVALIDATE_SHORT_TERM_MODEL:
+                    invalidateShortTermModel();
                     break;
             }
         }
diff --git a/services/core/java/com/android/server/display/BrightnessTracker.java b/services/core/java/com/android/server/display/BrightnessTracker.java
index 524de91..df60c66 100644
--- a/services/core/java/com/android/server/display/BrightnessTracker.java
+++ b/services/core/java/com/android/server/display/BrightnessTracker.java
@@ -70,6 +70,8 @@
 import java.util.ArrayList;
 
 import java.util.Deque;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -225,15 +227,24 @@
      * @return List of recent {@link BrightnessChangeEvent}s
      */
     public ParceledListSlice<BrightnessChangeEvent> getEvents(int userId, boolean includePackage) {
-        // TODO include apps from any managed profiles in the brightness information.
         BrightnessChangeEvent[] events;
         synchronized (mEventsLock) {
             events = mEvents.toArray();
         }
+        int[] profiles = mInjector.getProfileIds(mUserManager, userId);
+        Map<Integer, Boolean> toRedact = new HashMap<>();
+        for (int i = 0; i < profiles.length; ++i) {
+            int profileId = profiles[i];
+            // Include slider interactions when a managed profile app is in the
+            // foreground but always redact the package name.
+            boolean redact = (!includePackage) || profileId != userId;
+            toRedact.put(profiles[i], redact);
+        }
         ArrayList<BrightnessChangeEvent> out = new ArrayList<>(events.length);
         for (int i = 0; i < events.length; ++i) {
-            if (events[i].userId == userId) {
-                if (includePackage) {
+            Boolean redact = toRedact.get(events[i].userId);
+            if (redact != null) {
+                if (!redact) {
                     out.add(events[i]);
                 } else {
                     BrightnessChangeEvent event = new BrightnessChangeEvent((events[i]),
@@ -817,6 +828,14 @@
             return userManager.getUserHandle(userSerialNumber);
         }
 
+        public int[] getProfileIds(UserManager userManager, int userId) {
+            if (userManager != null) {
+                return userManager.getProfileIds(userId, false);
+            } else {
+                return new int[]{userId};
+            }
+        }
+
         public ActivityManager.StackInfo getFocusedStack() throws RemoteException {
             return ActivityManager.getService().getFocusedStackInfo();
         }
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 692535c..3da3551 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -421,7 +421,7 @@
                 byteToken[i] = token.get(i);
             }
             // Send to Keystore
-            KeyStore.getInstance().addAuthToken(byteToken, mCurrentUserId);
+            KeyStore.getInstance().addAuthToken(byteToken);
         }
         if (client != null && client.onAuthenticated(fingerId, groupId)) {
             removeClient(client);
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 52f5917..0e7e540 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -43,8 +43,8 @@
 import android.content.IntentFilter;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.ServiceInfo;
 import android.database.ContentObserver;
 import android.net.Uri;
@@ -65,6 +65,7 @@
 import android.provider.Settings;
 import android.text.format.DateUtils;
 import android.util.KeyValueListParser;
+import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
@@ -78,14 +79,15 @@
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
+import com.android.server.AppStateTracker;
 import com.android.server.DeviceIdleController;
 import com.android.server.FgThread;
-import com.android.server.AppStateTracker;
 import com.android.server.LocalServices;
 import com.android.server.job.JobSchedulerServiceDumpProto.ActiveJob;
 import com.android.server.job.JobSchedulerServiceDumpProto.PendingJob;
-import com.android.server.job.JobStore.JobStatusFunctor;
+import com.android.server.job.JobSchedulerServiceDumpProto.RegisteredJob;
 import com.android.server.job.controllers.AppIdleController;
 import com.android.server.job.controllers.BackgroundJobsController;
 import com.android.server.job.controllers.BatteryController;
@@ -109,6 +111,7 @@
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
+import java.util.function.Consumer;
 import java.util.function.Predicate;
 
 /**
@@ -125,8 +128,8 @@
  */
 public final class JobSchedulerService extends com.android.server.SystemService
         implements StateChangedListener, JobCompletedListener {
-    static final String TAG = "JobSchedulerService";
-    public static final boolean DEBUG = false;
+    public static final String TAG = "JobScheduler";
+    public static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
     public static final boolean DEBUG_STANDBY = DEBUG || false;
 
     /** The maximum number of concurrent jobs we run at one time. */
@@ -156,21 +159,26 @@
     static final int MSG_CHECK_JOB = 1;
     static final int MSG_STOP_JOB = 2;
     static final int MSG_CHECK_JOB_GREEDY = 3;
+    static final int MSG_UID_STATE_CHANGED = 4;
+    static final int MSG_UID_GONE = 5;
+    static final int MSG_UID_ACTIVE = 6;
+    static final int MSG_UID_IDLE = 7;
 
     /**
      * Track Services that have currently active or pending jobs. The index is provided by
      * {@link JobStatus#getServiceToken()}
      */
     final List<JobServiceContext> mActiveServices = new ArrayList<>();
+
     /** List of controllers that will notify this service of updates to jobs. */
-    List<StateController> mControllers;
+    private final List<StateController> mControllers;
     /** Need direct access to this for testing. */
-    BatteryController mBatteryController;
+    private final BatteryController mBatteryController;
     /** Need direct access to this for testing. */
-    StorageController mStorageController;
+    private final StorageController mStorageController;
     /** Need directly for sending uid state changes */
-    private BackgroundJobsController mBackgroundJobsController;
-    private DeviceIdleJobsController mDeviceIdleJobsController;
+    private final DeviceIdleJobsController mDeviceIdleJobsController;
+
     /**
      * Queue of pending jobs. The JobServiceContext class will receive jobs from this list
      * when ready to execute them.
@@ -252,12 +260,48 @@
      */
     int[] mTmpAssignPreferredUidForContext = new int[MAX_JOB_CONTEXTS_COUNT];
 
+    private class ConstantsObserver extends ContentObserver {
+        private ContentResolver mResolver;
+
+        public ConstantsObserver(Handler handler) {
+            super(handler);
+        }
+
+        public void start(ContentResolver resolver) {
+            mResolver = resolver;
+            mResolver.registerContentObserver(Settings.Global.getUriFor(
+                    Settings.Global.JOB_SCHEDULER_CONSTANTS), false, this);
+            updateConstants();
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            updateConstants();
+        }
+
+        private void updateConstants() {
+            synchronized (mLock) {
+                try {
+                    mConstants.updateConstantsLocked(Settings.Global.getString(mResolver,
+                            Settings.Global.JOB_SCHEDULER_CONSTANTS));
+                } catch (IllegalArgumentException e) {
+                    // Failed to parse the settings string, log this and move on
+                    // with defaults.
+                    Slog.e(TAG, "Bad jobscheduler settings", e);
+                }
+            }
+
+            // Reset the heartbeat alarm based on the new heartbeat duration
+            setNextHeartbeatAlarm();
+        }
+    }
+
     /**
      * All times are in milliseconds. These constants are kept synchronized with the system
      * global Settings. Any access to this class or its fields should be done while
      * holding the JobSchedulerService.mLock lock.
      */
-    private final class Constants extends ContentObserver {
+    public static class Constants {
         // Key names stored in the settings value.
         private static final String KEY_MIN_IDLE_COUNT = "min_idle_count";
         private static final String KEY_MIN_CHARGING_COUNT = "min_charging_count";
@@ -282,6 +326,8 @@
         private static final String KEY_STANDBY_WORKING_BEATS = "standby_working_beats";
         private static final String KEY_STANDBY_FREQUENT_BEATS = "standby_frequent_beats";
         private static final String KEY_STANDBY_RARE_BEATS = "standby_rare_beats";
+        private static final String KEY_CONN_CONGESTION_DELAY_FRAC = "conn_congestion_delay_frac";
+        private static final String KEY_CONN_PREFETCH_RELAX_FRAC = "conn_prefetch_relax_frac";
 
         private static final int DEFAULT_MIN_IDLE_COUNT = 1;
         private static final int DEFAULT_MIN_CHARGING_COUNT = 1;
@@ -305,6 +351,8 @@
         private static final int DEFAULT_STANDBY_WORKING_BEATS = 11;  // ~ 2 hours, with 11min beats
         private static final int DEFAULT_STANDBY_FREQUENT_BEATS = 43; // ~ 8 hours
         private static final int DEFAULT_STANDBY_RARE_BEATS = 130; // ~ 24 hours
+        private static final float DEFAULT_CONN_CONGESTION_DELAY_FRAC = 0.5f;
+        private static final float DEFAULT_CONN_PREFETCH_RELAX_FRAC = 0.5f;
 
         /**
          * Minimum # of idle jobs that must be ready in order to force the JMS to schedule things
@@ -399,7 +447,6 @@
          * hour or day, so that the heartbeat drifts relative to wall-clock milestones.
          */
         long STANDBY_HEARTBEAT_TIME = DEFAULT_STANDBY_HEARTBEAT_TIME;
-
         /**
          * Mapping: standby bucket -> number of heartbeats between each sweep of that
          * bucket's jobs.
@@ -414,171 +461,126 @@
                 DEFAULT_STANDBY_FREQUENT_BEATS,
                 DEFAULT_STANDBY_RARE_BEATS
         };
+        /**
+         * The fraction of a job's running window that must pass before we
+         * consider running it when the network is congested.
+         */
+        public float CONN_CONGESTION_DELAY_FRAC = DEFAULT_CONN_CONGESTION_DELAY_FRAC;
+        /**
+         * The fraction of a prefetch job's running window that must pass before
+         * we consider matching it against a metered network.
+         */
+        public float CONN_PREFETCH_RELAX_FRAC = DEFAULT_CONN_PREFETCH_RELAX_FRAC;
 
-        private ContentResolver mResolver;
         private final KeyValueListParser mParser = new KeyValueListParser(',');
 
-        public Constants(Handler handler) {
-            super(handler);
-        }
-
-        public void start(ContentResolver resolver) {
-            mResolver = resolver;
-            mResolver.registerContentObserver(Settings.Global.getUriFor(
-                    Settings.Global.JOB_SCHEDULER_CONSTANTS), false, this);
-            updateConstants();
-        }
-
-        @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            updateConstants();
-        }
-
-        private void updateConstants() {
-            synchronized (mLock) {
-                try {
-                    mParser.setString(Settings.Global.getString(mResolver,
-                            Settings.Global.JOB_SCHEDULER_CONSTANTS));
-                } catch (IllegalArgumentException e) {
-                    // Failed to parse the settings string, log this and move on
-                    // with defaults.
-                    Slog.e(TAG, "Bad jobscheduler settings", e);
-                }
-
-                MIN_IDLE_COUNT = mParser.getInt(KEY_MIN_IDLE_COUNT,
-                        DEFAULT_MIN_IDLE_COUNT);
-                MIN_CHARGING_COUNT = mParser.getInt(KEY_MIN_CHARGING_COUNT,
-                        DEFAULT_MIN_CHARGING_COUNT);
-                MIN_BATTERY_NOT_LOW_COUNT = mParser.getInt(KEY_MIN_BATTERY_NOT_LOW_COUNT,
-                        DEFAULT_MIN_BATTERY_NOT_LOW_COUNT);
-                MIN_STORAGE_NOT_LOW_COUNT = mParser.getInt(KEY_MIN_STORAGE_NOT_LOW_COUNT,
-                        DEFAULT_MIN_STORAGE_NOT_LOW_COUNT);
-                MIN_CONNECTIVITY_COUNT = mParser.getInt(KEY_MIN_CONNECTIVITY_COUNT,
-                        DEFAULT_MIN_CONNECTIVITY_COUNT);
-                MIN_CONTENT_COUNT = mParser.getInt(KEY_MIN_CONTENT_COUNT,
-                        DEFAULT_MIN_CONTENT_COUNT);
-                MIN_READY_JOBS_COUNT = mParser.getInt(KEY_MIN_READY_JOBS_COUNT,
-                        DEFAULT_MIN_READY_JOBS_COUNT);
-                HEAVY_USE_FACTOR = mParser.getFloat(KEY_HEAVY_USE_FACTOR,
-                        DEFAULT_HEAVY_USE_FACTOR);
-                MODERATE_USE_FACTOR = mParser.getFloat(KEY_MODERATE_USE_FACTOR,
-                        DEFAULT_MODERATE_USE_FACTOR);
-                FG_JOB_COUNT = mParser.getInt(KEY_FG_JOB_COUNT,
-                        DEFAULT_FG_JOB_COUNT);
-                BG_NORMAL_JOB_COUNT = mParser.getInt(KEY_BG_NORMAL_JOB_COUNT,
-                        DEFAULT_BG_NORMAL_JOB_COUNT);
-                if ((FG_JOB_COUNT+BG_NORMAL_JOB_COUNT) > MAX_JOB_CONTEXTS_COUNT) {
-                    BG_NORMAL_JOB_COUNT = MAX_JOB_CONTEXTS_COUNT - FG_JOB_COUNT;
-                }
-                BG_MODERATE_JOB_COUNT = mParser.getInt(KEY_BG_MODERATE_JOB_COUNT,
-                        DEFAULT_BG_MODERATE_JOB_COUNT);
-                if ((FG_JOB_COUNT+BG_MODERATE_JOB_COUNT) > MAX_JOB_CONTEXTS_COUNT) {
-                    BG_MODERATE_JOB_COUNT = MAX_JOB_CONTEXTS_COUNT - FG_JOB_COUNT;
-                }
-                BG_LOW_JOB_COUNT = mParser.getInt(KEY_BG_LOW_JOB_COUNT,
-                        DEFAULT_BG_LOW_JOB_COUNT);
-                if ((FG_JOB_COUNT+BG_LOW_JOB_COUNT) > MAX_JOB_CONTEXTS_COUNT) {
-                    BG_LOW_JOB_COUNT = MAX_JOB_CONTEXTS_COUNT - FG_JOB_COUNT;
-                }
-                BG_CRITICAL_JOB_COUNT = mParser.getInt(KEY_BG_CRITICAL_JOB_COUNT,
-                        DEFAULT_BG_CRITICAL_JOB_COUNT);
-                if ((FG_JOB_COUNT+BG_CRITICAL_JOB_COUNT) > MAX_JOB_CONTEXTS_COUNT) {
-                    BG_CRITICAL_JOB_COUNT = MAX_JOB_CONTEXTS_COUNT - FG_JOB_COUNT;
-                }
-                MAX_STANDARD_RESCHEDULE_COUNT = mParser.getInt(KEY_MAX_STANDARD_RESCHEDULE_COUNT,
-                        DEFAULT_MAX_STANDARD_RESCHEDULE_COUNT);
-                MAX_WORK_RESCHEDULE_COUNT = mParser.getInt(KEY_MAX_WORK_RESCHEDULE_COUNT,
-                        DEFAULT_MAX_WORK_RESCHEDULE_COUNT);
-                MIN_LINEAR_BACKOFF_TIME = mParser.getDurationMillis(KEY_MIN_LINEAR_BACKOFF_TIME,
-                        DEFAULT_MIN_LINEAR_BACKOFF_TIME);
-                MIN_EXP_BACKOFF_TIME = mParser.getDurationMillis(KEY_MIN_EXP_BACKOFF_TIME,
-                        DEFAULT_MIN_EXP_BACKOFF_TIME);
-                STANDBY_HEARTBEAT_TIME = mParser.getDurationMillis(KEY_STANDBY_HEARTBEAT_TIME,
-                        DEFAULT_STANDBY_HEARTBEAT_TIME);
-                STANDBY_BEATS[1] = mParser.getInt(KEY_STANDBY_WORKING_BEATS,
-                        DEFAULT_STANDBY_WORKING_BEATS);
-                STANDBY_BEATS[2] = mParser.getInt(KEY_STANDBY_FREQUENT_BEATS,
-                        DEFAULT_STANDBY_FREQUENT_BEATS);
-                STANDBY_BEATS[3] = mParser.getInt(KEY_STANDBY_RARE_BEATS,
-                        DEFAULT_STANDBY_RARE_BEATS);
+        void updateConstantsLocked(String value) {
+            try {
+                mParser.setString(value);
+            } catch (Exception e) {
+                // Failed to parse the settings string, log this and move on
+                // with defaults.
+                Slog.e(TAG, "Bad jobscheduler settings", e);
             }
 
-            // Reset the heartbeat alarm based on the new heartbeat duration
-            setNextHeartbeatAlarm();
+            MIN_IDLE_COUNT = mParser.getInt(KEY_MIN_IDLE_COUNT,
+                    DEFAULT_MIN_IDLE_COUNT);
+            MIN_CHARGING_COUNT = mParser.getInt(KEY_MIN_CHARGING_COUNT,
+                    DEFAULT_MIN_CHARGING_COUNT);
+            MIN_BATTERY_NOT_LOW_COUNT = mParser.getInt(KEY_MIN_BATTERY_NOT_LOW_COUNT,
+                    DEFAULT_MIN_BATTERY_NOT_LOW_COUNT);
+            MIN_STORAGE_NOT_LOW_COUNT = mParser.getInt(KEY_MIN_STORAGE_NOT_LOW_COUNT,
+                    DEFAULT_MIN_STORAGE_NOT_LOW_COUNT);
+            MIN_CONNECTIVITY_COUNT = mParser.getInt(KEY_MIN_CONNECTIVITY_COUNT,
+                    DEFAULT_MIN_CONNECTIVITY_COUNT);
+            MIN_CONTENT_COUNT = mParser.getInt(KEY_MIN_CONTENT_COUNT,
+                    DEFAULT_MIN_CONTENT_COUNT);
+            MIN_READY_JOBS_COUNT = mParser.getInt(KEY_MIN_READY_JOBS_COUNT,
+                    DEFAULT_MIN_READY_JOBS_COUNT);
+            HEAVY_USE_FACTOR = mParser.getFloat(KEY_HEAVY_USE_FACTOR,
+                    DEFAULT_HEAVY_USE_FACTOR);
+            MODERATE_USE_FACTOR = mParser.getFloat(KEY_MODERATE_USE_FACTOR,
+                    DEFAULT_MODERATE_USE_FACTOR);
+            FG_JOB_COUNT = mParser.getInt(KEY_FG_JOB_COUNT,
+                    DEFAULT_FG_JOB_COUNT);
+            BG_NORMAL_JOB_COUNT = mParser.getInt(KEY_BG_NORMAL_JOB_COUNT,
+                    DEFAULT_BG_NORMAL_JOB_COUNT);
+            if ((FG_JOB_COUNT+BG_NORMAL_JOB_COUNT) > MAX_JOB_CONTEXTS_COUNT) {
+                BG_NORMAL_JOB_COUNT = MAX_JOB_CONTEXTS_COUNT - FG_JOB_COUNT;
+            }
+            BG_MODERATE_JOB_COUNT = mParser.getInt(KEY_BG_MODERATE_JOB_COUNT,
+                    DEFAULT_BG_MODERATE_JOB_COUNT);
+            if ((FG_JOB_COUNT+BG_MODERATE_JOB_COUNT) > MAX_JOB_CONTEXTS_COUNT) {
+                BG_MODERATE_JOB_COUNT = MAX_JOB_CONTEXTS_COUNT - FG_JOB_COUNT;
+            }
+            BG_LOW_JOB_COUNT = mParser.getInt(KEY_BG_LOW_JOB_COUNT,
+                    DEFAULT_BG_LOW_JOB_COUNT);
+            if ((FG_JOB_COUNT+BG_LOW_JOB_COUNT) > MAX_JOB_CONTEXTS_COUNT) {
+                BG_LOW_JOB_COUNT = MAX_JOB_CONTEXTS_COUNT - FG_JOB_COUNT;
+            }
+            BG_CRITICAL_JOB_COUNT = mParser.getInt(KEY_BG_CRITICAL_JOB_COUNT,
+                    DEFAULT_BG_CRITICAL_JOB_COUNT);
+            if ((FG_JOB_COUNT+BG_CRITICAL_JOB_COUNT) > MAX_JOB_CONTEXTS_COUNT) {
+                BG_CRITICAL_JOB_COUNT = MAX_JOB_CONTEXTS_COUNT - FG_JOB_COUNT;
+            }
+            MAX_STANDARD_RESCHEDULE_COUNT = mParser.getInt(KEY_MAX_STANDARD_RESCHEDULE_COUNT,
+                    DEFAULT_MAX_STANDARD_RESCHEDULE_COUNT);
+            MAX_WORK_RESCHEDULE_COUNT = mParser.getInt(KEY_MAX_WORK_RESCHEDULE_COUNT,
+                    DEFAULT_MAX_WORK_RESCHEDULE_COUNT);
+            MIN_LINEAR_BACKOFF_TIME = mParser.getDurationMillis(KEY_MIN_LINEAR_BACKOFF_TIME,
+                    DEFAULT_MIN_LINEAR_BACKOFF_TIME);
+            MIN_EXP_BACKOFF_TIME = mParser.getDurationMillis(KEY_MIN_EXP_BACKOFF_TIME,
+                    DEFAULT_MIN_EXP_BACKOFF_TIME);
+            STANDBY_HEARTBEAT_TIME = mParser.getDurationMillis(KEY_STANDBY_HEARTBEAT_TIME,
+                    DEFAULT_STANDBY_HEARTBEAT_TIME);
+            STANDBY_BEATS[1] = mParser.getInt(KEY_STANDBY_WORKING_BEATS,
+                    DEFAULT_STANDBY_WORKING_BEATS);
+            STANDBY_BEATS[2] = mParser.getInt(KEY_STANDBY_FREQUENT_BEATS,
+                    DEFAULT_STANDBY_FREQUENT_BEATS);
+            STANDBY_BEATS[3] = mParser.getInt(KEY_STANDBY_RARE_BEATS,
+                    DEFAULT_STANDBY_RARE_BEATS);
+            CONN_CONGESTION_DELAY_FRAC = mParser.getFloat(KEY_CONN_CONGESTION_DELAY_FRAC,
+                    DEFAULT_CONN_CONGESTION_DELAY_FRAC);
+            CONN_PREFETCH_RELAX_FRAC = mParser.getFloat(KEY_CONN_PREFETCH_RELAX_FRAC,
+                    DEFAULT_CONN_PREFETCH_RELAX_FRAC);
         }
 
-        void dump(PrintWriter pw) {
-            pw.println("  Settings:");
-
-            pw.print("    "); pw.print(KEY_MIN_IDLE_COUNT); pw.print("=");
-            pw.print(MIN_IDLE_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_MIN_CHARGING_COUNT); pw.print("=");
-            pw.print(MIN_CHARGING_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_MIN_BATTERY_NOT_LOW_COUNT); pw.print("=");
-            pw.print(MIN_BATTERY_NOT_LOW_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_MIN_STORAGE_NOT_LOW_COUNT); pw.print("=");
-            pw.print(MIN_STORAGE_NOT_LOW_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_MIN_CONNECTIVITY_COUNT); pw.print("=");
-            pw.print(MIN_CONNECTIVITY_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_MIN_CONTENT_COUNT); pw.print("=");
-            pw.print(MIN_CONTENT_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_MIN_READY_JOBS_COUNT); pw.print("=");
-            pw.print(MIN_READY_JOBS_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_HEAVY_USE_FACTOR); pw.print("=");
-            pw.print(HEAVY_USE_FACTOR); pw.println();
-
-            pw.print("    "); pw.print(KEY_MODERATE_USE_FACTOR); pw.print("=");
-            pw.print(MODERATE_USE_FACTOR); pw.println();
-
-            pw.print("    "); pw.print(KEY_FG_JOB_COUNT); pw.print("=");
-            pw.print(FG_JOB_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_BG_NORMAL_JOB_COUNT); pw.print("=");
-            pw.print(BG_NORMAL_JOB_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_BG_MODERATE_JOB_COUNT); pw.print("=");
-            pw.print(BG_MODERATE_JOB_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_BG_LOW_JOB_COUNT); pw.print("=");
-            pw.print(BG_LOW_JOB_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_BG_CRITICAL_JOB_COUNT); pw.print("=");
-            pw.print(BG_CRITICAL_JOB_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_MAX_STANDARD_RESCHEDULE_COUNT); pw.print("=");
-            pw.print(MAX_STANDARD_RESCHEDULE_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_MAX_WORK_RESCHEDULE_COUNT); pw.print("=");
-            pw.print(MAX_WORK_RESCHEDULE_COUNT); pw.println();
-
-            pw.print("    "); pw.print(KEY_MIN_LINEAR_BACKOFF_TIME); pw.print("=");
-            pw.print(MIN_LINEAR_BACKOFF_TIME); pw.println();
-
-            pw.print("    "); pw.print(KEY_MIN_EXP_BACKOFF_TIME); pw.print("=");
-            pw.print(MIN_EXP_BACKOFF_TIME); pw.println();
-
-            pw.print("    "); pw.print(KEY_STANDBY_HEARTBEAT_TIME); pw.print("=");
-            pw.print(STANDBY_HEARTBEAT_TIME); pw.println();
-
-            pw.print("    standby_beats={");
+        void dump(IndentingPrintWriter pw) {
+            pw.println("Settings:");
+            pw.increaseIndent();
+            pw.printPair(KEY_MIN_IDLE_COUNT, MIN_IDLE_COUNT).println();
+            pw.printPair(KEY_MIN_CHARGING_COUNT, MIN_CHARGING_COUNT).println();
+            pw.printPair(KEY_MIN_BATTERY_NOT_LOW_COUNT, MIN_BATTERY_NOT_LOW_COUNT).println();
+            pw.printPair(KEY_MIN_STORAGE_NOT_LOW_COUNT, MIN_STORAGE_NOT_LOW_COUNT).println();
+            pw.printPair(KEY_MIN_CONNECTIVITY_COUNT, MIN_CONNECTIVITY_COUNT).println();
+            pw.printPair(KEY_MIN_CONTENT_COUNT, MIN_CONTENT_COUNT).println();
+            pw.printPair(KEY_MIN_READY_JOBS_COUNT, MIN_READY_JOBS_COUNT).println();
+            pw.printPair(KEY_HEAVY_USE_FACTOR, HEAVY_USE_FACTOR).println();
+            pw.printPair(KEY_MODERATE_USE_FACTOR, MODERATE_USE_FACTOR).println();
+            pw.printPair(KEY_FG_JOB_COUNT, FG_JOB_COUNT).println();
+            pw.printPair(KEY_BG_NORMAL_JOB_COUNT, BG_NORMAL_JOB_COUNT).println();
+            pw.printPair(KEY_BG_MODERATE_JOB_COUNT, BG_MODERATE_JOB_COUNT).println();
+            pw.printPair(KEY_BG_LOW_JOB_COUNT, BG_LOW_JOB_COUNT).println();
+            pw.printPair(KEY_BG_CRITICAL_JOB_COUNT, BG_CRITICAL_JOB_COUNT).println();
+            pw.printPair(KEY_MAX_STANDARD_RESCHEDULE_COUNT, MAX_STANDARD_RESCHEDULE_COUNT).println();
+            pw.printPair(KEY_MAX_WORK_RESCHEDULE_COUNT, MAX_WORK_RESCHEDULE_COUNT).println();
+            pw.printPair(KEY_MIN_LINEAR_BACKOFF_TIME, MIN_LINEAR_BACKOFF_TIME).println();
+            pw.printPair(KEY_MIN_EXP_BACKOFF_TIME, MIN_EXP_BACKOFF_TIME).println();
+            pw.printPair(KEY_STANDBY_HEARTBEAT_TIME, STANDBY_HEARTBEAT_TIME).println();
+            pw.print("standby_beats={");
             pw.print(STANDBY_BEATS[0]);
             for (int i = 1; i < STANDBY_BEATS.length; i++) {
                 pw.print(", ");
                 pw.print(STANDBY_BEATS[i]);
             }
             pw.println('}');
+            pw.printPair(KEY_CONN_CONGESTION_DELAY_FRAC, CONN_CONGESTION_DELAY_FRAC).println();
+            pw.printPair(KEY_CONN_PREFETCH_RELAX_FRAC, CONN_PREFETCH_RELAX_FRAC).println();
+            pw.decreaseIndent();
         }
 
         void dump(ProtoOutputStream proto, long fieldId) {
             final long token = proto.start(fieldId);
-
             proto.write(ConstantsProto.MIN_IDLE_COUNT, MIN_IDLE_COUNT);
             proto.write(ConstantsProto.MIN_CHARGING_COUNT, MIN_CHARGING_COUNT);
             proto.write(ConstantsProto.MIN_BATTERY_NOT_LOW_COUNT, MIN_BATTERY_NOT_LOW_COUNT);
@@ -598,16 +600,17 @@
             proto.write(ConstantsProto.MIN_LINEAR_BACKOFF_TIME_MS, MIN_LINEAR_BACKOFF_TIME);
             proto.write(ConstantsProto.MIN_EXP_BACKOFF_TIME_MS, MIN_EXP_BACKOFF_TIME);
             proto.write(ConstantsProto.STANDBY_HEARTBEAT_TIME_MS, STANDBY_HEARTBEAT_TIME);
-
             for (int period : STANDBY_BEATS) {
                 proto.write(ConstantsProto.STANDBY_BEATS, period);
             }
-
+            proto.write(ConstantsProto.CONN_CONGESTION_DELAY_FRAC, CONN_CONGESTION_DELAY_FRAC);
+            proto.write(ConstantsProto.CONN_PREFETCH_RELAX_FRAC, CONN_PREFETCH_RELAX_FRAC);
             proto.end(token);
         }
     }
 
     final Constants mConstants;
+    final ConstantsObserver mConstantsObserver;
 
     static final Comparator<JobStatus> mEnqueueTimeComparator = (o1, o2) -> {
         if (o1.enqueueTime < o2.enqueueTime) {
@@ -737,32 +740,19 @@
 
     final private IUidObserver mUidObserver = new IUidObserver.Stub() {
         @Override public void onUidStateChanged(int uid, int procState, long procStateSeq) {
-            updateUidState(uid, procState);
+            mHandler.obtainMessage(MSG_UID_STATE_CHANGED, uid, procState).sendToTarget();
         }
 
         @Override public void onUidGone(int uid, boolean disabled) {
-            updateUidState(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
-            if (disabled) {
-                cancelJobsForUid(uid, "uid gone");
-            }
-            synchronized (mLock) {
-                mDeviceIdleJobsController.setUidActiveLocked(uid, false);
-            }
+            mHandler.obtainMessage(MSG_UID_GONE, uid, disabled ? 1 : 0).sendToTarget();
         }
 
         @Override public void onUidActive(int uid) throws RemoteException {
-            synchronized (mLock) {
-                mDeviceIdleJobsController.setUidActiveLocked(uid, true);
-            }
+            mHandler.obtainMessage(MSG_UID_ACTIVE, uid, 0).sendToTarget();
         }
 
         @Override public void onUidIdle(int uid, boolean disabled) {
-            if (disabled) {
-                cancelJobsForUid(uid, "app uid idle");
-            }
-            synchronized (mLock) {
-                mDeviceIdleJobsController.setUidActiveLocked(uid, false);
-            }
+            mHandler.obtainMessage(MSG_UID_IDLE, uid, disabled ? 1 : 0).sendToTarget();
         }
 
         @Override public void onUidCachedChanged(int uid, boolean cached) {
@@ -777,6 +767,10 @@
         return mJobs;
     }
 
+    public Constants getConstants() {
+        return mConstants;
+    }
+
     @Override
     public void onStartUser(int userHandle) {
         mStartedUsers = ArrayUtils.appendInt(mStartedUsers, userHandle);
@@ -1096,7 +1090,8 @@
                 LocalServices.getService(ActivityManagerInternal.class));
 
         mHandler = new JobHandler(context.getMainLooper());
-        mConstants = new Constants(mHandler);
+        mConstants = new Constants();
+        mConstantsObserver = new ConstantsObserver(mHandler);
         mJobSchedulerStub = new JobSchedulerStub();
 
         // Set up the app standby bucketing tracker
@@ -1112,17 +1107,17 @@
 
         // Create the controllers.
         mControllers = new ArrayList<StateController>();
-        mControllers.add(ConnectivityController.get(this));
-        mControllers.add(TimeController.get(this));
-        mControllers.add(IdleController.get(this));
-        mBatteryController = BatteryController.get(this);
+        mControllers.add(new ConnectivityController(this));
+        mControllers.add(new TimeController(this));
+        mControllers.add(new IdleController(this));
+        mBatteryController = new BatteryController(this);
         mControllers.add(mBatteryController);
-        mStorageController = StorageController.get(this);
+        mStorageController = new StorageController(this);
         mControllers.add(mStorageController);
-        mControllers.add(BackgroundJobsController.get(this));
-        mControllers.add(AppIdleController.get(this));
-        mControllers.add(ContentObserverController.get(this));
-        mDeviceIdleJobsController = DeviceIdleJobsController.get(this);
+        mControllers.add(new BackgroundJobsController(this));
+        mControllers.add(new AppIdleController(this));
+        mControllers.add(new ContentObserverController(this));
+        mDeviceIdleJobsController = new DeviceIdleJobsController(this);
         mControllers.add(mDeviceIdleJobsController);
 
         // If the job store determined that it can't yet reschedule persisted jobs,
@@ -1183,7 +1178,7 @@
     @Override
     public void onBootPhase(int phase) {
         if (PHASE_SYSTEM_SERVICES_READY == phase) {
-            mConstants.start(getContext().getContentResolver());
+            mConstantsObserver.start(getContext().getContentResolver());
 
             mAppStateTracker = Preconditions.checkNotNull(
                     LocalServices.getService(AppStateTracker.class));
@@ -1226,13 +1221,10 @@
                                     getContext().getMainLooper()));
                 }
                 // Attach jobs to their controllers.
-                mJobs.forEachJob(new JobStatusFunctor() {
-                    @Override
-                    public void process(JobStatus job) {
-                        for (int controller = 0; controller < mControllers.size(); controller++) {
-                            final StateController sc = mControllers.get(controller);
-                            sc.maybeStartTrackingJobLocked(job, null);
-                        }
+                mJobs.forEachJob((job) -> {
+                    for (int controller = 0; controller < mControllers.size(); controller++) {
+                        final StateController sc = mControllers.get(controller);
+                        sc.maybeStartTrackingJobLocked(job, null);
                     }
                 });
                 // GO GO GO!
@@ -1557,6 +1549,44 @@
                         cancelJobImplLocked((JobStatus) message.obj, null,
                                 "app no longer allowed to run");
                         break;
+
+                    case MSG_UID_STATE_CHANGED: {
+                        final int uid = message.arg1;
+                        final int procState = message.arg2;
+                        updateUidState(uid, procState);
+                        break;
+                    }
+                    case MSG_UID_GONE: {
+                        final int uid = message.arg1;
+                        final boolean disabled = message.arg2 != 0;
+                        updateUidState(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+                        if (disabled) {
+                            cancelJobsForUid(uid, "uid gone");
+                        }
+                        synchronized (mLock) {
+                            mDeviceIdleJobsController.setUidActiveLocked(uid, false);
+                        }
+                        break;
+                    }
+                    case MSG_UID_ACTIVE: {
+                        final int uid = message.arg1;
+                        synchronized (mLock) {
+                            mDeviceIdleJobsController.setUidActiveLocked(uid, true);
+                        }
+                        break;
+                    }
+                    case MSG_UID_IDLE: {
+                        final int uid = message.arg1;
+                        final boolean disabled = message.arg2 != 0;
+                        if (disabled) {
+                            cancelJobsForUid(uid, "app uid idle");
+                        }
+                        synchronized (mLock) {
+                            mDeviceIdleJobsController.setUidActiveLocked(uid, false);
+                        }
+                        break;
+                    }
+
                 }
                 maybeRunPendingJobsLocked();
                 // Don't remove JOB_EXPIRED in case one came along while processing the queue.
@@ -1601,11 +1631,11 @@
         }
     }
 
-    final class ReadyJobQueueFunctor implements JobStatusFunctor {
+    final class ReadyJobQueueFunctor implements Consumer<JobStatus> {
         ArrayList<JobStatus> newReadyJobs;
 
         @Override
-        public void process(JobStatus job) {
+        public void accept(JobStatus job) {
             if (isReadyToBeExecutedLocked(job)) {
                 if (DEBUG) {
                     Slog.d(TAG, "    queued " + job.toShortString());
@@ -1639,7 +1669,7 @@
      * If more than 4 jobs total are ready we send them all off.
      * TODO: It would be nice to consolidate these sort of high-level policies somewhere.
      */
-    final class MaybeReadyJobQueueFunctor implements JobStatusFunctor {
+    final class MaybeReadyJobQueueFunctor implements Consumer<JobStatus> {
         int chargingCount;
         int batteryNotLowCount;
         int storageNotLowCount;
@@ -1655,7 +1685,7 @@
 
         // Functor method invoked for each job via JobStore.forEachJob()
         @Override
-        public void process(JobStatus job) {
+        public void accept(JobStatus job) {
             if (isReadyToBeExecutedLocked(job)) {
                 try {
                     if (ActivityManager.getService().isAppStartModeDisabled(job.getUid(),
@@ -2172,12 +2202,9 @@
         public List<JobInfo> getSystemScheduledPendingJobs() {
             synchronized (mLock) {
                 final List<JobInfo> pendingJobs = new ArrayList<JobInfo>();
-                mJobs.forEachJob(Process.SYSTEM_UID, new JobStatusFunctor() {
-                    @Override
-                    public void process(JobStatus job) {
-                        if (job.getJob().isPeriodic() || !isCurrentlyActiveLocked(job)) {
-                            pendingJobs.add(job.getJob());
-                        }
+                mJobs.forEachJob(Process.SYSTEM_UID, (job) -> {
+                    if (job.getJob().isPeriodic() || !isCurrentlyActiveLocked(job)) {
+                        pendingJobs.add(job.getJob());
                     }
                 });
                 return pendingJobs;
@@ -2243,7 +2270,7 @@
 
         @Override
         public void onAppIdleStateChanged(final String packageName, final @UserIdInt int userId,
-                boolean idle, int bucket) {
+                boolean idle, int bucket, int reason) {
             final int uid = mLocalPM.getPackageUid(packageName,
                     PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
             if (uid < 0) {
@@ -2306,7 +2333,7 @@
         }
     }
 
-    static class DeferredJobCounter implements JobStatusFunctor {
+    static class DeferredJobCounter implements Consumer<JobStatus> {
         private int mDeferred = 0;
 
         public int numDeferred() {
@@ -2314,7 +2341,7 @@
         }
 
         @Override
-        public void process(JobStatus job) {
+        public void accept(JobStatus job) {
             if (job.getWhenStandbyDeferred() > 0) {
                 mDeferred++;
             }
@@ -2595,12 +2622,13 @@
                 }
             }
 
-            long identityToken = Binder.clearCallingIdentity();
+            final long identityToken = Binder.clearCallingIdentity();
             try {
                 if (proto) {
                     JobSchedulerService.this.dumpInternalProto(fd, filterUid);
                 } else {
-                    JobSchedulerService.this.dumpInternal(pw, filterUid);
+                    JobSchedulerService.this.dumpInternal(new IndentingPrintWriter(pw, "  "),
+                            filterUid);
                 }
             } finally {
                 Binder.restoreCallingIdentity(identityToken);
@@ -2899,13 +2927,34 @@
         });
     }
 
-    void dumpInternal(final PrintWriter pw, int filterUid) {
+    void dumpInternal(final IndentingPrintWriter pw, int filterUid) {
         final int filterUidFinal = UserHandle.getAppId(filterUid);
         final long nowElapsed = sElapsedRealtimeClock.millis();
         final long nowUptime = sUptimeMillisClock.millis();
+        final Predicate<JobStatus> predicate = (js) -> {
+            return filterUidFinal == -1 || UserHandle.getAppId(js.getUid()) == filterUidFinal
+                    || UserHandle.getAppId(js.getSourceUid()) == filterUidFinal;
+        };
         synchronized (mLock) {
             mConstants.dump(pw);
             pw.println();
+
+            pw.println("  Heartbeat:");
+            pw.print("    Current:    "); pw.println(mHeartbeat);
+            pw.println("    Next");
+            pw.print("      ACTIVE:   "); pw.println(mNextBucketHeartbeat[0]);
+            pw.print("      WORKING:  "); pw.println(mNextBucketHeartbeat[1]);
+            pw.print("      FREQUENT: "); pw.println(mNextBucketHeartbeat[2]);
+            pw.print("      RARE:     "); pw.println(mNextBucketHeartbeat[3]);
+            pw.print("    Last heartbeat: ");
+            TimeUtils.formatDuration(mLastHeartbeatTime, nowElapsed, pw);
+            pw.println();
+            pw.print("    Next heartbeat: ");
+            TimeUtils.formatDuration(mLastHeartbeatTime + mConstants.STANDBY_HEARTBEAT_TIME,
+                    nowElapsed, pw);
+            pw.println();
+            pw.println();
+
             pw.println("Started users: " + Arrays.toString(mStartedUsers));
             pw.print("Registered ");
             pw.print(mJobs.size());
@@ -2918,11 +2967,15 @@
                     pw.println(job.toShortStringExceptUniqueId());
 
                     // Skip printing details if the caller requested a filter
-                    if (!job.shouldDump(filterUidFinal)) {
+                    if (!predicate.test(job)) {
                         continue;
                     }
 
                     job.dump(pw, "    ", true, nowElapsed);
+                    pw.print("    Last run heartbeat: ");
+                    pw.print(heartbeatWhenJobsLastRun(job));
+                    pw.println();
+
                     pw.print("    Ready: ");
                     pw.print(isReadyToBeExecutedLocked(job));
                     pw.print(" (job=");
@@ -2952,7 +3005,10 @@
             }
             for (int i=0; i<mControllers.size(); i++) {
                 pw.println();
-                mControllers.get(i).dumpControllerStateLocked(pw, filterUidFinal);
+                pw.println(mControllers.get(i).getClass().getSimpleName() + ":");
+                pw.increaseIndent();
+                mControllers.get(i).dumpControllerStateLocked(pw, predicate);
+                pw.decreaseIndent();
             }
             pw.println();
             pw.println("Uid priority overrides:");
@@ -3055,9 +3111,23 @@
         final int filterUidFinal = UserHandle.getAppId(filterUid);
         final long nowElapsed = sElapsedRealtimeClock.millis();
         final long nowUptime = sUptimeMillisClock.millis();
+        final Predicate<JobStatus> predicate = (js) -> {
+            return filterUidFinal == -1 || UserHandle.getAppId(js.getUid()) == filterUidFinal
+                    || UserHandle.getAppId(js.getSourceUid()) == filterUidFinal;
+        };
 
         synchronized (mLock) {
             mConstants.dump(proto, JobSchedulerServiceDumpProto.SETTINGS);
+            proto.write(JobSchedulerServiceDumpProto.CURRENT_HEARTBEAT, mHeartbeat);
+            proto.write(JobSchedulerServiceDumpProto.NEXT_HEARTBEAT, mNextBucketHeartbeat[0]);
+            proto.write(JobSchedulerServiceDumpProto.NEXT_HEARTBEAT, mNextBucketHeartbeat[1]);
+            proto.write(JobSchedulerServiceDumpProto.NEXT_HEARTBEAT, mNextBucketHeartbeat[2]);
+            proto.write(JobSchedulerServiceDumpProto.NEXT_HEARTBEAT, mNextBucketHeartbeat[3]);
+            proto.write(JobSchedulerServiceDumpProto.LAST_HEARTBEAT_TIME_MILLIS,
+                    mLastHeartbeatTime - nowUptime);
+            proto.write(JobSchedulerServiceDumpProto.NEXT_HEARTBEAT_TIME_MILLIS,
+                    mLastHeartbeatTime + mConstants.STANDBY_HEARTBEAT_TIME - nowUptime);
+
             for (int u : mStartedUsers) {
                 proto.write(JobSchedulerServiceDumpProto.STARTED_USERS, u);
             }
@@ -3069,7 +3139,7 @@
                     job.writeToShortProto(proto, JobSchedulerServiceDumpProto.RegisteredJob.INFO);
 
                     // Skip printing details if the caller requested a filter
-                    if (!job.shouldDump(filterUidFinal)) {
+                    if (!predicate.test(job)) {
                         continue;
                     }
 
@@ -3096,13 +3166,14 @@
                     }
                     proto.write(JobSchedulerServiceDumpProto.RegisteredJob.IS_COMPONENT_PRESENT,
                             componentPresent);
+                    proto.write(RegisteredJob.LAST_RUN_HEARTBEAT, heartbeatWhenJobsLastRun(job));
 
                     proto.end(rjToken);
                 }
             }
             for (StateController controller : mControllers) {
                 controller.dumpControllerStateLocked(
-                        proto, JobSchedulerServiceDumpProto.CONTROLLERS, filterUidFinal);
+                        proto, JobSchedulerServiceDumpProto.CONTROLLERS, predicate);
             }
             for (int i=0; i< mUidPriorityOverride.size(); i++) {
                 int uid = mUidPriorityOverride.keyAt(i);
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index cf27882..7235faa 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -19,6 +19,7 @@
 import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
 import static com.android.server.job.JobSchedulerService.sSystemClock;
 
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.IActivityManager;
 import android.app.job.JobInfo;
@@ -62,6 +63,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
+import java.util.function.Consumer;
 import java.util.function.Predicate;
 
 /**
@@ -286,22 +288,23 @@
      * transient unified collections for them to iterate over and then discard, or creating
      * iterators every time a client needs to perform a sweep.
      */
-    public void forEachJob(JobStatusFunctor functor) {
-        mJobSet.forEachJob(functor);
+    public void forEachJob(Consumer<JobStatus> functor) {
+        mJobSet.forEachJob(null, functor);
     }
 
-    public void forEachJob(int uid, JobStatusFunctor functor) {
+    public void forEachJob(@Nullable Predicate<JobStatus> filterPredicate,
+            Consumer<JobStatus> functor) {
+        mJobSet.forEachJob(filterPredicate, functor);
+    }
+
+    public void forEachJob(int uid, Consumer<JobStatus> functor) {
         mJobSet.forEachJob(uid, functor);
     }
 
-    public void forEachJobForSourceUid(int sourceUid, JobStatusFunctor functor) {
+    public void forEachJobForSourceUid(int sourceUid, Consumer<JobStatus> functor) {
         mJobSet.forEachJobForSourceUid(sourceUid, functor);
     }
 
-    public interface JobStatusFunctor {
-        public void process(JobStatus jobStatus);
-    }
-
     /** Version of the db schema. */
     private static final int JOBS_FILE_VERSION = 0;
     /** Tag corresponds to constraints this job needs. */
@@ -342,12 +345,9 @@
             final List<JobStatus> storeCopy = new ArrayList<JobStatus>();
             synchronized (mLock) {
                 // Clone the jobs so we can release the lock before writing.
-                mJobSet.forEachJob(new JobStatusFunctor() {
-                    @Override
-                    public void process(JobStatus job) {
-                        if (job.isPersisted()) {
-                            storeCopy.add(new JobStatus(job));
-                        }
+                mJobSet.forEachJob(null, (job) -> {
+                    if (job.isPersisted()) {
+                        storeCopy.add(new JobStatus(job));
                     }
                 });
             }
@@ -1184,31 +1184,35 @@
             return total;
         }
 
-        public void forEachJob(JobStatusFunctor functor) {
+        public void forEachJob(@Nullable Predicate<JobStatus> filterPredicate,
+                Consumer<JobStatus> functor) {
             for (int uidIndex = mJobs.size() - 1; uidIndex >= 0; uidIndex--) {
                 ArraySet<JobStatus> jobs = mJobs.valueAt(uidIndex);
                 if (jobs != null) {
                     for (int i = jobs.size() - 1; i >= 0; i--) {
-                        functor.process(jobs.valueAt(i));
+                        final JobStatus jobStatus = jobs.valueAt(i);
+                        if ((filterPredicate == null) || filterPredicate.test(jobStatus)) {
+                            functor.accept(jobStatus);
+                        }
                     }
                 }
             }
         }
 
-        public void forEachJob(int callingUid, JobStatusFunctor functor) {
+        public void forEachJob(int callingUid, Consumer<JobStatus> functor) {
             ArraySet<JobStatus> jobs = mJobs.get(callingUid);
             if (jobs != null) {
                 for (int i = jobs.size() - 1; i >= 0; i--) {
-                    functor.process(jobs.valueAt(i));
+                    functor.accept(jobs.valueAt(i));
                 }
             }
         }
 
-        public void forEachJobForSourceUid(int sourceUid, JobStatusFunctor functor) {
+        public void forEachJobForSourceUid(int sourceUid, Consumer<JobStatus> functor) {
             final ArraySet<JobStatus> jobs = mJobsPerSourceUid.get(sourceUid);
             if (jobs != null) {
                 for (int i = jobs.size() - 1; i >= 0; i--) {
-                    functor.process(jobs.valueAt(i));
+                    functor.accept(jobs.valueAt(i));
                 }
             }
         }
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 8d11d1e..ed29a4c 100644
--- a/services/core/java/com/android/server/job/controllers/AppIdleController.java
+++ b/services/core/java/com/android/server/job/controllers/AppIdleController.java
@@ -17,17 +17,18 @@
 package com.android.server.job.controllers;
 
 import android.app.usage.UsageStatsManagerInternal;
-import android.content.Context;
 import android.os.UserHandle;
+import android.util.Log;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.LocalServices;
 import com.android.server.job.JobSchedulerService;
-import com.android.server.job.JobStore;
 import com.android.server.job.StateControllerProto;
 
-import java.io.PrintWriter;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
 
 /**
  * Controls when apps are considered idle and if jobs pertaining to those apps should
@@ -36,35 +37,32 @@
  * out of idle state, it will be allowed to run scheduled jobs.
  */
 public final class AppIdleController extends StateController {
+    private static final String TAG = "JobScheduler.AppIdle";
+    private static final boolean DEBUG = JobSchedulerService.DEBUG
+            || Log.isLoggable(TAG, Log.DEBUG);
 
-    private static final String LOG_TAG = "AppIdleController";
-    private static final boolean DEBUG = false;
-
-    // Singleton factory
-    private static Object sCreationLock = new Object();
-    private static volatile AppIdleController sController;
-    private final JobSchedulerService mJobSchedulerService;
     private final UsageStatsManagerInternal mUsageStatsInternal;
     private boolean mInitializedParoleOn;
     boolean mAppIdleParoleOn;
 
-    final class GlobalUpdateFunc implements JobStore.JobStatusFunctor {
+    final class GlobalUpdateFunc implements Consumer<JobStatus> {
         boolean mChanged;
 
-        @Override public void process(JobStatus jobStatus) {
+        @Override
+        public void accept(JobStatus jobStatus) {
             String packageName = jobStatus.getSourcePackageName();
             final boolean appIdle = !mAppIdleParoleOn && mUsageStatsInternal.isAppIdle(packageName,
                     jobStatus.getSourceUid(), jobStatus.getSourceUserId());
             if (DEBUG) {
-                Slog.d(LOG_TAG, "Setting idle state of " + packageName + " to " + appIdle);
+                Slog.d(TAG, "Setting idle state of " + packageName + " to " + appIdle);
             }
             if (jobStatus.setAppNotIdleConstraintSatisfied(!appIdle)) {
                 mChanged = true;
             }
         }
-    };
+    }
 
-    final static class PackageUpdateFunc implements JobStore.JobStatusFunctor {
+    final static class PackageUpdateFunc implements Consumer<JobStatus> {
         final int mUserId;
         final String mPackage;
         final boolean mIdle;
@@ -76,33 +74,23 @@
             mIdle = idle;
         }
 
-        @Override public void process(JobStatus jobStatus) {
+        @Override
+        public void accept(JobStatus jobStatus) {
             if (jobStatus.getSourcePackageName().equals(mPackage)
                     && jobStatus.getSourceUserId() == mUserId) {
                 if (jobStatus.setAppNotIdleConstraintSatisfied(!mIdle)) {
                     if (DEBUG) {
-                        Slog.d(LOG_TAG, "App Idle state changed, setting idle state of "
+                        Slog.d(TAG, "App Idle state changed, setting idle state of "
                                 + mPackage + " to " + mIdle);
                     }
                     mChanged = true;
                 }
             }
         }
-    };
-
-    public static AppIdleController get(JobSchedulerService service) {
-        synchronized (sCreationLock) {
-            if (sController == null) {
-                sController = new AppIdleController(service, service.getContext(),
-                        service.getLock());
-            }
-            return sController;
-        }
     }
 
-    private AppIdleController(JobSchedulerService service, Context context, Object lock) {
-        super(service, context, lock);
-        mJobSchedulerService = service;
+    public AppIdleController(JobSchedulerService service) {
+        super(service);
         mUsageStatsInternal = LocalServices.getService(UsageStatsManagerInternal.class);
         mAppIdleParoleOn = true;
         mUsageStatsInternal.addAppIdleStateChangeListener(new AppIdleStateChangeListener());
@@ -118,7 +106,7 @@
         final boolean appIdle = !mAppIdleParoleOn && mUsageStatsInternal.isAppIdle(packageName,
                 jobStatus.getSourceUid(), jobStatus.getSourceUserId());
         if (DEBUG) {
-            Slog.d(LOG_TAG, "Start tracking, setting idle state of "
+            Slog.d(TAG, "Start tracking, setting idle state of "
                     + packageName + " to " + appIdle);
         }
         jobStatus.setAppNotIdleConstraintSatisfied(!appIdle);
@@ -130,56 +118,46 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(final PrintWriter pw, final int filterUid) {
-        pw.print("AppIdle: parole on = ");
-        pw.println(mAppIdleParoleOn);
-        mJobSchedulerService.getJobStore().forEachJob(new JobStore.JobStatusFunctor() {
-            @Override public void process(JobStatus jobStatus) {
-                // Skip printing details if the caller requested a filter
-                if (!jobStatus.shouldDump(filterUid)) {
-                    return;
-                }
-                pw.print("  #");
-                jobStatus.printUniqueId(pw);
-                pw.print(" from ");
-                UserHandle.formatUid(pw, jobStatus.getSourceUid());
-                pw.print(": ");
-                pw.print(jobStatus.getSourcePackageName());
-                if ((jobStatus.satisfiedConstraints&JobStatus.CONSTRAINT_APP_NOT_IDLE) != 0) {
-                    pw.println(" RUNNABLE");
-                } else {
-                    pw.println(" WAITING");
-                }
+    public void dumpControllerStateLocked(final IndentingPrintWriter pw,
+            final Predicate<JobStatus> predicate) {
+        pw.println("Parole on: " + mAppIdleParoleOn);
+        pw.println();
+
+        mService.getJobStore().forEachJob(predicate, (jobStatus) -> {
+            pw.print("#");
+            jobStatus.printUniqueId(pw);
+            pw.print(" from ");
+            UserHandle.formatUid(pw, jobStatus.getSourceUid());
+            pw.print(": ");
+            pw.print(jobStatus.getSourcePackageName());
+            if ((jobStatus.satisfiedConstraints&JobStatus.CONSTRAINT_APP_NOT_IDLE) != 0) {
+                pw.println(" RUNNABLE");
+            } else {
+                pw.println(" WAITING");
             }
         });
     }
 
     @Override
-    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
+            Predicate<JobStatus> predicate) {
         final long token = proto.start(fieldId);
         final long mToken = proto.start(StateControllerProto.APP_IDLE);
 
         proto.write(StateControllerProto.AppIdleController.IS_PAROLE_ON, mAppIdleParoleOn);
 
-        mJobSchedulerService.getJobStore().forEachJob(new JobStore.JobStatusFunctor() {
-            @Override public void process(JobStatus js) {
-                // Skip printing details if the caller requested a filter
-                if (!js.shouldDump(filterUid)) {
-                    return;
-                }
-
-                final long jsToken =
-                        proto.start(StateControllerProto.AppIdleController.TRACKED_JOBS);
-                js.writeToShortProto(proto, StateControllerProto.AppIdleController.TrackedJob.INFO);
-                proto.write(StateControllerProto.AppIdleController.TrackedJob.SOURCE_UID,
-                        js.getSourceUid());
-                proto.write(StateControllerProto.AppIdleController.TrackedJob.SOURCE_PACKAGE_NAME,
-                        js.getSourcePackageName());
-                proto.write(
-                        StateControllerProto.AppIdleController.TrackedJob.ARE_CONSTRAINTS_SATISFIED,
-                        (js.satisfiedConstraints & JobStatus.CONSTRAINT_APP_NOT_IDLE) != 0);
-                proto.end(jsToken);
-            }
+        mService.getJobStore().forEachJob(predicate, (js) -> {
+            final long jsToken =
+                    proto.start(StateControllerProto.AppIdleController.TRACKED_JOBS);
+            js.writeToShortProto(proto, StateControllerProto.AppIdleController.TrackedJob.INFO);
+            proto.write(StateControllerProto.AppIdleController.TrackedJob.SOURCE_UID,
+                    js.getSourceUid());
+            proto.write(StateControllerProto.AppIdleController.TrackedJob.SOURCE_PACKAGE_NAME,
+                    js.getSourcePackageName());
+            proto.write(
+                    StateControllerProto.AppIdleController.TrackedJob.ARE_CONSTRAINTS_SATISFIED,
+                    (js.satisfiedConstraints & JobStatus.CONSTRAINT_APP_NOT_IDLE) != 0);
+            proto.end(jsToken);
         });
 
         proto.end(mToken);
@@ -195,7 +173,7 @@
             }
             mAppIdleParoleOn = isAppIdleParoleOn;
             GlobalUpdateFunc update = new GlobalUpdateFunc();
-            mJobSchedulerService.getJobStore().forEachJob(update);
+            mService.getJobStore().forEachJob(update);
             if (update.mChanged) {
                 changed = true;
             }
@@ -208,7 +186,8 @@
     private final class AppIdleStateChangeListener
             extends UsageStatsManagerInternal.AppIdleStateChangeListener {
         @Override
-        public void onAppIdleStateChanged(String packageName, int userId, boolean idle, int bucket) {
+        public void onAppIdleStateChanged(String packageName, int userId, boolean idle, int bucket,
+                int reason) {
             boolean changed = false;
             synchronized (mLock) {
                 if (mAppIdleParoleOn) {
@@ -216,7 +195,7 @@
                 }
 
                 PackageUpdateFunc update = new PackageUpdateFunc(userId, packageName, idle);
-                mJobSchedulerService.getJobStore().forEachJob(update);
+                mService.getJobStore().forEachJob(update);
                 if (update.mChanged) {
                     changed = true;
                 }
@@ -229,7 +208,7 @@
         @Override
         public void onParoleStateChanged(boolean isParoleOn) {
             if (DEBUG) {
-                Slog.d(LOG_TAG, "Parole on: " + isParoleOn);
+                Slog.d(TAG, "Parole on: " + isParoleOn);
             }
             setAppIdleParoleOn(isParoleOn);
         }
diff --git a/services/core/java/com/android/server/job/controllers/BackgroundJobsController.java b/services/core/java/com/android/server/job/controllers/BackgroundJobsController.java
index e8057fb..36e75115 100644
--- a/services/core/java/com/android/server/job/controllers/BackgroundJobsController.java
+++ b/services/core/java/com/android/server/job/controllers/BackgroundJobsController.java
@@ -16,49 +16,33 @@
 
 package com.android.server.job.controllers;
 
-import android.content.Context;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.util.Log;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
 import com.android.server.AppStateTracker;
 import com.android.server.AppStateTracker.Listener;
 import com.android.server.LocalServices;
 import com.android.server.job.JobSchedulerService;
-import com.android.server.job.JobStore;
 import com.android.server.job.StateControllerProto;
 import com.android.server.job.StateControllerProto.BackgroundJobsController.TrackedJob;
 
-import java.io.PrintWriter;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
 
 public final class BackgroundJobsController extends StateController {
-
-    private static final String LOG_TAG = "BackgroundJobsController";
-    private static final boolean DEBUG = JobSchedulerService.DEBUG;
-
-    // Singleton factory
-    private static final Object sCreationLock = new Object();
-    private static volatile BackgroundJobsController sController;
-
-    private final JobSchedulerService mJobSchedulerService;
+    private static final String TAG = "JobScheduler.Background";
+    private static final boolean DEBUG = JobSchedulerService.DEBUG
+            || Log.isLoggable(TAG, Log.DEBUG);
 
     private final AppStateTracker mAppStateTracker;
 
-    public static BackgroundJobsController get(JobSchedulerService service) {
-        synchronized (sCreationLock) {
-            if (sController == null) {
-                sController = new BackgroundJobsController(service, service.getContext(),
-                        service.getLock());
-            }
-            return sController;
-        }
-    }
-
-    private BackgroundJobsController(JobSchedulerService service, Context context, Object lock) {
-        super(service, context, lock);
-        mJobSchedulerService = service;
+    public BackgroundJobsController(JobSchedulerService service) {
+        super(service);
 
         mAppStateTracker = Preconditions.checkNotNull(
                 LocalServices.getService(AppStateTracker.class));
@@ -76,19 +60,15 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(final PrintWriter pw, final int filterUid) {
-        pw.println("BackgroundJobsController");
+    public void dumpControllerStateLocked(final IndentingPrintWriter pw,
+            final Predicate<JobStatus> predicate) {
+        mAppStateTracker.dump(pw);
+        pw.println();
 
-        mAppStateTracker.dump(pw, "");
-
-        pw.println("Job state:");
-        mJobSchedulerService.getJobStore().forEachJob((jobStatus) -> {
-            if (!jobStatus.shouldDump(filterUid)) {
-                return;
-            }
+        mService.getJobStore().forEachJob(predicate, (jobStatus) -> {
             final int uid = jobStatus.getSourceUid();
             final String sourcePkg = jobStatus.getSourcePackageName();
-            pw.print("  #");
+            pw.print("#");
             jobStatus.printUniqueId(pw);
             pw.print(" from ");
             UserHandle.formatUid(pw, uid);
@@ -114,17 +94,15 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
+            Predicate<JobStatus> predicate) {
         final long token = proto.start(fieldId);
         final long mToken = proto.start(StateControllerProto.BACKGROUND);
 
         mAppStateTracker.dumpProto(proto,
                 StateControllerProto.BackgroundJobsController.FORCE_APP_STANDBY_TRACKER);
 
-        mJobSchedulerService.getJobStore().forEachJob((jobStatus) -> {
-            if (!jobStatus.shouldDump(filterUid)) {
-                return;
-            }
+        mService.getJobStore().forEachJob(predicate, (jobStatus) -> {
             final long jsToken =
                     proto.start(StateControllerProto.BackgroundJobsController.TRACKED_JOBS);
 
@@ -175,11 +153,11 @@
 
         final long start = DEBUG ? SystemClock.elapsedRealtimeNanos() : 0;
 
-        mJobSchedulerService.getJobStore().forEachJob(updateTrackedJobs);
+        mService.getJobStore().forEachJob(updateTrackedJobs);
 
         final long time = DEBUG ? (SystemClock.elapsedRealtimeNanos() - start) : 0;
         if (DEBUG) {
-            Slog.d(LOG_TAG, String.format(
+            Slog.d(TAG, String.format(
                     "Job status updated: %d/%d checked/total jobs, %d us",
                     updateTrackedJobs.mCheckedCount,
                     updateTrackedJobs.mTotalCount,
@@ -204,7 +182,7 @@
         return jobStatus.setBackgroundNotRestrictedConstraintSatisfied(canRun);
     }
 
-    private final class UpdateJobFunctor implements JobStore.JobStatusFunctor {
+    private final class UpdateJobFunctor implements Consumer<JobStatus> {
         private final int mFilterUid;
 
         boolean mChanged = false;
@@ -216,7 +194,7 @@
         }
 
         @Override
-        public void process(JobStatus jobStatus) {
+        public void accept(JobStatus jobStatus) {
             mTotalCount++;
             if ((mFilterUid > 0) && (mFilterUid != jobStatus.getSourceUid())) {
                 return;
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 8d3d116..46658ad 100644
--- a/services/core/java/com/android/server/job/controllers/BatteryController.java
+++ b/services/core/java/com/android/server/job/controllers/BatteryController.java
@@ -26,16 +26,17 @@
 import android.os.BatteryManagerInternal;
 import android.os.UserHandle;
 import android.util.ArraySet;
+import android.util.Log;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.LocalServices;
 import com.android.server.job.JobSchedulerService;
-import com.android.server.job.StateChangedListener;
 import com.android.server.job.StateControllerProto;
 
-import java.io.PrintWriter;
+import java.util.function.Predicate;
 
 /**
  * Simple controller that tracks whether the phone is charging or not. The phone is considered to
@@ -43,38 +44,20 @@
  * ACTION_BATTERY_OK.
  */
 public final class BatteryController extends StateController {
-    private static final String TAG = "JobScheduler.Batt";
-
-    private static final Object sCreationLock = new Object();
-    private static volatile BatteryController sController;
+    private static final String TAG = "JobScheduler.Battery";
+    private static final boolean DEBUG = JobSchedulerService.DEBUG
+            || Log.isLoggable(TAG, Log.DEBUG);
 
     private final ArraySet<JobStatus> mTrackedTasks = new ArraySet<>();
     private ChargingTracker mChargeTracker;
 
-    public static BatteryController get(JobSchedulerService taskManagerService) {
-        synchronized (sCreationLock) {
-            if (sController == null) {
-                sController = new BatteryController(taskManagerService,
-                        taskManagerService.getContext(), taskManagerService.getLock());
-            }
-        }
-        return sController;
-    }
-
     @VisibleForTesting
     public ChargingTracker getTracker() {
         return mChargeTracker;
     }
 
-    @VisibleForTesting
-    public static BatteryController getForTesting(StateChangedListener stateChangedListener,
-                                           Context context) {
-        return new BatteryController(stateChangedListener, context, new Object());
-    }
-
-    private BatteryController(StateChangedListener stateChangedListener, Context context,
-            Object lock) {
-        super(stateChangedListener, context, lock);
+    public BatteryController(JobSchedulerService service) {
+        super(service);
         mChargeTracker = new ChargingTracker();
         mChargeTracker.startTracking();
     }
@@ -241,24 +224,23 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
-        pw.print("Battery: stable power = ");
-        pw.print(mChargeTracker.isOnStablePower());
-        pw.print(", not low = ");
-        pw.println(mChargeTracker.isBatteryNotLow());
+    public void dumpControllerStateLocked(IndentingPrintWriter pw,
+            Predicate<JobStatus> predicate) {
+        pw.println("Stable power: " + mChargeTracker.isOnStablePower());
+        pw.println("Not low: " + mChargeTracker.isBatteryNotLow());
+
         if (mChargeTracker.isMonitoring()) {
             pw.print("MONITORING: seq=");
             pw.println(mChargeTracker.getSeq());
         }
-        pw.print("Tracking ");
-        pw.print(mTrackedTasks.size());
-        pw.println(":");
+        pw.println();
+
         for (int i = 0; i < mTrackedTasks.size(); i++) {
             final JobStatus js = mTrackedTasks.valueAt(i);
-            if (!js.shouldDump(filterUid)) {
+            if (!predicate.test(js)) {
                 continue;
             }
-            pw.print("  #");
+            pw.print("#");
             js.printUniqueId(pw);
             pw.print(" from ");
             UserHandle.formatUid(pw, js.getSourceUid());
@@ -267,7 +249,8 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
+            Predicate<JobStatus> predicate) {
         final long token = proto.start(fieldId);
         final long mToken = proto.start(StateControllerProto.BATTERY);
 
@@ -283,7 +266,7 @@
 
         for (int i = 0; i < mTrackedTasks.size(); i++) {
             final JobStatus js = mTrackedTasks.valueAt(i);
-            if (!js.shouldDump(filterUid)) {
+            if (!predicate.test(js)) {
                 continue;
             }
             final long jsToken = proto.start(StateControllerProto.BatteryController.TRACKED_JOBS);
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 77e813e..abe55bb 100644
--- a/services/core/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
@@ -21,7 +21,6 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
 
 import android.app.job.JobInfo;
-import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
 import android.net.INetworkPolicyListener;
@@ -35,17 +34,19 @@
 import android.os.UserHandle;
 import android.text.format.DateUtils;
 import android.util.ArraySet;
+import android.util.Log;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.job.JobSchedulerService;
+import com.android.server.job.JobSchedulerService.Constants;
 import com.android.server.job.JobServiceContext;
-import com.android.server.job.StateChangedListener;
 import com.android.server.job.StateControllerProto;
 
-import java.io.PrintWriter;
+import java.util.function.Predicate;
 
 /**
  * Handles changes in connectivity.
@@ -56,8 +57,9 @@
  */
 public final class ConnectivityController extends StateController implements
         ConnectivityManager.OnNetworkActiveListener {
-    private static final String TAG = "JobScheduler.Conn";
-    private static final boolean DEBUG = false;
+    private static final String TAG = "JobScheduler.Connectivity";
+    private static final boolean DEBUG = JobSchedulerService.DEBUG
+            || Log.isLoggable(TAG, Log.DEBUG);
 
     private final ConnectivityManager mConnManager;
     private final NetworkPolicyManager mNetPolicyManager;
@@ -66,22 +68,8 @@
     @GuardedBy("mLock")
     private final ArraySet<JobStatus> mTrackedJobs = new ArraySet<>();
 
-    /** Singleton. */
-    private static ConnectivityController sSingleton;
-    private static Object sCreationLock = new Object();
-
-    public static ConnectivityController get(JobSchedulerService jms) {
-        synchronized (sCreationLock) {
-            if (sSingleton == null) {
-                sSingleton = new ConnectivityController(jms, jms.getContext(), jms.getLock());
-            }
-            return sSingleton;
-        }
-    }
-
-    private ConnectivityController(StateChangedListener stateChangedListener, Context context,
-            Object lock) {
-        super(stateChangedListener, context, lock);
+    public ConnectivityController(JobSchedulerService service) {
+        super(service);
 
         mConnManager = mContext.getSystemService(ConnectivityManager.class);
         mNetPolicyManager = mContext.getSystemService(NetworkPolicyManager.class);
@@ -120,7 +108,7 @@
      */
     @SuppressWarnings("unused")
     private static boolean isInsane(JobStatus jobStatus, Network network,
-            NetworkCapabilities capabilities) {
+            NetworkCapabilities capabilities, Constants constants) {
         final long estimatedBytes = jobStatus.getEstimatedNetworkBytes();
         if (estimatedBytes == JobInfo.NETWORK_BYTES_UNKNOWN) {
             // We don't know how large the job is; cross our fingers!
@@ -151,11 +139,11 @@
 
     @SuppressWarnings("unused")
     private static boolean isCongestionDelayed(JobStatus jobStatus, Network network,
-            NetworkCapabilities capabilities) {
+            NetworkCapabilities capabilities, Constants constants) {
         // If network is congested, and job is less than 50% through the
         // developer-requested window, then we're okay delaying the job.
         if (!capabilities.hasCapability(NET_CAPABILITY_NOT_CONGESTED)) {
-            return jobStatus.getFractionRunTime() < 0.5;
+            return jobStatus.getFractionRunTime() < constants.CONN_CONGESTION_DELAY_FRAC;
         } else {
             return false;
         }
@@ -163,14 +151,14 @@
 
     @SuppressWarnings("unused")
     private static boolean isStrictSatisfied(JobStatus jobStatus, Network network,
-            NetworkCapabilities capabilities) {
+            NetworkCapabilities capabilities, Constants constants) {
         return jobStatus.getJob().getRequiredNetwork().networkCapabilities
                 .satisfiedByNetworkCapabilities(capabilities);
     }
 
     @SuppressWarnings("unused")
     private static boolean isRelaxedSatisfied(JobStatus jobStatus, Network network,
-            NetworkCapabilities capabilities) {
+            NetworkCapabilities capabilities, Constants constants) {
         // Only consider doing this for prefetching jobs
         if ((jobStatus.getJob().getFlags() & JobInfo.FLAG_IS_PREFETCH) == 0) {
             return false;
@@ -182,7 +170,7 @@
                         .removeCapability(NET_CAPABILITY_NOT_METERED);
         if (relaxed.satisfiedByNetworkCapabilities(capabilities)) {
             // TODO: treat this as "maybe" response; need to check quotas
-            return jobStatus.getFractionRunTime() > 0.5;
+            return jobStatus.getFractionRunTime() > constants.CONN_PREFETCH_RELAX_FRAC;
         } else {
             return false;
         }
@@ -190,21 +178,21 @@
 
     @VisibleForTesting
     static boolean isSatisfied(JobStatus jobStatus, Network network,
-            NetworkCapabilities capabilities) {
+            NetworkCapabilities capabilities, Constants constants) {
         // Zeroth, we gotta have a network to think about being satisfied
         if (network == null || capabilities == null) return false;
 
         // First, are we insane?
-        if (isInsane(jobStatus, network, capabilities)) return false;
+        if (isInsane(jobStatus, network, capabilities, constants)) return false;
 
         // Second, is the network congested?
-        if (isCongestionDelayed(jobStatus, network, capabilities)) return false;
+        if (isCongestionDelayed(jobStatus, network, capabilities, constants)) return false;
 
         // Third, is the network a strict match?
-        if (isStrictSatisfied(jobStatus, network, capabilities)) return true;
+        if (isStrictSatisfied(jobStatus, network, capabilities, constants)) return true;
 
         // Third, is the network a relaxed match?
-        if (isRelaxedSatisfied(jobStatus, network, capabilities)) return true;
+        if (isRelaxedSatisfied(jobStatus, network, capabilities, constants)) return true;
 
         return false;
     }
@@ -220,7 +208,7 @@
         final NetworkCapabilities capabilities = mConnManager.getNetworkCapabilities(network);
 
         final boolean connected = (info != null) && info.isConnected();
-        final boolean satisfied = isSatisfied(jobStatus, network, capabilities);
+        final boolean satisfied = isSatisfied(jobStatus, network, capabilities, mConstants);
 
         final boolean changed = jobStatus
                 .setConnectivityConstraintSatisfied(connected && satisfied);
@@ -329,18 +317,15 @@
 
     @GuardedBy("mLock")
     @Override
-    public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
-        pw.print("Connectivity: connected=");
-        pw.println(mConnected);
-
-        pw.print("Tracking ");
-        pw.print(mTrackedJobs.size());
-        pw.println(" jobs");
+    public void dumpControllerStateLocked(IndentingPrintWriter pw,
+            Predicate<JobStatus> predicate) {
+        pw.println("System connected: " + mConnected);
+        pw.println();
 
         for (int i = 0; i < mTrackedJobs.size(); i++) {
             final JobStatus js = mTrackedJobs.valueAt(i);
-            if (js.shouldDump(filterUid)) {
-                pw.print("  #");
+            if (predicate.test(js)) {
+                pw.print("#");
                 js.printUniqueId(pw);
                 pw.print(" from ");
                 UserHandle.formatUid(pw, js.getSourceUid());
@@ -353,7 +338,8 @@
 
     @GuardedBy("mLock")
     @Override
-    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
+            Predicate<JobStatus> predicate) {
         final long token = proto.start(fieldId);
         final long mToken = proto.start(StateControllerProto.CONNECTIVITY);
 
@@ -361,7 +347,7 @@
 
         for (int i = 0; i < mTrackedJobs.size(); i++) {
             final JobStatus js = mTrackedJobs.valueAt(i);
-            if (!js.shouldDump(filterUid)) {
+            if (!predicate.test(js)) {
                 continue;
             }
             final long jsToken = proto.start(StateControllerProto.ConnectivityController.TRACKED_JOBS);
diff --git a/services/core/java/com/android/server/job/controllers/ContentObserverController.java b/services/core/java/com/android/server/job/controllers/ContentObserverController.java
index 7394e23f..a775cf5 100644
--- a/services/core/java/com/android/server/job/controllers/ContentObserverController.java
+++ b/services/core/java/com/android/server/job/controllers/ContentObserverController.java
@@ -18,33 +18,33 @@
 
 import android.annotation.UserIdInt;
 import android.app.job.JobInfo;
-import android.content.Context;
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.UserHandle;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.TimeUtils;
-import android.util.ArrayMap;
-import android.util.ArraySet;
 import android.util.proto.ProtoOutputStream;
 
-import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.job.JobSchedulerService;
-import com.android.server.job.StateChangedListener;
 import com.android.server.job.StateControllerProto;
 import com.android.server.job.StateControllerProto.ContentObserverController.Observer.TriggerContentData;
 
-import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.function.Predicate;
 
 /**
  * Controller for monitoring changes to content URIs through a ContentObserver.
  */
 public final class ContentObserverController extends StateController {
-    private static final String TAG = "JobScheduler.Content";
-    private static final boolean DEBUG = false;
+    private static final String TAG = "JobScheduler.ContentObserver";
+    private static final boolean DEBUG = JobSchedulerService.DEBUG
+            || Log.isLoggable(TAG, Log.DEBUG);
 
     /**
      * Maximum number of changing URIs we will batch together to report.
@@ -58,9 +58,6 @@
      */
     private static final int URIS_URGENT_THRESHOLD = 40;
 
-    private static final Object sCreationLock = new Object();
-    private static volatile ContentObserverController sController;
-
     final private ArraySet<JobStatus> mTrackedTasks = new ArraySet<>();
     /**
      * Per-userid {@link JobInfo.TriggerContentUri} keyed ContentObserver cache.
@@ -69,26 +66,9 @@
             new SparseArray<>();
     final Handler mHandler;
 
-    public static ContentObserverController get(JobSchedulerService taskManagerService) {
-        synchronized (sCreationLock) {
-            if (sController == null) {
-                sController = new ContentObserverController(taskManagerService,
-                        taskManagerService.getContext(), taskManagerService.getLock());
-            }
-        }
-        return sController;
-    }
-
-    @VisibleForTesting
-    public static ContentObserverController getForTesting(StateChangedListener stateChangedListener,
-                                           Context context) {
-        return new ContentObserverController(stateChangedListener, context, new Object());
-    }
-
-    private ContentObserverController(StateChangedListener stateChangedListener, Context context,
-                Object lock) {
-        super(stateChangedListener, context, lock);
-        mHandler = new Handler(context.getMainLooper());
+    public ContentObserverController(JobSchedulerService service) {
+        super(service);
+        mHandler = new Handler(mContext.getMainLooper());
     }
 
     @Override
@@ -373,22 +353,25 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
-        pw.println("Content:");
+    public void dumpControllerStateLocked(IndentingPrintWriter pw,
+            Predicate<JobStatus> predicate) {
         for (int i = 0; i < mTrackedTasks.size(); i++) {
             JobStatus js = mTrackedTasks.valueAt(i);
-            if (!js.shouldDump(filterUid)) {
+            if (!predicate.test(js)) {
                 continue;
             }
-            pw.print("  #");
+            pw.print("#");
             js.printUniqueId(pw);
             pw.print(" from ");
             UserHandle.formatUid(pw, js.getSourceUid());
             pw.println();
         }
+        pw.println();
+
         int N = mObservers.size();
         if (N > 0) {
-            pw.println("  Observers:");
+            pw.println("Observers:");
+            pw.increaseIndent();
             for (int userIdx = 0; userIdx < N; userIdx++) {
                 final int userId = mObservers.keyAt(userIdx);
                 ArrayMap<JobInfo.TriggerContentUri, ObserverInstance> observersOfUser =
@@ -400,7 +383,7 @@
                     boolean shouldDump = false;
                     for (int j = 0; j < M; j++) {
                         JobInstance inst = obs.mJobs.valueAt(j);
-                        if (inst.mJobStatus.shouldDump(filterUid)) {
+                        if (predicate.test(inst.mJobStatus)) {
                             shouldDump = true;
                             break;
                         }
@@ -408,7 +391,6 @@
                     if (!shouldDump) {
                         continue;
                     }
-                    pw.print("    ");
                     JobInfo.TriggerContentUri trigger = observersOfUser.keyAt(observerIdx);
                     pw.print(trigger.getUri());
                     pw.print(" 0x");
@@ -416,17 +398,20 @@
                     pw.print(" (");
                     pw.print(System.identityHashCode(obs));
                     pw.println("):");
-                    pw.println("      Jobs:");
+                    pw.increaseIndent();
+                    pw.println("Jobs:");
+                    pw.increaseIndent();
                     for (int j = 0; j < M; j++) {
                         JobInstance inst = obs.mJobs.valueAt(j);
-                        pw.print("        #");
+                        pw.print("#");
                         inst.mJobStatus.printUniqueId(pw);
                         pw.print(" from ");
                         UserHandle.formatUid(pw, inst.mJobStatus.getSourceUid());
                         if (inst.mChangedAuthorities != null) {
                             pw.println(":");
+                            pw.increaseIndent();
                             if (inst.mTriggerPending) {
-                                pw.print("          Trigger pending: update=");
+                                pw.print("Trigger pending: update=");
                                 TimeUtils.formatDuration(
                                         inst.mJobStatus.getTriggerContentUpdateDelay(), pw);
                                 pw.print(", max=");
@@ -434,35 +419,38 @@
                                         inst.mJobStatus.getTriggerContentMaxDelay(), pw);
                                 pw.println();
                             }
-                            pw.println("          Changed Authorities:");
+                            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));
                                 }
                             }
+                            pw.decreaseIndent();
                         } else {
                             pw.println();
                         }
                     }
+                    pw.decreaseIndent();
+                    pw.decreaseIndent();
                 }
             }
+            pw.decreaseIndent();
         }
     }
 
     @Override
-    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
+            Predicate<JobStatus> predicate) {
         final long token = proto.start(fieldId);
         final long mToken = proto.start(StateControllerProto.CONTENT_OBSERVER);
 
         for (int i = 0; i < mTrackedTasks.size(); i++) {
             JobStatus js = mTrackedTasks.valueAt(i);
-            if (!js.shouldDump(filterUid)) {
+            if (!predicate.test(js)) {
                 continue;
             }
             final long jsToken =
@@ -491,7 +479,7 @@
                 boolean shouldDump = false;
                 for (int j = 0; j < m; j++) {
                     JobInstance inst = obs.mJobs.valueAt(j);
-                    if (inst.mJobStatus.shouldDump(filterUid)) {
+                    if (predicate.test(inst.mJobStatus)) {
                         shouldDump = true;
                         break;
                     }
diff --git a/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java b/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java
index 0dbcbee..127a5c8 100644
--- a/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java
+++ b/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java
@@ -27,37 +27,36 @@
 import android.os.PowerManager;
 import android.os.UserHandle;
 import android.util.ArraySet;
+import android.util.Log;
 import android.util.Slog;
 import android.util.SparseBooleanArray;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.DeviceIdleController;
 import com.android.server.LocalServices;
 import com.android.server.job.JobSchedulerService;
-import com.android.server.job.JobStore;
 import com.android.server.job.StateControllerProto;
 import com.android.server.job.StateControllerProto.DeviceIdleJobsController.TrackedJob;
 
-import java.io.PrintWriter;
 import java.util.Arrays;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
 
 /**
  * When device is dozing, set constraint for all jobs, except whitelisted apps, as not satisfied.
  * When device is not dozing, set constraint for all jobs as satisfied.
  */
 public final class DeviceIdleJobsController extends StateController {
+    private static final String TAG = "JobScheduler.DeviceIdle";
+    private static final boolean DEBUG = JobSchedulerService.DEBUG
+            || Log.isLoggable(TAG, Log.DEBUG);
 
-    private static final String LOG_TAG = "DeviceIdleJobsController";
-    private static final boolean LOG_DEBUG = false;
     private static final long BACKGROUND_JOBS_DELAY = 3000;
 
     static final int PROCESS_BACKGROUND_JOBS = 1;
 
-    // Singleton factory
-    private static Object sCreationLock = new Object();
-    private static DeviceIdleJobsController sController;
-
     /**
      * These are jobs added with a special flag to indicate that they should be exempted from doze
      * when the app is temp whitelisted or in the foreground.
@@ -66,7 +65,6 @@
     private final SparseBooleanArray mForegroundUids;
     private final DeviceIdleUpdateFunctor mDeviceIdleUpdateFunctor;
     private final DeviceIdleJobsDelayHandler mHandler;
-    private final JobSchedulerService mJobSchedulerService;
     private final PowerManager mPowerManager;
     private final DeviceIdleController.LocalService mLocalDeviceIdleController;
 
@@ -77,19 +75,6 @@
     private int[] mDeviceIdleWhitelistAppIds;
     private int[] mPowerSaveTempWhitelistAppIds;
 
-    /**
-     * Returns a singleton for the DeviceIdleJobsController
-     */
-    public static DeviceIdleJobsController get(JobSchedulerService service) {
-        synchronized (sCreationLock) {
-            if (sController == null) {
-                sController = new DeviceIdleJobsController(service, service.getContext(),
-                        service.getLock());
-            }
-            return sController;
-        }
-    }
-
     // onReceive
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
@@ -104,8 +89,8 @@
                     synchronized (mLock) {
                         mDeviceIdleWhitelistAppIds =
                                 mLocalDeviceIdleController.getPowerSaveWhitelistUserAppIds();
-                        if (LOG_DEBUG) {
-                            Slog.d(LOG_TAG, "Got whitelist "
+                        if (DEBUG) {
+                            Slog.d(TAG, "Got whitelist "
                                     + Arrays.toString(mDeviceIdleWhitelistAppIds));
                         }
                     }
@@ -114,8 +99,8 @@
                     synchronized (mLock) {
                         mPowerSaveTempWhitelistAppIds =
                                 mLocalDeviceIdleController.getPowerSaveTempWhitelistAppIds();
-                        if (LOG_DEBUG) {
-                            Slog.d(LOG_TAG, "Got temp whitelist "
+                        if (DEBUG) {
+                            Slog.d(TAG, "Got temp whitelist "
                                     + Arrays.toString(mPowerSaveTempWhitelistAppIds));
                         }
                         boolean changed = false;
@@ -131,12 +116,10 @@
         }
     };
 
-    private DeviceIdleJobsController(JobSchedulerService jobSchedulerService, Context context,
-            Object lock) {
-        super(jobSchedulerService, context, lock);
+    public DeviceIdleJobsController(JobSchedulerService service) {
+        super(service);
 
-        mJobSchedulerService = jobSchedulerService;
-        mHandler = new DeviceIdleJobsDelayHandler(context.getMainLooper());
+        mHandler = new DeviceIdleJobsDelayHandler(mContext.getMainLooper());
         // Register for device idle mode changes
         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         mLocalDeviceIdleController =
@@ -163,16 +146,16 @@
                 changed = true;
             }
             mDeviceIdleMode = enabled;
-            if (LOG_DEBUG) Slog.d(LOG_TAG, "mDeviceIdleMode=" + mDeviceIdleMode);
+            if (DEBUG) Slog.d(TAG, "mDeviceIdleMode=" + mDeviceIdleMode);
             if (enabled) {
                 mHandler.removeMessages(PROCESS_BACKGROUND_JOBS);
-                mJobSchedulerService.getJobStore().forEachJob(mDeviceIdleUpdateFunctor);
+                mService.getJobStore().forEachJob(mDeviceIdleUpdateFunctor);
             } else {
                 // When coming out of doze, process all foreground uids immediately, while others
                 // will be processed after a delay of 3 seconds.
                 for (int i = 0; i < mForegroundUids.size(); i++) {
                     if (mForegroundUids.valueAt(i)) {
-                        mJobSchedulerService.getJobStore().forEachJobForSourceUid(
+                        mService.getJobStore().forEachJobForSourceUid(
                                 mForegroundUids.keyAt(i), mDeviceIdleUpdateFunctor);
                     }
                 }
@@ -193,12 +176,12 @@
         if (!changed) {
             return;
         }
-        if (LOG_DEBUG) {
-            Slog.d(LOG_TAG, "uid " + uid + " going " + (active ? "active" : "inactive"));
+        if (DEBUG) {
+            Slog.d(TAG, "uid " + uid + " going " + (active ? "active" : "inactive"));
         }
         mForegroundUids.put(uid, active);
         mDeviceIdleUpdateFunctor.mChanged = false;
-        mJobSchedulerService.getJobStore().forEachJobForSourceUid(uid, mDeviceIdleUpdateFunctor);
+        mService.getJobStore().forEachJobForSourceUid(uid, mDeviceIdleUpdateFunctor);
         if (mDeviceIdleUpdateFunctor.mChanged) {
             mStateChangedListener.onControllerStateChanged();
         }
@@ -245,71 +228,64 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(final PrintWriter pw, final int filterUid) {
-        pw.println("DeviceIdleJobsController");
-        pw.println("mDeviceIdleMode=" + mDeviceIdleMode);
-        mJobSchedulerService.getJobStore().forEachJob(new JobStore.JobStatusFunctor() {
-            @Override public void process(JobStatus jobStatus) {
-                if (!jobStatus.shouldDump(filterUid)) {
-                    return;
-                }
-                pw.print("  #");
-                jobStatus.printUniqueId(pw);
-                pw.print(" from ");
-                UserHandle.formatUid(pw, jobStatus.getSourceUid());
-                pw.print(": ");
-                pw.print(jobStatus.getSourcePackageName());
-                pw.print((jobStatus.satisfiedConstraints
-                        & JobStatus.CONSTRAINT_DEVICE_NOT_DOZING) != 0
-                                ? " RUNNABLE" : " WAITING");
-                if (jobStatus.dozeWhitelisted) {
-                    pw.print(" WHITELISTED");
-                }
-                if (mAllowInIdleJobs.contains(jobStatus)) {
-                    pw.print(" ALLOWED_IN_DOZE");
-                }
-                pw.println();
+    public void dumpControllerStateLocked(final IndentingPrintWriter pw,
+            final Predicate<JobStatus> predicate) {
+        pw.println("Idle mode: " + mDeviceIdleMode);
+        pw.println();
+
+        mService.getJobStore().forEachJob(predicate, (jobStatus) -> {
+            pw.print("#");
+            jobStatus.printUniqueId(pw);
+            pw.print(" from ");
+            UserHandle.formatUid(pw, jobStatus.getSourceUid());
+            pw.print(": ");
+            pw.print(jobStatus.getSourcePackageName());
+            pw.print((jobStatus.satisfiedConstraints
+                    & JobStatus.CONSTRAINT_DEVICE_NOT_DOZING) != 0
+                            ? " RUNNABLE" : " WAITING");
+            if (jobStatus.dozeWhitelisted) {
+                pw.print(" WHITELISTED");
             }
+            if (mAllowInIdleJobs.contains(jobStatus)) {
+                pw.print(" ALLOWED_IN_DOZE");
+            }
+            pw.println();
         });
     }
 
     @Override
-    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
+            Predicate<JobStatus> predicate) {
         final long token = proto.start(fieldId);
         final long mToken = proto.start(StateControllerProto.DEVICE_IDLE);
 
         proto.write(StateControllerProto.DeviceIdleJobsController.IS_DEVICE_IDLE_MODE,
                 mDeviceIdleMode);
-        mJobSchedulerService.getJobStore().forEachJob(new JobStore.JobStatusFunctor() {
-            @Override public void process(JobStatus jobStatus) {
-                if (!jobStatus.shouldDump(filterUid)) {
-                    return;
-                }
-                final long jsToken =
-                        proto.start(StateControllerProto.DeviceIdleJobsController.TRACKED_JOBS);
+        mService.getJobStore().forEachJob(predicate, (jobStatus) -> {
+            final long jsToken =
+                    proto.start(StateControllerProto.DeviceIdleJobsController.TRACKED_JOBS);
 
-                jobStatus.writeToShortProto(proto, TrackedJob.INFO);
-                proto.write(TrackedJob.SOURCE_UID, jobStatus.getSourceUid());
-                proto.write(TrackedJob.SOURCE_PACKAGE_NAME, jobStatus.getSourcePackageName());
-                proto.write(TrackedJob.ARE_CONSTRAINTS_SATISFIED,
-                        (jobStatus.satisfiedConstraints &
-                            JobStatus.CONSTRAINT_DEVICE_NOT_DOZING) != 0);
-                proto.write(TrackedJob.IS_DOZE_WHITELISTED, jobStatus.dozeWhitelisted);
-                proto.write(TrackedJob.IS_ALLOWED_IN_DOZE, mAllowInIdleJobs.contains(jobStatus));
+            jobStatus.writeToShortProto(proto, TrackedJob.INFO);
+            proto.write(TrackedJob.SOURCE_UID, jobStatus.getSourceUid());
+            proto.write(TrackedJob.SOURCE_PACKAGE_NAME, jobStatus.getSourcePackageName());
+            proto.write(TrackedJob.ARE_CONSTRAINTS_SATISFIED,
+                    (jobStatus.satisfiedConstraints &
+                        JobStatus.CONSTRAINT_DEVICE_NOT_DOZING) != 0);
+            proto.write(TrackedJob.IS_DOZE_WHITELISTED, jobStatus.dozeWhitelisted);
+            proto.write(TrackedJob.IS_ALLOWED_IN_DOZE, mAllowInIdleJobs.contains(jobStatus));
 
-                proto.end(jsToken);
-            }
+            proto.end(jsToken);
         });
 
         proto.end(mToken);
         proto.end(token);
     }
 
-    final class DeviceIdleUpdateFunctor implements JobStore.JobStatusFunctor {
+    final class DeviceIdleUpdateFunctor implements Consumer<JobStatus> {
         boolean mChanged;
 
         @Override
-        public void process(JobStatus jobStatus) {
+        public void accept(JobStatus jobStatus) {
             mChanged |= updateTaskStateLocked(jobStatus);
         }
     }
@@ -326,7 +302,7 @@
                     // Just process all the jobs, the ones in foreground should already be running.
                     synchronized (mLock) {
                         mDeviceIdleUpdateFunctor.mChanged = false;
-                        mJobSchedulerService.getJobStore().forEachJob(mDeviceIdleUpdateFunctor);
+                        mService.getJobStore().forEachJob(mDeviceIdleUpdateFunctor);
                         if (mDeviceIdleUpdateFunctor.mChanged) {
                             mStateChangedListener.onControllerStateChanged();
                         }
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 a9bc7e0..1dbcfd6 100644
--- a/services/core/java/com/android/server/job/controllers/IdleController.java
+++ b/services/core/java/com/android/server/job/controllers/IdleController.java
@@ -26,18 +26,21 @@
 import android.content.IntentFilter;
 import android.os.UserHandle;
 import android.util.ArraySet;
+import android.util.Log;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.am.ActivityManagerService;
 import com.android.server.job.JobSchedulerService;
-import com.android.server.job.StateChangedListener;
 import com.android.server.job.StateControllerProto;
 
-import java.io.PrintWriter;
+import java.util.function.Predicate;
 
 public final class IdleController extends StateController {
-    private static final String TAG = "IdleController";
+    private static final String TAG = "JobScheduler.Idle";
+    private static final boolean DEBUG = JobSchedulerService.DEBUG
+            || Log.isLoggable(TAG, Log.DEBUG);
 
     // Policy: we decide that we're "idle" if the device has been unused /
     // screen off or dreaming for at least this long
@@ -46,22 +49,8 @@
     final ArraySet<JobStatus> mTrackedTasks = new ArraySet<>();
     IdlenessTracker mIdleTracker;
 
-    // Singleton factory
-    private static Object sCreationLock = new Object();
-    private static volatile IdleController sController;
-
-    public static IdleController get(JobSchedulerService service) {
-        synchronized (sCreationLock) {
-            if (sController == null) {
-                sController = new IdleController(service, service.getContext(), service.getLock());
-            }
-            return sController;
-        }
-    }
-
-    private IdleController(StateChangedListener stateChangedListener, Context context,
-                Object lock) {
-        super(stateChangedListener, context, lock);
+    public IdleController(JobSchedulerService service) {
+        super(service);
         initIdleStateTracking();
     }
 
@@ -200,18 +189,17 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
-        pw.print("Idle: ");
-        pw.println(mIdleTracker.isIdle());
-        pw.print("Tracking ");
-        pw.print(mTrackedTasks.size());
-        pw.println(":");
+    public void dumpControllerStateLocked(IndentingPrintWriter pw,
+            Predicate<JobStatus> predicate) {
+        pw.println("Currently idle: " + mIdleTracker.isIdle());
+        pw.println();
+
         for (int i = 0; i < mTrackedTasks.size(); i++) {
             final JobStatus js = mTrackedTasks.valueAt(i);
-            if (!js.shouldDump(filterUid)) {
+            if (!predicate.test(js)) {
                 continue;
             }
-            pw.print("  #");
+            pw.print("#");
             js.printUniqueId(pw);
             pw.print(" from ");
             UserHandle.formatUid(pw, js.getSourceUid());
@@ -220,7 +208,8 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
+            Predicate<JobStatus> predicate) {
         final long token = proto.start(fieldId);
         final long mToken = proto.start(StateControllerProto.IDLE);
 
@@ -228,7 +217,7 @@
 
         for (int i = 0; i < mTrackedTasks.size(); i++) {
             final JobStatus js = mTrackedTasks.valueAt(i);
-            if (!js.shouldDump(filterUid)) {
+            if (!predicate.test(js)) {
                 continue;
             }
             final long jsToken = proto.start(StateControllerProto.IdleController.TRACKED_JOBS);
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 3867306..5616197 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -302,7 +302,6 @@
         this.numFailures = numFailures;
 
         int requiredConstraints = job.getConstraintFlags();
-
         if (job.getRequiredNetwork() != null) {
             requiredConstraints |= CONSTRAINT_CONNECTIVITY;
         }
@@ -323,6 +322,13 @@
         mInternalFlags = internalFlags;
 
         updateEstimatedNetworkBytesLocked();
+
+        if (job.getRequiredNetwork() != null) {
+            // Later, when we check if a given network satisfies the required
+            // network, we need to know the UID that is requesting it, so push
+            // our source UID into place.
+            job.getRequiredNetwork().networkCapabilities.setSingleUid(this.sourceUid);
+        }
     }
 
     /** Copy constructor: used specifically when cloning JobStatus objects for persistence,
@@ -882,11 +888,6 @@
         return mLastFailedRunTime;
     }
 
-    public boolean shouldDump(int filterUid) {
-        return filterUid == -1 || UserHandle.getAppId(getUid()) == filterUid
-                || UserHandle.getAppId(getSourceUid()) == filterUid;
-    }
-
     /**
      * @return Whether or not this job is ready to run, based on its requirements. This is true if
      * the constraints are satisfied <strong>or</strong> the deadline on the job has expired.
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 d3055e6..495109d 100644
--- a/services/core/java/com/android/server/job/controllers/StateController.java
+++ b/services/core/java/com/android/server/job/controllers/StateController.java
@@ -19,10 +19,12 @@
 import android.content.Context;
 import android.util.proto.ProtoOutputStream;
 
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.job.JobSchedulerService;
+import com.android.server.job.JobSchedulerService.Constants;
 import com.android.server.job.StateChangedListener;
 
-import java.io.PrintWriter;
+import java.util.function.Predicate;
 
 /**
  * Incorporates shared controller logic between the various controllers of the JobManager.
@@ -30,16 +32,18 @@
  * are ready to run, or whether they must be stopped.
  */
 public abstract class StateController {
-    protected static final boolean DEBUG = JobSchedulerService.DEBUG;
+    protected final JobSchedulerService mService;
+    protected final StateChangedListener mStateChangedListener;
     protected final Context mContext;
     protected final Object mLock;
-    protected final StateChangedListener mStateChangedListener;
+    protected final Constants mConstants;
 
-    public StateController(StateChangedListener stateChangedListener, Context context,
-            Object lock) {
-        mStateChangedListener = stateChangedListener;
-        mContext = context;
-        mLock = lock;
+    StateController(JobSchedulerService service) {
+        mService = service;
+        mStateChangedListener = service;
+        mContext = service.getContext();
+        mLock = service.getLock();
+        mConstants = service.getConstants();
     }
 
     /**
@@ -65,7 +69,8 @@
     public void rescheduleForFailureLocked(JobStatus newJob, JobStatus failureToReschedule) {
     }
 
-    public abstract void dumpControllerStateLocked(PrintWriter pw, int filterUid);
+    public abstract void dumpControllerStateLocked(IndentingPrintWriter pw,
+            Predicate<JobStatus> predicate);
     public abstract void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
-            int filterUid);
+            Predicate<JobStatus> predicate);
 }
diff --git a/services/core/java/com/android/server/job/controllers/StorageController.java b/services/core/java/com/android/server/job/controllers/StorageController.java
index 0519b63..c2ae53f 100644
--- a/services/core/java/com/android/server/job/controllers/StorageController.java
+++ b/services/core/java/com/android/server/job/controllers/StorageController.java
@@ -24,53 +24,36 @@
 import android.content.IntentFilter;
 import android.os.UserHandle;
 import android.util.ArraySet;
+import android.util.Log;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.job.JobSchedulerService;
-import com.android.server.job.StateChangedListener;
 import com.android.server.job.StateControllerProto;
 import com.android.server.storage.DeviceStorageMonitorService;
 
-import java.io.PrintWriter;
+import java.util.function.Predicate;
 
 /**
  * Simple controller that tracks the status of the device's storage.
  */
 public final class StorageController extends StateController {
-    private static final String TAG = "JobScheduler.Stor";
-
-    private static final Object sCreationLock = new Object();
-    private static volatile StorageController sController;
+    private static final String TAG = "JobScheduler.Storage";
+    private static final boolean DEBUG = JobSchedulerService.DEBUG
+            || Log.isLoggable(TAG, Log.DEBUG);
 
     private final ArraySet<JobStatus> mTrackedTasks = new ArraySet<JobStatus>();
-    private StorageTracker mStorageTracker;
-
-    public static StorageController get(JobSchedulerService taskManagerService) {
-        synchronized (sCreationLock) {
-            if (sController == null) {
-                sController = new StorageController(taskManagerService,
-                        taskManagerService.getContext(), taskManagerService.getLock());
-            }
-        }
-        return sController;
-    }
+    private final StorageTracker mStorageTracker;
 
     @VisibleForTesting
     public StorageTracker getTracker() {
         return mStorageTracker;
     }
 
-    @VisibleForTesting
-    public static StorageController getForTesting(StateChangedListener stateChangedListener,
-            Context context) {
-        return new StorageController(stateChangedListener, context, new Object());
-    }
-
-    private StorageController(StateChangedListener stateChangedListener, Context context,
-            Object lock) {
-        super(stateChangedListener, context, lock);
+    public StorageController(JobSchedulerService service) {
+        super(service);
         mStorageTracker = new StorageTracker();
         mStorageTracker.startTracking();
     }
@@ -172,20 +155,18 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
-        pw.print("Storage: not low = ");
-        pw.print(mStorageTracker.isStorageNotLow());
-        pw.print(", seq=");
-        pw.println(mStorageTracker.getSeq());
-        pw.print("Tracking ");
-        pw.print(mTrackedTasks.size());
-        pw.println(":");
+    public void dumpControllerStateLocked(IndentingPrintWriter pw,
+            Predicate<JobStatus> predicate) {
+        pw.println("Not low: " + mStorageTracker.isStorageNotLow());
+        pw.println("Sequence: " + mStorageTracker.getSeq());
+        pw.println();
+
         for (int i = 0; i < mTrackedTasks.size(); i++) {
             final JobStatus js = mTrackedTasks.valueAt(i);
-            if (!js.shouldDump(filterUid)) {
+            if (!predicate.test(js)) {
                 continue;
             }
-            pw.print("  #");
+            pw.print("#");
             js.printUniqueId(pw);
             pw.print(" from ");
             UserHandle.formatUid(pw, js.getSourceUid());
@@ -194,7 +175,8 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
+            Predicate<JobStatus> predicate) {
         final long token = proto.start(fieldId);
         final long mToken = proto.start(StateControllerProto.STORAGE);
 
@@ -205,7 +187,7 @@
 
         for (int i = 0; i < mTrackedTasks.size(); i++) {
             final JobStatus js = mTrackedTasks.valueAt(i);
-            if (!js.shouldDump(filterUid)) {
+            if (!predicate.test(js)) {
                 continue;
             }
             final long jsToken = proto.start(StateControllerProto.StorageController.TRACKED_JOBS);
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 a91f5a4..fa48b5e 100644
--- a/services/core/java/com/android/server/job/controllers/TimeController.java
+++ b/services/core/java/com/android/server/job/controllers/TimeController.java
@@ -25,19 +25,20 @@
 import android.os.Process;
 import android.os.UserHandle;
 import android.os.WorkSource;
+import android.util.Log;
 import android.util.Slog;
 import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
 
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.job.JobSchedulerService;
-import com.android.server.job.StateChangedListener;
 import com.android.server.job.StateControllerProto;
 
-import java.io.PrintWriter;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
+import java.util.function.Predicate;
 
 /**
  * This class sets an alarm for the next expiring job, and determines whether a job's minimum
@@ -45,6 +46,8 @@
  */
 public final class TimeController extends StateController {
     private static final String TAG = "JobScheduler.Time";
+    private static final boolean DEBUG = JobSchedulerService.DEBUG
+            || Log.isLoggable(TAG, Log.DEBUG);
 
     /** Deadline alarm tag for logging purposes */
     private final String DEADLINE_TAG = "*job.deadline*";
@@ -59,23 +62,13 @@
     private AlarmManager mAlarmService = null;
     /** List of tracked jobs, sorted asc. by deadline */
     private final List<JobStatus> mTrackedJobs = new LinkedList<>();
-    /** Singleton. */
-    private static TimeController mSingleton;
 
-    public static synchronized TimeController get(JobSchedulerService jms) {
-        if (mSingleton == null) {
-            mSingleton = new TimeController(jms, jms.getContext(), jms.getLock());
-        }
-        return mSingleton;
-    }
-
-    private TimeController(StateChangedListener stateChangedListener, Context context,
-                Object lock) {
-        super(stateChangedListener, context, lock);
+    public TimeController(JobSchedulerService service) {
+        super(service);
 
         mNextJobExpiredElapsedMillis = Long.MAX_VALUE;
         mNextDelayExpiredElapsedMillis = Long.MAX_VALUE;
-        mChainedAttributionEnabled = WorkSource.isChainedBatteryAttributionEnabled(context);
+        mChainedAttributionEnabled = WorkSource.isChainedBatteryAttributionEnabled(mContext);
     }
 
     /**
@@ -345,25 +338,24 @@
     };
 
     @Override
-    public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
+    public void dumpControllerStateLocked(IndentingPrintWriter pw,
+            Predicate<JobStatus> predicate) {
         final long nowElapsed = sElapsedRealtimeClock.millis();
-        pw.print("Alarms: now=");
-        pw.print(nowElapsed);
-        pw.println();
+        pw.println("Elapsed clock: " + nowElapsed);
+
         pw.print("Next delay alarm in ");
         TimeUtils.formatDuration(mNextDelayExpiredElapsedMillis, nowElapsed, pw);
         pw.println();
         pw.print("Next deadline alarm in ");
         TimeUtils.formatDuration(mNextJobExpiredElapsedMillis, nowElapsed, pw);
         pw.println();
-        pw.print("Tracking ");
-        pw.print(mTrackedJobs.size());
-        pw.println(":");
+        pw.println();
+
         for (JobStatus ts : mTrackedJobs) {
-            if (!ts.shouldDump(filterUid)) {
+            if (!predicate.test(ts)) {
                 continue;
             }
-            pw.print("  #");
+            pw.print("#");
             ts.printUniqueId(pw);
             pw.print(" from ");
             UserHandle.formatUid(pw, ts.getSourceUid());
@@ -384,7 +376,8 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+    public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
+            Predicate<JobStatus> predicate) {
         final long token = proto.start(fieldId);
         final long mToken = proto.start(StateControllerProto.TIME);
 
@@ -396,7 +389,7 @@
                 mNextJobExpiredElapsedMillis - nowElapsed);
 
         for (JobStatus ts : mTrackedJobs) {
-            if (!ts.shouldDump(filterUid)) {
+            if (!predicate.test(ts)) {
                 continue;
             }
             final long tsToken = proto.start(StateControllerProto.TimeController.TRACKED_JOBS);
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 9d2a8e2..729ac0c 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -215,6 +215,8 @@
     private static final int REQUEST_SUPL_CONNECTION = 14;
     private static final int RELEASE_SUPL_CONNECTION = 15;
     private static final int REQUEST_LOCATION = 16;
+    private static final int REPORT_LOCATION = 17; // HAL reports location
+    private static final int REPORT_SV_STATUS = 18; // HAL reports SV status
 
     // Request setid
     private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1;
@@ -266,7 +268,7 @@
         }
     }
 
-    // Simple class to hold stats reported in the Extras Bundle
+    // Threadsafe class to hold stats reported in the Extras Bundle
     private static class LocationExtras {
         private int mSvCount;
         private int mMeanCn0;
@@ -278,9 +280,11 @@
         }
 
         public void set(int svCount, int meanCn0, int maxCn0) {
-            mSvCount = svCount;
-            mMeanCn0 = meanCn0;
-            mMaxCn0 = maxCn0;
+            synchronized(this) {
+                mSvCount = svCount;
+                mMeanCn0 = meanCn0;
+                mMaxCn0 = maxCn0;
+            }
             setBundle(mBundle);
         }
 
@@ -291,14 +295,18 @@
         // Also used by outside methods to add to other bundles
         public void setBundle(Bundle extras) {
             if (extras != null) {
-                extras.putInt("satellites", mSvCount);
-                extras.putInt("meanCn0", mMeanCn0);
-                extras.putInt("maxCn0", mMaxCn0);
+                synchronized (this) {
+                    extras.putInt("satellites", mSvCount);
+                    extras.putInt("meanCn0", mMeanCn0);
+                    extras.putInt("maxCn0", mMaxCn0);
+                }
             }
         }
 
         public Bundle getBundle() {
-            return mBundle;
+            synchronized (this) {
+                return new Bundle(mBundle);
+            }
         }
     }
 
@@ -411,7 +419,6 @@
     private final Context mContext;
     private final NtpTrustedTime mNtpTime;
     private final ILocationManager mILocationManager;
-    private Location mLocation = new Location(LocationManager.GPS_PROVIDER);
     private final LocationExtras mLocationExtras = new LocationExtras();
     private final GnssStatusListenerHelper mListenerHelper;
     private final GnssMeasurementsProvider mGnssMeasurementsProvider;
@@ -452,7 +459,7 @@
     private final PendingIntent mWakeupIntent;
     private final PendingIntent mTimeoutIntent;
 
-    private final IAppOpsService mAppOpsService;
+    private final AppOpsManager mAppOps;
     private final IBatteryStats mBatteryStats;
 
     // Current list of underlying location clients.
@@ -758,8 +765,6 @@
         mNtpTime = NtpTrustedTime.getInstance(context);
         mILocationManager = ilocationManager;
 
-        mLocation.setExtras(mLocationExtras.getBundle());
-
         // Create a wake lock
         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
@@ -777,8 +782,7 @@
         mConnMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
 
         // App ops service to keep track of who is accessing the GPS
-        mAppOpsService = IAppOpsService.Stub.asInterface(ServiceManager.getService(
-                Context.APP_OPS_SERVICE));
+        mAppOps = mContext.getSystemService(AppOpsManager.class);
 
         // Battery statistics service to be notified when GPS turns on or off
         mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
@@ -1485,26 +1489,16 @@
             if (newChains != null) {
                 for (int i = 0; i < newChains.size(); ++i) {
                     final WorkChain newChain = newChains.get(i);
-                    try {
-                        mAppOpsService.startOperation(AppOpsManager.getToken(mAppOpsService),
-                                AppOpsManager.OP_GPS, newChain.getAttributionUid(),
-                                newChain.getAttributionTag());
-                    } catch (RemoteException e) {
-                        Log.w(TAG, "RemoteException", e);
-                    }
+                    mAppOps.startOpNoThrow(AppOpsManager.OP_GPS, newChain.getAttributionUid(),
+                            newChain.getAttributionTag());
                 }
             }
 
             if (goneChains != null) {
                 for (int i = 0; i < goneChains.size(); i++) {
                     final WorkChain goneChain = goneChains.get(i);
-                    try {
-                        mAppOpsService.finishOperation(AppOpsManager.getToken(mAppOpsService),
-                                AppOpsManager.OP_GPS, goneChain.getAttributionUid(),
-                                goneChain.getAttributionTag());
-                    } catch (RemoteException e) {
-                        Log.w(TAG, "RemoteException", e);
-                    }
+                    mAppOps.finishOp(AppOpsManager.OP_GPS, goneChain.getAttributionUid(),
+                            goneChain.getAttributionTag());
                 }
             }
 
@@ -1520,24 +1514,15 @@
             // Update sources that were not previously tracked.
             if (newWork != null) {
                 for (int i = 0; i < newWork.size(); i++) {
-                    try {
-                        mAppOpsService.startOperation(AppOpsManager.getToken(mAppOpsService),
-                                AppOpsManager.OP_GPS, newWork.get(i), newWork.getName(i));
-                    } catch (RemoteException e) {
-                        Log.w(TAG, "RemoteException", e);
-                    }
+                    mAppOps.startOpNoThrow(AppOpsManager.OP_GPS,
+                            newWork.get(i), newWork.getName(i));
                 }
             }
 
             // Update sources that are no longer tracked.
             if (goneWork != null) {
                 for (int i = 0; i < goneWork.size(); i++) {
-                    try {
-                        mAppOpsService.finishOperation(AppOpsManager.getToken(mAppOpsService),
-                                AppOpsManager.OP_GPS, goneWork.get(i), goneWork.getName(i));
-                    } catch (RemoteException e) {
-                        Log.w(TAG, "RemoteException", e);
-                    }
+                    mAppOps.finishOp(AppOpsManager.OP_GPS, goneWork.get(i), goneWork.getName(i));
                 }
             }
         }
@@ -1699,7 +1684,6 @@
             mStarted = false;
             mSingleShot = false;
             native_stop();
-            mTimeToFirstFix = 0;
             mLastFixTime = 0;
 
             // reset SV count to zero
@@ -1726,6 +1710,10 @@
      * called from native code to update our position.
      */
     private void reportLocation(boolean hasLatLong, Location location) {
+        sendMessage(REPORT_LOCATION, hasLatLong ? 1 : 0, location);
+    }
+
+    private void handleReportLocation(boolean hasLatLong, Location location) {
         if (location.hasSpeed()) {
             mItarSpeedLimitExceeded = location.getSpeed() > ITAR_SPEED_LIMIT_METERS_PER_SECOND;
         }
@@ -1739,18 +1727,15 @@
 
         if (VERBOSE) Log.v(TAG, "reportLocation " + location.toString());
 
-        synchronized (mLocation) {
-            mLocation = location;
-            // It would be nice to push the elapsed real-time timestamp
-            // further down the stack, but this is still useful
-            mLocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
-            mLocation.setExtras(mLocationExtras.getBundle());
+        // It would be nice to push the elapsed real-time timestamp
+        // further down the stack, but this is still useful
+        location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
+        location.setExtras(mLocationExtras.getBundle());
 
-            try {
-                mILocationManager.reportLocation(mLocation, false);
-            } catch (RemoteException e) {
-                Log.e(TAG, "RemoteException calling reportLocation");
-            }
+        try {
+            mILocationManager.reportLocation(location, false);
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException calling reportLocation");
         }
 
         mGnssMetrics.logReceivedLocationStatus(hasLatLong);
@@ -1835,54 +1820,73 @@
         }
     }
 
+    // Helper class to carry data to handler for reportSvStatus
+    private static class SvStatusInfo {
+        public int mSvCount;
+        public int[] mSvidWithFlags;
+        public float[] mCn0s;
+        public float[] mSvElevations;
+        public float[] mSvAzimuths;
+        public float[] mSvCarrierFreqs;
+    }
+
     /**
      * called from native code to update SV info
      */
-    private void reportSvStatus() {
-        int svCount = native_read_sv_status(mSvidWithFlags,
-                mCn0s,
-                mSvElevations,
-                mSvAzimuths,
-                mSvCarrierFreqs);
+    private void reportSvStatus(int svCount, int[] svidWithFlags, float[] cn0s,
+            float[] svElevations, float[] svAzimuths, float[] svCarrierFreqs) {
+        SvStatusInfo svStatusInfo = new SvStatusInfo();
+        svStatusInfo.mSvCount = svCount;
+        svStatusInfo.mSvidWithFlags = svidWithFlags;
+        svStatusInfo.mCn0s = cn0s;
+        svStatusInfo.mSvElevations = svElevations;
+        svStatusInfo.mSvAzimuths = svAzimuths;
+        svStatusInfo.mSvCarrierFreqs = svCarrierFreqs;
+
+        sendMessage(REPORT_SV_STATUS, 0, svStatusInfo);
+    }
+
+    private void handleReportSvStatus(SvStatusInfo info) {
         mListenerHelper.onSvStatusChanged(
-                svCount,
-                mSvidWithFlags,
-                mCn0s,
-                mSvElevations,
-                mSvAzimuths,
-                mSvCarrierFreqs);
+                info.mSvCount,
+                info.mSvidWithFlags,
+                info.mCn0s,
+                info.mSvElevations,
+                info.mSvAzimuths,
+                info.mSvCarrierFreqs);
 
         // Log CN0 as part of GNSS metrics
-        mGnssMetrics.logCn0(mCn0s, svCount);
+        mGnssMetrics.logCn0(info.mCn0s, info.mSvCount);
 
         if (VERBOSE) {
-            Log.v(TAG, "SV count: " + svCount);
+            Log.v(TAG, "SV count: " + info.mSvCount);
         }
         // Calculate number of satellites used in fix.
         int usedInFixCount = 0;
         int maxCn0 = 0;
         int meanCn0 = 0;
-        for (int i = 0; i < svCount; i++) {
-            if ((mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
+        for (int i = 0; i < info.mSvCount; i++) {
+            if ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
                 ++usedInFixCount;
-                if (mCn0s[i] > maxCn0) {
-                    maxCn0 = (int) mCn0s[i];
+                if (info.mCn0s[i] > maxCn0) {
+                    maxCn0 = (int) info.mCn0s[i];
                 }
-                meanCn0 += mCn0s[i];
+                meanCn0 += info.mCn0s[i];
             }
             if (VERBOSE) {
-                Log.v(TAG, "svid: " + (mSvidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH) +
-                        " cn0: " + mCn0s[i] +
-                        " elev: " + mSvElevations[i] +
-                        " azimuth: " + mSvAzimuths[i] +
-                        " carrier frequency: " + mSvCarrierFreqs[i] +
-                        ((mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) == 0
+                Log.v(TAG, "svid: " + (info.mSvidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH) +
+                        " cn0: " + info.mCn0s[i] +
+                        " elev: " + info.mSvElevations[i] +
+                        " azimuth: " + info.mSvAzimuths[i] +
+                        " carrier frequency: " + info.mSvCarrierFreqs[i] +
+                        ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) == 0
                                 ? "  " : " E") +
-                        ((mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_ALMANAC_DATA) == 0
+                        ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_ALMANAC_DATA) == 0
                                 ? "  " : " A") +
-                        ((mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) == 0
+                        ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) == 0
                                 ? "" : "U") +
-                        ((mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) == 0
+                        ((info.mSvidWithFlags[i] &
+                                GnssStatus.GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) == 0
                                 ? "" : "F"));
             }
         }
@@ -2479,6 +2483,12 @@
                 case INITIALIZE_HANDLER:
                     handleInitialize();
                     break;
+                case REPORT_LOCATION:
+                    handleReportLocation(msg.arg1 == 1, (Location) msg.obj);
+                    break;
+                case REPORT_SV_STATUS:
+                    handleReportSvStatus((SvStatusInfo) msg.obj);
+                    break;
             }
             if (msg.arg2 == 1) {
                 // wakelock was taken for this message, release it
@@ -2798,6 +2808,10 @@
                 return "SUBSCRIPTION_OR_SIM_CHANGED";
             case INITIALIZE_HANDLER:
                 return "INITIALIZE_HANDLER";
+            case REPORT_LOCATION:
+                return "REPORT_LOCATION";
+            case REPORT_SV_STATUS:
+                return "REPORT_SV_STATUS";
             default:
                 return "<Unknown>";
         }
@@ -2862,15 +2876,6 @@
         }
     }
 
-    // for GPS SV statistics
-    private static final int MAX_SVS = 64;
-
-    // preallocated arrays, to avoid memory allocation in reportStatus()
-    private int mSvidWithFlags[] = new int[MAX_SVS];
-    private float mCn0s[] = new float[MAX_SVS];
-    private float mSvElevations[] = new float[MAX_SVS];
-    private float mSvAzimuths[] = new float[MAX_SVS];
-    private float mSvCarrierFreqs[] = new float[MAX_SVS];
     // preallocated to avoid memory allocation in reportNmea()
     private byte[] mNmeaBuffer = new byte[120];
 
@@ -2899,11 +2904,6 @@
 
     private native void native_delete_aiding_data(int flags);
 
-    // returns number of SVs
-    // mask[0] is ephemeris mask and mask[1] is almanac mask
-    private native int native_read_sv_status(int[] prnWithFlags, float[] cn0s, float[] elevations,
-            float[] azimuths, float[] carrierFrequencies);
-
     private native int native_read_nmea(byte[] buffer, int bufferSize);
 
     private native void native_inject_best_location(
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 6deff36..752ab8f 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -80,6 +80,7 @@
 import android.security.keystore.KeyProtection;
 import android.security.keystore.UserNotAuthenticatedException;
 import android.security.keystore.recovery.KeyChainProtectionParams;
+import android.security.keystore.recovery.RecoveryCertPath;
 import android.security.keystore.recovery.WrappedApplicationKey;
 import android.security.keystore.recovery.KeyChainSnapshot;
 import android.service.gatekeeper.GateKeeperResponse;
@@ -2001,13 +2002,12 @@
     }
 
     @Override
-    public void setRecoveryStatus(@NonNull String packageName, @Nullable String[] aliases,
-            int status) throws RemoteException {
-        mRecoverableKeyStoreManager.setRecoveryStatus(packageName, aliases, status);
+    public void setRecoveryStatus(String alias, int status) throws RemoteException {
+        mRecoverableKeyStoreManager.setRecoveryStatus(alias, status);
     }
 
-    public Map getRecoveryStatus(@Nullable String packageName) throws RemoteException {
-        return mRecoverableKeyStoreManager.getRecoveryStatus(packageName);
+    public Map getRecoveryStatus() throws RemoteException {
+        return mRecoverableKeyStoreManager.getRecoveryStatus();
     }
 
     @Override
@@ -2042,6 +2042,15 @@
                 vaultParams, vaultChallenge, secrets);
     }
 
+    @Override
+    public byte[] startRecoverySessionWithCertPath(@NonNull String sessionId,
+            @NonNull RecoveryCertPath verifierCertPath, @NonNull byte[] vaultParams,
+            @NonNull byte[] vaultChallenge, @NonNull List<KeyChainProtectionParams> secrets)
+            throws RemoteException {
+        return mRecoverableKeyStoreManager.startRecoverySessionWithCertPath(
+                sessionId, verifierCertPath, vaultParams, vaultChallenge, secrets);
+    }
+
     public void closeSession(@NonNull String sessionId) throws RemoteException {
         mRecoverableKeyStoreManager.closeSession(sessionId);
     }
@@ -2065,8 +2074,13 @@
     }
 
     @Override
-    public String generateKey(@NonNull String alias, byte[] account) throws RemoteException {
-        return mRecoverableKeyStoreManager.generateKey(alias, account);
+    public String generateKey(@NonNull String alias) throws RemoteException {
+        return mRecoverableKeyStoreManager.generateKey(alias);
+    }
+
+    @Override
+    public String importKey(@NonNull String alias, byte[] keyBytes) throws RemoteException {
+        return mRecoverableKeyStoreManager.importKey(alias, keyBytes);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java
index dee24c7..8efce86 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java
@@ -289,6 +289,7 @@
                 .setMaxAttempts(TRUSTED_HARDWARE_MAX_ATTEMPTS)
                 .setCounterId(counterId)
                 .setTrustedHardwarePublicKey(SecureBox.encodePublicKey(publicKey))
+                .setTrustedHardwareCertPath(certPath)
                 .setServerParams(vaultHandle)
                 .setKeyChainProtectionParams(metadataList)
                 .setWrappedApplicationKeys(createApplicationKeyEntries(encryptedApplicationKeys))
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncUtils.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncUtils.java
index 89e2deb..a7d32ed 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncUtils.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncUtils.java
@@ -273,12 +273,16 @@
      *
      * @param key The bytes of the key.
      * @return The key.
-     * @throws NoSuchAlgorithmException if the public key algorithm is unavailable.
      * @throws InvalidKeySpecException if the bytes of the key are not a valid key.
      */
-    public static PublicKey deserializePublicKey(byte[] key)
-            throws NoSuchAlgorithmException, InvalidKeySpecException {
-        KeyFactory keyFactory = KeyFactory.getInstance(PUBLIC_KEY_FACTORY_ALGORITHM);
+    public static PublicKey deserializePublicKey(byte[] key) throws InvalidKeySpecException {
+        KeyFactory keyFactory;
+        try {
+            keyFactory = KeyFactory.getInstance(PUBLIC_KEY_FACTORY_ALGORITHM);
+        } catch (NoSuchAlgorithmException e) {
+            // Should not happen
+            throw new RuntimeException(e);
+        }
         X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(key);
         return keyFactory.generatePublic(publicKeySpec);
     }
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGenerator.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGenerator.java
index 2fe3f4e..7ebe8bf 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGenerator.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGenerator.java
@@ -16,6 +16,8 @@
 
 package com.android.server.locksettings.recoverablekeystore;
 
+import android.annotation.NonNull;
+
 import com.android.server.locksettings.recoverablekeystore.storage.RecoverableKeyStoreDb;
 
 import java.security.InvalidKeyException;
@@ -25,20 +27,24 @@
 
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
 
+// TODO: Rename RecoverableKeyGenerator to RecoverableKeyManager as it can import a key too now
 /**
- * Generates keys and stores them both in AndroidKeyStore and on disk, in wrapped form.
+ * Generates/imports keys and stores them both in AndroidKeyStore and on disk, in wrapped form.
  *
- * <p>Generates 256-bit AES keys, which can be used for encrypt / decrypt with AES/GCM/NoPadding.
+ * <p>Generates/imports 256-bit AES keys, which can be used for encrypt and decrypt with AES-GCM.
  * They are synced to disk wrapped by a platform key. This allows them to be exported to a remote
  * service.
  *
  * @hide
  */
 public class RecoverableKeyGenerator {
+
     private static final int RESULT_CANNOT_INSERT_ROW = -1;
-    private static final String KEY_GENERATOR_ALGORITHM = "AES";
-    private static final int KEY_SIZE_BITS = 256;
+    private static final String SECRET_KEY_ALGORITHM = "AES";
+
+    static final int KEY_SIZE_BITS = 256;
 
     /**
      * A new {@link RecoverableKeyGenerator} instance.
@@ -52,7 +58,7 @@
             throws NoSuchAlgorithmException {
         // NB: This cannot use AndroidKeyStore as the provider, as we need access to the raw key
         // material, so that it can be synced to disk in encrypted form.
-        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_GENERATOR_ALGORITHM);
+        KeyGenerator keyGenerator = KeyGenerator.getInstance(SECRET_KEY_ALGORITHM);
         return new RecoverableKeyGenerator(keyGenerator, database);
     }
 
@@ -102,4 +108,41 @@
         mDatabase.setShouldCreateSnapshot(userId, uid, true);
         return key.getEncoded();
     }
+
+    /**
+     * Imports an AES key with the given alias.
+     *
+     * <p>Stores in the AndroidKeyStore, as well as persisting in wrapped form to disk. It is
+     * persisted to disk so that it can be synced remotely, and then recovered on another device.
+     * The generated key allows encrypt/decrypt only using AES/GCM/NoPadding.
+     *
+     * @param platformKey The user's platform key, with which to wrap the generated key.
+     * @param userId The user ID of the profile to which the calling app belongs.
+     * @param uid The uid of the application that will own the key.
+     * @param alias The alias by which the key will be known in the recoverable key store.
+     * @param keyBytes The raw bytes of the AES key to be imported.
+     * @throws RecoverableKeyStorageException if there is some error persisting the key either to
+     *     the database.
+     * @throws KeyStoreException if there is a KeyStore error wrapping the generated key.
+     * @throws InvalidKeyException if the platform key cannot be used to wrap keys.
+     *
+     * @hide
+     */
+    public void importKey(
+            @NonNull PlatformEncryptionKey platformKey, int userId, int uid, @NonNull String alias,
+            @NonNull byte[] keyBytes)
+            throws RecoverableKeyStorageException, KeyStoreException, InvalidKeyException {
+        SecretKey key = new SecretKeySpec(keyBytes, SECRET_KEY_ALGORITHM);
+
+        WrappedKey wrappedKey = WrappedKey.fromSecretKey(platformKey, key);
+        long result = mDatabase.insertKey(userId, uid, alias, wrappedKey);
+
+        if (result == RESULT_CANNOT_INSERT_ROW) {
+            throw new RecoverableKeyStorageException(
+                    String.format(
+                            Locale.US, "Failed writing (%d, %s) to database.", uid, alias));
+        }
+
+        mDatabase.setShouldCreateSnapshot(userId, uid, true);
+    }
 }
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
index 5460756..1e0703a 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
@@ -16,12 +16,13 @@
 
 package com.android.server.locksettings.recoverablekeystore;
 
-import static android.security.keystore.RecoveryController.ERROR_BAD_CERTIFICATE_FORMAT;
-import static android.security.keystore.RecoveryController.ERROR_DECRYPTION_FAILED;
-import static android.security.keystore.RecoveryController.ERROR_INSECURE_USER;
-import static android.security.keystore.RecoveryController.ERROR_NO_SNAPSHOT_PENDING;
-import static android.security.keystore.RecoveryController.ERROR_SERVICE_INTERNAL_ERROR;
-import static android.security.keystore.RecoveryController.ERROR_SESSION_EXPIRED;
+import static android.security.keystore.recovery.RecoveryController.ERROR_BAD_CERTIFICATE_FORMAT;
+import static android.security.keystore.recovery.RecoveryController.ERROR_DECRYPTION_FAILED;
+import static android.security.keystore.recovery.RecoveryController.ERROR_INSECURE_USER;
+import static android.security.keystore.recovery.RecoveryController.ERROR_INVALID_KEY_FORMAT;
+import static android.security.keystore.recovery.RecoveryController.ERROR_NO_SNAPSHOT_PENDING;
+import static android.security.keystore.recovery.RecoveryController.ERROR_SERVICE_INTERNAL_ERROR;
+import static android.security.keystore.recovery.RecoveryController.ERROR_SESSION_EXPIRED;
 
 import android.Manifest;
 import android.annotation.NonNull;
@@ -34,6 +35,7 @@
 import android.os.UserHandle;
 import android.security.keystore.recovery.KeyChainProtectionParams;
 import android.security.keystore.recovery.KeyChainSnapshot;
+import android.security.keystore.recovery.RecoveryCertPath;
 import android.security.keystore.recovery.RecoveryController;
 import android.security.keystore.recovery.WrappedApplicationKey;
 import android.security.KeyStore;
@@ -41,6 +43,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.HexDump;
+import com.android.server.locksettings.recoverablekeystore.certificate.CertUtils;
 import com.android.server.locksettings.recoverablekeystore.storage.ApplicationKeyStorage;
 import com.android.server.locksettings.recoverablekeystore.certificate.CertParsingException;
 import com.android.server.locksettings.recoverablekeystore.certificate.CertValidationException;
@@ -58,6 +61,7 @@
 import java.security.UnrecoverableKeyException;
 import java.security.cert.CertPath;
 import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
 import java.security.spec.InvalidKeySpecException;
 import java.security.spec.X509EncodedKeySpec;
 import java.util.Arrays;
@@ -277,42 +281,22 @@
     }
 
     /**
-     * Updates recovery status for the application given its {@code packageName}.
-     *
-     * @param packageName which recoverable key statuses will be returned
-     * @param aliases - KeyStore aliases or {@code null} for all aliases of the app
-     * @param status - new status
+     * Sets the recovery status of key with {@code alias} to {@code status}.
      */
-    public void setRecoveryStatus(
-            @NonNull String packageName, @Nullable String[] aliases, int status)
-            throws RemoteException {
+    public void setRecoveryStatus(String alias, int status) throws RemoteException {
         checkRecoverKeyStorePermission();
-        int uid = Binder.getCallingUid();
-        if (packageName != null) {
-            // TODO: get uid for package name, when many apps are supported.
-        }
-        if (aliases == null) {
-            // Get all keys for the app.
-            Map<String, Integer> allKeys = mDatabase.getStatusForAllKeys(uid);
-            aliases = new String[allKeys.size()];
-            allKeys.keySet().toArray(aliases);
-        }
-        for (String alias: aliases) {
-            mDatabase.setRecoveryStatus(uid, alias, status);
-        }
+        mDatabase.setRecoveryStatus(Binder.getCallingUid(), alias, status);
     }
 
     /**
-     * Gets recovery status for caller or other application {@code packageName}.
-     * @param packageName which recoverable keys statuses will be returned.
+     * Returns recovery statuses for all keys belonging to the calling uid.
      *
-     * @return {@code Map} from KeyStore alias to recovery status.
+     * @return {@link Map} from key alias to recovery status. Recovery status is one of
+     *     {@link RecoveryController#RECOVERY_STATUS_SYNCED},
+     *     {@link RecoveryController#RECOVERY_STATUS_SYNC_IN_PROGRESS} or
+     *     {@link RecoveryController#RECOVERY_STATUS_PERMANENT_FAILURE}.
      */
-    public @NonNull Map<String, Integer> getRecoveryStatus(@Nullable String packageName)
-            throws RemoteException {
-        // Any application should be able to check status for its own keys.
-        // If caller is a recovery agent it can check statuses for other packages, but
-        // only for recoverable keys it manages.
+    public @NonNull Map<String, Integer> getRecoveryStatus() throws RemoteException {
         return mDatabase.getStatusForAllKeys(Binder.getCallingUid());
     }
 
@@ -369,7 +353,7 @@
     }
 
     /**
-     * Initializes recovery session.
+     * Initializes recovery session given the X509-encoded public key of the recovery service.
      *
      * @param sessionId A unique ID to identify the recovery session.
      * @param verifierPublicKey X509-encoded public key.
@@ -377,6 +361,8 @@
      * @param vaultChallenge Challenge issued by vault service.
      * @param secrets Lock-screen hashes. For now only a single secret is supported.
      * @return Encrypted bytes of recovery claim. This can then be issued to the vault service.
+     * @deprecated Use {@link #startRecoverySessionWithCertPath(String, RecoveryCertPath, byte[],
+     *         byte[], List)} instead.
      *
      * @hide
      */
@@ -398,11 +384,9 @@
         PublicKey publicKey;
         try {
             publicKey = KeySyncUtils.deserializePublicKey(verifierPublicKey);
-        } catch (NoSuchAlgorithmException e) {
-            // Should never happen
-            throw new RuntimeException(e);
         } catch (InvalidKeySpecException e) {
-            throw new ServiceSpecificException(ERROR_BAD_CERTIFICATE_FORMAT, "Not a valid X509 key");
+            throw new ServiceSpecificException(ERROR_BAD_CERTIFICATE_FORMAT,
+                    "Not a valid X509 key");
         }
         // The raw public key bytes contained in vaultParams must match the ones given in
         // verifierPublicKey; otherwise, the user secret may be decrypted by a key that is not owned
@@ -435,6 +419,54 @@
     }
 
     /**
+     * Initializes recovery session given the certificate path of the recovery service.
+     *
+     * @param sessionId A unique ID to identify the recovery session.
+     * @param verifierCertPath The certificate path of the recovery service.
+     * @param vaultParams Additional params associated with vault.
+     * @param vaultChallenge Challenge issued by vault service.
+     * @param secrets Lock-screen hashes. For now only a single secret is supported.
+     * @return Encrypted bytes of recovery claim. This can then be issued to the vault service.
+     *
+     * @hide
+     */
+    public @NonNull byte[] startRecoverySessionWithCertPath(
+            @NonNull String sessionId,
+            @NonNull RecoveryCertPath verifierCertPath,
+            @NonNull byte[] vaultParams,
+            @NonNull byte[] vaultChallenge,
+            @NonNull List<KeyChainProtectionParams> secrets)
+            throws RemoteException {
+        checkRecoverKeyStorePermission();
+
+        CertPath certPath;
+        try {
+            certPath = verifierCertPath.getCertPath();
+        } catch (CertificateException e) {
+            throw new ServiceSpecificException(ERROR_BAD_CERTIFICATE_FORMAT,
+                    "Failed decode the certificate path");
+        }
+
+        try {
+            CertUtils.validateCertPath(TrustedRootCert.TRUSTED_ROOT_CERT, certPath);
+        } catch (CertValidationException e) {
+            Log.e(TAG, "Failed to validate the given cert path", e);
+            // TODO: Change this to ERROR_INVALID_CERTIFICATE once ag/3666620 is submitted
+            throw new ServiceSpecificException(ERROR_BAD_CERTIFICATE_FORMAT, e.getMessage());
+        }
+
+        byte[] verifierPublicKey = certPath.getCertificates().get(0).getPublicKey().getEncoded();
+        if (verifierPublicKey == null) {
+            Log.e(TAG, "Failed to encode verifierPublicKey");
+            throw new ServiceSpecificException(ERROR_BAD_CERTIFICATE_FORMAT,
+                    "Failed to encode verifierPublicKey");
+        }
+
+        return startRecoverySession(
+                sessionId, verifierPublicKey, vaultParams, vaultChallenge, secrets);
+    }
+
+    /**
      * Invoked by a recovery agent after a successful recovery claim is sent to the remote vault
      * service.
      *
@@ -477,6 +509,7 @@
      *
      * <p>TODO: Once AndroidKeyStore has added move api, do not return raw bytes.
      *
+     * @deprecated
      * @hide
      */
     public byte[] generateAndStoreKey(@NonNull String alias) throws RemoteException {
@@ -526,7 +559,7 @@
      *
      * @return grant alias, which caller can use to access the key.
      */
-    public String generateKey(@NonNull String alias, byte[] account) throws RemoteException {
+    public String generateKey(@NonNull String alias) throws RemoteException {
         int uid = Binder.getCallingUid();
         int userId = UserHandle.getCallingUserId();
 
@@ -546,8 +579,58 @@
             byte[] secretKey =
                     mRecoverableKeyGenerator.generateAndStoreKey(encryptionKey, userId, uid, alias);
             mApplicationKeyStorage.setSymmetricKeyEntry(userId, uid, alias, secretKey);
-            String grantAlias = mApplicationKeyStorage.getGrantAlias(userId, uid, alias);
-            return grantAlias;
+            return mApplicationKeyStorage.getGrantAlias(userId, uid, alias);
+        } catch (KeyStoreException | InvalidKeyException | RecoverableKeyStorageException e) {
+            throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR, e.getMessage());
+        }
+    }
+
+    /**
+     * Imports a 256-bit AES-GCM key named {@code alias}. The key is stored in system service
+     * keystore namespace.
+     *
+     * @param alias the alias provided by caller as a reference to the key.
+     * @param keyBytes the raw bytes of the 256-bit AES key.
+     * @return grant alias, which caller can use to access the key.
+     * @throws RemoteException if the given key is invalid or some internal errors occur.
+     *
+     * @hide
+     */
+    public String importKey(@NonNull String alias, @NonNull byte[] keyBytes)
+            throws RemoteException {
+        if (keyBytes == null ||
+                keyBytes.length != RecoverableKeyGenerator.KEY_SIZE_BITS / Byte.SIZE) {
+            Log.e(TAG, "The given key for import doesn't have the required length "
+                    + RecoverableKeyGenerator.KEY_SIZE_BITS);
+            throw new ServiceSpecificException(ERROR_INVALID_KEY_FORMAT,
+                    "The given key does not contain " + RecoverableKeyGenerator.KEY_SIZE_BITS
+                            + " bits.");
+        }
+
+        int uid = Binder.getCallingUid();
+        int userId = UserHandle.getCallingUserId();
+
+        // TODO: Refactor RecoverableKeyGenerator to wrap the PlatformKey logic
+
+        PlatformEncryptionKey encryptionKey;
+        try {
+            encryptionKey = mPlatformKeyManager.getEncryptKey(userId);
+        } catch (NoSuchAlgorithmException e) {
+            // Impossible: all algorithms must be supported by AOSP
+            throw new RuntimeException(e);
+        } catch (KeyStoreException | UnrecoverableKeyException e) {
+            throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR, e.getMessage());
+        } catch (InsecureUserException e) {
+            throw new ServiceSpecificException(ERROR_INSECURE_USER, e.getMessage());
+        }
+
+        try {
+            // Wrap the key by the platform key and store the wrapped key locally
+            mRecoverableKeyGenerator.importKey(encryptionKey, userId, uid, alias, keyBytes);
+
+            // Import the key to Android KeyStore and get grant
+            mApplicationKeyStorage.setSymmetricKeyEntry(userId, uid, alias, keyBytes);
+            return mApplicationKeyStorage.getGrantAlias(userId, uid, alias);
         } catch (KeyStoreException | InvalidKeyException | RecoverableKeyStorageException e) {
             throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR, e.getMessage());
         }
@@ -603,14 +686,6 @@
         }
     }
 
-    private String constructLoggingMessage(String key, byte[] value) {
-        if (value == null) {
-            return key + " is null";
-        } else {
-            return key + ": " + HexDump.toHexString(value);
-        }
-    }
-
     /**
      * Uses {@code recoveryKey} to decrypt {@code applicationKeys}.
      *
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/WrappedKey.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/WrappedKey.java
index d85e89e..0077242 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/WrappedKey.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/WrappedKey.java
@@ -16,7 +16,7 @@
 
 package com.android.server.locksettings.recoverablekeystore;
 
-import android.security.keystore.RecoveryController;
+import android.security.keystore.recovery.RecoveryController;
 import android.util.Log;
 
 import java.security.InvalidAlgorithmParameterException;
@@ -107,7 +107,7 @@
      * @param keyMaterial The encrypted bytes of the key material.
      * @param platformKeyGenerationId The generation ID of the key used to wrap this key.
      *
-     * @see RecoveryController.RECOVERY_STATUS_SYNC_IN_PROGRESS
+     * @see RecoveryController#RECOVERY_STATUS_SYNC_IN_PROGRESS
      * @hide
      */
     public WrappedKey(byte[] nonce, byte[] keyMaterial, int platformKeyGenerationId) {
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/certificate/CertUtils.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/certificate/CertUtils.java
index 09ec5ad..6e08949 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/certificate/CertUtils.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/certificate/CertUtils.java
@@ -40,6 +40,7 @@
 import java.security.cert.CertPathValidator;
 import java.security.cert.CertPathValidatorException;
 import java.security.cert.CertStore;
+import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.CollectionCertStoreParameters;
@@ -292,6 +293,42 @@
         return certPath;
     }
 
+    /**
+     * Validates a given {@code CertPath} against the trusted root certificate.
+     *
+     * @param trustedRoot the trusted root certificate
+     * @param certPath the certificate path to be validated
+     * @throws CertValidationException if the given certificate path is invalid, e.g., is expired,
+     *                                 or does not have a valid signature
+     */
+    public static void validateCertPath(X509Certificate trustedRoot, CertPath certPath)
+            throws CertValidationException {
+        validateCertPath(/*validationDate=*/ null, trustedRoot, certPath);
+    }
+
+    /**
+     * Validates a given {@code CertPath} against a given {@code validationDate}. If the given
+     * validation date is null, the current date will be used.
+     */
+    @VisibleForTesting
+    static void validateCertPath(@Nullable Date validationDate, X509Certificate trustedRoot,
+            CertPath certPath) throws CertValidationException {
+        if (certPath.getCertificates().isEmpty()) {
+            throw new CertValidationException("The given certificate path is empty");
+        }
+        if (!(certPath.getCertificates().get(0) instanceof X509Certificate)) {
+            throw new CertValidationException(
+                    "The given certificate path does not contain X509 certificates");
+        }
+
+        List<X509Certificate> certificates = (List<X509Certificate>) certPath.getCertificates();
+        X509Certificate leafCert = certificates.get(0);
+        List<X509Certificate> intermediateCerts =
+                certificates.subList(/*fromIndex=*/ 1, certificates.size());
+
+        validateCert(validationDate, trustedRoot, intermediateCerts, leafCert);
+    }
+
     @VisibleForTesting
     static CertPath buildCertPath(PKIXParameters pkixParams) throws CertValidationException {
         CertPathBuilder certPathBuilder;
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/ApplicationKeyStorage.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/ApplicationKeyStorage.java
index 600a534..3d97623 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/ApplicationKeyStorage.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/ApplicationKeyStorage.java
@@ -16,15 +16,13 @@
 
 package com.android.server.locksettings.recoverablekeystore.storage;
 
-import static android.security.keystore.RecoveryController.ERROR_SERVICE_INTERNAL_ERROR;
+import static android.security.keystore.recovery.RecoveryController.ERROR_SERVICE_INTERNAL_ERROR;
 
 import android.annotation.Nullable;
 import android.os.ServiceSpecificException;
 import android.security.Credentials;
-import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyProperties;
 import android.security.keystore.KeyProtection;
-import android.security.keystore.recovery.KeyChainSnapshot;
 import android.security.KeyStore;
 
 import com.android.internal.annotations.VisibleForTesting;
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbContract.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbContract.java
index 1cb5d91..8983ec3 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbContract.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbContract.java
@@ -70,6 +70,122 @@
     }
 
     /**
+     * Table holding encrypted snapshots of the recoverable key store.
+     */
+    static class SnapshotsEntry implements BaseColumns {
+        static final String TABLE_NAME = "snapshots";
+
+        /**
+         * The version number of the snapshot.
+         */
+        static final String COLUMN_NAME_VERSION = "version";
+
+        /**
+         * The ID of the user whose keystore was snapshotted.
+         */
+        static final String COLUMN_NAME_USER_ID = "user_id";
+
+        /**
+         * The UID of the app that owns the snapshot (i.e., the recovery agent).
+         */
+        static final String COLUMN_NAME_UID = "uid";
+
+        /**
+         * The maximum number of attempts allowed to attempt to decrypt the recovery key.
+         */
+        static final String COLUMN_NAME_MAX_ATTEMPTS = "max_attempts";
+
+        /**
+         * The ID of the counter in the trusted hardware module.
+         */
+        static final String COLUMN_NAME_COUNTER_ID = "counter_id";
+
+        /**
+         * Server parameters used to help identify the device (during recovery).
+         */
+        static final String SERVER_PARAMS = "server_params";
+
+        /**
+         * The public key of the trusted hardware module. This key has been used to encrypt the
+         * snapshot, to ensure that it can only be read by the trusted module.
+         */
+        static final String TRUSTED_HARDWARE_PUBLIC_KEY = "thm_public_key";
+
+        /**
+         * {@link java.security.cert.CertPath} signing the trusted hardware module to whose public
+         * key this snapshot is encrypted.
+         */
+        static final String CERT_PATH = "cert_path";
+
+        /**
+         * The recovery key, encrypted with the user's lock screen and the trusted hardware module's
+         * public key.
+         */
+        static final String ENCRYPTED_RECOVERY_KEY = "encrypted_recovery_key";
+    }
+
+    /**
+     * Table holding encrypted keys belonging to a particular snapshot.
+     */
+    static class SnapshotKeysEntry implements BaseColumns {
+        static final String TABLE_NAME = "snapshot_keys";
+
+        /**
+         * ID of the associated snapshot entry in {@link SnapshotsEntry}.
+         */
+        static final String COLUMN_NAME_SNAPSHOT_ID = "snapshot_id";
+
+        /**
+         * Alias of the key.
+         */
+        static final String COLUMN_NAME_ALIAS = "alias";
+
+        /**
+         * Key material, encrypted with the recovery key from the snapshot.
+         */
+        static final String COLUMN_NAME_ENCRYPTED_BYTES = "encrypted_key_bytes";
+    }
+
+    /**
+     * A layer of protection associated with a snapshot.
+     */
+    static class SnapshotProtectionParams implements BaseColumns {
+        static final String TABLE_NAME = "snapshot_protection_params";
+
+        /**
+         * ID of the associated snapshot entry in {@link SnapshotsEntry}.
+         */
+        static final String COLUMN_NAME_SNAPSHOT_ID = "snapshot_id";
+
+        /**
+         * Type of secret used to generate recovery key. One of
+         * {@link android.security.keystore.recovery.KeyChainProtectionParams#TYPE_LOCKSCREEN} or
+         * {@link android.security.keystore.recovery.KeyChainProtectionParams#TYPE_CUSTOM_PASSWORD}.
+         */
+        static final String COLUMN_NAME_SECRET_TYPE = "secret_type";
+
+        /**
+         * If a lock screen, the type of UI used. One of
+         * {@link android.security.keystore.recovery.KeyChainProtectionParams#UI_FORMAT_PATTERN},
+         * {@link android.security.keystore.recovery.KeyChainProtectionParams#UI_FORMAT_PIN}, or
+         * {@link android.security.keystore.recovery.KeyChainProtectionParams#UI_FORMAT_PASSWORD}.
+         */
+        static final String COLUMN_NAME_LOCKSCREEN_UI_TYPE = "lock_screen_ui_type";
+
+        /**
+         * The algorithm used to derive cryptographic material from the key and salt. One of
+         * {@link android.security.keystore.recovery.KeyDerivationParams#ALGORITHM_SHA256} or
+         * {@link android.security.keystore.recovery.KeyDerivationParams#ALGORITHM_ARGON2ID}.
+         */
+        static final String COLUMN_NAME_KEY_DERIVATION_ALGORITHM = "key_derivation_algorithm";
+
+        /**
+         * The salt used along with the secret to generate cryptographic material.
+         */
+        static final String COLUMN_NAME_KEY_DERIVATION_SALT = "key_derivation_salt";
+    }
+
+    /**
      * Recoverable KeyStore metadata for a specific user profile.
      */
     static class UserMetadataEntry implements BaseColumns {
diff --git a/services/core/java/com/android/server/media/MediaSession2Record.java b/services/core/java/com/android/server/media/MediaSession2Record.java
deleted file mode 100644
index 97c7bf6c..0000000
--- a/services/core/java/com/android/server/media/MediaSession2Record.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.media;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.media.MediaController2;
-import android.media.MediaSession2;
-import android.media.SessionToken2;
-import android.util.Log;
-import java.util.concurrent.Executor;
-
-/**
- * Records a {@link MediaSession2} and holds {@link MediaController2}.
- * <p>
- * Owner of this object should handle synchronization.
- */
-class MediaSession2Record {
-    interface SessionDestroyedListener {
-        void onSessionDestroyed(MediaSession2Record record);
-    }
-
-    private static final String TAG = "Session2Record";
-    private static final boolean DEBUG = true; // TODO(jaewan): Change
-
-    private final Context mContext;
-    private final SessionToken2 mSessionToken;
-    private final SessionDestroyedListener mSessionDestroyedListener;
-
-    // TODO(jaewan): Replace these with the mContext.getMainExecutor()
-    private final Executor mMainExecutor;
-
-    private MediaController2 mController;
-
-    /**
-     * Constructor
-     */
-    public MediaSession2Record(@NonNull Context context, @NonNull SessionToken2 token,
-            @NonNull SessionDestroyedListener listener) {
-        mContext = context;
-        mSessionToken = token;
-        mSessionDestroyedListener = listener;
-        mMainExecutor = (runnable) -> runnable.run();
-    }
-
-    public Context getContext() {
-        return mContext;
-    }
-
-    public void onSessionDestroyed() {
-        if (mController != null) {
-            mController.close();
-            // close() triggers ControllerCallback.onDisconnected() here already.
-            mController = null;
-        }
-    }
-
-    public boolean onSessionCreated(SessionToken2 token) {
-        if (mController != null) {
-            // Disclaimer: This may fail if following happens for an app.
-            //             Step 1) Create a session in the process #1
-            //             Step 2) Process #1 is killed
-            //             Step 3) Before the death of process #1 is delivered,
-            //                     (i.e. ControllerCallback#onDisconnected is called),
-            //                     new process is started and create another session with the same
-            //                     id in the new process.
-            //             Step 4) fail!!! But this is tricky case that wouldn't happen in normal.
-            Log.w(TAG, "Cannot create a new session with the id=" + token.getId() + " in the"
-                    + " pkg=" + token.getPackageName() + ". ID should be unique in a package");
-            return false;
-        }
-        mController = new MediaController2(mContext, token, mMainExecutor,
-                new ControllerCallback());
-        return true;
-    }
-
-    /**
-     * @return token
-     */
-    public SessionToken2 getToken() {
-        return mSessionToken;
-    }
-
-    /**
-     * @return controller
-     */
-    public MediaController2 getController() {
-        return mController;
-    }
-
-    @Override
-    public String toString() {
-        return getToken() == null
-                ? "Token {null}" : "SessionRecord {" + getToken().toString() + "}";
-    }
-
-    private class ControllerCallback extends MediaController2.ControllerCallback {
-        // This is called on the random thread with no lock. So place ensure followings.
-        //   1. Don't touch anything in the parent class that needs synchronization.
-        //      All other APIs in the MediaSession2Record assumes that server would use them with
-        //      the lock hold.
-        //   2. This can be called after the controller registered is closed.
-        @Override
-        public void onDisconnected() {
-            if (DEBUG) {
-                Log.d(TAG, "onDisconnected, token=" + getToken());
-            }
-            mSessionDestroyedListener.onSessionDestroyed(MediaSession2Record.this);
-        }
-    };
-}
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 21d86c4..b110e88 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -42,6 +42,7 @@
 import android.media.IAudioService;
 import android.media.IRemoteVolumeController;
 import android.media.ISessionTokensListener;
+import android.media.MediaController2;
 import android.media.MediaLibraryService2;
 import android.media.MediaSessionService2;
 import android.media.SessionToken2;
@@ -70,6 +71,7 @@
 import android.provider.Settings;
 import android.speech.RecognizerIntent;
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -86,7 +88,10 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * System implementation of MediaSessionManager
@@ -132,14 +137,7 @@
     // MediaSession2 support
     // TODO(jaewan): Support multi-user and managed profile.
     // TODO(jaewan): Make it priority list for handling volume/media key.
-    private final List<MediaSession2Record> mSessions = new ArrayList<>();
-
-    private final MediaSession2Record.SessionDestroyedListener mSessionDestroyedListener =
-            (record) -> {
-                synchronized (mLock) {
-                    destroySessionLocked(record);
-                }
-            };
+    private final Map<SessionToken2, MediaController2> mSessionRecords = new ArrayMap<>();
 
     public MediaSessionService(Context context) {
         super(context);
@@ -523,12 +521,13 @@
         synchronized (mLock) {
             // List to keep the session services that need be removed because they don't exist
             // in the 'services' above.
-            List<MediaSession2Record> removeCandidates = new ArrayList<>();
-            for (int i = 0; i < mSessions.size(); i++) {
-                if (mSessions.get(i).getToken().getType() != TYPE_SESSION) {
-                    removeCandidates.add(mSessions.get(i));
+            Set<SessionToken2> sessionTokensToRemove = new HashSet<>();
+            for (SessionToken2 token : mSessionRecords.keySet()) {
+                if (token.getType() != TYPE_SESSION) {
+                    sessionTokensToRemove.add(token);
                 }
             }
+
             for (int i = 0; i < services.size(); i++) {
                 if (services.get(i) == null || services.get(i).serviceInfo == null) {
                     continue;
@@ -550,57 +549,25 @@
                     Log.w(TAG, "Invalid session service", e);
                     continue;
                 }
-                boolean found = false;
-                for (int j = 0; j < mSessions.size(); j++) {
-                    if (token.equals(mSessions.get(j).getToken())) {
-                        // If the token already exists, keep it in the mSessions.
-                        removeCandidates.remove(mSessions.get(j));
-                        found = true;
-                        break;
-                    }
-                }
-                if (!found) {
+                // If the token already exists, keep it in the mSessions by removing from
+                // sessionTokensToRemove.
+                if (!sessionTokensToRemove.remove(token)) {
                     // New session service is found.
-                    MediaSession2Record record = new MediaSession2Record(getContext(),
-                            token, mSessionDestroyedListener);
-                    mSessions.add(record);
+                    mSessionRecords.put(token, null);
                 }
             }
-            for (int i = 0; i < removeCandidates.size(); i++) {
-                removeCandidates.get(i).onSessionDestroyed();
-                mSessions.remove(removeCandidates.get(i));
+            for (SessionToken2 token : sessionTokensToRemove) {
+                mSessionRecords.remove(token);
             }
-            removeCandidates.clear();
         }
         if (DEBUG) {
-            Log.d(TAG, "Found " + mSessions.size() + " session services");
-            for (int i = 0; i < mSessions.size(); i++) {
-                Log.d(TAG, "   " + mSessions.get(i).getToken());
+            Log.d(TAG, "Found " + mSessionRecords.size() + " session services");
+            for (SessionToken2 token : mSessionRecords.keySet()) {
+                Log.d(TAG, "   " + token);
             }
         }
     }
 
-    private MediaSession2Record getSessionRecordLocked(int uid, String packageName, String id) {
-        for (int i = 0; i < mSessions.size(); i++) {
-            SessionToken2 token = mSessions.get(i).getToken();
-            if (token.getUid() == uid && token.getPackageName().equals(packageName)
-                    && token.getId().equals(id)) {
-                return mSessions.get(i);
-            }
-        }
-        return null;
-    }
-
-    private void destroySessionLocked(MediaSession2Record record) {
-        if (DEBUG) {
-            Log.d(TAG, record.toString() + " becomes inactive");
-        }
-        record.onSessionDestroyed();
-        if (record.getToken().getType() == TYPE_SESSION) {
-            mSessions.remove(record);
-        }
-    }
-
     private void enforcePackageName(String packageName, int uid) {
         if (TextUtils.isEmpty(packageName)) {
             throw new IllegalArgumentException("packageName may not be empty");
@@ -811,6 +778,16 @@
         return mUserRecords.get(fullUserId);
     }
 
+    void destroySession2Internal(SessionToken2 token) {
+        synchronized (mLock) {
+            if (token.getType() == SessionToken2.TYPE_SESSION) {
+                mSessionRecords.remove(token);
+            } else {
+                mSessionRecords.put(token, null);
+            }
+        }
+    }
+
     /**
      * Information about a full user and its corresponding managed profiles.
      *
@@ -1502,66 +1479,75 @@
 
                 // TODO(jaewan): Remove this debug command before ship.
                 if (args != null && args.length > 0 && "--purge".equals(args[0])) {
-                    mSessions.clear();
+                    mSessionRecords.clear();
                 }
                 pw.println();
-                pw.println("Session2: size=" + mSessions.size());
-                for (int i = 0; i < mSessions.size(); i++) {
-                    pw.println("  " + mSessions.get(i));
+                pw.println("Session2: size=" + mSessionRecords.size());
+                for (SessionToken2 token : mSessionRecords.keySet()) {
+                    pw.println("  " + token);
                 }
             }
         }
 
+        /**
+         * Called when a {@link android.media.MediaSession2} instance is created.
+         * <p>
+         * This does two things.
+         *   1. Keep the newly created session in the service
+         *   2. Do sanity check to ensure unique id per package, and return result
+         *
+         * @param sessionToken SessionToken2 object in bundled form
+         * @return {@code true} if the session's id isn't used by the package now. {@code false}
+         *     otherwise.
+         */
         @Override
-        public boolean onSessionCreated(Bundle sessionToken) {
+        public boolean createSession2(Bundle sessionToken) {
             final int uid = Binder.getCallingUid();
-            final int pid = Binder.getCallingPid();
             final SessionToken2 token = SessionToken2.fromBundle(getContext(), sessionToken);
             if (token == null || token.getUid() != uid) {
                 Log.w(TAG, "onSessionCreated failed, expected caller uid=" + token.getUid()
                         + " but from uid=" + uid);
             }
             if (DEBUG) {
-                Log.d(TAG, "onSessionCreated " + token);
+                Log.d(TAG, "createSession2: " + token);
             }
             synchronized (mLock) {
-                MediaSession2Record record = getSessionRecordLocked(
-                        uid, token.getPackageName(), token.getId());
-                if (record != null) {
-                    return record.onSessionCreated(token);
-                } else {
-                    record = new MediaSession2Record(
-                            getContext(), token, mSessionDestroyedListener);
-                    mSessions.add(record);
-                    return record.onSessionCreated(token);
+                MediaController2 controller = mSessionRecords.get(token);
+                if (controller != null && controller.isConnected()) {
+                    return false;
                 }
+                Context context = getContext();
+                mSessionRecords.put(token, new MediaController2(context, token,
+                        context.getMainExecutor(), new ControllerCallback(token)));
+                return true;
             }
         }
 
+        /**
+         * Called when a {@link android.media.MediaSession2} instance is closed. (i.e. destroyed)
+         * <p>
+         * Ideally service should know that a session is destroyed through the
+         * {@link android.media.MediaController2.ControllerCallback#onDisconnected()}, which is
+         * asynchronous call. However, we also need synchronous way together to address timing
+         * issue. If the package recreates the session almost immediately, which happens commonly
+         * for tests, service will reject the creation through {@link #onSessionCreated(Bundle)}
+         * if the service hasn't notified previous destroy yet. This synchronous API will address
+         * the issue.
+         *
+         * @param sessionToken SessionToken2 object in bundled form
+         */
         @Override
-        public void onSessionDestroyed(Bundle sessionToken) {
+        public void destroySession2(Bundle sessionToken) {
             final int uid = Binder.getCallingUid();
-            final int pid = Binder.getCallingPid();
             final SessionToken2 token = SessionToken2.fromBundle(getContext(), sessionToken);
             if (token == null || token.getUid() != uid) {
                 Log.w(TAG, "onSessionDestroyed failed, expected caller uid=" + token.getUid()
                         + " but from uid=" + uid);
             }
             if (DEBUG) {
-                Log.d(TAG, "onSessionDestroyed " + token);
+                Log.d(TAG, "destroySession2 " + token);
             }
-            synchronized (mLock) {
-                MediaSession2Record record = getSessionRecordLocked(
-                        uid, token.getPackageName(), token.getId());
-                if (record != null) {
-                    record.onSessionDestroyed();
-                } else {
-                    if (DEBUG) {
-                        Log.d(TAG, "Cannot find a session record to destroy. uid=" + uid
-                                + ", pkg=" + token.getPackageName() + ", id=" + token.getId());
-                    }
-                }
-            }
+            destroySession2Internal(token);
         }
 
         // TODO(jaewan): Protect this API with permission
@@ -1570,19 +1556,15 @@
                 boolean sessionServiceOnly) throws RemoteException {
             List<Bundle> tokens = new ArrayList<>();
             synchronized (mLock) {
-                for (int i = 0; i < mSessions.size(); i++) {
-                    MediaSession2Record record = mSessions.get(i);
-                    boolean isSessionService = (record.getToken().getType() != TYPE_SESSION);
-                    boolean isActive = record.getController() != null;
-                    if ((!activeSessionOnly && isSessionService)
-                            || (!sessionServiceOnly && isActive)) {
-                        SessionToken2 token = record.getToken();
-                        if (token != null) {
-                            tokens.add(token.toBundle());
-                        } else {
-                            Log.wtf(TAG, "Null token for record=" + record);
-                        }
+                for (Map.Entry<SessionToken2, MediaController2> record
+                        : mSessionRecords.entrySet()) {
+                    boolean isSessionService = (record.getKey().getType() != TYPE_SESSION);
+                    boolean isActive = record.getValue() != null;
+                    if ((activeSessionOnly && !isActive)
+                            || (sessionServiceOnly && !isSessionService) ){
+                        continue;
                     }
+                    tokens.add(record.getKey().toBundle());
                 }
             }
             return tokens;
@@ -1994,4 +1976,18 @@
             obtainMessage(MSG_SESSIONS_CHANGED, userIdInteger).sendToTarget();
         }
     }
+
+    private class ControllerCallback extends MediaController2.ControllerCallback {
+
+        private final SessionToken2 mToken;
+
+        ControllerCallback(SessionToken2 token) {
+            mToken = token;
+        }
+
+        @Override
+        public void onDisconnected() {
+            destroySession2Internal(mToken);
+        }
+    };
 }
diff --git a/services/core/java/com/android/server/media/MediaUpdateService.java b/services/core/java/com/android/server/media/MediaUpdateService.java
index 6921ccd..f38b353 100644
--- a/services/core/java/com/android/server/media/MediaUpdateService.java
+++ b/services/core/java/com/android/server/media/MediaUpdateService.java
@@ -16,27 +16,21 @@
 
 package com.android.server.media;
 
-import android.content.Context;
-import android.content.Intent;
-import android.media.IMediaResourceMonitor;
-import android.os.Binder;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.Log;
-import android.util.Slog;
-import com.android.server.SystemService;
-
 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.media.IMediaExtractorUpdateService;
 import android.os.IBinder;
+import android.os.Handler;
 import android.os.PatternMatcher;
 import android.os.ServiceManager;
-import android.media.IMediaExtractorUpdateService;
-
-import java.lang.Exception;
+import android.os.UserHandle;
+import android.util.Log;
+import android.util.Slog;
+import com.android.server.SystemService;
 
 /** This class provides a system service that manages media framework updates. */
 public class MediaUpdateService extends SystemService {
@@ -46,9 +40,11 @@
     private static final String EXTRACTOR_UPDATE_SERVICE_NAME = "media.extractor.update";
 
     private IMediaExtractorUpdateService mMediaExtractorUpdateService;
+    final Handler mHandler;
 
     public MediaUpdateService(Context context) {
         super(context);
+        mHandler = new Handler();
     }
 
     @Override
@@ -77,7 +73,12 @@
         }
         if (binder != null) {
             mMediaExtractorUpdateService = IMediaExtractorUpdateService.Stub.asInterface(binder);
-            packageStateChanged();
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    packageStateChanged();
+                }
+            });
         } else {
             Slog.w(TAG, EXTRACTOR_UPDATE_SERVICE_NAME + " not found.");
         }
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index bd9ec55..ab55553 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -28,6 +28,11 @@
 import static android.content.Intent.ACTION_USER_ADDED;
 import static android.content.Intent.ACTION_USER_REMOVED;
 import static android.content.Intent.EXTRA_UID;
+import static android.content.pm.PackageManager.MATCH_ANY_USER;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
+import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
+import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
@@ -61,9 +66,7 @@
 import static android.net.NetworkPolicyManager.resolveNetworkId;
 import static android.net.NetworkPolicyManager.uidPoliciesToString;
 import static android.net.NetworkPolicyManager.uidRulesToString;
-import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER;
-import static android.net.NetworkTemplate.MATCH_MOBILE_4G;
-import static android.net.NetworkTemplate.MATCH_MOBILE_ALL;
+import static android.net.NetworkTemplate.MATCH_MOBILE;
 import static android.net.NetworkTemplate.MATCH_WIFI;
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
 import static android.net.TrafficStats.MB_IN_BYTES;
@@ -71,7 +74,6 @@
 import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED;
 import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT;
 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-import static android.text.format.DateUtils.DAY_IN_MILLIS;
 
 import static com.android.internal.util.ArrayUtils.appendInt;
 import static com.android.internal.util.Preconditions.checkNotNull;
@@ -139,15 +141,16 @@
 import android.net.NetworkRequest;
 import android.net.NetworkSpecifier;
 import android.net.NetworkState;
+import android.net.NetworkStats;
 import android.net.NetworkTemplate;
 import android.net.StringNetworkSpecifier;
 import android.net.TrafficStats;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
+import android.os.BestClock;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Environment;
-import android.os.BestClock;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IDeviceIdleController;
@@ -359,7 +362,7 @@
 
     private final Context mContext;
     private final IActivityManager mActivityManager;
-    private final INetworkStatsService mNetworkStats;
+    private NetworkStatsManagerInternal mNetworkStats;
     private final INetworkManagementService mNetworkManager;
     private UsageStatsManagerInternal mUsageStats;
     private final Clock mClock;
@@ -516,10 +519,9 @@
     // TODO: migrate notifications to SystemUI
 
     public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
-            INetworkStatsService networkStats, INetworkManagementService networkManagement) {
-        this(context, activityManager, networkStats, networkManagement,
-                AppGlobals.getPackageManager(), getDefaultClock(), getDefaultSystemDir(),
-                false);
+            INetworkManagementService networkManagement) {
+        this(context, activityManager, networkManagement, AppGlobals.getPackageManager(),
+                getDefaultClock(), getDefaultSystemDir(), false);
     }
 
     private static @NonNull File getDefaultSystemDir() {
@@ -532,11 +534,10 @@
     }
 
     public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
-            INetworkStatsService networkStats, INetworkManagementService networkManagement,
-            IPackageManager pm, Clock clock, File systemDir, boolean suppressDefaultPolicy) {
+            INetworkManagementService networkManagement, IPackageManager pm, Clock clock,
+            File systemDir, boolean suppressDefaultPolicy) {
         mContext = checkNotNull(context, "missing context");
         mActivityManager = checkNotNull(activityManager, "missing activityManager");
-        mNetworkStats = checkNotNull(networkStats, "missing networkStats");
         mNetworkManager = checkNotNull(networkManagement, "missing networkManagement");
         mDeviceIdleController = IDeviceIdleController.Stub.asInterface(ServiceManager.getService(
                 Context.DEVICE_IDLE_CONTROLLER));
@@ -660,6 +661,7 @@
             }
 
             mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
+            mNetworkStats = LocalServices.getService(NetworkStatsManagerInternal.class);
 
             synchronized (mUidRulesFirstLock) {
                 synchronized (mNetworkPoliciesSecondLock) {
@@ -1063,9 +1065,9 @@
             if (policy.isOverLimit(totalBytes)) {
                 final boolean snoozedThisCycle = policy.lastLimitSnooze >= cycleStart;
                 if (snoozedThisCycle) {
-                    enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes);
+                    enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes, null);
                 } else {
-                    enqueueNotification(policy, TYPE_LIMIT, totalBytes);
+                    enqueueNotification(policy, TYPE_LIMIT, totalBytes, null);
                     notifyOverLimitNL(policy.template);
                 }
 
@@ -1074,7 +1076,7 @@
 
                 final boolean snoozedThisCycle = policy.lastWarningSnooze >= cycleStart;
                 if (policy.isOverWarning(totalBytes) && !snoozedThisCycle) {
-                    enqueueNotification(policy, TYPE_WARNING, totalBytes);
+                    enqueueNotification(policy, TYPE_WARNING, totalBytes, null);
                 }
             }
 
@@ -1082,7 +1084,9 @@
             // far past the plan limits.
             if (policy.limitBytes != LIMIT_DISABLED) {
                 final long recentDuration = TimeUnit.DAYS.toMillis(4);
-                final long recentBytes = getTotalBytes(policy.template, now - recentDuration, now);
+                final long recentStart = now - recentDuration;
+                final long recentEnd = now;
+                final long recentBytes = getTotalBytes(policy.template, recentStart, recentEnd);
 
                 final long cycleDuration = cycleEnd - cycleStart;
                 final long projectedBytes = (recentBytes * cycleDuration) / recentDuration;
@@ -1096,7 +1100,8 @@
                 final boolean snoozedRecently = policy.lastRapidSnooze >= now
                         - DateUtils.DAY_IN_MILLIS;
                 if (projectedBytes > alertBytes && !snoozedRecently) {
-                    enqueueNotification(policy, TYPE_RAPID, 0);
+                    enqueueNotification(policy, TYPE_RAPID, 0,
+                            findRapidBlame(policy.template, recentStart, recentEnd));
                 }
             }
         }
@@ -1111,6 +1116,45 @@
     }
 
     /**
+     * Attempt to find a specific app to blame for rapid data usage during the
+     * given time period.
+     */
+    private @Nullable ApplicationInfo findRapidBlame(NetworkTemplate template,
+            long start, long end) {
+        long totalBytes = 0;
+        long maxBytes = 0;
+        int maxUid = 0;
+
+        final NetworkStats stats = getNetworkUidBytes(template, start, end);
+        NetworkStats.Entry entry = null;
+        for (int i = 0; i < stats.size(); i++) {
+            entry = stats.getValues(i, entry);
+            final long bytes = entry.rxBytes + entry.txBytes;
+            totalBytes += bytes;
+            if (bytes > maxBytes) {
+                maxBytes = bytes;
+                maxUid = entry.uid;
+            }
+        }
+
+        // Only point blame if the majority of usage was done by a single app.
+        // TODO: support shared UIDs
+        if (maxBytes > 0 && maxBytes > totalBytes / 2) {
+            final String[] packageNames = mContext.getPackageManager().getPackagesForUid(maxUid);
+            if (packageNames.length == 1) {
+                try {
+                    return mContext.getPackageManager().getApplicationInfo(packageNames[0],
+                            MATCH_ANY_USER | MATCH_DISABLED_COMPONENTS | MATCH_DIRECT_BOOT_AWARE
+                                    | MATCH_DIRECT_BOOT_UNAWARE | MATCH_UNINSTALLED_PACKAGES);
+                } catch (NameNotFoundException ignored) {
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /**
      * Test if given {@link NetworkTemplate} is relevant to user based on
      * current device state, such as when
      * {@link TelephonyManager#getSubscriberId()} matches. This is regardless of
@@ -1157,7 +1201,8 @@
      * Show notification for combined {@link NetworkPolicy} and specific type,
      * like {@link #TYPE_LIMIT}. Okay to call multiple times.
      */
-    private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes) {
+    private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes,
+            ApplicationInfo rapidBlame) {
         final NotificationId notificationId = new NotificationId(policy, type);
         final Notification.Builder builder =
                 new Notification.Builder(mContext, SystemNotificationChannels.NETWORK_ALERTS);
@@ -1167,16 +1212,15 @@
                 com.android.internal.R.color.system_notification_accent_color));
 
         final Resources res = mContext.getResources();
-        CharSequence body = null;
+        final CharSequence title;
+        final CharSequence body;
         switch (type) {
             case TYPE_WARNING: {
-                final CharSequence title = res.getText(R.string.data_usage_warning_title);
-                body = res.getString(R.string.data_usage_warning_body);
+                title = res.getText(R.string.data_usage_warning_title);
+                body = res.getString(R.string.data_usage_warning_body,
+                        Formatter.formatFileSize(mContext, totalBytes));
 
                 builder.setSmallIcon(R.drawable.stat_notify_error);
-                builder.setTicker(title);
-                builder.setContentTitle(title);
-                builder.setContentText(body);
 
                 final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template);
                 builder.setDeleteIntent(PendingIntent.getBroadcast(
@@ -1189,34 +1233,20 @@
                 break;
             }
             case TYPE_LIMIT: {
-                body = res.getText(R.string.data_usage_limit_body);
-
-                final CharSequence title;
-                int icon = R.drawable.stat_notify_disabled_data;
                 switch (policy.template.getMatchRule()) {
-                    case MATCH_MOBILE_3G_LOWER:
-                        title = res.getText(R.string.data_usage_3g_limit_title);
-                        break;
-                    case MATCH_MOBILE_4G:
-                        title = res.getText(R.string.data_usage_4g_limit_title);
-                        break;
-                    case MATCH_MOBILE_ALL:
+                    case MATCH_MOBILE:
                         title = res.getText(R.string.data_usage_mobile_limit_title);
                         break;
                     case MATCH_WIFI:
                         title = res.getText(R.string.data_usage_wifi_limit_title);
-                        icon = R.drawable.stat_notify_error;
                         break;
                     default:
-                        title = null;
-                        break;
+                        return;
                 }
+                body = res.getText(R.string.data_usage_limit_body);
 
                 builder.setOngoing(true);
-                builder.setSmallIcon(icon);
-                builder.setTicker(title);
-                builder.setContentTitle(title);
-                builder.setContentText(body);
+                builder.setSmallIcon(R.drawable.stat_notify_disabled_data);
 
                 final Intent intent = buildNetworkOverLimitIntent(res, policy.template);
                 builder.setContentIntent(PendingIntent.getActivity(
@@ -1224,34 +1254,22 @@
                 break;
             }
             case TYPE_LIMIT_SNOOZED: {
-                final long overBytes = totalBytes - policy.limitBytes;
-                body = res.getString(R.string.data_usage_limit_snoozed_body,
-                        Formatter.formatFileSize(mContext, overBytes));
-
-                final CharSequence title;
                 switch (policy.template.getMatchRule()) {
-                    case MATCH_MOBILE_3G_LOWER:
-                        title = res.getText(R.string.data_usage_3g_limit_snoozed_title);
-                        break;
-                    case MATCH_MOBILE_4G:
-                        title = res.getText(R.string.data_usage_4g_limit_snoozed_title);
-                        break;
-                    case MATCH_MOBILE_ALL:
+                    case MATCH_MOBILE:
                         title = res.getText(R.string.data_usage_mobile_limit_snoozed_title);
                         break;
                     case MATCH_WIFI:
                         title = res.getText(R.string.data_usage_wifi_limit_snoozed_title);
                         break;
                     default:
-                        title = null;
-                        break;
+                        return;
                 }
+                final long overBytes = totalBytes - policy.limitBytes;
+                body = res.getString(R.string.data_usage_limit_snoozed_body,
+                        Formatter.formatFileSize(mContext, overBytes));
 
                 builder.setOngoing(true);
                 builder.setSmallIcon(R.drawable.stat_notify_error);
-                builder.setTicker(title);
-                builder.setContentTitle(title);
-                builder.setContentText(body);
                 builder.setChannelId(SystemNotificationChannels.NETWORK_STATUS);
 
                 final Intent intent = buildViewDataUsageIntent(res, policy.template);
@@ -1260,13 +1278,15 @@
                 break;
             }
             case TYPE_RAPID: {
-                final CharSequence title = res.getText(R.string.data_usage_rapid_title);
-                body = res.getText(R.string.data_usage_rapid_body);
+                title = res.getText(R.string.data_usage_rapid_title);
+                if (rapidBlame != null) {
+                    body = res.getString(R.string.data_usage_rapid_app_body,
+                            rapidBlame.loadLabel(mContext.getPackageManager()));
+                } else {
+                    body = res.getString(R.string.data_usage_rapid_body);
+                }
 
                 builder.setSmallIcon(R.drawable.stat_notify_error);
-                builder.setTicker(title);
-                builder.setContentTitle(title);
-                builder.setContentText(body);
 
                 final Intent snoozeIntent = buildSnoozeRapidIntent(policy.template);
                 builder.setDeleteIntent(PendingIntent.getBroadcast(
@@ -1277,11 +1297,15 @@
                         mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT));
                 break;
             }
+            default: {
+                return;
+            }
         }
 
-        if (!TextUtils.isEmpty(body)) {
-            builder.setStyle(new Notification.BigTextStyle().bigText(body));
-        }
+        builder.setTicker(title);
+        builder.setContentTitle(title);
+        builder.setContentText(body);
+        builder.setStyle(new Notification.BigTextStyle().bigText(body));
 
         mContext.getSystemService(NotificationManager.class).notifyAsUser(notificationId.getTag(),
                 notificationId.getId(), builder.build(), UserHandle.ALL);
@@ -1537,7 +1561,7 @@
         // TODO: reach into ConnectivityManager to proactively disable bringing
         // up this network, since we know that traffic will be blocked.
 
-        if (template.getMatchRule() == MATCH_MOBILE_ALL) {
+        if (template.getMatchRule() == MATCH_MOBILE) {
             // If mobile data usage hits the limit or if the user resumes the data, we need to
             // notify telephony.
             final SubscriptionManager sm = mContext.getSystemService(SubscriptionManager.class);
@@ -1954,9 +1978,7 @@
                             metered = readBooleanAttribute(in, ATTR_METERED);
                         } else {
                             switch (networkTemplate) {
-                                case MATCH_MOBILE_3G_LOWER:
-                                case MATCH_MOBILE_4G:
-                                case MATCH_MOBILE_ALL:
+                                case MATCH_MOBILE:
                                     metered = true;
                                     break;
                                 default:
@@ -3243,8 +3265,6 @@
         }
         try {
             mNetworkStats.setUidForeground(uid, uidForeground);
-        } catch (RemoteException e) {
-            // ignored; service lives in system_server
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
         }
@@ -3927,7 +3947,8 @@
             extends UsageStatsManagerInternal.AppIdleStateChangeListener {
 
         @Override
-        public void onAppIdleStateChanged(String packageName, int userId, boolean idle, int bucket) {
+        public void onAppIdleStateChanged(String packageName, int userId, boolean idle, int bucket,
+                int reason) {
             try {
                 final int uid = mContext.getPackageManager().getPackageUidAsUser(packageName,
                         PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
@@ -4028,13 +4049,9 @@
 
                     synchronized (mNetworkPoliciesSecondLock) {
                         if (mMeteredIfaces.contains(iface)) {
-                            try {
-                                // force stats update to make sure we have
-                                // numbers that caused alert to trigger.
-                                mNetworkStats.forceUpdate();
-                            } catch (RemoteException e) {
-                                // ignored; service lives in system_server
-                            }
+                            // force stats update to make sure we have
+                            // numbers that caused alert to trigger.
+                            mNetworkStats.forceUpdate();
 
                             updateNetworkEnabledNL();
                             updateNotificationsNL();
@@ -4075,14 +4092,10 @@
                 }
                 case MSG_ADVISE_PERSIST_THRESHOLD: {
                     final long lowestRule = (Long) msg.obj;
-                    try {
-                        // make sure stats are recorded frequently enough; we aim
-                        // for 2MB threshold for 2GB/month rules.
-                        final long persistThreshold = lowestRule / 1000;
-                        mNetworkStats.advisePersistThreshold(persistThreshold);
-                    } catch (RemoteException e) {
-                        // ignored; service lives in system_server
-                    }
+                    // make sure stats are recorded frequently enough; we aim
+                    // for 2MB threshold for 2GB/month rules.
+                    final long persistThreshold = lowestRule / 1000;
+                    mNetworkStats.advisePersistThreshold(persistThreshold);
                     return true;
                 }
                 case MSG_UPDATE_INTERFACE_QUOTA: {
@@ -4366,15 +4379,26 @@
         }
     }
 
+    @Deprecated
     private long getTotalBytes(NetworkTemplate template, long start, long end) {
+        return getNetworkTotalBytes(template, start, end);
+    }
+
+    private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
         try {
             return mNetworkStats.getNetworkTotalBytes(template, start, end);
         } catch (RuntimeException e) {
-            Slog.w(TAG, "problem reading network stats: " + e);
+            Slog.w(TAG, "Failed to read network stats: " + e);
             return 0;
-        } catch (RemoteException e) {
-            // ignored; service lives in system_server
-            return 0;
+        }
+    }
+
+    private NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
+        try {
+            return mNetworkStats.getNetworkUidBytes(template, start, end);
+        } catch (RuntimeException e) {
+            Slog.w(TAG, "Failed to read network stats: " + e);
+            return new NetworkStats(SystemClock.elapsedRealtime(), 0);
         }
     }
 
diff --git a/services/core/java/com/android/server/net/NetworkStatsCollection.java b/services/core/java/com/android/server/net/NetworkStatsCollection.java
index 3cc4d83..a5f8dc7 100644
--- a/services/core/java/com/android/server/net/NetworkStatsCollection.java
+++ b/services/core/java/com/android/server/net/NetworkStatsCollection.java
@@ -106,6 +106,10 @@
         reset();
     }
 
+    public void clear() {
+        reset();
+    }
+
     public void reset() {
         mStats.clear();
         mStartMillis = Long.MAX_VALUE;
diff --git a/services/core/java/com/android/server/net/NetworkStatsManagerInternal.java b/services/core/java/com/android/server/net/NetworkStatsManagerInternal.java
new file mode 100644
index 0000000..4843ede
--- /dev/null
+++ b/services/core/java/com/android/server/net/NetworkStatsManagerInternal.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.net;
+
+import android.net.NetworkStats;
+import android.net.NetworkTemplate;
+
+public abstract class NetworkStatsManagerInternal {
+    /** Return network layer usage total for traffic that matches template. */
+    public abstract long getNetworkTotalBytes(NetworkTemplate template, long start, long end);
+
+    /** Return network layer usage per-UID for traffic that matches template. */
+    public abstract NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end);
+
+    /** Mark given UID as being in foreground for stats purposes. */
+    public abstract void setUidForeground(int uid, boolean uidForeground);
+
+    /** Advise persistance threshold; may be overridden internally. */
+    public abstract void advisePersistThreshold(long thresholdBytes);
+
+    /** Force update of statistics. */
+    public abstract void forceUpdate();
+}
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 32e15c9..93c04fe 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -49,7 +49,6 @@
 import static android.provider.Settings.Global.NETSTATS_GLOBAL_ALERT_BYTES;
 import static android.provider.Settings.Global.NETSTATS_POLL_INTERVAL;
 import static android.provider.Settings.Global.NETSTATS_SAMPLE_ENABLED;
-import static android.provider.Settings.Global.NETSTATS_TIME_CACHE_MAX_AGE;
 import static android.provider.Settings.Global.NETSTATS_UID_BUCKET_DURATION;
 import static android.provider.Settings.Global.NETSTATS_UID_DELETE_AGE;
 import static android.provider.Settings.Global.NETSTATS_UID_PERSIST_BYTES;
@@ -95,10 +94,10 @@
 import android.net.NetworkStatsHistory;
 import android.net.NetworkTemplate;
 import android.net.TrafficStats;
+import android.os.BestClock;
 import android.os.Binder;
 import android.os.DropBoxManager;
 import android.os.Environment;
-import android.os.BestClock;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
@@ -134,6 +133,7 @@
 import com.android.internal.util.FileRotator;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.EventLogTags;
+import com.android.server.LocalServices;
 import com.android.server.connectivity.Tethering;
 
 import java.io.File;
@@ -333,6 +333,9 @@
         mStatsObservers = checkNotNull(statsObservers, "missing NetworkStatsObservers");
         mSystemDir = checkNotNull(systemDir, "missing systemDir");
         mBaseDir = checkNotNull(baseDir, "missing baseDir");
+
+        LocalServices.addService(NetworkStatsManagerInternal.class,
+                new NetworkStatsManagerInternalImpl());
     }
 
     @VisibleForTesting
@@ -640,7 +643,7 @@
     private SubscriptionPlan resolveSubscriptionPlan(NetworkTemplate template, int flags) {
         SubscriptionPlan plan = null;
         if ((flags & NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN) != 0
-                && (template.getMatchRule() == NetworkTemplate.MATCH_MOBILE_ALL)
+                && (template.getMatchRule() == NetworkTemplate.MATCH_MOBILE)
                 && mSettings.getAugmentEnabled()) {
             if (LOGD) Slog.d(TAG, "Resolving plan for " + template);
             final long token = Binder.clearCallingIdentity();
@@ -701,12 +704,8 @@
         }
     }
 
-    @Override
-    public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
-        // Special case - since this is for internal use only, don't worry about
-        // a full access level check and just require the signature/privileged
-        // permission.
-        mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
+    private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
+        assertSystemReady();
         assertBandwidthControlEnabled();
 
         // NOTE: if callers want to get non-augmented data, they should go
@@ -716,6 +715,18 @@
                 NetworkStatsAccess.Level.DEVICE, Binder.getCallingUid()).getTotalBytes();
     }
 
+    private NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
+        assertSystemReady();
+        assertBandwidthControlEnabled();
+
+        final NetworkStatsCollection uidComplete;
+        synchronized (mStatsLock) {
+            uidComplete = mUidRecorder.getOrLoadCompleteLocked();
+        }
+        return uidComplete.getSummary(template, start, end, NetworkStatsAccess.Level.DEVICE,
+                android.os.Process.SYSTEM_UID);
+    }
+
     @Override
     public NetworkStats getDataLayerSnapshotForUid(int uid) throws RemoteException {
         if (Binder.getCallingUid() != uid) {
@@ -777,10 +788,8 @@
         }
     }
 
-    @Override
-    public void setUidForeground(int uid, boolean uidForeground) {
-        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-
+    @VisibleForTesting
+    void setUidForeground(int uid, boolean uidForeground) {
         synchronized (mStatsLock) {
             final int set = uidForeground ? SET_FOREGROUND : SET_DEFAULT;
             final int oldSet = mActiveUidCounterSet.get(uid, SET_DEFAULT);
@@ -817,9 +826,7 @@
         }
     }
 
-    @Override
-    public void advisePersistThreshold(long thresholdBytes) {
-        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+    private void advisePersistThreshold(long thresholdBytes) {
         assertBandwidthControlEnabled();
 
         // clamp threshold into safe range
@@ -1330,6 +1337,33 @@
         removeUidsLocked(uids);
     }
 
+    private class NetworkStatsManagerInternalImpl extends NetworkStatsManagerInternal {
+        @Override
+        public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
+            return NetworkStatsService.this.getNetworkTotalBytes(template, start, end);
+        }
+
+        @Override
+        public NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
+            return NetworkStatsService.this.getNetworkUidBytes(template, start, end);
+        }
+
+        @Override
+        public void setUidForeground(int uid, boolean uidForeground) {
+            NetworkStatsService.this.setUidForeground(uid, uidForeground);
+        }
+
+        @Override
+        public void advisePersistThreshold(long thresholdBytes) {
+            NetworkStatsService.this.advisePersistThreshold(thresholdBytes);
+        }
+
+        @Override
+        public void forceUpdate() {
+            NetworkStatsService.this.forceUpdate();
+        }
+    }
+
     @Override
     protected void dump(FileDescriptor fd, PrintWriter rawWriter, String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, TAG, rawWriter)) return;
@@ -1550,6 +1584,12 @@
         }
     }
 
+    private void assertSystemReady() {
+        if (!mSystemReady) {
+            throw new IllegalStateException("System not ready");
+        }
+    }
+
     private void assertBandwidthControlEnabled() {
         if (!isBandwidthControlEnabled()) {
             throw new IllegalStateException("Bandwidth module disabled");
diff --git a/services/core/java/com/android/server/notification/BadgeExtractor.java b/services/core/java/com/android/server/notification/BadgeExtractor.java
index 184f8b2..d8a30ae 100644
--- a/services/core/java/com/android/server/notification/BadgeExtractor.java
+++ b/services/core/java/com/android/server/notification/BadgeExtractor.java
@@ -61,4 +61,9 @@
     public void setConfig(RankingConfig config) {
         mConfig = config;
     }
+
+    @Override
+    public void setZenHelper(ZenModeHelper helper) {
+
+    }
 }
diff --git a/services/core/java/com/android/server/notification/ImportanceExtractor.java b/services/core/java/com/android/server/notification/ImportanceExtractor.java
index 452121c..dfdd55b 100644
--- a/services/core/java/com/android/server/notification/ImportanceExtractor.java
+++ b/services/core/java/com/android/server/notification/ImportanceExtractor.java
@@ -50,4 +50,9 @@
     public void setConfig(RankingConfig config) {
         mConfig = config;
     }
+
+    @Override
+    public void setZenHelper(ZenModeHelper helper) {
+
+    }
 }
diff --git a/services/core/java/com/android/server/notification/NotificationAdjustmentExtractor.java b/services/core/java/com/android/server/notification/NotificationAdjustmentExtractor.java
index 3bfd93f..97bbc23 100644
--- a/services/core/java/com/android/server/notification/NotificationAdjustmentExtractor.java
+++ b/services/core/java/com/android/server/notification/NotificationAdjustmentExtractor.java
@@ -44,4 +44,9 @@
     public void setConfig(RankingConfig config) {
         // config is not used
     }
+
+    @Override
+    public void setZenHelper(ZenModeHelper helper) {
+
+    }
 }
diff --git a/services/core/java/com/android/server/notification/NotificationChannelExtractor.java b/services/core/java/com/android/server/notification/NotificationChannelExtractor.java
index 11c7ab7..d66fd57 100644
--- a/services/core/java/com/android/server/notification/NotificationChannelExtractor.java
+++ b/services/core/java/com/android/server/notification/NotificationChannelExtractor.java
@@ -52,4 +52,9 @@
     public void setConfig(RankingConfig config) {
         mConfig = config;
     }
+
+    @Override
+    public void setZenHelper(ZenModeHelper helper) {
+
+    }
 }
diff --git a/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java b/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
index 91fee46..bf777e0 100644
--- a/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
+++ b/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
@@ -85,4 +85,9 @@
     public void setConfig(RankingConfig config) {
         // ignore: config has no relevant information yet.
     }
+
+    @Override
+    public void setZenHelper(ZenModeHelper helper) {
+
+    }
 }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index c4953b5..ef354cd 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1312,11 +1312,6 @@
         }
         mUsageStats = usageStats;
         mRankingHandler = new RankingHandlerWorker(mRankingThread.getLooper());
-        mRankingHelper = new RankingHelper(getContext(),
-                mPackageManagerClient,
-                mRankingHandler,
-                mUsageStats,
-                extractorNames);
         mConditionProviders = conditionProviders;
         mZenModeHelper = new ZenModeHelper(getContext(), mHandler.getLooper(), mConditionProviders);
         mZenModeHelper.addCallback(new ZenModeHelper.Callback() {
@@ -1335,6 +1330,7 @@
                 synchronized (mNotificationLock) {
                     updateInterruptionFilterLocked();
                 }
+                mRankingHandler.requestSort();
             }
 
             @Override
@@ -1342,6 +1338,12 @@
                 sendRegisteredOnlyBroadcast(NotificationManager.ACTION_NOTIFICATION_POLICY_CHANGED);
             }
         });
+        mRankingHelper = new RankingHelper(getContext(),
+                mPackageManagerClient,
+                mRankingHandler,
+                mZenModeHelper,
+                mUsageStats,
+                extractorNames);
         mSnoozeHelper = snoozeHelper;
         mGroupHelper = groupHelper;
 
@@ -4734,6 +4736,7 @@
             ArrayList<ArrayList<String>> overridePeopleBefore = new ArrayList<>(N);
             ArrayList<ArrayList<SnoozeCriterion>> snoozeCriteriaBefore = new ArrayList<>(N);
             ArrayList<Integer> userSentimentBefore = new ArrayList<>(N);
+            ArrayList<Integer> suppressVisuallyBefore = new ArrayList<>(N);
             for (int i = 0; i < N; i++) {
                 final NotificationRecord r = mNotificationList.get(i);
                 orderBefore.add(r.getKey());
@@ -4744,6 +4747,7 @@
                 overridePeopleBefore.add(r.getPeopleOverride());
                 snoozeCriteriaBefore.add(r.getSnoozeCriteria());
                 userSentimentBefore.add(r.getUserSentiment());
+                suppressVisuallyBefore.add(r.getSuppressedVisualEffects());
                 mRankingHelper.extractSignals(r);
             }
             mRankingHelper.sort(mNotificationList);
@@ -4756,7 +4760,9 @@
                         || !Objects.equals(groupKeyBefore.get(i), r.getGroupKey())
                         || !Objects.equals(overridePeopleBefore.get(i), r.getPeopleOverride())
                         || !Objects.equals(snoozeCriteriaBefore.get(i), r.getSnoozeCriteria())
-                        || !Objects.equals(userSentimentBefore.get(i), r.getUserSentiment())) {
+                        || !Objects.equals(userSentimentBefore.get(i), r.getUserSentiment())
+                        || !Objects.equals(suppressVisuallyBefore.get(i),
+                        r.getSuppressedVisualEffects())) {
                     mHandler.scheduleSendRankingUpdate();
                     return;
                 }
diff --git a/services/core/java/com/android/server/notification/NotificationSignalExtractor.java b/services/core/java/com/android/server/notification/NotificationSignalExtractor.java
index 31f8b27..24c1d59 100644
--- a/services/core/java/com/android/server/notification/NotificationSignalExtractor.java
+++ b/services/core/java/com/android/server/notification/NotificationSignalExtractor.java
@@ -22,6 +22,8 @@
  * Extracts signals that will be useful to the {@link NotificationComparator} and caches them
  *  on the {@link NotificationRecord} object. These annotations will
  *  not be passed on to {@link android.service.notification.NotificationListenerService}s.
+ *
+ *  If you add a new Extractor be sure to add it to R.array.config_notificationSignalExtractors.
  */
 public interface NotificationSignalExtractor {
 
@@ -44,4 +46,10 @@
      * @param config information about which signals are important.
      */
     void setConfig(RankingConfig config);
+
+    /**
+     * @param helper Helper to determine what components of notifications should be blocked due to
+     *               DND.
+     */
+    void setZenHelper(ZenModeHelper helper);
 }
diff --git a/services/core/java/com/android/server/notification/PriorityExtractor.java b/services/core/java/com/android/server/notification/PriorityExtractor.java
index 7a287db..612c624 100644
--- a/services/core/java/com/android/server/notification/PriorityExtractor.java
+++ b/services/core/java/com/android/server/notification/PriorityExtractor.java
@@ -53,4 +53,9 @@
     public void setConfig(RankingConfig config) {
         mConfig = config;
     }
+
+    @Override
+    public void setZenHelper(ZenModeHelper helper) {
+
+    }
 }
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index dc936d2..b280bde 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -102,7 +102,7 @@
     private SparseBooleanArray mBadgingEnabled;
 
     public RankingHelper(Context context, PackageManager pm, RankingHandler rankingHandler,
-            NotificationUsageStats usageStats, String[] extractorNames) {
+            ZenModeHelper zenHelper, NotificationUsageStats usageStats, String[] extractorNames) {
         mContext = context;
         mRankingHandler = rankingHandler;
         mPm = pm;
@@ -120,6 +120,7 @@
                         (NotificationSignalExtractor) extractorClass.newInstance();
                 extractor.initialize(mContext, usageStats);
                 extractor.setConfig(this);
+                extractor.setZenHelper(zenHelper);
                 mSignalExtractors[i] = extractor;
             } catch (ClassNotFoundException e) {
                 Slog.w(TAG, "Couldn't find extractor " + extractorNames[i] + ".", e);
diff --git a/services/core/java/com/android/server/notification/ValidateNotificationPeople.java b/services/core/java/com/android/server/notification/ValidateNotificationPeople.java
index fd9ffb2..c0c66b2 100644
--- a/services/core/java/com/android/server/notification/ValidateNotificationPeople.java
+++ b/services/core/java/com/android/server/notification/ValidateNotificationPeople.java
@@ -16,6 +16,7 @@
 
 package com.android.server.notification;
 
+import android.annotation.Nullable;
 import android.app.Notification;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -45,8 +46,6 @@
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 
-import android.os.SystemClock;
-
 /**
  * This {@link NotificationSignalExtractor} attempts to validate
  * people references. Also elevates the priority of real people.
@@ -144,6 +143,11 @@
         // ignore: config has no relevant information yet.
     }
 
+    @Override
+    public void setZenHelper(ZenModeHelper helper) {
+
+    }
+
     /**
      * @param extras extras of the notification with EXTRA_PEOPLE populated
      * @param timeoutMs timeout in milliseconds to wait for contacts response
@@ -226,7 +230,6 @@
 
     private PeopleRankingReconsideration validatePeople(Context context, String key, Bundle extras,
             List<String> peopleOverride, float[] affinityOut) {
-        long start = SystemClock.elapsedRealtime();
         float affinity = NONE;
         if (extras == null) {
             return null;
@@ -234,7 +237,7 @@
         final Set<String> people = new ArraySet<>(peopleOverride);
         final String[] notificationPeople = getExtraPeople(extras);
         if (notificationPeople != null ) {
-            people.addAll(Arrays.asList(getExtraPeople(extras)));
+            people.addAll(Arrays.asList(notificationPeople));
         }
 
         if (VERBOSE) Slog.i(TAG, "Validating: " + key + " for " + context.getUserId());
@@ -278,7 +281,31 @@
 
     // VisibleForTesting
     public static String[] getExtraPeople(Bundle extras) {
-        Object people = extras.get(Notification.EXTRA_PEOPLE_LIST);
+        String[] peopleList = getExtraPeopleForKey(extras, Notification.EXTRA_PEOPLE_LIST);
+        String[] legacyPeople = getExtraPeopleForKey(extras, Notification.EXTRA_PEOPLE);
+        return combineLists(legacyPeople, peopleList);
+    }
+
+    private static String[] combineLists(String[] first, String[] second) {
+        if (first == null) {
+            return second;
+        }
+        if (second == null) {
+            return first;
+        }
+        ArraySet<String> people = new ArraySet<>(first.length + second.length);
+        for (String person: first) {
+            people.add(person);
+        }
+        for (String person: second) {
+            people.add(person);
+        }
+        return (String[]) people.toArray();
+    }
+
+    @Nullable
+    private static String[] getExtraPeopleForKey(Bundle extras, String key) {
+        Object people = extras.get(key);
         if (people instanceof String[]) {
             return (String[]) people;
         }
@@ -444,7 +471,8 @@
         private float mContactAffinity = NONE;
         private NotificationRecord mRecord;
 
-        private PeopleRankingReconsideration(Context context, String key, LinkedList<String> pendingLookups) {
+        private PeopleRankingReconsideration(Context context, String key,
+                LinkedList<String> pendingLookups) {
             super(key);
             mContext = context;
             mPendingLookups = pendingLookups;
@@ -452,7 +480,6 @@
 
         @Override
         public void work() {
-            long start = SystemClock.elapsedRealtime();
             if (VERBOSE) Slog.i(TAG, "Executing: validation for: " + mKey);
             long timeStartMs = System.currentTimeMillis();
             for (final String handle: mPendingLookups) {
@@ -478,7 +505,9 @@
                         final String cacheKey = getCacheKey(mContext.getUserId(), handle);
                         mPeopleCache.put(cacheKey, lookupResult);
                     }
-                    if (DEBUG) Slog.d(TAG, "lookup contactAffinity is " + lookupResult.getAffinity());
+                    if (DEBUG) {
+                        Slog.d(TAG, "lookup contactAffinity is " + lookupResult.getAffinity());
+                    }
                     mContactAffinity = Math.max(mContactAffinity, lookupResult.getAffinity());
                 } else {
                     if (DEBUG) Slog.d(TAG, "lookupResult is null");
diff --git a/services/core/java/com/android/server/notification/VisibilityExtractor.java b/services/core/java/com/android/server/notification/VisibilityExtractor.java
index 37dbe3a..db54846 100644
--- a/services/core/java/com/android/server/notification/VisibilityExtractor.java
+++ b/services/core/java/com/android/server/notification/VisibilityExtractor.java
@@ -52,4 +52,9 @@
     public void setConfig(RankingConfig config) {
         mConfig = config;
     }
+
+    @Override
+    public void setZenHelper(ZenModeHelper helper) {
+
+    }
 }
diff --git a/services/core/java/com/android/server/notification/ZenModeExtractor.java b/services/core/java/com/android/server/notification/ZenModeExtractor.java
new file mode 100644
index 0000000..74f9806
--- /dev/null
+++ b/services/core/java/com/android/server/notification/ZenModeExtractor.java
@@ -0,0 +1,73 @@
+/*
+* Copyright (C) 2018 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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.notification;
+
+import static android.service.notification.NotificationListenerService.SUPPRESSED_EFFECT_SCREEN_OFF;
+import static android.service.notification.NotificationListenerService.SUPPRESSED_EFFECT_SCREEN_ON;
+
+import android.content.Context;
+import android.util.Log;
+import android.util.Slog;
+
+/**
+ * This {@link ZenModeExtractor} updates intercepted and visual interruption states.
+ */
+public class ZenModeExtractor implements NotificationSignalExtractor {
+    private static final String TAG = "ZenModeExtractor";
+    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private ZenModeHelper mZenModeHelper;
+
+    public void initialize(Context ctx, NotificationUsageStats usageStats) {
+        if (DBG) Slog.d(TAG, "Initializing  " + getClass().getSimpleName() + ".");
+    }
+
+    public RankingReconsideration process(NotificationRecord record) {
+        if (record == null || record.getNotification() == null) {
+            if (DBG) Slog.d(TAG, "skipping empty notification");
+            return null;
+        }
+
+        if (mZenModeHelper == null) {
+            if (DBG) Slog.d(TAG, "skipping - no zen info available");
+            return null;
+        }
+
+        record.setIntercepted(mZenModeHelper.shouldIntercept(record));
+        if (record.isIntercepted()) {
+            int suppressed = (mZenModeHelper.shouldSuppressWhenScreenOff()
+                    ? SUPPRESSED_EFFECT_SCREEN_OFF : 0)
+                    | (mZenModeHelper.shouldSuppressWhenScreenOn()
+                    ? SUPPRESSED_EFFECT_SCREEN_ON : 0);
+            record.setSuppressedVisualEffects(suppressed);
+        } else {
+            record.setSuppressedVisualEffects(0);
+        }
+
+        return null;
+    }
+
+    @Override
+    public void setConfig(RankingConfig config) {
+        // ignore: config has no relevant information yet.
+    }
+
+    @Override
+    public void setZenHelper(ZenModeHelper helper) {
+        mZenModeHelper = helper;
+    }
+}
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 7467954..fd51be5 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -64,6 +64,8 @@
 import com.android.server.pm.Installer;
 import com.android.server.pm.UserManagerService;
 
+import libcore.util.EmptyArray;
+
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.File;
@@ -303,10 +305,10 @@
         schedulePersistSettings();
     }
 
-    private static Set<String> getDefaultOverlayPackages() {
+    private static String[] getDefaultOverlayPackages() {
         final String str = SystemProperties.get(DEFAULT_OVERLAYS_PROP);
         if (TextUtils.isEmpty(str)) {
-            return Collections.emptySet();
+            return EmptyArray.STRING;
         }
 
         final ArraySet<String> defaultPackages = new ArraySet<>();
@@ -315,7 +317,7 @@
                 defaultPackages.add(packageName);
             }
         }
-        return defaultPackages;
+        return defaultPackages.toArray(new String[defaultPackages.size()]);
     }
 
     private final class PackageReceiver extends BroadcastReceiver {
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index 43b1708..74eb2ea 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -60,13 +60,13 @@
     private final PackageManagerHelper mPackageManager;
     private final IdmapManager mIdmapManager;
     private final OverlayManagerSettings mSettings;
-    private final Set<String> mDefaultOverlays;
+    private final String[] mDefaultOverlays;
     private final OverlayChangeListener mListener;
 
     OverlayManagerServiceImpl(@NonNull final PackageManagerHelper packageManager,
             @NonNull final IdmapManager idmapManager,
             @NonNull final OverlayManagerSettings settings,
-            @NonNull final Set<String> defaultOverlays,
+            @NonNull final String[] defaultOverlays,
             @NonNull final OverlayChangeListener listener) {
         mPackageManager = packageManager;
         mIdmapManager = idmapManager;
@@ -104,31 +104,27 @@
         for (int i = 0; i < overlayPackagesSize; i++) {
             final PackageInfo overlayPackage = overlayPackages.get(i);
             final OverlayInfo oi = storedOverlayInfos.get(overlayPackage.packageName);
-            if (oi == null || !oi.targetPackageName.equals(overlayPackage.overlayTarget)
-                    || !Objects.equals(oi.category, overlayPackage.overlayCategory)) {
-                // Update the overlay if it didn't exist or had the wrong target package.
+            if (oi == null || !oi.targetPackageName.equals(overlayPackage.overlayTarget)) {
+                // Reset the overlay if it didn't exist or had the wrong target package.
                 mSettings.init(overlayPackage.packageName, newUserId,
                         overlayPackage.overlayTarget,
                         overlayPackage.applicationInfo.getBaseCodePath(),
-                        overlayPackage.isStaticOverlayPackage(), overlayPackage.overlayPriority,
+                        overlayPackage.isStaticOverlayPackage(),
+                        overlayPackage.overlayPriority,
                         overlayPackage.overlayCategory);
 
-                if (oi == null) {
-                    // This overlay does not exist in our settings.
-                    if (overlayPackage.isStaticOverlayPackage() ||
-                            mDefaultOverlays.contains(overlayPackage.packageName)) {
-                        // Enable this overlay by default.
-                        if (DEBUG) {
-                            Slog.d(TAG, "Enabling overlay " + overlayPackage.packageName
-                                    + " for user " + newUserId + " by default");
-                        }
-                        mSettings.setEnabled(overlayPackage.packageName, newUserId, true);
-                    }
-                } else {
+                if (oi != null) {
                     // The targetPackageName we have stored doesn't match the overlay's target.
                     // Queue the old target for an update as well.
                     packagesToUpdateAssets.add(oi.targetPackageName);
                 }
+            } else {
+                // Update all other components of an overlay that don't require a hard reset.
+                if (!Objects.equals(oi.category, overlayPackage.overlayCategory)) {
+                    // When changing categories, it is ok just to update our internal state.
+                    mSettings.setCategory(overlayPackage.packageName, newUserId,
+                            overlayPackage.overlayCategory);
+                }
             }
 
             try {
@@ -160,6 +156,42 @@
                 iter.remove();
             }
         }
+
+        // Collect all of the categories in which we have at least one overlay enabled.
+        final ArraySet<String> enabledCategories = new ArraySet<>();
+        final ArrayMap<String, List<OverlayInfo>> userOverlays =
+                mSettings.getOverlaysForUser(newUserId);
+        final int userOverlayTargetCount = userOverlays.size();
+        for (int i = 0; i < userOverlayTargetCount; i++) {
+            final List<OverlayInfo> overlayList = userOverlays.valueAt(i);
+            final int overlayCount = overlayList != null ? overlayList.size() : 0;
+            for (int j = 0; j < overlayCount; j++) {
+                final OverlayInfo oi = overlayList.get(j);
+                if (oi.isEnabled()) {
+                    enabledCategories.add(oi.category);
+                }
+            }
+        }
+
+        // Enable the default overlay if its category does not have a single overlay enabled.
+        for (final String defaultOverlay : mDefaultOverlays) {
+            try {
+                final OverlayInfo oi = mSettings.getOverlayInfo(defaultOverlay, newUserId);
+                if (!enabledCategories.contains(oi.category)) {
+                    Slog.w(TAG, "Enabling default overlay '" + defaultOverlay + "' for target '"
+                            + oi.targetPackageName + "' in category '" + oi.category + "' for user "
+                            + newUserId);
+                    mSettings.setEnabled(oi.packageName, newUserId, true);
+                    if (updateState(oi.targetPackageName, oi.packageName, newUserId, 0)) {
+                        packagesToUpdateAssets.add(oi.targetPackageName);
+                    }
+                }
+            } catch (OverlayManagerSettings.BadKeyException e) {
+                Slog.e(TAG, "Failed to set default overlay '" + defaultOverlay + "' for user "
+                        + newUserId, e);
+            }
+        }
+
         return new ArrayList<>(packagesToUpdateAssets);
     }
 
@@ -325,6 +357,11 @@
                 mSettings.init(packageName, userId, pkg.overlayTarget,
                         pkg.applicationInfo.getBaseCodePath(), pkg.isStaticOverlayPackage(),
                         pkg.overlayPriority, pkg.overlayCategory);
+            } else {
+                if (!Objects.equals(oldOi.category, pkg.overlayCategory)) {
+                    // Update the category in-place.
+                    mSettings.setCategory(packageName, userId, pkg.overlayCategory);
+                }
             }
 
             if (updateState(pkg.overlayTarget, packageName, userId, 0)) {
diff --git a/services/core/java/com/android/server/om/OverlayManagerSettings.java b/services/core/java/com/android/server/om/OverlayManagerSettings.java
index e57fa0b..0b9412b 100644
--- a/services/core/java/com/android/server/om/OverlayManagerSettings.java
+++ b/services/core/java/com/android/server/om/OverlayManagerSettings.java
@@ -20,6 +20,7 @@
 import static com.android.server.om.OverlayManagerService.TAG;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.om.OverlayInfo;
 import android.util.ArrayMap;
 import android.util.Slog;
@@ -39,6 +40,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -70,6 +72,9 @@
                 new SettingsItem(packageName, userId, targetPackageName, baseCodePath,
                         isStatic, priority, overlayCategory);
         if (isStatic) {
+            // All static overlays are always enabled.
+            item.setEnabled(true);
+
             int i;
             for (i = mItems.size() - 1; i >= 0; i--) {
                 SettingsItem parentItem = mItems.get(i);
@@ -122,6 +127,15 @@
         return mItems.get(idx).setBaseCodePath(path);
     }
 
+    boolean setCategory(@NonNull final String packageName, final int userId,
+            @Nullable String category) throws BadKeyException {
+        final int idx = select(packageName, userId);
+        if (idx < 0) {
+            throw new BadKeyException(packageName, userId);
+        }
+        return mItems.get(idx).setCategory(category);
+    }
+
     boolean getEnabled(@NonNull final String packageName, final int userId) throws BadKeyException {
         final int idx = select(packageName, userId);
         if (idx < 0) {
@@ -420,7 +434,7 @@
         private OverlayInfo mCache;
         private boolean mIsStatic;
         private int mPriority;
-        private final String mCategory;
+        private String mCategory;
 
         SettingsItem(@NonNull final String packageName, final int userId,
                 @NonNull final String targetPackageName, @NonNull final String baseCodePath,
@@ -431,7 +445,7 @@
             mTargetPackageName = targetPackageName;
             mBaseCodePath = baseCodePath;
             mState = state;
-            mIsEnabled = isEnabled;
+            mIsEnabled = isEnabled || isStatic;
             mCategory = category;
             mCache = null;
             mIsStatic = isStatic;
@@ -483,7 +497,11 @@
             return mIsEnabled;
         }
 
-        private boolean setEnabled(final boolean enable) {
+        private boolean setEnabled(boolean enable) {
+            if (mIsStatic) {
+                return false;
+            }
+
             if (mIsEnabled != enable) {
                 mIsEnabled = enable;
                 invalidateCache();
@@ -492,6 +510,15 @@
             return false;
         }
 
+        private boolean setCategory(String category) {
+            if (!Objects.equals(mCategory, category)) {
+                mCategory = category.intern();
+                invalidateCache();
+                return true;
+            }
+            return false;
+        }
+
         private OverlayInfo getOverlayInfo() {
             if (mCache == null) {
                 mCache = new OverlayInfo(mPackageName, mTargetPackageName, mCategory, mBaseCodePath,
diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
index 8591304..e315bc5 100644
--- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java
+++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
@@ -146,6 +146,12 @@
         Intent intent = registerReceiver(null, filter);
         int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
         int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
+        boolean present = intent.getBooleanExtra(BatteryManager.EXTRA_PRESENT, true);
+
+        if (!present) {
+            // No battery, treat as if 100%, no possibility of draining battery.
+            return 100;
+        }
 
         if (level < 0 || scale <= 0) {
             // Battery data unavailable. This should never happen, so assume the worst.
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 4a2f577..5cf7903 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -176,6 +176,7 @@
 import android.content.pm.PackageParser.PackageParserException;
 import android.content.pm.PackageParser.ParseFlags;
 import android.content.pm.PackageParser.ServiceIntentInfo;
+import android.content.pm.PackageParser.SigningDetails;
 import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
 import android.content.pm.PackageStats;
 import android.content.pm.PackageUserState;
@@ -237,6 +238,7 @@
 import android.security.KeyStore;
 import android.security.SystemKeyStore;
 import android.service.pm.PackageServiceDumpProto;
+import android.service.textclassifier.TextClassifierService;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.text.TextUtils;
@@ -1392,6 +1394,7 @@
     final @NonNull String mRequiredUninstallerPackage;
     final @Nullable String mSetupWizardPackage;
     final @Nullable String mStorageManagerPackage;
+    final @Nullable String mSystemTextClassifierPackage;
     final @NonNull String mServicesSystemSharedLibraryPackageName;
     final @NonNull String mSharedSystemSharedLibraryPackageName;
 
@@ -2952,6 +2955,9 @@
                     filter.setPriority(0);
                 }
             }
+
+            mSystemTextClassifierPackage = getSystemTextClassifierPackageName();
+
             mDeferProtectedFilters = false;
             mProtectedFilters.clear();
 
@@ -6686,7 +6692,9 @@
             return result;
         }
         final PackageSetting ps = mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
-        if (ps == null) {
+        if (ps == null
+                || ps.getUserState().get(userId) == null
+                || !ps.getUserState().get(userId).isEnabled(mInstantAppInstallerActivity, 0)) {
             return result;
         }
         final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
@@ -20251,6 +20259,11 @@
     }
 
     @Override
+    public String getSystemTextClassifierPackageName() {
+        return mContext.getString(R.string.config_defaultTextClassifierPackage);
+    }
+
+    @Override
     public void setApplicationEnabledSetting(String appPackageName,
             int newState, int flags, int userId, String callingPackage) {
         if (!sUserManager.exists(userId)) return;
@@ -23310,6 +23323,39 @@
         }
 
         @Override
+        public boolean isDataRestoreSafe(byte[] restoringFromSigHash, String packageName) {
+            SigningDetails sd = getSigningDetails(packageName);
+            if (sd == null) {
+                return false;
+            }
+            return sd.hasSha256Certificate(restoringFromSigHash,
+                    SigningDetails.CertCapabilities.INSTALLED_DATA);
+        }
+
+        @Override
+        public boolean isDataRestoreSafe(Signature restoringFromSig, String packageName) {
+            SigningDetails sd = getSigningDetails(packageName);
+            if (sd == null) {
+                return false;
+            }
+            return sd.hasCertificate(restoringFromSig,
+                    SigningDetails.CertCapabilities.INSTALLED_DATA);
+        }
+
+        private SigningDetails getSigningDetails(String packageName) {
+            synchronized (mPackages) {
+                if (packageName == null) {
+                    return null;
+                }
+                PackageParser.Package p = mPackages.get(packageName);
+                if (p == null) {
+                    return null;
+                }
+                return p.mSigningDetails;
+            }
+        }
+
+        @Override
         public int getPermissionFlagsTEMP(String permName, String packageName, int userId) {
             return PackageManagerService.this.getPermissionFlags(permName, packageName, userId);
         }
@@ -23385,6 +23431,8 @@
                     return "android";
                 case PackageManagerInternal.PACKAGE_VERIFIER:
                     return mRequiredVerifierPackage;
+                case PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER:
+                    return mSystemTextClassifierPackage;
             }
             return null;
         }
@@ -23544,6 +23592,11 @@
         }
 
         @Override
+        public ComponentName getDefaultHomeActivity(int userId) {
+            return PackageManagerService.this.getDefaultHomeActivity(userId);
+        }
+
+        @Override
         public void setDeviceAndProfileOwnerPackages(
                 int deviceOwnerUserId, String deviceOwnerPackage,
                 SparseArray<String> profileOwnerPackages) {
diff --git a/services/core/java/com/android/server/pm/ShortcutLauncher.java b/services/core/java/com/android/server/pm/ShortcutLauncher.java
index cedf476..0fecb631 100644
--- a/services/core/java/com/android/server/pm/ShortcutLauncher.java
+++ b/services/core/java/com/android/server/pm/ShortcutLauncher.java
@@ -230,7 +230,7 @@
         out.startTag(null, TAG_ROOT);
         ShortcutService.writeAttr(out, ATTR_PACKAGE_NAME, getPackageName());
         ShortcutService.writeAttr(out, ATTR_LAUNCHER_USER_ID, getPackageUserId());
-        getPackageInfo().saveToXml(out, forBackup);
+        getPackageInfo().saveToXml(mShortcutUser.mService, out, forBackup);
 
         for (int i = 0; i < size; i++) {
             final PackageWithUser pu = mPinnedShortcuts.keyAt(i);
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index e4c74ed..92e261a 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -490,7 +490,7 @@
      * <p>This takes care of the resetting the counter for foreground apps as well as after
      * locale changes.
      */
-    public int getApiCallCount() {
+    public int getApiCallCount(boolean unlimited) {
         final ShortcutService s = mShortcutUser.mService;
 
         // Reset the counter if:
@@ -498,8 +498,9 @@
         // - the package is *not* in foreground now, but was in foreground at some point
         // since the previous time it had been.
         if (s.isUidForegroundLocked(mPackageUid)
-                || mLastKnownForegroundElapsedTime
-                    < s.getUidLastForegroundElapsedTimeLocked(mPackageUid)) {
+                || (mLastKnownForegroundElapsedTime
+                    < s.getUidLastForegroundElapsedTimeLocked(mPackageUid))
+                || unlimited) {
             mLastKnownForegroundElapsedTime = s.injectElapsedRealtime();
             resetRateLimiting();
         }
@@ -538,10 +539,10 @@
      * <p>This takes care of the resetting the counter for foreground apps as well as after
      * locale changes, which is done internally by {@link #getApiCallCount}.
      */
-    public boolean tryApiCall() {
+    public boolean tryApiCall(boolean unlimited) {
         final ShortcutService s = mShortcutUser.mService;
 
-        if (getApiCallCount() >= s.mMaxUpdatesPerInterval) {
+        if (getApiCallCount(unlimited) >= s.mMaxUpdatesPerInterval) {
             return false;
         }
         mApiCallCount++;
@@ -1248,7 +1249,7 @@
         pw.print(prefix);
         pw.print("  ");
         pw.print("Calls: ");
-        pw.print(getApiCallCount());
+        pw.print(getApiCallCount(/*unlimited=*/ false));
         pw.println();
 
         // getApiCallCount() may have updated mLastKnownForegroundElapsedTime.
@@ -1347,7 +1348,7 @@
         ShortcutService.writeAttr(out, ATTR_NAME, getPackageName());
         ShortcutService.writeAttr(out, ATTR_CALL_COUNT, mApiCallCount);
         ShortcutService.writeAttr(out, ATTR_LAST_RESET, mLastResetTime);
-        getPackageInfo().saveToXml(out, forBackup);
+        getPackageInfo().saveToXml(mShortcutUser.mService, out, forBackup);
 
         for (int j = 0; j < size; j++) {
             saveShortcut(out, mShortcuts.valueAt(j), forBackup,
diff --git a/services/core/java/com/android/server/pm/ShortcutPackageInfo.java b/services/core/java/com/android/server/pm/ShortcutPackageInfo.java
index 3d37229..44dd924 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackageInfo.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackageInfo.java
@@ -18,10 +18,12 @@
 import android.annotation.NonNull;
 import android.annotation.UserIdInt;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.ShortcutInfo;
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.LocalServices;
 import com.android.server.backup.BackupUtils;
 
 import libcore.util.HexEncoding;
@@ -48,6 +50,7 @@
     private static final String ATTR_LAST_UPDATE_TIME = "last_udpate_time";
     private static final String ATTR_BACKUP_SOURCE_VERSION = "bk_src_version";
     private static final String ATTR_BACKUP_ALLOWED = "allow-backup";
+    private static final String ATTR_BACKUP_ALLOWED_INITIALIZED = "allow-backup-initialized";
     private static final String ATTR_BACKUP_SOURCE_BACKUP_ALLOWED = "bk_src_backup-allowed";
     private static final String ATTR_SHADOW = "shadow";
 
@@ -136,7 +139,8 @@
 
     //@DisabledReason
     public int canRestoreTo(ShortcutService s, PackageInfo currentPackage, boolean anyVersionOkay) {
-        if (!BackupUtils.signaturesMatch(mSigHashes, currentPackage)) {
+        PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
+        if (!BackupUtils.signaturesMatch(mSigHashes, currentPackage, pmi)) {
             Slog.w(TAG, "Can't restore: Package signature mismatch");
             return ShortcutInfo.DISABLED_REASON_SIGNATURE_MISMATCH;
         }
@@ -187,7 +191,11 @@
         mSigHashes = BackupUtils.hashSignatureArray(pi.signatures);
     }
 
-    public void saveToXml(XmlSerializer out, boolean forBackup) throws IOException {
+    public void saveToXml(ShortcutService s, XmlSerializer out, boolean forBackup)
+            throws IOException {
+        if (forBackup && !mBackupAllowedInitialized) {
+            s.wtf("Backup happened before mBackupAllowed is initialized.");
+        }
 
         out.startTag(null, TAG_ROOT);
 
@@ -196,6 +204,10 @@
         ShortcutService.writeAttr(out, ATTR_SHADOW, mIsShadow);
         ShortcutService.writeAttr(out, ATTR_BACKUP_ALLOWED, mBackupAllowed);
 
+        // We don't need to save this field (we don't even read it back), but it'll show up
+        // in the dumpsys in the backup / restore payload.
+        ShortcutService.writeAttr(out, ATTR_BACKUP_ALLOWED_INITIALIZED, mBackupAllowedInitialized);
+
         ShortcutService.writeAttr(out, ATTR_BACKUP_SOURCE_VERSION, mBackupSourceVersionCode);
         ShortcutService.writeAttr(out,
                 ATTR_BACKUP_SOURCE_BACKUP_ALLOWED, mBackupSourceBackupAllowed);
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 034fd23..70fb616 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -15,6 +15,7 @@
  */
 package com.android.server.pm;
 
+import android.Manifest.permission;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -1726,6 +1727,9 @@
         final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
         final int size = newShortcuts.size();
 
+        final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission(
+                injectBinderCallingPid(), injectBinderCallingUid());
+
         synchronized (mLock) {
             throwIfUserLockedL(userId);
 
@@ -1738,7 +1742,7 @@
             ps.enforceShortcutCountsBeforeOperation(newShortcuts, OPERATION_SET);
 
             // Throttling.
-            if (!ps.tryApiCall()) {
+            if (!ps.tryApiCall(unlimited)) {
                 return false;
             }
 
@@ -1777,6 +1781,9 @@
         final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
         final int size = newShortcuts.size();
 
+        final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission(
+                injectBinderCallingPid(), injectBinderCallingUid());
+
         synchronized (mLock) {
             throwIfUserLockedL(userId);
 
@@ -1790,7 +1797,7 @@
             ps.enforceShortcutCountsBeforeOperation(newShortcuts, OPERATION_UPDATE);
 
             // Throttling.
-            if (!ps.tryApiCall()) {
+            if (!ps.tryApiCall(unlimited)) {
                 return false;
             }
 
@@ -1859,6 +1866,9 @@
         final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
         final int size = newShortcuts.size();
 
+        final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission(
+                injectBinderCallingPid(), injectBinderCallingUid());
+
         synchronized (mLock) {
             throwIfUserLockedL(userId);
 
@@ -1875,7 +1885,7 @@
             assignImplicitRanks(newShortcuts);
 
             // Throttling.
-            if (!ps.tryApiCall()) {
+            if (!ps.tryApiCall(unlimited)) {
                 return false;
             }
             for (int i = 0; i < size; i++) {
@@ -2144,11 +2154,14 @@
     public int getRemainingCallCount(String packageName, @UserIdInt int userId) {
         verifyCaller(packageName, userId);
 
+        final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission(
+                injectBinderCallingPid(), injectBinderCallingUid());
+
         synchronized (mLock) {
             throwIfUserLockedL(userId);
 
             final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
-            return mMaxUpdatesPerInterval - ps.getApiCallCount();
+            return mMaxUpdatesPerInterval - ps.getApiCallCount(unlimited);
         }
     }
 
@@ -2298,6 +2311,15 @@
                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
     }
 
+    /**
+     * Returns true if the caller has the "UNLIMITED_SHORTCUTS_API_CALLS" permission.
+     */
+    @VisibleForTesting
+    boolean injectHasUnlimitedShortcutsApiCallsPermission(int callingPid, int callingUid) {
+        return mContext.checkPermission(permission.UNLIMITED_SHORTCUTS_API_CALLS,
+                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
+    }
+
     // This method is extracted so we can directly call this method from unit tests,
     // even when hasShortcutPermission() is overridden.
     @VisibleForTesting
@@ -3103,7 +3125,8 @@
         try {
             return mIPackageManager.getPackageInfo(
                     packageName, PACKAGE_MATCH_FLAGS
-                            | (getSignatures ? PackageManager.GET_SIGNATURES : 0), userId);
+                            | (getSignatures ? PackageManager.GET_SIGNING_CERTIFICATES : 0),
+                    userId);
         } catch (RemoteException e) {
             // Shouldn't happen.
             Slog.wtf(TAG, "RemoteException", e);
@@ -3523,9 +3546,11 @@
             // Update the signatures for all packages.
             user.forAllPackageItems(spi -> spi.refreshPackageSignatureAndSave());
 
+            // Rescan all apps; this will also update the version codes and "allow-backup".
+            user.forAllPackages(pkg -> pkg.rescanPackageIfNeeded(
+                    /*isNewApp=*/ false, /*forceRescan=*/ true));
+
             // Set the version code for the launchers.
-            // We shouldn't do this for publisher packages, because we don't want to update the
-            // version code without rescanning the manifest.
             user.forAllLaunchers(launcher -> launcher.ensurePackageInfo());
 
             // Save to the filesystem.
@@ -3544,7 +3569,9 @@
                 Slog.w(TAG, "Backup failed.", e);
                 return null;
             }
-            return os.toByteArray();
+            byte[] payload = os.toByteArray();
+            mShortcutDumpFiles.save("backup-1-payload.txt", payload);
+            return payload;
         }
     }
 
@@ -3824,6 +3851,8 @@
                 pw.print(next);
                 pw.print("] ");
                 pw.print(formatTime(next));
+                pw.println();
+                pw.println();
 
                 pw.print("  Config:");
                 pw.print("    Max icon dim: ");
@@ -4197,6 +4226,11 @@
         return getCallingUid();
     }
 
+    @VisibleForTesting
+    int injectBinderCallingPid() {
+        return getCallingPid();
+    }
+
     private int getCallingUserId() {
         return UserHandle.getUserId(injectBinderCallingUid());
     }
@@ -4214,7 +4248,6 @@
     }
 
     // Injection point.
-    @VisibleForTesting
     String injectBuildFingerprint() {
         return Build.FINGERPRINT;
     }
diff --git a/services/core/java/com/android/server/pm/ShortcutUser.java b/services/core/java/com/android/server/pm/ShortcutUser.java
index c044c1c..505e4ee 100644
--- a/services/core/java/com/android/server/pm/ShortcutUser.java
+++ b/services/core/java/com/android/server/pm/ShortcutUser.java
@@ -23,7 +23,6 @@
 import android.text.TextUtils;
 import android.text.format.Formatter;
 import android.util.ArrayMap;
-import android.util.ArraySet;
 import android.util.Log;
 import android.util.Slog;
 
@@ -62,6 +61,7 @@
     // Suffix "2" was added to force rescan all packages after the next OTA.
     private static final String ATTR_LAST_APP_SCAN_TIME = "last-app-scan-time2";
     private static final String ATTR_LAST_APP_SCAN_OS_FINGERPRINT = "last-app-scan-fp";
+    private static final String ATTR_RESTORE_SOURCE_FINGERPRINT = "restore-from-fp";
     private static final String KEY_USER_ID = "userId";
     private static final String KEY_LAUNCHERS = "launchers";
     private static final String KEY_PACKAGES = "packages";
@@ -128,6 +128,7 @@
     private long mLastAppScanTime;
 
     private String mLastAppScanOsFingerprint;
+    private String mRestoreFromOsFingerprint;
 
     public ShortcutUser(ShortcutService service, int userId) {
         mService = service;
@@ -340,8 +341,13 @@
                     mLastAppScanTime);
             ShortcutService.writeAttr(out, ATTR_LAST_APP_SCAN_OS_FINGERPRINT,
                     mLastAppScanOsFingerprint);
+            ShortcutService.writeAttr(out, ATTR_RESTORE_SOURCE_FINGERPRINT,
+                    mRestoreFromOsFingerprint);
 
             ShortcutService.writeTagValue(out, TAG_LAUNCHER, mLastKnownLauncher);
+        } else {
+            ShortcutService.writeAttr(out, ATTR_RESTORE_SOURCE_FINGERPRINT,
+                    mService.injectBuildFingerprint());
         }
 
         // Can't use forEachPackageItem due to the checked exceptions.
@@ -387,6 +393,8 @@
             ret.mLastAppScanTime = lastAppScanTime < currentTime ? lastAppScanTime : 0;
             ret.mLastAppScanOsFingerprint = ShortcutService.parseStringAttribute(parser,
                     ATTR_LAST_APP_SCAN_OS_FINGERPRINT);
+            ret.mRestoreFromOsFingerprint = ShortcutService.parseStringAttribute(parser,
+                    ATTR_RESTORE_SOURCE_FINGERPRINT);
             final int outerDepth = parser.getDepth();
             int type;
             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
@@ -524,6 +532,8 @@
         restored.mLaunchers.clear();
         restored.mPackages.clear();
 
+        mRestoreFromOsFingerprint = restored.mRestoreFromOsFingerprint;
+
         Slog.i(TAG, "Restored: L=" + restoredLaunchers[0]
                 + " P=" + restoredPackages[0]
                 + " S=" + restoredShortcuts[0]);
@@ -539,14 +549,21 @@
             pw.print("  Last app scan: [");
             pw.print(mLastAppScanTime);
             pw.print("] ");
-            pw.print(ShortcutService.formatTime(mLastAppScanTime));
-            pw.print("  Last app scan FP: ");
-            pw.print(mLastAppScanOsFingerprint);
-            pw.println();
+            pw.println(ShortcutService.formatTime(mLastAppScanTime));
 
             prefix += prefix + "  ";
 
             pw.print(prefix);
+            pw.print("Last app scan FP: ");
+            pw.println(mLastAppScanOsFingerprint);
+
+            pw.print(prefix);
+            pw.print("Restore from FP: ");
+            pw.print(mRestoreFromOsFingerprint);
+            pw.println();
+
+
+            pw.print(prefix);
             pw.print("Cached launcher: ");
             pw.print(mCachedLauncher);
             pw.println();
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index de7e21a..2c7df6c 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -2584,9 +2584,6 @@
             Log.w(LOG_TAG, "Cannot add user. Not enough space on disk.");
             return null;
         }
-        if (ActivityManager.isLowRamDeviceStatic()) {
-            return null;
-        }
         final boolean isGuest = (flags & UserInfo.FLAG_GUEST) != 0;
         final boolean isManagedProfile = (flags & UserInfo.FLAG_MANAGED_PROFILE) != 0;
         final boolean isRestricted = (flags & UserInfo.FLAG_RESTRICTED) != 0;
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index 41570c4..b5d8326 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -565,21 +565,21 @@
                     break;
                 case UserManager.DISALLOW_AMBIENT_DISPLAY:
                     if (newValue) {
-                        android.provider.Settings.Secure.putString(
+                        android.provider.Settings.Secure.putIntForUser(
                                 context.getContentResolver(),
-                                Settings.Secure.DOZE_ENABLED, "0");
-                        android.provider.Settings.Secure.putString(
+                                Settings.Secure.DOZE_ENABLED, 0, userId);
+                        android.provider.Settings.Secure.putIntForUser(
                                 context.getContentResolver(),
-                                Settings.Secure.DOZE_ALWAYS_ON, "0");
-                        android.provider.Settings.Secure.putString(
+                                Settings.Secure.DOZE_ALWAYS_ON, 0, userId);
+                        android.provider.Settings.Secure.putIntForUser(
                                 context.getContentResolver(),
-                                Settings.Secure.DOZE_PULSE_ON_PICK_UP, "0");
-                        android.provider.Settings.Secure.putString(
+                                Settings.Secure.DOZE_PULSE_ON_PICK_UP, 0, userId);
+                        android.provider.Settings.Secure.putIntForUser(
                                 context.getContentResolver(),
-                                Settings.Secure.DOZE_PULSE_ON_LONG_PRESS, "0");
-                        android.provider.Settings.Secure.putString(
+                                Settings.Secure.DOZE_PULSE_ON_LONG_PRESS, 0, userId);
+                        android.provider.Settings.Secure.putIntForUser(
                                 context.getContentResolver(),
-                                Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP, "0");
+                                Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP, 0, userId);
                     }
                     break;
                 case UserManager.DISALLOW_CONFIG_LOCATION:
diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
index e290272..2ece2b2 100644
--- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java
+++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
@@ -19,18 +19,20 @@
 import android.Manifest;
 import android.annotation.UserIdInt;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageParser;
 import android.content.pm.dex.ArtManager;
 import android.content.pm.dex.ArtManager.ProfileType;
+import android.content.pm.dex.ArtManagerInternal;
 import android.content.pm.dex.DexMetadataHelper;
+import android.content.pm.dex.PackageOptimizationInfo;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Handler;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
-import android.content.pm.IPackageManager;
 import android.content.pm.dex.ISnapshotRuntimeProfileCallback;
 import android.os.SystemProperties;
 import android.os.UserHandle;
@@ -42,8 +44,13 @@
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.Preconditions;
+import com.android.server.LocalServices;
 import com.android.server.pm.Installer;
 import com.android.server.pm.Installer.InstallerException;
+
+import dalvik.system.DexFile;
+
+import dalvik.system.VMRuntime;
 import java.io.File;
 import java.io.FileNotFoundException;
 import libcore.io.IoUtils;
@@ -86,6 +93,8 @@
         mInstaller = installer;
         mInstallLock = installLock;
         mHandler = new Handler(BackgroundThread.getHandler().getLooper());
+
+        LocalServices.addService(ArtManagerInternal.class, new ArtManagerInternalImpl());
     }
 
     @Override
@@ -397,4 +406,30 @@
         }
         return result;
     }
+
+    private class ArtManagerInternalImpl extends ArtManagerInternal {
+        @Override
+        public PackageOptimizationInfo getPackageOptimizationInfo(
+                ApplicationInfo info, String abi) {
+            String compilationReason;
+            String compilationFilter;
+            try {
+                String isa = VMRuntime.getInstructionSet(abi);
+                String[] stats = DexFile.getDexFileOptimizationStatus(info.getBaseCodePath(), isa);
+                compilationFilter = stats[0];
+                compilationReason = stats[1];
+            } catch (FileNotFoundException e) {
+                Slog.e(TAG, "Could not get optimizations status for " + info.getBaseCodePath(), e);
+                compilationFilter = "error";
+                compilationReason = "error";
+            } catch (IllegalArgumentException e) {
+                Slog.wtf(TAG, "Requested optimization status for " + info.getBaseCodePath()
+                        + " due to an invalid abi " + abi, e);
+                compilationFilter = "error";
+                compilationReason = "error";
+            }
+
+            return new PackageOptimizationInfo(compilationFilter, compilationReason);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java
index 75a6106..bcf4b07 100644
--- a/services/core/java/com/android/server/pm/permission/BasePermission.java
+++ b/services/core/java/com/android/server/pm/permission/BasePermission.java
@@ -228,6 +228,10 @@
     public boolean isVendorPrivileged() {
         return (protectionLevel & PermissionInfo.PROTECTION_FLAG_VENDOR_PRIVILEGED) != 0;
     }
+    public boolean isSystemTextClassifier() {
+        return (protectionLevel & PermissionInfo.PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER)
+                != 0;
+    }
 
     public void transfer(@NonNull String origPackageName, @NonNull String newPackageName) {
         if (!origPackageName.equals(sourcePackageName)) {
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index afaafbc..afa9dd0 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -1148,6 +1148,13 @@
                 // this app is a setup wizard, then it gets the permission.
                 allowed = true;
             }
+            if (!allowed && bp.isSystemTextClassifier()
+                    && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
+                            PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER,
+                            UserHandle.USER_SYSTEM))) {
+                // Special permissions for the system default text classifier.
+                allowed = true;
+            }
         }
         return allowed;
     }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 7a5a6c5..eaa17ca 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -485,7 +485,7 @@
     boolean mSafeMode;
     private final ArraySet<WindowState> mScreenDecorWindows = new ArraySet<>();
     WindowState mStatusBar = null;
-    int mStatusBarHeight;
+    private final int[] mStatusBarHeightForRotation = new int[4];
     WindowState mNavigationBar = null;
     boolean mHasNavigationBar = false;
     boolean mNavigationBarCanMove = false; // can the navigation bar ever move to the side?
@@ -785,6 +785,9 @@
 
     private int mCurrentUserId;
 
+    /* Whether accessibility is magnifying the screen */
+    private boolean mScreenMagnificationActive;
+
     // Maps global key codes to the components that will handle them.
     private GlobalKeyManager mGlobalKeyManager;
 
@@ -2655,6 +2658,11 @@
                         | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
                 attrs.flags &= ~WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
                 break;
+            case TYPE_DREAM:
+                // Dreams don't have an app window token and can thus not be letterboxed.
+                // Hence always let them extend under the cutout.
+                attrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+                break;
             case TYPE_STATUS_BAR:
 
                 // If the Keyguard is in a hidden state (occluded by another window), we force to
@@ -2760,8 +2768,12 @@
         Context uiContext = getSystemUiContext();
         final Resources res = uiContext.getResources();
 
-        mStatusBarHeight =
-                res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
+        mStatusBarHeightForRotation[mPortraitRotation] =
+                mStatusBarHeightForRotation[mUpsideDownRotation] = res.getDimensionPixelSize(
+                                com.android.internal.R.dimen.status_bar_height_portrait);
+        mStatusBarHeightForRotation[mLandscapeRotation] =
+                mStatusBarHeightForRotation[mSeascapeRotation] = res.getDimensionPixelSize(
+                        com.android.internal.R.dimen.status_bar_height_landscape);
 
         // Height of the navigation bar when presented horizontally at bottom
         mNavigationBarHeightForRotationDefault[mPortraitRotation] =
@@ -2876,11 +2888,11 @@
         // of the screen.
         // TODO(multi-display): Support status bars on secondary displays.
         if (displayId == DEFAULT_DISPLAY) {
-            int statusBarHeight = mStatusBarHeight;
+            int statusBarHeight = mStatusBarHeightForRotation[rotation];
             if (displayCutout != null) {
                 // If there is a cutout, it may already have accounted for some part of the status
                 // bar height.
-                statusBarHeight = Math.max(0, mStatusBarHeight - displayCutout.getSafeInsetTop());
+                statusBarHeight = Math.max(0, statusBarHeight - displayCutout.getSafeInsetTop());
             }
             return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation, uiMode, displayId,
                     displayCutout) - statusBarHeight;
@@ -4641,7 +4653,8 @@
                 displayFrames.mDisplayCutout);
 
         // For layout, the status bar is always at the top with our fixed height.
-        displayFrames.mStable.top = displayFrames.mUnrestricted.top + mStatusBarHeight;
+        displayFrames.mStable.top = displayFrames.mUnrestricted.top
+                + mStatusBarHeightForRotation[displayFrames.mRotation];
 
         boolean statusBarTransient = (sysui & View.STATUS_BAR_TRANSIENT) != 0;
         boolean statusBarTranslucent = (sysui
@@ -5244,9 +5257,7 @@
         final boolean attachedInParent = attached != null && !layoutInScreen;
         // Ensure that windows with a DEFAULT or NEVER display cutout mode are laid out in
         // the cutout safe zone.
-        // Windows that are attached to a parent and laid out in said parent are already avoiding
-        // the cutout according to that parent and don't need to be further constrained.
-        if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS && !attachedInParent) {
+        if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) {
             final Rect displayCutoutSafeExceptMaybeTop = mTmpRect;
             displayCutoutSafeExceptMaybeTop.set(displayFrames.mDisplayCutoutSafe);
             if (layoutInScreen && layoutInsetDecor && !requestedFullscreen
@@ -5257,7 +5268,14 @@
                 // the window from that area.
                 displayCutoutSafeExceptMaybeTop.top = Integer.MIN_VALUE;
             }
-            pf.intersectUnchecked(displayCutoutSafeExceptMaybeTop);
+            // Windows that are attached to a parent and laid out in said parent are already
+            // avoidingthe cutout according to that parent and don't need to be further constrained.
+            if (!attachedInParent) {
+                pf.intersectUnchecked(displayCutoutSafeExceptMaybeTop);
+            }
+            // Make sure that NO_LIMITS windows clipped to the display don't extend into the display
+            // don't extend under the cutout.
+            df.intersectUnchecked(displayCutoutSafeExceptMaybeTop);
         }
 
         // Content should never appear in the cutout.
@@ -5629,9 +5647,7 @@
         final int fl = PolicyControl.getWindowFlags(null,
                 mTopFullscreenOpaqueWindowState.getAttrs());
         if (localLOGV) {
-            Slog.d(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw()
-                    + " shown position: "
-                    + mTopFullscreenOpaqueWindowState.getShownPositionLw());
+            Slog.d(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw());
             Slog.d(TAG, "attr: " + mTopFullscreenOpaqueWindowState.getAttrs()
                     + " lp.flags=0x" + Integer.toHexString(fl));
         }
@@ -6695,7 +6711,7 @@
             mWindowManagerDrawComplete = false;
             mScreenOnListener = screenOnListener;
 
-            if (mKeyguardDelegate != null) {
+            if (mKeyguardDelegate != null && mKeyguardDelegate.hasKeyguard()) {
                 mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
                 mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT,
                         getKeyguardDrawnTimeout());
@@ -6925,7 +6941,7 @@
 
         // Navigation bar and status bar.
         getNonDecorInsetsLw(displayRotation, displayWidth, displayHeight, displayCutout, outInsets);
-        outInsets.top = Math.max(outInsets.top, mStatusBarHeight);
+        outInsets.top = Math.max(outInsets.top, mStatusBarHeightForRotation[displayRotation]);
     }
 
     @Override
@@ -8154,7 +8170,11 @@
      */
     private int configureNavBarOpacity(int visibility, boolean dockedStackVisible,
             boolean freeformStackVisible, boolean isDockedDividerResizing) {
-        if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) {
+        if (mScreenMagnificationActive) {
+            // When the screen is magnified, the nav bar should be opaque since its background
+            // can vary as the user pans and zooms
+            visibility = setNavBarOpaqueFlag(visibility);
+        } else if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) {
             if (dockedStackVisible || freeformStackVisible || isDockedDividerResizing) {
                 visibility = setNavBarOpaqueFlag(visibility);
             }
@@ -8309,6 +8329,14 @@
     }
 
     @Override
+    public void onScreenMagnificationStateChanged(boolean active) {
+        synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
+            mScreenMagnificationActive = active;
+            updateSystemUiVisibilityLw();
+        }
+    }
+
+    @Override
     public void writeToProto(ProtoOutputStream proto, long fieldId) {
         final long token = proto.start(fieldId);
         proto.write(LAST_SYSTEM_UI_FLAGS, mLastSystemUiFlags);
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index dde4bc8..a07f5eb 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -232,14 +232,6 @@
         public Rect getFrameLw();
 
         /**
-         * Retrieve the current position of the window that is actually shown.
-         * Must be called with the window manager lock held.
-         *
-         * @return Point The point holding the shown window position.
-         */
-        public Point getShownPositionLw();
-
-        /**
          * Retrieve the frame of the display that this window was last
          * laid out in.  Must be called with the
          * window manager lock held.
@@ -1700,6 +1692,13 @@
     boolean canDismissBootAnimation();
 
     /**
+     * Called when the magnification state changes.
+     *
+     * @param active Whether magnification is active (that is, we are zoomed in).
+     */
+    void onScreenMagnificationStateChanged(boolean active);
+
+    /**
      * Convert the user rotation mode to a human readable format.
      */
     static String userRotationModeToString(int mode) {
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index 18f4a3c..58e8f77 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -242,6 +242,10 @@
         return false;
     }
 
+    public boolean hasKeyguard() {
+        return mKeyguardState.deviceHasKeyguard;
+    }
+
     public boolean isInputRestricted() {
         if (mKeyguardService != null) {
             mKeyguardState.inputRestricted = mKeyguardService.isInputRestricted();
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
index efcadad..941cd44 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
@@ -19,8 +19,6 @@
 import android.app.ActivityManager;
 import android.content.Context;
 import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.security.IKeystoreService;
 import android.util.Slog;
 
 import com.android.internal.policy.IKeyguardService;
@@ -53,16 +51,11 @@
     private final LockPatternUtils mLockPatternUtils;
     private final StateCallback mCallback;
 
-    IKeystoreService mKeystoreService;
-
     public KeyguardStateMonitor(Context context, IKeyguardService service, StateCallback callback) {
         mLockPatternUtils = new LockPatternUtils(context);
         mCurrentUserId = ActivityManager.getCurrentUser();
         mCallback = callback;
 
-        mKeystoreService = IKeystoreService.Stub.asInterface(ServiceManager
-                .getService("android.security.keystore"));
-
         try {
             service.addStateMonitorCallback(this);
         } catch (RemoteException e) {
@@ -93,12 +86,6 @@
     @Override // Binder interface
     public void onShowingStateChanged(boolean showing) {
         mIsShowing = showing;
-
-        if (showing) try {
-            mKeystoreService.lock(mCurrentUserId); // as long as this doesn't recur...
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Error locking keystore", e);
-        }
     }
 
     @Override // Binder interface
diff --git a/services/core/java/com/android/server/power/BatterySaverPolicy.java b/services/core/java/com/android/server/power/BatterySaverPolicy.java
index 08dc97e..16336b3 100644
--- a/services/core/java/com/android/server/power/BatterySaverPolicy.java
+++ b/services/core/java/com/android/server/power/BatterySaverPolicy.java
@@ -68,6 +68,7 @@
     private static final String KEY_FORCE_ALL_APPS_STANDBY = "force_all_apps_standby";
     private static final String KEY_FORCE_BACKGROUND_CHECK = "force_background_check";
     private static final String KEY_OPTIONAL_SENSORS_DISABLED = "optional_sensors_disabled";
+    private static final String KEY_AOD_DISABLED = "aod_disabled";
 
     private static final String KEY_CPU_FREQ_INTERACTIVE = "cpufreq-i";
     private static final String KEY_CPU_FREQ_NONINTERACTIVE = "cpufreq-n";
@@ -200,11 +201,17 @@
     private boolean mForceBackgroundCheck;
 
     /**
-     * Weather to show non-essential sensors (e.g. edge sensors) or not.
+     * Whether to show non-essential sensors (e.g. edge sensors) or not.
      */
     @GuardedBy("mLock")
     private boolean mOptionalSensorsDisabled;
 
+    /**
+     * Whether AOD is enabled or not.
+     */
+    @GuardedBy("mLock")
+    private boolean mAodDisabled;
+
     @GuardedBy("mLock")
     private Context mContext;
 
@@ -339,6 +346,7 @@
         mForceAllAppsStandby = parser.getBoolean(KEY_FORCE_ALL_APPS_STANDBY, true);
         mForceBackgroundCheck = parser.getBoolean(KEY_FORCE_BACKGROUND_CHECK, true);
         mOptionalSensorsDisabled = parser.getBoolean(KEY_OPTIONAL_SENSORS_DISABLED, true);
+        mAodDisabled = parser.getBoolean(KEY_AOD_DISABLED, true);
 
         // Get default value from Settings.Secure
         final int defaultGpsMode = Settings.Secure.getInt(mContentResolver, SECURE_KEY_GPS_MODE,
@@ -375,6 +383,7 @@
 
         if (mLaunchBoostDisabled) sb.append("l");
         if (mOptionalSensorsDisabled) sb.append("S");
+        if (mAodDisabled) sb.append("o");
 
         sb.append(mGpsMode);
 
@@ -437,6 +446,9 @@
                 case ServiceType.OPTIONAL_SENSORS:
                     return builder.setBatterySaverEnabled(mOptionalSensorsDisabled)
                             .build();
+                case ServiceType.AOD:
+                    return builder.setBatterySaverEnabled(mAodDisabled)
+                            .build();
                 default:
                     return builder.setBatterySaverEnabled(realMode)
                             .build();
@@ -491,6 +503,7 @@
             pw.println("  " + KEY_FORCE_ALL_APPS_STANDBY + "=" + mForceAllAppsStandby);
             pw.println("  " + KEY_FORCE_BACKGROUND_CHECK + "=" + mForceBackgroundCheck);
             pw.println("  " + KEY_OPTIONAL_SENSORS_DISABLED + "=" + mOptionalSensorsDisabled);
+            pw.println("  " + KEY_AOD_DISABLED + "=" + mAodDisabled);
             pw.println();
 
             pw.print("  Interactive File values:\n");
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 3072f21..b729b6a 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -91,7 +91,7 @@
 
     private final Context mContext;
     private final IBatteryStats mBatteryStats;
-    private final IAppOpsService mAppOps;
+    private final AppOpsManager mAppOps;
     private final SuspendBlocker mSuspendBlocker;
     private final WindowManagerPolicy mPolicy;
     private final ActivityManagerInternal mActivityManagerInternal;
@@ -134,11 +134,10 @@
     private boolean mUserActivityPending;
 
     public Notifier(Looper looper, Context context, IBatteryStats batteryStats,
-            IAppOpsService appOps, SuspendBlocker suspendBlocker,
-            WindowManagerPolicy policy) {
+            SuspendBlocker suspendBlocker, WindowManagerPolicy policy) {
         mContext = context;
         mBatteryStats = batteryStats;
-        mAppOps = appOps;
+        mAppOps = mContext.getSystemService(AppOpsManager.class);
         mSuspendBlocker = suspendBlocker;
         mPolicy = policy;
         mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
@@ -194,8 +193,7 @@
                     mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, historyTag,
                             monitorType, unimportantForLogging);
                     // XXX need to deal with disabled operations.
-                    mAppOps.startOperation(AppOpsManager.getToken(mAppOps),
-                            AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
+                    mAppOps.startOpNoThrow(AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
                 }
             } catch (RemoteException ex) {
                 // Ignore
@@ -295,8 +293,7 @@
                 } else {
                     mBatteryStats.noteStopWakelock(ownerUid, ownerPid, tag,
                             historyTag, monitorType);
-                    mAppOps.finishOperation(AppOpsManager.getToken(mAppOps),
-                            AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
+                    mAppOps.finishOp(AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
                 }
             } catch (RemoteException ex) {
                 // Ignore
@@ -539,12 +536,11 @@
         try {
             mBatteryStats.noteWakeUp(reason, reasonUid);
             if (opPackageName != null) {
-                mAppOps.noteOperation(AppOpsManager.OP_TURN_SCREEN_ON, opUid, opPackageName);
+                mAppOps.noteOpNoThrow(AppOpsManager.OP_TURN_SCREEN_ON, opUid, opPackageName);
             }
         } catch (RemoteException ex) {
             // Ignore
         }
-
     }
 
     /**
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index d67acc4..f77b0ee 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -759,8 +759,7 @@
             // with the animations and other critical functions of the power manager.
             mBatteryStats = BatteryStatsService.getService();
             mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,
-                    mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
-                    mPolicy);
+                    createSuspendBlockerLocked("PowerManagerService.Broadcasts"), mPolicy);
 
             mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,
                     createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"),
diff --git a/services/core/java/com/android/server/slice/PinnedSliceState.java b/services/core/java/com/android/server/slice/PinnedSliceState.java
index 8da16d7..f9a4ea2 100644
--- a/services/core/java/com/android/server/slice/PinnedSliceState.java
+++ b/services/core/java/com/android/server/slice/PinnedSliceState.java
@@ -16,7 +16,6 @@
 
 import static android.app.slice.SliceManager.PERMISSION_GRANTED;
 
-import android.app.slice.ISliceListener;
 import android.app.slice.Slice;
 import android.app.slice.SliceProvider;
 import android.app.slice.SliceSpec;
@@ -106,10 +105,6 @@
         setSlicePinned(false);
     }
 
-    public void onChange() {
-        mService.getHandler().post(this::handleBind);
-    }
-
     private void setSlicePinned(boolean pinned) {
         synchronized (mLock) {
             if (mSlicePinned == pinned) return;
@@ -122,45 +117,23 @@
         }
     }
 
-    public void addSliceListener(ISliceListener listener, String pkg, SliceSpec[] specs,
-            boolean hasPermission) {
+    public void pin(String pkg, SliceSpec[] specs, IBinder token) {
         synchronized (mLock) {
-            if (mListeners.size() == 0) {
-                mService.listen(mUri);
-            }
+            mListeners.put(token, new ListenerInfo(token, pkg, true,
+                    Binder.getCallingUid(), Binder.getCallingPid()));
             try {
-                listener.asBinder().linkToDeath(mDeathRecipient, 0);
+                token.linkToDeath(mDeathRecipient, 0);
             } catch (RemoteException e) {
             }
-            mListeners.put(listener.asBinder(), new ListenerInfo(listener, pkg, hasPermission,
-                    Binder.getCallingUid(), Binder.getCallingPid()));
             mergeSpecs(specs);
-            setSlicePinned(hasPermission);
-        }
-    }
-
-    public boolean removeSliceListener(ISliceListener listener) {
-        synchronized (mLock) {
-            listener.asBinder().unlinkToDeath(mDeathRecipient, 0);
-            if (mListeners.containsKey(listener.asBinder()) && mListeners.size() == 1) {
-                mService.unlisten(mUri);
-            }
-            mListeners.remove(listener.asBinder());
-        }
-        return !hasPinOrListener();
-    }
-
-    public void pin(String pkg, SliceSpec[] specs) {
-        synchronized (mLock) {
             setSlicePinned(true);
-            mPinnedPkgs.add(pkg);
-            mergeSpecs(specs);
         }
     }
 
-    public boolean unpin(String pkg) {
+    public boolean unpin(String pkg, IBinder token) {
         synchronized (mLock) {
-            mPinnedPkgs.remove(pkg);
+            token.unlinkToDeath(mDeathRecipient, 0);
+            mListeners.remove(token);
         }
         return !hasPinOrListener();
     }
@@ -171,30 +144,6 @@
         }
     }
 
-    public void recheckPackage(String pkg) {
-        synchronized (mLock) {
-            for (int i = 0; i < mListeners.size(); i++) {
-                ListenerInfo info = mListeners.valueAt(i);
-                if (!info.hasPermission && Objects.equals(info.pkg, pkg)) {
-                    mService.getHandler().post(() -> {
-                        // This bind lets the app itself participate in the permission grant.
-                        Slice s = doBind(info);
-                        if (mService.checkAccess(info.pkg, mUri, info.callingUid, info.callingPid)
-                                == PERMISSION_GRANTED) {
-                            info.hasPermission = true;
-                            setSlicePinned(true);
-                            try {
-                                info.listener.onSliceUpdated(s);
-                            } catch (RemoteException e) {
-                                checkSelfRemove();
-                            }
-                        }
-                    });
-                }
-            }
-        }
-    }
-
     @VisibleForTesting
     public boolean hasPinOrListener() {
         synchronized (mLock) {
@@ -213,7 +162,6 @@
     private void checkSelfRemove() {
         if (!hasPinOrListener()) {
             // All the listeners died, remove from pinned state.
-            mService.unlisten(mUri);
             mService.removePinnedSlice(mUri);
         }
     }
@@ -223,7 +171,7 @@
         synchronized (mLock) {
             for (int i = mListeners.size() - 1; i >= 0; i--) {
                 ListenerInfo l = mListeners.valueAt(i);
-                if (!l.listener.asBinder().isBinderAlive()) {
+                if (!l.token.isBinderAlive()) {
                     mListeners.removeAt(i);
                 }
             }
@@ -231,62 +179,6 @@
         }
     }
 
-    private void handleBind() {
-        Slice cachedSlice = doBind(null);
-        synchronized (mLock) {
-            if (!hasPinOrListener()) return;
-            for (int i = mListeners.size() - 1; i >= 0; i--) {
-                ListenerInfo info = mListeners.valueAt(i);
-                Slice s = cachedSlice;
-                if (s == null || s.hasHint(Slice.HINT_CALLER_NEEDED)
-                        || !info.hasPermission) {
-                    s = doBind(info);
-                }
-                if (s == null) {
-                    mListeners.removeAt(i);
-                    continue;
-                }
-                try {
-                    info.listener.onSliceUpdated(s);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Unable to notify slice " + mUri, e);
-                    mListeners.removeAt(i);
-                    continue;
-                }
-            }
-            checkSelfRemove();
-        }
-    }
-
-    private Slice doBind(ListenerInfo info) {
-        try (ContentProviderClient client = getClient()) {
-            if (client == null) return null;
-            Bundle extras = new Bundle();
-            extras.putParcelable(SliceProvider.EXTRA_BIND_URI, mUri);
-            extras.putParcelableArrayList(SliceProvider.EXTRA_SUPPORTED_SPECS,
-                    new ArrayList<>(Arrays.asList(mSupportedSpecs)));
-            if (info != null) {
-                extras.putString(SliceProvider.EXTRA_OVERRIDE_PKG, info.pkg);
-                extras.putInt(SliceProvider.EXTRA_OVERRIDE_UID, info.callingUid);
-                extras.putInt(SliceProvider.EXTRA_OVERRIDE_PID, info.callingPid);
-            }
-            final Bundle res;
-            try {
-                res = client.call(SliceProvider.METHOD_SLICE, null, extras);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Unable to bind slice " + mUri, e);
-                return null;
-            }
-            if (res == null) return null;
-            Bundle.setDefusable(res, true);
-            return res.getParcelable(SliceProvider.EXTRA_SLICE);
-        } catch (Throwable t) {
-            // Calling out of the system process, make sure they don't throw anything at us.
-            Log.e(TAG, "Caught throwable while binding " + mUri, t);
-            return null;
-        }
-    }
-
     private void handleSendPinned() {
         try (ContentProviderClient client = getClient()) {
             if (client == null) return;
@@ -315,15 +207,15 @@
 
     private class ListenerInfo {
 
-        private ISliceListener listener;
+        private IBinder token;
         private String pkg;
         private boolean hasPermission;
         private int callingUid;
         private int callingPid;
 
-        public ListenerInfo(ISliceListener listener, String pkg, boolean hasPermission,
+        public ListenerInfo(IBinder token, String pkg, boolean hasPermission,
                 int callingUid, int callingPid) {
-            this.listener = listener;
+            this.token = token;
             this.pkg = pkg;
             this.hasPermission = hasPermission;
             this.callingUid = callingUid;
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index a1def44..51e4709 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -28,7 +28,6 @@
 import android.app.AppOpsManager;
 import android.app.ContentProviderHolder;
 import android.app.IActivityManager;
-import android.app.slice.ISliceListener;
 import android.app.slice.ISliceManager;
 import android.app.slice.SliceManager;
 import android.app.slice.SliceSpec;
@@ -39,7 +38,6 @@
 import android.content.IntentFilter;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.ResolveInfo;
-import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Environment;
@@ -52,7 +50,6 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.AtomicFile;
-import android.util.Log;
 import android.util.Slog;
 import android.util.Xml.Encoding;
 
@@ -94,7 +91,6 @@
     @GuardedBy("mLock")
     private final ArraySet<SliceGrant> mUserGrants = new ArraySet<>();
     private final Handler mHandler;
-    private final ContentObserver mObserver;
     @GuardedBy("mSliceAccessFile")
     private final AtomicFile mSliceAccessFile;
     @GuardedBy("mAccessList")
@@ -113,16 +109,6 @@
         mAssistUtils = new AssistUtils(context);
         mHandler = new Handler(looper);
 
-        mObserver = new ContentObserver(mHandler) {
-            @Override
-            public void onChange(boolean selfChange, Uri uri, int userId) {
-                try {
-                    getPinnedSlice(maybeAddUserId(uri, userId)).onChange();
-                } catch (IllegalStateException e) {
-                    Log.e(TAG, "Received change for unpinned slice " + uri, e);
-                }
-            }
-        };
         final File systemDir = new File(Environment.getDataDirectory(), "system");
         mSliceAccessFile = new AtomicFile(new File(systemDir, "slice_access.xml"));
         mAccessList = new SliceFullAccessList(mContext);
@@ -163,40 +149,19 @@
 
     ///  ----- ISliceManager stuff -----
     @Override
-    public void addSliceListener(Uri uri, String pkg, ISliceListener listener, SliceSpec[] specs)
-            throws RemoteException {
+    public void pinSlice(String pkg, Uri uri, SliceSpec[] specs, IBinder token) throws RemoteException {
         verifyCaller(pkg);
+        enforceAccess(pkg, uri);
         uri = maybeAddUserId(uri, Binder.getCallingUserHandle().getIdentifier());
-        enforceCrossUser(pkg, uri);
-        getOrCreatePinnedSlice(uri).addSliceListener(listener, pkg, specs,
-                checkAccess(pkg, uri, Binder.getCallingUid(), Binder.getCallingUid())
-                == PERMISSION_GRANTED);
+        getOrCreatePinnedSlice(uri).pin(pkg, specs, token);
     }
 
     @Override
-    public void removeSliceListener(Uri uri, String pkg, ISliceListener listener)
-            throws RemoteException {
+    public void unpinSlice(String pkg, Uri uri, IBinder token) throws RemoteException {
         verifyCaller(pkg);
+        enforceAccess(pkg, uri);
         uri = maybeAddUserId(uri, Binder.getCallingUserHandle().getIdentifier());
-        if (getPinnedSlice(uri).removeSliceListener(listener)) {
-            removePinnedSlice(uri);
-        }
-    }
-
-    @Override
-    public void pinSlice(String pkg, Uri uri, SliceSpec[] specs) throws RemoteException {
-        verifyCaller(pkg);
-        enforceFullAccess(pkg, "pinSlice", uri);
-        uri = maybeAddUserId(uri, Binder.getCallingUserHandle().getIdentifier());
-        getOrCreatePinnedSlice(uri).pin(pkg, specs);
-    }
-
-    @Override
-    public void unpinSlice(String pkg, Uri uri) throws RemoteException {
-        verifyCaller(pkg);
-        enforceFullAccess(pkg, "unpinSlice", uri);
-        uri = maybeAddUserId(uri, Binder.getCallingUserHandle().getIdentifier());
-        if (getPinnedSlice(uri).unpin(pkg)) {
+        if (getPinnedSlice(uri).unpin(pkg, token)) {
             removePinnedSlice(uri);
         }
     }
@@ -253,11 +218,6 @@
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
-        synchronized (mLock) {
-            for (PinnedSliceState p : mPinnedSlicesByUri.values()) {
-                p.recheckPackage(pkg);
-            }
-        }
     }
 
     // Backup/restore interface
@@ -457,21 +417,6 @@
         return cn.getPackageName().equals(pkg);
     }
 
-    public void listen(Uri uri) {
-        mContext.getContentResolver().registerContentObserver(uri, true, mObserver);
-    }
-
-    public void unlisten(Uri uri) {
-        mContext.getContentResolver().unregisterContentObserver(mObserver);
-        synchronized (mLock) {
-            mPinnedSlicesByUri.forEach((u, s) -> {
-                if (s.isListening()) {
-                    listen(u);
-                }
-            });
-        }
-    }
-
     private boolean isDefaultHomeApp(String pkg, int userId) {
         String defaultHome = getDefaultHome(userId);
 
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index d6359b8..6e017cd 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -100,6 +100,7 @@
 
     private final PendingIntent mAnomalyAlarmIntent;
     private final PendingIntent mPullingAlarmIntent;
+    private final PendingIntent mPeriodicAlarmIntent;
     private final BroadcastReceiver mAppUpdateReceiver;
     private final BroadcastReceiver mUserUpdateReceiver;
     private final ShutdownEventReceiver mShutdownEventReceiver;
@@ -123,6 +124,8 @@
                 new Intent(mContext, AnomalyAlarmReceiver.class), 0);
         mPullingAlarmIntent = PendingIntent.getBroadcast(
                 mContext, 0, new Intent(mContext, PullingAlarmReceiver.class), 0);
+        mPeriodicAlarmIntent = PendingIntent.getBroadcast(
+                mContext, 0, new Intent(mContext, PeriodicAlarmReceiver.class), 0);
         mAppUpdateReceiver = new AppUpdateReceiver();
         mUserUpdateReceiver = new BroadcastReceiver() {
             @Override
@@ -329,7 +332,28 @@
         }
     }
 
-    private final static class ShutdownEventReceiver extends BroadcastReceiver {
+    public final static class PeriodicAlarmReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (DEBUG)
+                Slog.d(TAG, "Time to poll something.");
+            synchronized (sStatsdLock) {
+                if (sStatsd == null) {
+                    Slog.w(TAG, "Could not access statsd to inform it of periodic alarm firing.");
+                    return;
+                }
+                try {
+                    // Two-way call to statsd to retain AlarmManager wakelock
+                    sStatsd.informAlarmForSubscriberTriggeringFired();
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "Failed to inform statsd of periodic alarm firing.", e);
+                }
+            }
+            // AlarmManager releases its own wakelock here.
+        }
+    }
+
+    public final static class ShutdownEventReceiver extends BroadcastReceiver {
         @Override
         public void onReceive(Context context, Intent intent) {
             /**
@@ -385,6 +409,35 @@
     }
 
     @Override // Binder call
+    public void setAlarmForSubscriberTriggering(long timestampMs) {
+        enforceCallingPermission();
+        if (DEBUG)
+            Slog.d(TAG, "Setting periodic alarm at " + timestampMs);
+        final long callingToken = Binder.clearCallingIdentity();
+        try {
+            // using ELAPSED_REALTIME, not ELAPSED_REALTIME_WAKEUP, so if device is asleep, will
+            // only fire when it awakens.
+            // This alarm is inexact, leaving its exactness completely up to the OS optimizations.
+            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, timestampMs, mPeriodicAlarmIntent);
+        } finally {
+            Binder.restoreCallingIdentity(callingToken);
+        }
+    }
+
+    @Override // Binder call
+    public void cancelAlarmForSubscriberTriggering() {
+        enforceCallingPermission();
+        if (DEBUG)
+            Slog.d(TAG, "Cancelling periodic alarm");
+        final long callingToken = Binder.clearCallingIdentity();
+        try {
+            mAlarmManager.cancel(mPeriodicAlarmIntent);
+        } finally {
+            Binder.restoreCallingIdentity(callingToken);
+        }
+    }
+
+    @Override // Binder call
     public void setPullingAlarms(long timestampMs, long intervalMs) {
         enforceCallingPermission();
         if (DEBUG)
@@ -418,10 +471,11 @@
     private void addNetworkStats(
             int tag, List<StatsLogEventWrapper> ret, NetworkStats stats, boolean withFGBG) {
         int size = stats.size();
+        long elapsedNanos = SystemClock.elapsedRealtimeNanos();
         NetworkStats.Entry entry = new NetworkStats.Entry(); // For recycling
         for (int j = 0; j < size; j++) {
             stats.getValues(j, entry);
-            StatsLogEventWrapper e = new StatsLogEventWrapper(tag, withFGBG ? 6 : 5);
+            StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tag, withFGBG ? 6 : 5);
             e.writeInt(entry.uid);
             if (withFGBG) {
                 e.writeInt(entry.set);
@@ -500,10 +554,11 @@
     private void pullKernelWakelock(int tagId, List<StatsLogEventWrapper> pulledData) {
         final KernelWakelockStats wakelockStats =
                 mKernelWakelockReader.readKernelWakelockStats(mTmpWakelockStats);
+        long elapsedNanos = SystemClock.elapsedRealtimeNanos();
         for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) {
             String name = ent.getKey();
             KernelWakelockStats.Entry kws = ent.getValue();
-            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, 4);
+            StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 4);
             e.writeString(name);
             e.writeInt(kws.mCount);
             e.writeInt(kws.mVersion);
@@ -576,8 +631,9 @@
 
     private void pullBluetoothBytesTransfer(int tagId, List<StatsLogEventWrapper> pulledData) {
         BluetoothActivityEnergyInfo info = pullBluetoothData();
+        long elapsedNanos = SystemClock.elapsedRealtimeNanos();
         for (UidTraffic traffic : info.getUidTraffic()) {
-            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, 3);
+            StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3);
             e.writeInt(traffic.getUid());
             e.writeLong(traffic.getRxBytes());
             e.writeLong(traffic.getTxBytes());
@@ -605,11 +661,12 @@
     }
 
     private void pullCpuTimePerFreq(int tagId, List<StatsLogEventWrapper> pulledData) {
+        long elapsedNanos = SystemClock.elapsedRealtimeNanos();
         for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) {
             long[] clusterTimeMs = mKernelCpuSpeedReaders[cluster].readAbsolute();
             if (clusterTimeMs != null) {
                 for (int speed = clusterTimeMs.length - 1; speed >= 0; --speed) {
-                    StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, 3);
+                    StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3);
                     e.writeInt(cluster);
                     e.writeInt(speed);
                     e.writeLong(clusterTimeMs[speed]);
@@ -630,7 +687,7 @@
                 SynchronousResultReceiver wifiReceiver = new SynchronousResultReceiver("wifi");
                 mWifiManager.requestActivityInfo(wifiReceiver);
                 final WifiActivityEnergyInfo wifiInfo = awaitControllerInfo(wifiReceiver);
-                StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, 6);
+                StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 6);
                 e.writeLong(wifiInfo.getTimeStamp());
                 e.writeInt(wifiInfo.getStackState());
                 e.writeLong(wifiInfo.getControllerTxTimeMillis());
@@ -655,7 +712,7 @@
             SynchronousResultReceiver modemReceiver = new SynchronousResultReceiver("telephony");
             mTelephony.requestModemActivityInfo(modemReceiver);
             final ModemActivityInfo modemInfo = awaitControllerInfo(modemReceiver);
-            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, 6);
+            StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 6);
             e.writeLong(modemInfo.getTimestamp());
             e.writeLong(modemInfo.getSleepTimeMillis());
             e.writeLong(modemInfo.getIdleTimeMillis());
@@ -672,7 +729,7 @@
 
     private void pullBluetoothActivityInfo(int tagId, List<StatsLogEventWrapper> pulledData) {
         BluetoothActivityEnergyInfo info = pullBluetoothData();
-        StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, 6);
+        StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 6);
         e.writeLong(info.getTimeStamp());
         e.writeInt(info.getBluetoothStackState());
         e.writeLong(info.getControllerTxTimeMillis());
@@ -695,13 +752,13 @@
     }
 
     private void pullSystemElapsedRealtime(int tagId, List<StatsLogEventWrapper> pulledData) {
-        StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, 1);
+        StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 1);
         e.writeLong(SystemClock.elapsedRealtime());
         pulledData.add(e);
     }
 
     private void pullDiskSpace(int tagId, List<StatsLogEventWrapper> pulledData) {
-        StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, 3);
+        StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 3);
         e.writeLong(mStatFsData.getAvailableBytes());
         e.writeLong(mStatFsSystem.getAvailableBytes());
         e.writeLong(mStatFsTemp.getAvailableBytes());
@@ -709,7 +766,7 @@
     }
 
     private void pullSystemUpTime(int tagId, List<StatsLogEventWrapper> pulledData) {
-        StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, 1);
+        StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 1);
         e.writeLong(SystemClock.uptimeMillis());
         pulledData.add(e);
     }
@@ -718,8 +775,9 @@
         List<ProcessMemoryState> processMemoryStates =
                 LocalServices.getService(ActivityManagerInternal.class)
                         .getMemoryStateForProcesses();
+        long elapsedNanos = SystemClock.elapsedRealtimeNanos();
         for (ProcessMemoryState processMemoryState : processMemoryStates) {
-            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, 8 /* fields */);
+            StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 8 /* fields */);
             e.writeInt(processMemoryState.uid);
             e.writeString(processMemoryState.processName);
             e.writeInt(processMemoryState.oomScore);
diff --git a/services/core/java/com/android/server/timezone/RulesManagerService.java b/services/core/java/com/android/server/timezone/RulesManagerService.java
index 872d723..23c4a337 100644
--- a/services/core/java/com/android/server/timezone/RulesManagerService.java
+++ b/services/core/java/com/android/server/timezone/RulesManagerService.java
@@ -92,6 +92,9 @@
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
     static final String REQUIRED_UPDATER_PERMISSION =
             android.Manifest.permission.UPDATE_TIME_ZONE_RULES;
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    static final String REQUIRED_QUERY_PERMISSION =
+            android.Manifest.permission.QUERY_TIME_ZONE_RULES;
     private static final File SYSTEM_TZ_DATA_FILE = new File("/system/usr/share/zoneinfo/tzdata");
     private static final File TZ_DATA_DIR = new File("/data/misc/zoneinfo");
 
@@ -131,7 +134,7 @@
 
     @Override // Binder call
     public RulesState getRulesState() {
-        mPermissionHelper.enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);
+        mPermissionHelper.enforceCallerHasPermission(REQUIRED_QUERY_PERMISSION);
 
         return getRulesStateInternal();
     }
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 844aafb..397c50f 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -859,6 +859,17 @@
             }
         }
 
+        public void scheduleTimeoutLocked() {
+            // If we didn't reset it right away, do so after we couldn't connect to
+            // it for an extended amount of time to avoid having a black wallpaper.
+            final Handler fgHandler = FgThread.getHandler();
+            fgHandler.removeCallbacks(mResetRunnable);
+            fgHandler.postDelayed(mResetRunnable, WALLPAPER_RECONNECT_TIMEOUT_MS);
+            if (DEBUG_LIVE) {
+                Slog.i(TAG, "Started wallpaper reconnect timeout for " + mWallpaper.wallpaperComponent);
+            }
+        }
+
         private void processDisconnect(final ServiceConnection connection) {
             synchronized (mLock) {
                 // The wallpaper disappeared.  If this isn't a system-default one, track
@@ -883,13 +894,13 @@
                         } else {
                             mWallpaper.lastDiedTime = SystemClock.uptimeMillis();
 
-                            // If we didn't reset it right away, do so after we couldn't connect to
-                            // it for an extended amount of time to avoid having a black wallpaper.
-                            final Handler fgHandler = FgThread.getHandler();
-                            fgHandler.removeCallbacks(mResetRunnable);
-                            fgHandler.postDelayed(mResetRunnable, WALLPAPER_RECONNECT_TIMEOUT_MS);
-                            if (DEBUG_LIVE) {
-                                Slog.i(TAG, "Started wallpaper reconnect timeout for " + wpService);
+                            clearWallpaperComponentLocked(mWallpaper);
+                            if (bindWallpaperComponentLocked(
+                                    wpService, false, false, mWallpaper, null)) {
+                                mWallpaper.connection.scheduleTimeoutLocked();
+                            } else {
+                                Slog.w(TAG, "Reverting to built-in wallpaper!");
+                                clearWallpaperLocked(true, FLAG_SYSTEM, mWallpaper.userId, null);
                             }
                         }
                         final String flattened = wpService.flattenToString();
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 659253f..c31cdec 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -87,6 +87,8 @@
 
     private WindowsForAccessibilityObserver mWindowsForAccessibilityObserver;
 
+    private boolean mScreenMagnificationActive;
+
     public void setMagnificationCallbacksLocked(MagnificationCallbacks callbacks) {
         if (callbacks != null) {
             if (mDisplayMagnifier != null) {
@@ -136,6 +138,11 @@
         if (mWindowsForAccessibilityObserver != null) {
             mWindowsForAccessibilityObserver.scheduleComputeChangedWindowsLocked();
         }
+        boolean nowActive = !spec.isNop();
+        if (nowActive != mScreenMagnificationActive) {
+            mScreenMagnificationActive = nowActive;
+            mService.mPolicy.onScreenMagnificationStateChanged(nowActive);
+        }
     }
 
     public void getMagnificationRegionLocked(Region outMagnificationRegion) {
diff --git a/services/core/java/com/android/server/wm/AnimationAdapter.java b/services/core/java/com/android/server/wm/AnimationAdapter.java
index ed4543e..64f77a2 100644
--- a/services/core/java/com/android/server/wm/AnimationAdapter.java
+++ b/services/core/java/com/android/server/wm/AnimationAdapter.java
@@ -39,6 +39,12 @@
     boolean getDetachWallpaper();
 
     /**
+     * @return Whether we should show the wallpaper during the animation.
+     * @see Animation#getShowWallpaper()
+     */
+    boolean getShowWallpaper();
+
+    /**
      * @return The background color behind the animation.
      */
     @ColorInt int getBackgroundColor();
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 0d36145..f0ca2ef 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -29,6 +29,7 @@
 import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
 import static android.view.WindowManager.TRANSIT_NONE;
 import static android.view.WindowManager.TRANSIT_TASK_CLOSE;
+import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
 import static android.view.WindowManager.TRANSIT_TASK_OPEN;
 import static android.view.WindowManager.TRANSIT_TASK_OPEN_BEHIND;
 import static android.view.WindowManager.TRANSIT_TASK_TO_BACK;
@@ -2138,6 +2139,10 @@
                     && isTransitionEqual(TRANSIT_ACTIVITY_CLOSE)) {
                 // Opening a new activity always supersedes a close for the anim.
                 setAppTransition(transit, flags);
+            } else if (isTaskTransit(transit) && isActivityTransit(mNextAppTransition)) {
+                // Task animations always supersede activity animations, because if we have both, it
+                // usually means that activity transition were just trampoline activities.
+                setAppTransition(transit, flags);
             }
         }
         boolean prepared = prepare();
@@ -2162,6 +2167,21 @@
                 || transit == TRANSIT_KEYGUARD_UNOCCLUDE;
     }
 
+    private static boolean isTaskTransit(int transit) {
+        return transit == TRANSIT_TASK_OPEN
+                || transit == TRANSIT_TASK_CLOSE
+                || transit == TRANSIT_TASK_OPEN_BEHIND
+                || transit == TRANSIT_TASK_TO_BACK
+                || transit == TRANSIT_TASK_TO_FRONT
+                || transit == TRANSIT_TASK_IN_PLACE;
+    }
+
+    private static boolean isActivityTransit(int transit) {
+        return transit == TRANSIT_ACTIVITY_OPEN
+                || transit == TRANSIT_ACTIVITY_CLOSE
+                || transit == TRANSIT_ACTIVITY_RELAUNCH;
+    }
+
     /**
      * @return whether the transition should show the thumbnail being scaled down.
      */
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index e9efd4e..40f772a 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -367,15 +367,14 @@
                     if (wtoken.isHidden()) {
                         wtoken.waitingToShow = true;
                     }
-
-                    if (wtoken.isClientHidden()) {
-                        // In the case where we are making an app visible but holding off for a
-                        // transition, we still need to tell the client to make its windows visible
-                        // so they get drawn. Otherwise, we will wait on performing the transition
-                        // until all windows have been drawn, they never will be, and we are sad.
-                        wtoken.setClientHidden(false);
-                    }
                 }
+
+                // In the case where we are making an app visible but holding off for a transition,
+                // we still need to tell the client to make its windows visible so they get drawn.
+                // Otherwise, we will wait on performing the transition until all windows have been
+                // drawn, they never will be, and we are sad.
+                wtoken.setClientHidden(false);
+
                 wtoken.requestUpdateWallpaperIfNeeded();
 
                 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "No longer Stopped: " + wtoken);
diff --git a/services/core/java/com/android/server/wm/AppWindowThumbnail.java b/services/core/java/com/android/server/wm/AppWindowThumbnail.java
index db95634..3cd3e8b 100644
--- a/services/core/java/com/android/server/wm/AppWindowThumbnail.java
+++ b/services/core/java/com/android/server/wm/AppWindowThumbnail.java
@@ -53,8 +53,7 @@
 
     AppWindowThumbnail(Transaction t, AppWindowToken appToken, GraphicBuffer thumbnailHeader) {
         mAppToken = appToken;
-        mSurfaceAnimator = new SurfaceAnimator(this, this::onAnimationFinished,
-                appToken.mService.mAnimator::addAfterPrepareSurfacesRunnable, appToken.mService);
+        mSurfaceAnimator = new SurfaceAnimator(this, this::onAnimationFinished, appToken.mService);
         mWidth = thumbnailHeader.getWidth();
         mHeight = thumbnailHeader.getHeight();
 
@@ -145,11 +144,6 @@
     }
 
     @Override
-    public void destroyAfterPendingTransaction(SurfaceControl surface) {
-        mAppToken.destroyAfterPendingTransaction(surface);
-    }
-
-    @Override
     public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) {
         t.setLayer(leash, Integer.MAX_VALUE);
     }
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index d646c07..c2cc7c9 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -367,6 +367,8 @@
         if (mClientHidden == hideClient || (hideClient && mDeferHidingClient)) {
             return;
         }
+        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "setClientHidden: " + this
+                + " clientHidden=" + hideClient + " Callers=" + Debug.getCallers(5));
         mClientHidden = hideClient;
         sendAppVisibilityToClients();
     }
@@ -1618,7 +1620,15 @@
 
     @Override
     public SurfaceControl getAnimationLeashParent() {
-        return getAppAnimationLayer();
+        // All normal app transitions take place in an animation layer which is below the pinned
+        // stack but may be above the parent stacks of the given animating apps.
+        // For transitions in the pinned stack (menu activity) we just let them occur as a child
+        // of the pinned stack.
+        if (!inPinnedWindowingMode()) {
+            return getAppAnimationLayer();
+        } else {
+            return getStack().getSurfaceControl();
+        }
     }
 
     boolean applyAnimationLocked(WindowManager.LayoutParams lp, int transit, boolean enter,
@@ -1668,6 +1678,9 @@
             }
             if (adapter != null) {
                 startAnimation(getPendingTransaction(), adapter, !isVisible());
+                if (adapter.getShowWallpaper()) {
+                    mDisplayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
+                }
             }
         } else {
             cancelAnimation();
@@ -1704,6 +1717,10 @@
                 frame.set(win.mFrame);
             } else if (win.isLetterboxedAppWindow()) {
                 frame.set(getTask().getBounds());
+            } else if (win.isDockedResizing()) {
+                // If we are animating while docked resizing, then use the stack bounds as the
+                // animation target (which will be different than the task bounds)
+                frame.set(getTask().getParent().getBounds());
             } else {
                 frame.set(win.mContainingFrame);
             }
@@ -1758,10 +1775,18 @@
 
     @Override
     public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) {
-
         // The leash is parented to the animation layer. We need to preserve the z-order by using
         // the prefix order index, but we boost if necessary.
-        int layer = getPrefixOrderIndex();
+        int layer = 0;
+        if (!inPinnedWindowingMode()) {
+            layer = getPrefixOrderIndex();
+        } else {
+            // Pinned stacks have animations take place within themselves rather than an animation
+            // layer so we need to preserve the order relative to the stack (e.g. the order of our
+            // task/parent).
+            layer = getParent().getPrefixOrderIndex();
+        }
+
         if (mNeedsZBoost) {
             layer += Z_BOOST_BASE;
         }
diff --git a/services/core/java/com/android/server/wm/Dimmer.java b/services/core/java/com/android/server/wm/Dimmer.java
index 4394a99..a180a3a 100644
--- a/services/core/java/com/android/server/wm/Dimmer.java
+++ b/services/core/java/com/android/server/wm/Dimmer.java
@@ -55,11 +55,6 @@
         }
 
         @Override
-        public void destroyAfterPendingTransaction(SurfaceControl surface) {
-            mHost.destroyAfterPendingTransaction(surface);
-        }
-
-        @Override
         public SurfaceControl.Builder makeAnimationLeash() {
             return mHost.makeAnimationLeash();
         }
@@ -119,7 +114,7 @@
                 if (!mDimming) {
                     mDimLayer.destroy();
                 }
-            }, mHost.mService.mAnimator::addAfterPrepareSurfacesRunnable, mHost.mService);
+            }, mHost.mService);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 473eeda..59bece0 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -154,6 +154,7 @@
 import com.android.internal.util.ToBooleanFunction;
 import com.android.internal.view.IInputMethodClient;
 import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.wm.utils.RotationCache;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -215,7 +216,8 @@
     int mInitialDisplayDensity = 0;
 
     DisplayCutout mInitialDisplayCutout;
-    DisplayCutout mDisplayCutoutOverride;
+    private final RotationCache<DisplayCutout, DisplayCutout> mDisplayCutoutCache
+            = new RotationCache<>(this::calculateDisplayCutoutForRotationUncached);
 
     /**
      * Overridden display size. Initialized with {@link #mInitialDisplayWidth}
@@ -380,11 +382,6 @@
      */
     private int mSurfaceSize;
 
-    /**
-     * A list of surfaces to be destroyed after {@link #mPendingTransaction} is applied.
-     */
-    private final ArrayList<SurfaceControl> mPendingDestroyingSurfaces = new ArrayList<>();
-
     /** Temporary float array to retrieve 3x3 matrix values. */
     private final float[] mTmpFloats = new float[9];
 
@@ -745,7 +742,14 @@
         mDividerControllerLocked = new DockedStackDividerController(service, this);
         mPinnedStackControllerLocked = new PinnedStackController(service, this);
 
-        mSurfaceSize = Math.max(mBaseDisplayHeight, mBaseDisplayWidth);
+        // We use this as our arbitrary surface size for buffer-less parents
+        // that don't impose cropping on their children. It may need to be larger
+        // than the display size because fullscreen windows can be shifted offscreen
+        // due to surfaceInsets. 2 times the largest display dimension feels like an
+        // appropriately arbitrary number. Eventually we would like to give SurfaceFlinger
+        // layers the ability to match their parent sizes and be able to skip
+        // such arbitrary size settings.
+        mSurfaceSize = Math.max(mBaseDisplayHeight, mBaseDisplayWidth) * 2;
 
         final SurfaceControl.Builder b = mService.makeSurfaceBuilder(mSession)
                 .setSize(mSurfaceSize, mSurfaceSize)
@@ -1198,14 +1202,18 @@
     }
 
     DisplayCutout calculateDisplayCutoutForRotation(int rotation) {
-        final DisplayCutout cutout = mInitialDisplayCutout;
+        return mDisplayCutoutCache.getOrCompute(mInitialDisplayCutout, rotation);
+    }
+
+    private DisplayCutout calculateDisplayCutoutForRotationUncached(
+            DisplayCutout cutout, int rotation) {
         if (cutout == null || cutout == DisplayCutout.NO_CUTOUT) {
             return cutout;
         }
         if (rotation == ROTATION_0) {
             return cutout.computeSafeInsets(mInitialDisplayWidth, mInitialDisplayHeight);
         }
-        final boolean rotated = (rotation == ROTATION_90 || mRotation == ROTATION_270);
+        final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
         final Path bounds = cutout.getBounds().getBoundaryPath();
         transformPhysicalToLogicalCoordinates(rotation, mInitialDisplayWidth, mInitialDisplayHeight,
                 mTmpMatrix);
@@ -1948,10 +1956,6 @@
                 }
             }
             mService.mAnimator.removeDisplayLocked(mDisplayId);
-
-            // The pending transaction won't be applied so we should
-            // just clean up any surfaces pending destruction.
-            onPendingTransactionApplied();
         } finally {
             mRemovingDisplay = false;
         }
@@ -2594,18 +2598,6 @@
         }, false /* traverseTopToBottom */);
     }
 
-    void enableSurfaceTrace(FileDescriptor fd) {
-        forAllWindows(w -> {
-            w.mWinAnimator.enableSurfaceTrace(fd);
-        }, true /* traverseTopToBottom */);
-    }
-
-    void disableSurfaceTrace() {
-        forAllWindows(w -> {
-            w.mWinAnimator.disableSurfaceTrace();
-        }, true /* traverseTopToBottom */);
-    }
-
     /**
      * Starts the Keyguard exit animation on all windows that don't belong to an app token.
      */
@@ -3577,7 +3569,7 @@
                     if (s.inSplitScreenWindowingMode() && mSplitScreenDividerAnchor != null) {
                         t.setLayer(mSplitScreenDividerAnchor, layer++);
                     }
-                    if (s.isSelfOrChildAnimating()) {
+                    if (s.isAppAnimating() && state != ALWAYS_ON_TOP_STATE) {
                         // Ensure the animation layer ends up above the
                         // highest animating stack and no higher.
                         layerForAnimationLayer = layer++;
@@ -3626,6 +3618,11 @@
             super(name, service);
         }
 
+        @Override
+        void assignChildLayers(SurfaceControl.Transaction t) {
+            assignChildLayers(t, null /* imeContainer */);
+        }
+
         void assignChildLayers(SurfaceControl.Transaction t, WindowContainer imeContainer) {
             boolean needAssignIme = imeContainer != null
                     && imeContainer.getSurfaceControl() != null;
@@ -3868,22 +3865,6 @@
     }
 
     @Override
-    public void destroyAfterPendingTransaction(SurfaceControl surface) {
-        mPendingDestroyingSurfaces.add(surface);
-    }
-
-    /**
-     * Destroys any surfaces that have been put into the pending list with
-     * {@link #destroyAfterPendingTransaction}.
-     */
-    void onPendingTransactionApplied() {
-        for (int i = mPendingDestroyingSurfaces.size() - 1; i >= 0; i--) {
-            mPendingDestroyingSurfaces.get(i).destroy();
-        }
-        mPendingDestroyingSurfaces.clear();
-    }
-
-    @Override
     void prepareSurfaces() {
         final ScreenRotationAnimation screenRotationAnimation =
                 mService.mAnimator.getScreenRotationAnimationLocked(mDisplayId);
@@ -3897,6 +3878,7 @@
             mPendingTransaction.setAlpha(mWindowingLayer,
                     screenRotationAnimation.getEnterTransformation().getAlpha());
         }
+
         super.prepareSurfaces();
     }
 
diff --git a/services/core/java/com/android/server/wm/DisplayWindowController.java b/services/core/java/com/android/server/wm/DisplayWindowController.java
index 0e12838..e3e4a46 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowController.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowController.java
@@ -50,7 +50,9 @@
             }
 
             if (mContainer == null) {
-                throw new IllegalArgumentException("Trying to add displayId=" + displayId);
+                throw new IllegalArgumentException("Trying to add displayId=" + displayId
+                        + " display=" + display
+                        + " dc=" + mRoot.getDisplayContent(displayId));
             }
         }
     }
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 423be63..1f1efc4 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -174,7 +174,7 @@
             final int position = DockedDividerUtils.calculatePositionForBounds(mTmpRect, dockSide,
                     getContentWidth());
 
-            DisplayCutout displayCutout = mDisplayContent.calculateDisplayCutoutForRotation(
+            final DisplayCutout displayCutout = mDisplayContent.calculateDisplayCutoutForRotation(
                     rotation);
 
             // Since we only care about feasible states, snap to the closest snap target, like it
@@ -242,7 +242,7 @@
             final int appWidth = mService.mPolicy.getNonDecorDisplayWidth(dw, dh, rotation,
                 baseConfig.uiMode, displayId, displayCutout);
             final int appHeight = mService.mPolicy.getNonDecorDisplayHeight(dw, dh, rotation,
-                baseConfig.uiMode, displayId, mDisplayContent.getDisplayInfo().displayCutout);
+                baseConfig.uiMode, displayId, displayCutout);
             mService.mPolicy.getNonDecorInsetsLw(rotation, dw, dh, displayCutout, mTmpRect);
             final int leftInset = mTmpRect.left;
             final int topInset = mTmpRect.top;
@@ -620,7 +620,12 @@
         if (wasMinimized && mMinimizedDock && containsAppInDockedStack(openingApps)
                 && appTransition != TRANSIT_NONE &&
                 !AppTransition.isKeyguardGoingAwayTransit(appTransition)) {
-            mService.showRecentApps();
+            if (mService.mAmInternal.isRecentsComponentHomeActivity(mService.mCurrentUserId)) {
+                // When the home activity is the recents component and we are already minimized,
+                // then there is nothing to do here since home is already visible
+            } else {
+                mService.showRecentApps();
+            }
         }
     }
 
@@ -641,7 +646,7 @@
         return mMinimizedDock;
     }
 
-    private void checkMinimizeChanged(boolean animate) {
+    void checkMinimizeChanged(boolean animate) {
         if (mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility() == null) {
             return;
         }
@@ -693,7 +698,7 @@
         final boolean imeChanged = clearImeAdjustAnimation();
         boolean minimizedChange = false;
         if (isHomeStackResizable()) {
-            notifyDockedStackMinimizedChanged(minimizedDock, true /* animate */,
+            notifyDockedStackMinimizedChanged(minimizedDock, animate,
                     true /* isHomeStackResizable */);
             minimizedChange = true;
         } else {
diff --git a/services/core/java/com/android/server/wm/LocalAnimationAdapter.java b/services/core/java/com/android/server/wm/LocalAnimationAdapter.java
index 2173fa3..1b41cb8 100644
--- a/services/core/java/com/android/server/wm/LocalAnimationAdapter.java
+++ b/services/core/java/com/android/server/wm/LocalAnimationAdapter.java
@@ -43,6 +43,11 @@
     }
 
     @Override
+    public boolean getShowWallpaper() {
+        return mSpec.getShowWallpaper();
+    }
+
+    @Override
     public int getBackgroundColor() {
         return mSpec.getBackgroundColor();
     }
@@ -82,6 +87,13 @@
         }
 
         /**
+         * @see AnimationAdapter#getShowWallpaper
+         */
+        default boolean getShowWallpaper() {
+            return false;
+        }
+
+        /**
          * @see AnimationAdapter#getBackgroundColor
          */
         default int getBackgroundColor() {
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 78dd580..f7344b2 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -219,7 +219,7 @@
     private void addAnimation(Task task) {
         if (DEBUG) Log.d(TAG, "addAnimation(" + task.getName() + ")");
         final SurfaceAnimator anim = new SurfaceAnimator(task, null /* animationFinishedCallback */,
-                mService.mAnimator::addAfterPrepareSurfacesRunnable, mService);
+                mService);
         final TaskAnimationAdapter taskAdapter = new TaskAnimationAdapter(task);
         anim.startAnimation(task.getPendingTransaction(), taskAdapter, false /* hidden */);
         task.commitPendingTransaction();
@@ -256,18 +256,20 @@
 
     void cancelAnimation() {
         if (DEBUG) Log.d(TAG, "cancelAnimation()");
-        if (mCanceled) {
-            // We've already canceled the animation
-            return;
+        synchronized (mService.getWindowManagerLock()) {
+            if (mCanceled) {
+                // We've already canceled the animation
+                return;
+            }
+            mCanceled = true;
+            try {
+                mRunner.onAnimationCanceled();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Failed to cancel recents animation", e);
+            }
         }
-        mCanceled = true;
-        try {
-            mRunner.onAnimationCanceled();
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Failed to cancel recents animation", e);
-        }
-
         // Clean up and return to the previous app
+        // Don't hold the WM lock here as it calls back to AM/RecentsAnimation
         mCallbacks.onAnimationFinished(false /* moveHomeToTop */);
     }
 
@@ -368,6 +370,11 @@
         }
 
         @Override
+        public boolean getShowWallpaper() {
+            return false;
+        }
+
+        @Override
         public int getBackgroundColor() {
             return 0;
         }
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index 35fc99f..ed6e606 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -221,6 +221,11 @@
         }
 
         @Override
+        public boolean getShowWallpaper() {
+            return false;
+        }
+
+        @Override
         public int getBackgroundColor() {
             return 0;
         }
diff --git a/services/core/java/com/android/server/wm/RemoteEventTrace.java b/services/core/java/com/android/server/wm/RemoteEventTrace.java
deleted file mode 100644
index b214d35..0000000
--- a/services/core/java/com/android/server/wm/RemoteEventTrace.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm;
-
-import java.io.FileDescriptor;
-import java.io.FileOutputStream;
-import java.io.DataOutputStream;
-
-import android.os.StrictMode;
-import android.util.Slog;
-import android.os.Debug;
-
-// Counterpart to remote surface trace for events which are not tied to a particular surface.
-class RemoteEventTrace {
-    private static final String TAG = "RemoteEventTrace";
-
-    // We terminate all our messages with a recognizable marker, to avoid issues
-    // with partial reads (which ADB makes impossible to avoid).
-    static final byte[] sigil = {(byte)0xfc, (byte)0xfc, (byte)0xfc, (byte)0xfc};
-
-    private final WindowManagerService mService;
-    private final DataOutputStream mOut;
-
-    RemoteEventTrace(WindowManagerService service, FileDescriptor fd) {
-        mService = service;
-        mOut = new DataOutputStream(new FileOutputStream(fd, false));
-    }
-
-    void openSurfaceTransaction() {
-        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
-        try {
-            mOut.writeUTF("OpenTransaction");
-            writeSigil();
-        } catch (Exception e) {
-            logException(e);
-            mService.disableSurfaceTrace();
-        } finally {
-            StrictMode.setThreadPolicy(oldPolicy);
-        }
-    }
-
-    void closeSurfaceTransaction() {
-        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
-        try {
-            mOut.writeUTF("CloseTransaction");
-            writeSigil();
-        } catch (Exception e) {
-            logException(e);
-            mService.disableSurfaceTrace();
-        } finally {
-            StrictMode.setThreadPolicy(oldPolicy);
-        }
-    }
-
-    private void writeSigil() throws Exception {
-        mOut.write(RemoteEventTrace.sigil, 0, 4);
-    }
-
-    static void logException(Exception e) {
-        Slog.i(TAG, "Exception writing to SurfaceTrace (client vanished?): " + e.toString());
-    }
-}
diff --git a/services/core/java/com/android/server/wm/RemoteSurfaceTrace.java b/services/core/java/com/android/server/wm/RemoteSurfaceTrace.java
deleted file mode 100644
index 33e560f..0000000
--- a/services/core/java/com/android/server/wm/RemoteSurfaceTrace.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm;
-
-import android.graphics.Rect;
-import android.graphics.Region;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.StrictMode;
-import android.util.Slog;
-import android.view.SurfaceControl;
-
-import java.io.FileDescriptor;
-import java.io.FileOutputStream;
-import java.io.DataOutputStream;
-
-// A surface control subclass which logs events to a FD in binary format.
-// This can be used in our CTS tests to enable a pattern similar to mocking
-// the surface control.
-//
-// See cts/hostsidetests/../../SurfaceTraceReceiver.java for parsing side.
-class RemoteSurfaceTrace extends SurfaceControl {
-    static final String TAG = "RemoteSurfaceTrace";
-
-    final FileDescriptor mWriteFd;
-    final DataOutputStream mOut;
-
-    final WindowManagerService mService;
-    final WindowState mWindow;
-
-    RemoteSurfaceTrace(FileDescriptor fd, SurfaceControl wrapped,
-            WindowState window) {
-        super(wrapped);
-
-        mWriteFd = fd;
-        mOut = new DataOutputStream(new FileOutputStream(fd, false));
-
-        mWindow = window;
-        mService = mWindow.mService;
-    }
-
-    @Override
-    public void setAlpha(float alpha) {
-        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
-        try {
-            writeFloatEvent("Alpha", alpha);
-        } finally {
-            StrictMode.setThreadPolicy(oldPolicy);
-        }
-        super.setAlpha(alpha);
-    }
-
-    @Override
-    public void setLayer(int zorder) {
-        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
-        try {
-            writeIntEvent("Layer", zorder);
-        } finally {
-            StrictMode.setThreadPolicy(oldPolicy);
-        }
-        super.setLayer(zorder);
-    }
-
-    @Override
-    public void setPosition(float x, float y) {
-        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
-        try {
-            writeFloatEvent("Position", x, y);
-        } finally {
-            StrictMode.setThreadPolicy(oldPolicy);
-        }
-        super.setPosition(x, y);
-    }
-
-    @Override
-    public void setGeometryAppliesWithResize() {
-        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
-        try {
-            writeEvent("GeometryAppliesWithResize");
-        } finally {
-            StrictMode.setThreadPolicy(oldPolicy);
-        }
-        super.setGeometryAppliesWithResize();
-    }
-
-    @Override
-    public void setSize(int w, int h) {
-        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
-        try {
-            writeIntEvent("Size", w, h);
-        } finally {
-            StrictMode.setThreadPolicy(oldPolicy);
-        }
-        super.setSize(w, h);
-    }
-
-    @Override
-    public void setWindowCrop(Rect crop) {
-        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
-        try {
-            writeRectEvent("Crop", crop);
-        } finally {
-            StrictMode.setThreadPolicy(oldPolicy);
-        }
-        super.setWindowCrop(crop);
-    }
-
-    @Override
-    public void setFinalCrop(Rect crop) {
-        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
-        try {
-            writeRectEvent("FinalCrop", crop);
-        } finally {
-            StrictMode.setThreadPolicy(oldPolicy);
-        }
-        super.setFinalCrop(crop);
-    }
-
-    @Override
-    public void setLayerStack(int layerStack) {
-        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
-        try {
-            writeIntEvent("LayerStack", layerStack);
-        } finally {
-            StrictMode.setThreadPolicy(oldPolicy);
-        }
-        super.setLayerStack(layerStack);
-    }
-
-    @Override
-    public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
-        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
-        try {
-            writeFloatEvent("Matrix", dsdx, dtdx, dsdy, dtdy);
-        } finally {
-            StrictMode.setThreadPolicy(oldPolicy);
-        }
-        super.setMatrix(dsdx, dtdx, dsdy, dtdy);
-    }
-
-    @Override
-    public void hide() {
-        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
-        try {
-            writeEvent("Hide");
-        } finally {
-            StrictMode.setThreadPolicy(oldPolicy);
-        }
-        super.hide();
-    }
-
-    @Override
-    public void show() {
-        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
-        try {
-            writeEvent("Show");
-        } finally {
-            StrictMode.setThreadPolicy(oldPolicy);
-        }
-        super.show();
-    }
-
-    private void writeEvent(String tag) {
-        try {
-            mOut.writeUTF(tag);
-            mOut.writeUTF(mWindow.getWindowTag().toString());
-            writeSigil();
-        } catch (Exception e) {
-            RemoteEventTrace.logException(e);
-            mService.disableSurfaceTrace();
-        }
-    }
-
-    private void writeIntEvent(String tag, int... values) {
-        try {
-            mOut.writeUTF(tag);
-            mOut.writeUTF(mWindow.getWindowTag().toString());
-            for (int value: values) {
-                mOut.writeInt(value);
-            }
-            writeSigil();
-        } catch (Exception e) {
-            RemoteEventTrace.logException(e);
-            mService.disableSurfaceTrace();
-        }
-    }
-
-    private void writeFloatEvent(String tag, float... values) {
-        try {
-            mOut.writeUTF(tag);
-            mOut.writeUTF(mWindow.getWindowTag().toString());
-            for (float value: values) {
-                mOut.writeFloat(value);
-            }
-            writeSigil();
-        } catch (Exception e) {
-            RemoteEventTrace.logException(e);
-            mService.disableSurfaceTrace();
-        }
-    }
-
-    private void writeRectEvent(String tag, Rect value) {
-        writeFloatEvent(tag, value.left, value.top, value.right, value.bottom);
-    }
-
-    private void writeSigil() throws Exception {
-        mOut.write(RemoteEventTrace.sigil, 0, 4);
-    }
-}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index a4f20b01..f32c275 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -29,9 +29,7 @@
 import android.os.ParcelFileDescriptor;
 import android.os.PowerManager;
 import android.os.RemoteException;
-import android.os.SystemClock;
 import android.os.UserHandle;
-import android.provider.Settings;
 import android.util.ArraySet;
 import android.util.EventLog;
 import android.util.Slog;
@@ -50,9 +48,6 @@
 import java.util.List;
 import java.util.function.Consumer;
 
-import static android.app.AppOpsManager.MODE_ALLOWED;
-import static android.app.AppOpsManager.MODE_DEFAULT;
-import static android.app.AppOpsManager.OP_NONE;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
 import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
@@ -68,8 +63,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
@@ -130,13 +123,6 @@
     private final ArrayList<TaskStack> mTmpStackList = new ArrayList();
     private final ArrayList<Integer> mTmpStackIds = new ArrayList<>();
 
-    // State for the RemoteSurfaceTrace system used in testing. If this is enabled SurfaceControl
-    // instances will be replaced with an instance that writes a binary representation of all
-    // commands to mSurfaceTraceFd.
-    boolean mSurfaceTraceEnabled;
-    ParcelFileDescriptor mSurfaceTraceFd;
-    RemoteEventTrace mRemoteEventTrace;
-
     final WallpaperController mWallpaperController;
 
     private final Handler mHandler;
@@ -427,12 +413,7 @@
 
     void updateAppOpsState() {
         forAllWindows((w) -> {
-            if (w.mAppOp == OP_NONE) {
-                return;
-            }
-            final int mode = mService.mAppOps.noteOpNoThrow(w.mAppOp, w.getOwningUid(),
-                    w.getOwningPackage());
-            w.setAppOpVisibilityLw(mode == MODE_ALLOWED || mode == MODE_DEFAULT);
+            w.updateAppOpsState();
         }, false /* traverseTopToBottom */);
     }
 
@@ -606,8 +587,11 @@
         // If we are ready to perform an app transition, check through all of the app tokens to be
         // shown and see if they are ready to go.
         if (mService.mAppTransition.isReady()) {
-            defaultDisplay.pendingLayoutChanges |=
-                    surfacePlacer.handleAppTransitionReadyLocked();
+            // This needs to be split into two expressions, as handleAppTransitionReadyLocked may
+            // modify dc.pendingLayoutChanges, which would get lost when writing
+            // defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked()
+            final int layoutChanges = surfacePlacer.handleAppTransitionReadyLocked();
+            defaultDisplay.pendingLayoutChanges |= layoutChanges;
             if (DEBUG_LAYOUT_REPEATS)
                 surfacePlacer.debugLayoutRepeats("after handleAppTransitionReadyLocked",
                         defaultDisplay.pendingLayoutChanges);
@@ -811,7 +795,6 @@
         mService.enableScreenIfNeededLocked();
 
         mService.scheduleAnimationLocked();
-        mService.mWindowPlacerLocked.destroyPendingSurfaces();
 
         if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
                 "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
@@ -1011,30 +994,6 @@
         }
     }
 
-    void enableSurfaceTrace(ParcelFileDescriptor pfd) {
-        final FileDescriptor fd = pfd.getFileDescriptor();
-        if (mSurfaceTraceEnabled) {
-            disableSurfaceTrace();
-        }
-        mSurfaceTraceEnabled = true;
-        mRemoteEventTrace = new RemoteEventTrace(mService, fd);
-        mSurfaceTraceFd = pfd;
-        for (int displayNdx = mChildren.size() - 1; displayNdx >= 0; --displayNdx) {
-            final DisplayContent dc = mChildren.get(displayNdx);
-            dc.enableSurfaceTrace(fd);
-        }
-    }
-
-    void disableSurfaceTrace() {
-        mSurfaceTraceEnabled = false;
-        mRemoteEventTrace = null;
-        mSurfaceTraceFd = null;
-        for (int displayNdx = mChildren.size() - 1; displayNdx >= 0; --displayNdx) {
-            final DisplayContent dc = mChildren.get(displayNdx);
-            dc.disableSurfaceTrace();
-        }
-    }
-
     void dumpDisplayContents(PrintWriter pw) {
         pw.println("WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)");
         if (mService.mDisplayReady) {
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index 83baee1..76f5396 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -33,7 +33,6 @@
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.PrintWriter;
-import java.util.function.Consumer;
 
 /**
  * A class that can run animations on objects that have a set of child surfaces. We do this by
@@ -60,21 +59,17 @@
     /**
      * @param animatable The object to animate.
      * @param animationFinishedCallback Callback to invoke when an animation has finished running.
-     * @param addAfterPrepareSurfaces Consumer that takes a runnable and executes it after preparing
-     *                                surfaces in WM. Can be implemented differently during testing.
      */
     SurfaceAnimator(Animatable animatable, @Nullable Runnable animationFinishedCallback,
-            Consumer<Runnable> addAfterPrepareSurfaces, WindowManagerService service) {
+            WindowManagerService service) {
         mAnimatable = animatable;
         mService = service;
         mAnimationFinishedCallback = animationFinishedCallback;
-        mInnerAnimationFinishedCallback = getFinishedCallback(animationFinishedCallback,
-                addAfterPrepareSurfaces);
+        mInnerAnimationFinishedCallback = getFinishedCallback(animationFinishedCallback);
     }
 
     private OnAnimationFinishedCallback getFinishedCallback(
-            @Nullable Runnable animationFinishedCallback,
-            Consumer<Runnable> addAfterPrepareSurfaces) {
+            @Nullable Runnable animationFinishedCallback) {
         return anim -> {
             synchronized (mService.mWindowMap) {
                 final SurfaceAnimator target = mService.mAnimationTransferMap.remove(anim);
@@ -83,30 +78,13 @@
                     return;
                 }
 
-                // TODO: This should use pendingTransaction eventually, but right now things
-                // happening on the animation finished callback are happening on the global
-                // transaction.
-                // For now we need to run this after it's guaranteed that the transaction that
-                // reparents the surface onto the leash is executed already. Otherwise this may be
-                // executed first, leading to surface loss, as the reparent operations wouldn't
-                // be in order.
-                addAfterPrepareSurfaces.accept(() -> {
-                    if (anim != mAnimation) {
-                        // Callback was from another animation - ignore.
-                        return;
-                    }
-                    final Transaction t = new Transaction();
-                    SurfaceControl.openTransaction();
-                    try {
-                        reset(t, true /* destroyLeash */);
-                        if (animationFinishedCallback != null) {
-                            animationFinishedCallback.run();
-                        }
-                    } finally {
-                        SurfaceControl.mergeToGlobalTransaction(t);
-                        SurfaceControl.closeTransaction();
-                    }
-                });
+                if (anim != mAnimation) {
+                    return;
+                }
+                reset(mAnimatable.getPendingTransaction(), true /* destroyLeash */);
+                if (animationFinishedCallback != null) {
+                    animationFinishedCallback.run();
+                }
             }
         };
     }
@@ -282,15 +260,19 @@
         final SurfaceControl surface = mAnimatable.getSurfaceControl();
         final SurfaceControl parent = mAnimatable.getParentSurfaceControl();
 
+        boolean scheduleAnim = false;
+
         // If the surface was destroyed, we don't care to reparent it back.
         final boolean destroy = mLeash != null && surface != null && parent != null;
         if (destroy) {
             if (DEBUG_ANIM) Slog.i(TAG, "Reparenting to original parent");
             t.reparent(surface, parent.getHandle());
+            scheduleAnim = true;
         }
         mService.mAnimationTransferMap.remove(mAnimation);
         if (mLeash != null && destroyLeash) {
-            mAnimatable.destroyAfterPendingTransaction(mLeash);
+            t.destroy(mLeash);
+            scheduleAnim = true;
         }
         mLeash = null;
         mAnimation = null;
@@ -298,6 +280,11 @@
         // Make sure to inform the animatable after the leash was destroyed.
         if (destroy) {
             mAnimatable.onAnimationLeashDestroyed(t);
+            scheduleAnim = true;
+        }
+
+        if (scheduleAnim) {
+            mService.scheduleAnimationLocked();
         }
     }
 
@@ -379,13 +366,6 @@
         void onAnimationLeashDestroyed(Transaction t);
 
         /**
-         * Destroy a given surface after executing {@link #getPendingTransaction}.
-         *
-         * @see WindowContainer#destroyAfterPendingTransaction
-         */
-        void destroyAfterPendingTransaction(SurfaceControl surface);
-
-        /**
          * @return A new surface to be used for the animation leash, inserted at the correct
          *         position in the hierarchy.
          */
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 7d970d9..2e86351 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -687,11 +687,12 @@
         pw.println(doublePrefix + "mTempInsetBounds=" + mTempInsetBounds.toShortString());
 
         final String triplePrefix = doublePrefix + "  ";
+        final String quadruplePrefix = triplePrefix + "  ";
 
         for (int i = mChildren.size() - 1; i >= 0; i--) {
             final AppWindowToken wtoken = mChildren.get(i);
             pw.println(triplePrefix + "Activity #" + i + " " + wtoken);
-            wtoken.dump(pw, triplePrefix, dumpAll);
+            wtoken.dump(pw, quadruplePrefix, dumpAll);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index ba08fcd2..b5d00a7 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -751,8 +751,11 @@
     int getStackOutset() {
         if (inPinnedWindowingMode()) {
             final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics();
-            return mService.dipToPixel(PINNED_WINDOWING_MODE_ELEVATION_IN_DIP,
-                    displayMetrics);
+
+            // We multiply by two to match the client logic for converting view elevation
+            // to insets, as in {@link WindowManager.LayoutParams#setSurfaceInsets}
+            return (int)Math.ceil(mService.dipToPixel(PINNED_WINDOWING_MODE_ELEVATION_IN_DIP,
+                    displayMetrics) * 2);
         }
         return 0;
     }
@@ -824,6 +827,7 @@
         }
 
         updateDisplayInfo(bounds);
+        updateSurfaceBounds();
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index f2ad6fb..2873b6d 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -151,7 +151,10 @@
 
         final RecentsAnimationController recentsAnimationController =
                 mService.getRecentsAnimationController();
-        final boolean hasWallpaper = (w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
+        final boolean animationWallpaper = w.mAppToken != null && w.mAppToken.getAnimation() != null
+                && w.mAppToken.getAnimation().getShowWallpaper();
+        final boolean hasWallpaper = (w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0
+                || animationWallpaper;
         final boolean isRecentsTransitionTarget = (recentsAnimationController != null
                 && recentsAnimationController.isWallpaperVisible(w));
         if (isRecentsTransitionTarget) {
@@ -272,6 +275,8 @@
     }
 
     boolean updateWallpaperOffset(WindowState wallpaperWin, int dw, int dh, boolean sync) {
+        int xOffset = 0;
+        int yOffset = 0;
         boolean rawChanged = false;
         // Set the default wallpaper x-offset to either edge of the screen (depending on RTL), to
         // match the behavior of most Launchers
@@ -283,11 +288,8 @@
         if (mLastWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
             offset += mLastWallpaperDisplayOffsetX;
         }
-        boolean changed = wallpaperWin.mXOffset != offset;
-        if (changed) {
-            if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper " + wallpaperWin + " x: " + offset);
-            wallpaperWin.mXOffset = offset;
-        }
+        xOffset = offset;
+
         if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
             wallpaperWin.mWallpaperX = wpx;
             wallpaperWin.mWallpaperXStep = wpxs;
@@ -301,17 +303,16 @@
         if (mLastWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
             offset += mLastWallpaperDisplayOffsetY;
         }
-        if (wallpaperWin.mYOffset != offset) {
-            if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper " + wallpaperWin + " y: " + offset);
-            changed = true;
-            wallpaperWin.mYOffset = offset;
-        }
+        yOffset = offset;
+
         if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
             wallpaperWin.mWallpaperY = wpy;
             wallpaperWin.mWallpaperYStep = wpys;
             rawChanged = true;
         }
 
+        boolean changed = wallpaperWin.mWinAnimator.setWallpaperOffset(xOffset, yOffset);
+
         if (rawChanged && (wallpaperWin.mAttrs.privateFlags &
                 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS) != 0) {
             try {
diff --git a/services/core/java/com/android/server/wm/WallpaperWindowToken.java b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
index 2ae5c7b..ddda027 100644
--- a/services/core/java/com/android/server/wm/WallpaperWindowToken.java
+++ b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
@@ -74,10 +74,6 @@
         for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
             final WindowState wallpaper = mChildren.get(wallpaperNdx);
             if (wallpaperController.updateWallpaperOffset(wallpaper, dw, dh, sync)) {
-                final WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
-                winAnimator.computeShownFrameLocked();
-                // No need to lay out the windows - we can just set the wallpaper position directly.
-                winAnimator.setWallpaperOffset(wallpaper.mShownPosition);
                 // We only want to be synchronous with one wallpaper.
                 sync = false;
             }
diff --git a/services/core/java/com/android/server/wm/WindowAnimationSpec.java b/services/core/java/com/android/server/wm/WindowAnimationSpec.java
index 0863ee9..43fa3d5 100644
--- a/services/core/java/com/android/server/wm/WindowAnimationSpec.java
+++ b/services/core/java/com/android/server/wm/WindowAnimationSpec.java
@@ -69,6 +69,11 @@
     }
 
     @Override
+    public boolean getShowWallpaper() {
+        return mAnimation.getShowWallpaper();
+    }
+
+    @Override
     public int getBackgroundColor() {
         return mAnimation.getBackgroundColor();
     }
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 20349b9..ab10197 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -226,13 +226,6 @@
                 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION animate");
             }
 
-            final int numDisplays = mDisplayContentsAnimators.size();
-            for (int i = 0; i < numDisplays; i++) {
-                final int displayId = mDisplayContentsAnimators.keyAt(i);
-                final DisplayContent dc = mService.mRoot.getDisplayContent(displayId);
-                dc.onPendingTransactionApplied();
-            }
-
             boolean hasPendingLayoutChanges = mService.mRoot.hasPendingLayoutChanges(this);
             boolean doRequest = false;
             if (mBulkUpdateParams != 0) {
@@ -266,7 +259,6 @@
             }
 
             mService.destroyPreservedSurfaceLocked();
-            mService.mWindowPlacerLocked.destroyPendingSurfaces();
 
             executeAfterPrepareSurfacesRunnables();
 
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 1f7caff..b7525c0 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -109,8 +109,7 @@
     WindowContainer(WindowManagerService service) {
         mService = service;
         mPendingTransaction = service.mTransactionFactory.make();
-        mSurfaceAnimator = new SurfaceAnimator(this, this::onAnimationFinished,
-                service.mAnimator::addAfterPrepareSurfacesRunnable, service);
+        mSurfaceAnimator = new SurfaceAnimator(this, this::onAnimationFinished, service);
     }
 
     @Override
@@ -286,8 +285,9 @@
         }
 
         if (mSurfaceControl != null) {
-            destroyAfterPendingTransaction(mSurfaceControl);
+            getPendingTransaction().destroy(mSurfaceControl);
             mSurfaceControl = null;
+            scheduleAnimation();
         }
 
         if (mParent != null) {
@@ -406,6 +406,10 @@
                 }
                 break;
             default:
+                // TODO: Removing the child before reinserting requires the caller to provide a
+                //       position that takes into account the removed child (if the index of the
+                //       child < position, then the position should be adjusted). We should consider
+                //       doing this adjustment here and remove any adjustments in the callers.
                 mChildren.remove(child);
                 mChildren.add(position, child);
         }
@@ -1075,19 +1079,6 @@
         return mSurfaceControl;
     }
 
-    /**
-     * Destroy a given surface after executing mPendingTransaction. This is
-     * largely a workaround for destroy not being part of transactions
-     * rather than an intentional design, so please take care when
-     * expanding use.
-     */
-    @Override
-    public void destroyAfterPendingTransaction(SurfaceControl surface) {
-        if (mParent != null) {
-            mParent.destroyAfterPendingTransaction(surface);
-        }
-    }
-
     @Override
     public Transaction getPendingTransaction() {
         return mPendingTransaction;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 26ac79e..0c6429a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -50,6 +50,7 @@
 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
@@ -99,15 +100,15 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
-import static com.android.server.wm.proto.WindowManagerServiceProto.APP_TRANSITION;
-import static com.android.server.wm.proto.WindowManagerServiceProto.DISPLAY_FROZEN;
-import static com.android.server.wm.proto.WindowManagerServiceProto.FOCUSED_APP;
-import static com.android.server.wm.proto.WindowManagerServiceProto.FOCUSED_WINDOW;
-import static com.android.server.wm.proto.WindowManagerServiceProto.INPUT_METHOD_WINDOW;
-import static com.android.server.wm.proto.WindowManagerServiceProto.LAST_ORIENTATION;
-import static com.android.server.wm.proto.WindowManagerServiceProto.POLICY;
-import static com.android.server.wm.proto.WindowManagerServiceProto.ROOT_WINDOW_CONTAINER;
-import static com.android.server.wm.proto.WindowManagerServiceProto.ROTATION;
+import static com.android.server.wm.proto.WindowManagerServiceDumpProto.APP_TRANSITION;
+import static com.android.server.wm.proto.WindowManagerServiceDumpProto.DISPLAY_FROZEN;
+import static com.android.server.wm.proto.WindowManagerServiceDumpProto.FOCUSED_APP;
+import static com.android.server.wm.proto.WindowManagerServiceDumpProto.FOCUSED_WINDOW;
+import static com.android.server.wm.proto.WindowManagerServiceDumpProto.INPUT_METHOD_WINDOW;
+import static com.android.server.wm.proto.WindowManagerServiceDumpProto.LAST_ORIENTATION;
+import static com.android.server.wm.proto.WindowManagerServiceDumpProto.POLICY;
+import static com.android.server.wm.proto.WindowManagerServiceDumpProto.ROOT_WINDOW_CONTAINER;
+import static com.android.server.wm.proto.WindowManagerServiceDumpProto.ROTATION;
 
 import android.Manifest;
 import android.Manifest.permission;
@@ -821,9 +822,6 @@
         try {
             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "openSurfaceTransaction");
             synchronized (mWindowMap) {
-                if (mRoot.mSurfaceTraceEnabled) {
-                    mRoot.mRemoteEventTrace.openSurfaceTransaction();
-                }
                 SurfaceControl.openTransaction();
             }
         } finally {
@@ -842,9 +840,6 @@
                 try {
                     traceStateLocked(where);
                 } finally {
-                    if (mRoot.mSurfaceTraceEnabled) {
-                        mRoot.mRemoteEventTrace.closeSurfaceTransaction();
-                    }
                     SurfaceControl.closeTransaction();
                 }
             }
@@ -1383,14 +1378,8 @@
 
             win.attach();
             mWindowMap.put(client.asBinder(), win);
-            if (win.mAppOp != AppOpsManager.OP_NONE) {
-                int startOpResult = mAppOps.startOpNoThrow(win.mAppOp, win.getOwningUid(),
-                        win.getOwningPackage());
-                if ((startOpResult != AppOpsManager.MODE_ALLOWED) &&
-                        (startOpResult != AppOpsManager.MODE_DEFAULT)) {
-                    win.setAppOpVisibilityLw(false);
-                }
-            }
+
+            win.initAppOpsState();
 
             final boolean hideSystemAlertWindows = !mHidingNonSystemOverlayWindows.isEmpty();
             win.setForceHideNonSystemOverlayWindowIfNeeded(hideSystemAlertWindows);
@@ -1594,30 +1583,6 @@
         return false;
     }
 
-    @Override
-    public void enableSurfaceTrace(ParcelFileDescriptor pfd) {
-        final int callingUid = Binder.getCallingUid();
-        if (callingUid != SHELL_UID && callingUid != ROOT_UID) {
-            throw new SecurityException("Only shell can call enableSurfaceTrace");
-        }
-
-        synchronized (mWindowMap) {
-            mRoot.enableSurfaceTrace(pfd);
-        }
-    }
-
-    @Override
-    public void disableSurfaceTrace() {
-        final int callingUid = Binder.getCallingUid();
-        if (callingUid != SHELL_UID && callingUid != ROOT_UID &&
-            callingUid != SYSTEM_UID) {
-            throw new SecurityException("Only shell can call disableSurfaceTrace");
-        }
-        synchronized (mWindowMap) {
-            mRoot.disableSurfaceTrace();
-        }
-    }
-
     /**
      * Set mScreenCaptureDisabled for specific user
      */
@@ -1655,9 +1620,8 @@
     void postWindowRemoveCleanupLocked(WindowState win) {
         if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "postWindowRemoveCleanupLocked: " + win);
         mWindowMap.remove(win.mClient.asBinder());
-        if (win.mAppOp != AppOpsManager.OP_NONE) {
-            mAppOps.finishOp(win.mAppOp, win.getOwningUid(), win.getOwningPackage());
-        }
+
+        win.resetAppOpsState();
 
         if (mCurrentFocus == null) {
             mWinRemovedSinceNullFocus.add(win);
@@ -1913,6 +1877,11 @@
                     // No move or resize, but the controller checks for title changes as well
                     mAccessibilityController.onSomeWindowResizedOrMovedLocked();
                 }
+
+                if ((flagChanges & PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) {
+                    updateNonSystemOverlayWindowsVisibilityIfNeeded(
+                            win, win.mWinAnimator.getShown());
+                }
             }
 
             if (DEBUG_LAYOUT) Slog.v(TAG_WM, "Relayout " + win + ": viewVisibility=" + viewVisibility
@@ -1960,15 +1929,36 @@
             win.setDisplayLayoutNeeded();
             win.mGivenInsetsPending = (flags & WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
 
-            // We may be deferring layout passes at the moment, but since the client is interested
-            // in the new out values right now we need to force a layout.
-            mWindowPlacerLocked.performSurfacePlacement(true /* force */);
-
             // We should only relayout if the view is visible, it is a starting window, or the
             // associated appToken is not hidden.
             final boolean shouldRelayout = viewVisibility == View.VISIBLE &&
-                (win.mAppToken == null || win.mAttrs.type == TYPE_APPLICATION_STARTING
-                    || !win.mAppToken.isClientHidden());
+                    (win.mAppToken == null || win.mAttrs.type == TYPE_APPLICATION_STARTING
+                            || !win.mAppToken.isClientHidden());
+
+            // If we are not currently running the exit animation, we need to see about starting
+            // one.
+            // We don't want to animate visibility of windows which are pending replacement.
+            // In the case of activity relaunch child windows could request visibility changes as
+            // they are detached from the main application window during the tear down process.
+            // If we satisfied these visibility changes though, we would cause a visual glitch
+            // hiding the window before it's replacement was available. So we just do nothing on
+            // our side.
+            // This must be called before the call to performSurfacePlacement.
+            if (!shouldRelayout && winAnimator.hasSurface() && !win.mAnimatingExit) {
+                if (DEBUG_VISIBILITY) {
+                    Slog.i(TAG_WM,
+                            "Relayout invis " + win + ": mAnimatingExit=" + win.mAnimatingExit);
+                }
+                result |= RELAYOUT_RES_SURFACE_CHANGED;
+                if (!win.mWillReplaceWindow) {
+                    focusMayChange = tryStartExitingAnimation(win, winAnimator, isDefaultDisplay,
+                            focusMayChange);
+                }
+            }
+
+            // We may be deferring layout passes at the moment, but since the client is interested
+            // in the new out values right now we need to force a layout.
+            mWindowPlacerLocked.performSurfacePlacement(true /* force */);
 
             if (shouldRelayout) {
                 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: viewVisibility_1");
@@ -2001,24 +1991,6 @@
                 winAnimator.mEnterAnimationPending = false;
                 winAnimator.mEnteringAnimation = false;
 
-                if (winAnimator.hasSurface() && !win.mAnimatingExit) {
-                    if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Relayout invis " + win
-                            + ": mAnimatingExit=" + win.mAnimatingExit);
-                    // If we are not currently running the exit animation, we
-                    // need to see about starting one.
-                    // We don't want to animate visibility of windows which are pending
-                    // replacement. In the case of activity relaunch child windows
-                    // could request visibility changes as they are detached from the main
-                    // application window during the tear down process. If we satisfied
-                    // these visibility changes though, we would cause a visual glitch
-                    // hiding the window before it's replacement was available.
-                    // So we just do nothing on our side.
-                    if (!win.mWillReplaceWindow) {
-                        focusMayChange = tryStartExitingAnimation(
-                                win, winAnimator, isDefaultDisplay, focusMayChange);
-                    }
-                    result |= RELAYOUT_RES_SURFACE_CHANGED;
-                }
                 if (viewVisibility == View.VISIBLE && winAnimator.hasSurface()) {
                     // We already told the client to go invisible, but the message may not be
                     // handled yet, or it might want to draw a last frame. If we already have a
@@ -2116,6 +2088,10 @@
 
             win.setLastReportedMergedConfiguration(mergedConfiguration);
 
+            // Update the last inset values here because the values are sent back to the client.
+            // The last inset values represent the last client state.
+            win.updateLastInsetValues();
+
             outFrame.set(win.mCompatFrame);
             outOverscanInsets.set(win.mOverscanInsets);
             outContentInsets.set(win.mContentInsets);
@@ -2688,7 +2664,6 @@
             IRecentsAnimationRunner recentsAnimationRunner,
             RecentsAnimationController.RecentsAnimationCallbacks callbacks, int displayId) {
         synchronized (mWindowMap) {
-            cancelRecentsAnimation();
             mRecentsAnimationController = new RecentsAnimationController(this,
                     recentsAnimationRunner, callbacks, displayId);
             mRecentsAnimationController.initialize();
@@ -2713,12 +2688,12 @@
     }
 
     public void cancelRecentsAnimation() {
-        synchronized (mWindowMap) {
-            if (mRecentsAnimationController != null) {
-                // This call will call through to cleanupAnimation() below after the animation is
-                // canceled
-                mRecentsAnimationController.cancelAnimation();
-            }
+        // Note: Do not hold the WM lock, this will lock appropriately in the call which also
+        // calls through to AM/RecentsAnimation.onAnimationFinished()
+        if (mRecentsAnimationController != null) {
+            // This call will call through to cleanupAnimation() below after the animation is
+            // canceled
+            mRecentsAnimationController.cancelAnimation();
         }
     }
 
@@ -2769,6 +2744,13 @@
         mDockedStackCreateBounds = bounds;
     }
 
+    public void checkSplitScreenMinimizedChanged(boolean animate) {
+        synchronized (mWindowMap) {
+            final DisplayContent displayContent = getDefaultDisplayContentLocked();
+            displayContent.getDockedDividerController().checkMinimizeChanged(animate);
+        }
+    }
+
     public boolean isValidPictureInPictureAspectRatio(int displayId, float aspectRatio) {
         final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
         return displayContent.getPinnedStackController().isValidPictureInPictureAspectRatio(
@@ -6175,7 +6157,7 @@
 
     /**
      * Write to a protocol buffer output stream. Protocol buffer message definition is at
-     * {@link com.android.server.wm.proto.WindowManagerServiceProto}.
+     * {@link com.android.server.wm.proto.WindowManagerServiceDumpProto}.
      *
      * @param proto     Stream to write the WindowContainer object to.
      * @param trim      If true, reduce the amount of data written.
@@ -7397,7 +7379,8 @@
     }
 
     void updateNonSystemOverlayWindowsVisibilityIfNeeded(WindowState win, boolean surfaceShown) {
-        if (!win.hideNonSystemOverlayWindowsWhenVisible()) {
+        if (!win.hideNonSystemOverlayWindowsWhenVisible()
+                && !mHidingNonSystemOverlayWindows.contains(win)) {
             return;
         }
         final boolean systemAlertWindowsHidden = !mHidingNonSystemOverlayWindows.isEmpty();
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index e24c393..ab139db 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -74,8 +74,6 @@
                     return runSetScreenCapture(pw);
                 case "dismiss-keyguard":
                     return runDismissKeyguard(pw);
-                case "surface-trace":
-                    return runSurfaceTrace(pw);
                 case "tracing":
                     // XXX this should probably be changed to use openFileForSystem() to create
                     // the output trace file, so the shell gets the correct semantics for where
@@ -235,46 +233,6 @@
         return 0;
     }
 
-    private int runSurfaceTrace(PrintWriter pw) throws RemoteException {
-        final ParcelFileDescriptor pfd;
-        try {
-            pfd = ParcelFileDescriptor.dup(getOutFileDescriptor());
-        } catch (IOException e) {
-            getErrPrintWriter().println("Unable to dup output stream: " + e.getMessage());
-            return -1;
-        }
-        mInternal.enableSurfaceTrace(pfd);
-
-        // Read input until an explicit quit command is sent or the stream is closed (meaning
-        // the user killed the command).
-        try {
-            InputStream input = getRawInputStream();
-            InputStreamReader converter = new InputStreamReader(input);
-            BufferedReader in = new BufferedReader(converter);
-            String line;
-
-            while ((line = in.readLine()) != null) {
-                if (line.length() <= 0) {
-                    // no-op
-                } else if ("q".equals(line) || "quit".equals(line)) {
-                    break;
-                } else {
-                    pw.println("Invalid command: " + line);
-                }
-            }
-        } catch (IOException e) {
-            e.printStackTrace(pw);
-        } finally {
-            mInternal.disableSurfaceTrace();
-            try {
-                pfd.close();
-            } catch (IOException e) {
-            }
-        }
-
-        return 0;
-    }
-
     private int parseDimension(String s) throws NumberFormatException {
         if (s.endsWith("px")) {
             return Integer.parseInt(s.substring(0, s.length() - 2));
@@ -311,8 +269,6 @@
         pw.println("    Enable or disable screen capture.");
         pw.println("  dismiss-keyguard");
         pw.println("    Dismiss the keyguard, prompting user for auth if necessary.");
-        pw.println("  surface-trace");
-        pw.println("    Log surface commands to stdout in a binary format.");
         if (!IS_USER) {
             pw.println("  tracing (start | stop)");
             pw.println("    Start or stop window tracing.");
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index b706096..c5b270e 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -17,6 +17,9 @@
 package com.android.server.wm;
 
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.MODE_DEFAULT;
+import static android.app.AppOpsManager.OP_NONE;
 import static android.os.PowerManager.DRAW_WAKE_LOCK;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.view.Display.DEFAULT_DISPLAY;
@@ -138,7 +141,6 @@
 import static com.android.server.wm.proto.WindowStateProto.REMOVE_ON_EXIT;
 import static com.android.server.wm.proto.WindowStateProto.REQUESTED_HEIGHT;
 import static com.android.server.wm.proto.WindowStateProto.REQUESTED_WIDTH;
-import static com.android.server.wm.proto.WindowStateProto.SHOWN_POSITION;
 import static com.android.server.wm.proto.WindowStateProto.STABLE_INSETS;
 import static com.android.server.wm.proto.WindowStateProto.STACK_ID;
 import static com.android.server.wm.proto.WindowStateProto.SURFACE_INSETS;
@@ -298,12 +300,6 @@
     private final MergedConfiguration mLastReportedConfiguration = new MergedConfiguration();
 
     /**
-     * Actual position of the surface shown on-screen (may be modified by animation). These are
-     * in the screen's coordinate space (WITH the compatibility scale applied).
-     */
-    final Point mShownPosition = new Point();
-
-    /**
      * Insets that determine the actually visible area.  These are in the application's
      * coordinate space (without compatibility scale applied).
      */
@@ -462,10 +458,6 @@
     int mWallpaperDisplayOffsetX = Integer.MIN_VALUE;
     int mWallpaperDisplayOffsetY = Integer.MIN_VALUE;
 
-    // Wallpaper windows: pixels offset based on above variables.
-    int mXOffset;
-    int mYOffset;
-
     /**
      * This is set after IWindowSession.relayout() has been called at
      * least once for the window.  It allows us to detect the situation
@@ -771,8 +763,6 @@
         mRequestedHeight = 0;
         mLastRequestedWidth = 0;
         mLastRequestedHeight = 0;
-        mXOffset = 0;
-        mYOffset = 0;
         mLayer = 0;
         mInputWindowHandle = new InputWindowHandle(
                 mAppToken != null ? mAppToken.mInputApplicationHandle : null, this, c,
@@ -1138,11 +1128,6 @@
     }
 
     @Override
-    public Point getShownPositionLw() {
-        return mShownPosition;
-    }
-
-    @Override
     public Rect getDisplayFrameLw() {
         return mDisplayFrame;
     }
@@ -2571,7 +2556,7 @@
         }
     }
 
-    public void setAppOpVisibilityLw(boolean state) {
+    private void setAppOpVisibilityLw(boolean state) {
         if (mAppOpVisibility != state) {
             mAppOpVisibility = state;
             if (state) {
@@ -2588,6 +2573,49 @@
         }
     }
 
+    void initAppOpsState() {
+        if (mAppOp == OP_NONE || !mAppOpVisibility) {
+            return;
+        }
+        // If the app op was MODE_DEFAULT we would have checked the permission
+        // and add the window only if the permission was granted. Therefore, if
+        // the mode is MODE_DEFAULT we want the op to succeed as the window is
+        // shown.
+        final int mode = mService.mAppOps.startOpNoThrow(mAppOp,
+                getOwningUid(), getOwningPackage(), true);
+        if (mode != MODE_ALLOWED && mode != MODE_DEFAULT) {
+            setAppOpVisibilityLw(false);
+        }
+    }
+
+    void resetAppOpsState() {
+        if (mAppOp != OP_NONE && mAppOpVisibility) {
+            mService.mAppOps.finishOp(mAppOp, getOwningUid(), getOwningPackage());
+        }
+    }
+
+    void updateAppOpsState() {
+        if (mAppOp == OP_NONE) {
+            return;
+        }
+        final int uid = getOwningUid();
+        final String packageName = getOwningPackage();
+        if (mAppOpVisibility) {
+            // There is a race between the check and the finish calls but this is fine
+            // as this would mean we will get another change callback and will reconcile.
+            int mode = mService.mAppOps.checkOpNoThrow(mAppOp, uid, packageName);
+            if (mode != MODE_ALLOWED && mode != MODE_DEFAULT) {
+                mService.mAppOps.finishOp(mAppOp, uid, packageName);
+                setAppOpVisibilityLw(false);
+            }
+        } else {
+            final int mode = mService.mAppOps.startOpNoThrow(mAppOp, uid, packageName);
+            if (mode == MODE_ALLOWED || mode == MODE_DEFAULT) {
+                setAppOpVisibilityLw(true);
+            }
+        }
+    }
+
     public void hidePermanentlyLw() {
         if (!mPermanentlyHidden) {
             mPermanentlyHidden = true;
@@ -3136,7 +3164,6 @@
         mContentInsets.writeToProto(proto, CONTENT_INSETS);
         mAttrs.surfaceInsets.writeToProto(proto, SURFACE_INSETS);
         mSurfacePosition.writeToProto(proto, SURFACE_POSITION);
-        mShownPosition.writeToProto(proto, SHOWN_POSITION);
         mWinAnimator.writeToProto(proto, ANIMATOR);
         proto.write(ANIMATING_EXIT, mAnimatingExit);
         for (int i = 0; i < mChildren.size(); i++) {
@@ -3252,10 +3279,6 @@
             pw.print(prefix); pw.print("mRelayoutCalled="); pw.print(mRelayoutCalled);
                     pw.print(" mLayoutNeeded="); pw.println(mLayoutNeeded);
         }
-        if (mXOffset != 0 || mYOffset != 0) {
-            pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
-                    pw.print(" y="); pw.println(mYOffset);
-        }
         if (dumpAll) {
             pw.print(prefix); pw.print("mGivenContentInsets=");
                     mGivenContentInsets.printShortString(pw);
@@ -3274,7 +3297,6 @@
                     pw.println(getLastReportedConfiguration());
         }
         pw.print(prefix); pw.print("mHasSurface="); pw.print(mHasSurface);
-                pw.print(" mShownPosition="); mShownPosition.printShortString(pw);
                 pw.print(" isReadyForDisplay()="); pw.print(isReadyForDisplay());
                 pw.print(" mWindowRemovalAllowed="); pw.println(mWindowRemovalAllowed);
         if (dumpAll) {
@@ -4013,7 +4035,9 @@
 
         final boolean hasSurface = mWinAnimator.hasSurface();
         if (hasSurface) {
-            mWinAnimator.hide("onExitAnimationDone");
+            // Use pendingTransaction here so hide is done the same transaction as the other
+            // animations when exiting
+            mWinAnimator.hide(getPendingTransaction(), "onExitAnimationDone");
         }
 
         // If we have an app token, we ask it to destroy the surface for us, so that it can take
@@ -4195,9 +4219,8 @@
         final int width = mFrame.width();
         final int height = mFrame.height();
 
-        // Compute the offset of the window in relation to the decor rect.
-        final int left = mXOffset + mFrame.left;
-        final int top = mYOffset + mFrame.top;
+        final int left = mFrame.left;
+        final int top = mFrame.top;
 
         // Initialize the decor rect to the entire frame.
         if (isDockedResizing()) {
@@ -4299,14 +4322,9 @@
         // When we change the Surface size, in scenarios which may require changing
         // the surface position in sync with the resize, we use a preserved surface
         // so we can freeze it while waiting for the client to report draw on the newly
-        // sized surface.  Don't preserve surfaces if the insets change while animating the pinned
-        // stack since it can lead to issues if a new surface is created while calculating the
-        // scale for the animation using the source hint rect
-        // (see WindowStateAnimator#setSurfaceBoundariesLocked()).
-        if (isDragResizeChanged()
-                || (surfaceInsetsChanging() && !inPinnedWindowingMode())) {
-            mLastSurfaceInsets.set(mAttrs.surfaceInsets);
-
+        // sized surface. At the moment this logic is only in place for switching
+        // in and out of the big surface for split screen resize.
+        if (isDragResizeChanged()) {
             setDragResizing();
             // We can only change top level windows to the full-screen surface when
             // resizing (as we only have one full-screen surface). So there is no need
@@ -4391,8 +4409,8 @@
         float9[Matrix.MSKEW_Y] = mWinAnimator.mDtDx;
         float9[Matrix.MSKEW_X] = mWinAnimator.mDtDy;
         float9[Matrix.MSCALE_Y] = mWinAnimator.mDsDy;
-        int x = mSurfacePosition.x + mShownPosition.x;
-        int y = mSurfacePosition.y + mShownPosition.y;
+        int x = mSurfacePosition.x;
+        int y = mSurfacePosition.y;
 
         // If changed, also adjust transformFrameToSurfacePosition
         final WindowContainer parent = getParent();
@@ -4554,9 +4572,16 @@
         }
 
         transformFrameToSurfacePosition(mFrame.left, mFrame.top, mSurfacePosition);
+
         if (!mSurfaceAnimator.hasLeash() && !mLastSurfacePosition.equals(mSurfacePosition)) {
             t.setPosition(mSurfaceControl, mSurfacePosition.x, mSurfacePosition.y);
             mLastSurfacePosition.set(mSurfacePosition.x, mSurfacePosition.y);
+            if (surfaceInsetsChanging() && mWinAnimator.hasSurface()) {
+                mLastSurfaceInsets.set(mAttrs.surfaceInsets);
+                t.deferTransactionUntil(mSurfaceControl,
+                        mWinAnimator.mSurfaceController.mSurfaceControl.getHandle(),
+                        mAttrs.frameNumber);
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 9ce0537..13f05e0 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -164,6 +164,8 @@
 
     private boolean mAnimationStartDelayed;
 
+    private final SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction();
+
     /** The pixel format of the underlying SurfaceControl */
     int mSurfaceFormat;
 
@@ -209,6 +211,12 @@
     float mExtraHScale = (float) 1.0;
     float mExtraVScale = (float) 1.0;
 
+    // An offset in pixel of the surface contents from the window position. Used for Wallpaper
+    // to provide the effect of scrolling within a large surface. We just use these values as
+    // a cache.
+    int mXOffset = 0;
+    int mYOffset = 0;
+
     private final Rect mTmpSize = new Rect();
 
     private final SurfaceControl.Transaction mReparentTransaction = new SurfaceControl.Transaction();
@@ -280,16 +288,21 @@
         }
     }
 
-    void hide(String reason) {
+    void hide(SurfaceControl.Transaction transaction, String reason) {
         if (!mLastHidden) {
             //dump();
             mLastHidden = true;
             if (mSurfaceController != null) {
-                mSurfaceController.hideInTransaction(reason);
+                mSurfaceController.hide(transaction, reason);
             }
         }
     }
 
+    void hide(String reason) {
+        hide(mTmpTransaction, reason);
+        SurfaceControl.mergeToGlobalTransaction(mTmpTransaction);
+    }
+
     boolean finishDrawingLocked() {
         final boolean startingWindow =
                 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
@@ -438,7 +451,7 @@
             flags |= SurfaceControl.SECURE;
         }
 
-        mTmpSize.set(w.mFrame.left + w.mXOffset, w.mFrame.top + w.mYOffset, 0, 0);
+        mTmpSize.set(0, 0, 0, 0);
         calculateSurfaceBounds(w, attrs);
         final int width = mTmpSize.width();
         final int height = mTmpSize.height();
@@ -679,8 +692,8 @@
 
             // WindowState.prepareSurfaces expands for surface insets (in order they don't get
             // clipped by the WindowState surface), so we need to go into the other direction here.
-            tmpMatrix.postTranslate(mWin.mXOffset + mWin.mAttrs.surfaceInsets.left,
-                    mWin.mYOffset + mWin.mAttrs.surfaceInsets.top);
+            tmpMatrix.postTranslate(mWin.mAttrs.surfaceInsets.left,
+                    mWin.mAttrs.surfaceInsets.top);
 
 
             // "convert" it into SurfaceFlinger's format
@@ -695,9 +708,6 @@
             mDtDx = tmpFloats[Matrix.MSKEW_Y];
             mDtDy = tmpFloats[Matrix.MSKEW_X];
             mDsDy = tmpFloats[Matrix.MSCALE_Y];
-            float x = tmpFloats[Matrix.MTRANS_X];
-            float y = tmpFloats[Matrix.MTRANS_Y];
-            mWin.mShownPosition.set(Math.round(x), Math.round(y));
 
             // Now set the alpha...  but because our current hardware
             // can't do alpha transformation on a non-opaque surface,
@@ -707,8 +717,7 @@
             mShownAlpha = mAlpha;
             if (!mService.mLimitedAlphaCompositing
                     || (!PixelFormat.formatHasAlpha(mWin.mAttrs.format)
-                    || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDtDy, mDsDy)
-                            && x == frame.left && y == frame.top))) {
+                    || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDtDy, mDsDy)))) {
                 //Slog.i(TAG_WM, "Applying alpha transform");
                 if (screenAnimation) {
                     mShownAlpha *= screenRotationAnimation.getEnterTransformation().getAlpha();
@@ -738,10 +747,6 @@
                 TAG, "computeShownFrameLocked: " + this +
                 " not attached, mAlpha=" + mAlpha);
 
-        // WindowState.prepareSurfaces expands for surface insets (in order they don't get
-        // clipped by the WindowState surface), so we need to go into the other direction here.
-        mWin.mShownPosition.set(mWin.mXOffset + mWin.mAttrs.surfaceInsets.left,
-                mWin.mYOffset + mWin.mAttrs.surfaceInsets.top);
         mShownAlpha = mAlpha;
         mHaveMatrix = false;
         mDsDx = mWin.mGlobalScale;
@@ -792,12 +797,6 @@
         if (DEBUG_WINDOW_CROP) Slog.d(TAG, "win=" + w + " Initial clip rect: " + clipRect
                 + " fullscreen=" + fullscreen);
 
-        if (isFreeformResizing && !w.isChildWindow()) {
-            // For freeform resizing non child windows, we are using the big surface positioned
-            // at 0,0. Thus we must express the crop in that coordinate space.
-            clipRect.offset(w.mShownPosition.x, w.mShownPosition.y);
-        }
-
         w.expandForSurfaceInsets(clipRect);
 
         // The clip rect was generated assuming (0,0) as the window origin,
@@ -834,7 +833,7 @@
         final LayoutParams attrs = mWin.getAttrs();
         final Task task = w.getTask();
 
-        mTmpSize.set(w.mShownPosition.x, w.mShownPosition.y, 0, 0);
+        mTmpSize.set(0, 0, 0, 0);
         calculateSurfaceBounds(w, attrs);
 
         mExtraHScale = (float) 1.0;
@@ -870,17 +869,19 @@
         float surfaceWidth = mSurfaceController.getWidth();
         float surfaceHeight = mSurfaceController.getHeight();
 
+        final Rect insets = attrs.surfaceInsets;
+
         if (isForceScaled()) {
-            int hInsets = attrs.surfaceInsets.left + attrs.surfaceInsets.right;
-            int vInsets = attrs.surfaceInsets.top + attrs.surfaceInsets.bottom;
+            int hInsets = insets.left + insets.right;
+            int vInsets = insets.top + insets.bottom;
             float surfaceContentWidth = surfaceWidth - hInsets;
             float surfaceContentHeight = surfaceHeight - vInsets;
             if (!mForceScaleUntilResize) {
                 mSurfaceController.forceScaleableInTransaction(true);
             }
 
-            int posX = mTmpSize.left;
-            int posY = mTmpSize.top;
+            int posX = 0;
+            int posY = 0;
             task.mStack.getDimBounds(mTmpStackBounds);
 
             boolean allowStretching = false;
@@ -927,9 +928,19 @@
                 posX -= (int) (tw * mExtraHScale * mTmpSourceBounds.left);
                 posY -= (int) (th * mExtraVScale * mTmpSourceBounds.top);
 
-                // Always clip to the stack bounds since the surface can be larger with the current
-                // scale
-                clipRect = null;
+                // In pinned mode the clip rectangle applied to us by our stack has been
+                // expanded outwards to allow for shadows. However in case of source bounds set
+                // we need to crop to within the surface. The code above has scaled and positioned
+                // the surface to fit the unexpanded stack bounds, but now we need to reapply
+                // the cropping that the stack would have applied if it weren't expanded. This
+                // can be different in each direction based on the source bounds.
+                clipRect = mTmpClipRect;
+                clipRect.set((int)((insets.left + mTmpSourceBounds.left) * tw),
+                        (int)((insets.top + mTmpSourceBounds.top) * th),
+                        insets.left + (int)(surfaceWidth
+                                - (tw* (surfaceWidth - mTmpSourceBounds.right))),
+                        insets.top + (int)(surfaceHeight
+                                - (th * (surfaceHeight - mTmpSourceBounds.bottom))));
             } else {
                 // We want to calculate the scaling based on the content area, not based on
                 // the entire surface, so that we scale in sync with windows that don't have insets.
@@ -955,8 +966,8 @@
             // non inset content at the same position, we have to shift the whole window
             // forward. Likewise for scaling up, we've increased this distance, and we need
             // to shift by a negative number to compensate.
-            posX += attrs.surfaceInsets.left * (1 - mExtraHScale);
-            posY += attrs.surfaceInsets.top * (1 - mExtraVScale);
+            posX += insets.left * (1 - mExtraHScale);
+            posY += insets.top * (1 - mExtraVScale);
 
             mSurfaceController.setPositionInTransaction((float) Math.floor(posX),
                     (float) Math.floor(posY), recoveringMemory);
@@ -970,8 +981,7 @@
             mForceScaleUntilResize = true;
         } else {
             if (!w.mSeamlesslyRotated) {
-                mSurfaceController.setPositionInTransaction(mTmpSize.left, mTmpSize.top,
-                        recoveringMemory);
+                mSurfaceController.setPositionInTransaction(0, 0, recoveringMemory);
             }
         }
 
@@ -1139,24 +1149,26 @@
         mSurfaceController.setTransparentRegionHint(region);
     }
 
-    void setWallpaperOffset(Point shownPosition) {
-        final LayoutParams attrs = mWin.getAttrs();
-        final int left = shownPosition.x - attrs.surfaceInsets.left;
-        final int top = shownPosition.y - attrs.surfaceInsets.top;
+    boolean setWallpaperOffset(int dx, int dy) {
+        if (mXOffset == dx && mYOffset == dy) {
+            return false;
+        }
+        mXOffset = dx;
+        mYOffset = dy;
 
         try {
             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setWallpaperOffset");
             mService.openSurfaceTransaction();
-            mSurfaceController.setPositionInTransaction(mWin.mFrame.left + left,
-                    mWin.mFrame.top + top, false);
+            mSurfaceController.setPositionInTransaction(dx, dy, false);
             applyCrop(null, false);
         } catch (RuntimeException e) {
             Slog.w(TAG, "Error positioning surface of " + mWin
-                    + " pos=(" + left + "," + top + ")", e);
+                    + " pos=(" + dx + "," + dy + ")", e);
         } finally {
             mService.closeSurfaceTransaction("setWallpaperOffset");
             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
                     "<<< CLOSE TRANSACTION setWallpaperOffset");
+            return true;
         }
     }
 
@@ -1451,22 +1463,6 @@
                 DsDy * w.mVScale, false);
     }
 
-    void enableSurfaceTrace(FileDescriptor fd) {
-        if (mSurfaceController != null) {
-            mSurfaceController.installRemoteTrace(fd);
-        }
-    }
-
-    void disableSurfaceTrace() {
-        if (mSurfaceController != null) {
-            try {
-                mSurfaceController.removeRemoteTrace();
-            } catch (ClassCastException e) {
-                Slog.e(TAG, "Disable surface trace for " + this + " but its not enabled");
-            }
-        }
-    }
-
     /** The force-scaled state for a given window can persist past
      * the state for it's stack as the windows complete resizing
      * independently of one another.
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 554a600..9d6f8f7 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -86,6 +86,8 @@
     private final int mWindowType;
     private final Session mWindowSession;
 
+    private final SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction();
+
     public WindowSurfaceController(SurfaceSession s, String name, int w, int h, int format,
             int flags, WindowStateAnimator animator, int windowType, int ownerUid) {
         mAnimator = animator;
@@ -110,21 +112,8 @@
                 .setMetadata(windowType, ownerUid);
         mSurfaceControl = b.build();
         Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
-
-        if (mService.mRoot.mSurfaceTraceEnabled) {
-            installRemoteTrace(mService.mRoot.mSurfaceTraceFd.getFileDescriptor());
-        }
     }
 
-    void installRemoteTrace(FileDescriptor fd) {
-        mSurfaceControl = new RemoteSurfaceTrace(fd, mSurfaceControl, mAnimator.mWin);
-    }
-
-    void removeRemoteTrace() {
-        mSurfaceControl = new SurfaceControl(mSurfaceControl);
-    }
-
-
     private void logSurface(String msg, RuntimeException where) {
         String str = "  SURFACE " + msg + ": " + title;
         if (where != null) {
@@ -148,21 +137,23 @@
         }
     }
 
-    void hideInTransaction(String reason) {
+    void hide(SurfaceControl.Transaction transaction, String reason) {
         if (SHOW_TRANSACTIONS) logSurface("HIDE ( " + reason + " )", null);
         mHiddenForOtherReasons = true;
 
         mAnimator.destroyPreservedSurfaceLocked();
-        updateVisibility();
+        if (mSurfaceShown) {
+            hideSurface(transaction);
+        }
     }
 
-    private void hideSurface() {
+    private void hideSurface(SurfaceControl.Transaction transaction) {
         if (mSurfaceControl == null) {
             return;
         }
         setShown(false);
         try {
-            mSurfaceControl.hide();
+            transaction.hide(mSurfaceControl);
         } catch (RuntimeException e) {
             Slog.w(TAG, "Exception hiding surface in " + this);
         }
@@ -421,7 +412,8 @@
     private boolean updateVisibility() {
         if (mHiddenForCrop || mHiddenForOtherReasons) {
             if (mSurfaceShown) {
-                hideSurface();
+                hideSurface(mTmpTransaction);
+                SurfaceControl.mergeToGlobalTransaction(mTmpTransaction);
             }
             return false;
         } else {
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 66c7293..4179590 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -21,6 +21,7 @@
 import static android.app.ActivityManagerInternal.APP_TRANSITION_SPLASH_SCREEN;
 import static android.app.ActivityManagerInternal.APP_TRANSITION_WINDOWS_DRAWN;
 
+import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
 import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE;
@@ -102,7 +103,6 @@
     }
     private final LayerAndToken mTmpLayerAndToken = new LayerAndToken();
 
-    private final ArrayList<SurfaceControl> mPendingDestroyingSurfaces = new ArrayList<>();
     private final SparseIntArray mTempTransitionReasons = new SparseIntArray();
 
     private final Runnable mPerformSurfacePlacement;
@@ -608,6 +608,10 @@
         if (transit == TRANSIT_NONE) {
             return TRANSIT_NONE;
         }
+        // Never update the transition for the wallpaper if we are just docking from recents
+        if (transit == TRANSIT_DOCK_TASK_FROM_RECENTS) {
+            return TRANSIT_DOCK_TASK_FROM_RECENTS;
+        }
 
         // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
         final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
@@ -697,25 +701,6 @@
         }
     }
 
-    /**
-     * Puts the {@param surface} into a pending list to be destroyed after the current transaction
-     * has been committed.
-     */
-    void destroyAfterTransaction(SurfaceControl surface) {
-        mPendingDestroyingSurfaces.add(surface);
-    }
-
-    /**
-     * Destroys any surfaces that have been put into the pending list with
-     * {@link #destroyAfterTransaction}.
-     */
-    void destroyPendingSurfaces() {
-        for (int i = mPendingDestroyingSurfaces.size() - 1; i >= 0; i--) {
-            mPendingDestroyingSurfaces.get(i).destroy();
-        }
-        mPendingDestroyingSurfaces.clear();
-    }
-
     public void dump(PrintWriter pw, String prefix) {
         pw.println(prefix + "mTraversalScheduled=" + mTraversalScheduled);
         pw.println(prefix + "mHoldScreenWindow=" + mService.mRoot.mHoldScreenWindow);
diff --git a/services/core/java/com/android/server/wm/utils/RotationCache.java b/services/core/java/com/android/server/wm/utils/RotationCache.java
new file mode 100644
index 0000000..7a06cbc
--- /dev/null
+++ b/services/core/java/com/android/server/wm/utils/RotationCache.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.utils;
+
+import android.util.SparseArray;
+
+import java.util.Arrays;
+
+/**
+ * Caches the result of a rotation-dependent computation.
+ *
+ * The cache is discarded once the identity of the other parameter changes.
+ *
+ * @param <T> type of the parameter to the computation
+ * @param <R> type of the result of the computation
+ */
+public class RotationCache<T,R> {
+
+    private final RotationDependentComputation<T,R> mComputation;
+    private final SparseArray<R> mCache = new SparseArray<>(4);
+    private T mCachedFor;
+
+    public RotationCache(RotationDependentComputation<T, R> computation) {
+        mComputation = computation;
+    }
+
+    /**
+     * Looks up the result of the computation, or calculates it if needed.
+     *
+     * @param t a parameter to the rotation-dependent computation.
+     * @param rotation the rotation for which to perform the rotation-dependent computation.
+     * @return the result of the rotation-dependent computation.
+     */
+    public R getOrCompute(T t, int rotation) {
+        if (t != mCachedFor) {
+            mCache.clear();
+            mCachedFor = t;
+        }
+        final int idx = mCache.indexOfKey(rotation);
+        if (idx >= 0) {
+            return mCache.valueAt(idx);
+        }
+        final R result = mComputation.compute(t, rotation);
+        mCache.put(rotation, result);
+        return result;
+    }
+
+    /**
+     * A computation that takes a generic input and is dependent on the rotation. The result can
+     * be cached by {@link RotationCache}.
+     */
+    @FunctionalInterface
+    public interface RotationDependentComputation<T, R> {
+        R compute(T t, int rotation);
+    }
+}
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index c2771e4..0a1da57 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -99,14 +99,16 @@
 using android::hardware::gnss::V1_0::IGnssDebug;
 using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
 using android::hardware::gnss::V1_0::IGnssGeofencing;
-using android::hardware::gnss::V1_0::IGnssMeasurementCallback;
+using IGnssMeasurementCallback_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback;
 using android::hardware::gnss::V1_0::IGnssNavigationMessage;
 using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
 using android::hardware::gnss::V1_0::IGnssNi;
 using android::hardware::gnss::V1_0::IGnssNiCallback;
 using android::hardware::gnss::V1_0::IGnssXtra;
 using android::hardware::gnss::V1_0::IGnssXtraCallback;
+
 using android::hardware::gnss::V1_1::IGnssCallback;
+using android::hardware::gnss::V1_1::IGnssMeasurementCallback;
 
 struct GnssDeathRecipient : virtual public hidl_death_recipient
 {
@@ -393,10 +395,7 @@
     // New in 1.1
     Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
 
-    static GnssSvInfo sGnssSvList[static_cast<uint32_t>(
-            android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
-    static size_t sGnssSvListSize;
-
+    // TODO(b/73306084): Reconsider allocation cost vs threadsafety on these statics
     static const char* sNmeaString;
     static size_t sNmeaStringLength;
 };
@@ -412,11 +411,8 @@
     return Void();
 }
 
-IGnssCallback::GnssSvInfo GnssCallback::sGnssSvList[static_cast<uint32_t>(
-        android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
 const char* GnssCallback::sNmeaString = nullptr;
 size_t GnssCallback::sNmeaStringLength = 0;
-size_t GnssCallback::sGnssSvListSize = 0;
 
 Return<void> GnssCallback::gnssLocationCb(const GnssLocation& location) {
     JNIEnv* env = getJniEnv();
@@ -430,6 +426,7 @@
                         boolToJbool(hasLatLong),
                         jLocation);
     checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    env->DeleteLocalRef(jLocation);
     return Void();
 }
 
@@ -443,20 +440,55 @@
 Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) {
     JNIEnv* env = getJniEnv();
 
-    sGnssSvListSize = svStatus.numSvs;
-    if (sGnssSvListSize > static_cast<uint32_t>(
+    uint32_t listSize = svStatus.numSvs;
+    if (listSize > static_cast<uint32_t>(
             android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
-        ALOGD("Too many satellites %zd. Clamps to %u.", sGnssSvListSize,
+        ALOGD("Too many satellites %u. Clamps to %u.", listSize,
               static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
-        sGnssSvListSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
+        listSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
     }
 
-    // Copy GNSS SV info into sGnssSvList, if any.
-    if (svStatus.numSvs > 0) {
-        memcpy(sGnssSvList, svStatus.gnssSvList.data(), sizeof(GnssSvInfo) * sGnssSvListSize);
+    jintArray svidWithFlagArray = env->NewIntArray(listSize);
+    jfloatArray cn0Array = env->NewFloatArray(listSize);
+    jfloatArray elevArray = env->NewFloatArray(listSize);
+    jfloatArray azimArray = env->NewFloatArray(listSize);
+    jfloatArray carrierFreqArray = env->NewFloatArray(listSize);
+
+    jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
+    jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
+    jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
+    jfloat* azim = env->GetFloatArrayElements(azimArray, 0);
+    jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
+
+    /*
+     * Read GNSS SV info.
+     */
+    for (size_t i = 0; i < listSize; ++i) {
+        enum ShiftWidth: uint8_t {
+            SVID_SHIFT_WIDTH = 8,
+            CONSTELLATION_TYPE_SHIFT_WIDTH = 4
+        };
+
+        const IGnssCallback::GnssSvInfo& info = svStatus.gnssSvList.data()[i];
+        svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
+            (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
+            static_cast<uint32_t>(info.svFlag);
+        cn0s[i] = info.cN0Dbhz;
+        elev[i] = info.elevationDegrees;
+        azim[i] = info.azimuthDegrees;
+        carrierFreq[i] = info.carrierFrequencyHz;
     }
 
-    env->CallVoidMethod(mCallbacksObj, method_reportSvStatus);
+    env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
+    env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
+    env->ReleaseFloatArrayElements(elevArray, elev, 0);
+    env->ReleaseFloatArrayElements(azimArray, azim, 0);
+    env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
+
+    env->CallVoidMethod(mCallbacksObj, method_reportSvStatus,
+            static_cast<jint>(listSize), svidWithFlagArray, cn0Array, elevArray, azimArray,
+            carrierFreqArray);
+
     checkAndClearExceptionFromCallback(env, __FUNCTION__);
     return Void();
 }
@@ -575,6 +607,7 @@
                         timestamp);
 
     checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    env->DeleteLocalRef(jLocation);
     return Void();
 }
 
@@ -590,6 +623,7 @@
                         status,
                         jLocation);
     checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    env->DeleteLocalRef(jLocation);
     return Void();
 }
 
@@ -699,21 +733,24 @@
  * GnssMeasurement interface.
  */
 struct GnssMeasurementCallback : public IGnssMeasurementCallback {
-    Return<void> GnssMeasurementCb(const IGnssMeasurementCallback::GnssData& data);
+    Return<void> gnssMeasurementCb(const IGnssMeasurementCallback::GnssData& data) override;
+    Return<void> GnssMeasurementCb(const IGnssMeasurementCallback_V1_0::GnssData& data) override;
  private:
-    jobject translateGnssMeasurement(
-            JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement);
-    jobject translateGnssClock(
-            JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock);
+    void translateGnssMeasurement_V1_0(
+            JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurement,
+            JavaObject object);
     jobjectArray translateGnssMeasurements(
             JNIEnv* env,
             const IGnssMeasurementCallback::GnssMeasurement* measurements,
+            const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurements_v1_0,
             size_t count);
+    jobject translateGnssClock(
+            JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock);
     void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
 };
 
 
-Return<void> GnssMeasurementCallback::GnssMeasurementCb(
+Return<void> GnssMeasurementCallback::gnssMeasurementCb(
         const IGnssMeasurementCallback::GnssData& data) {
     JNIEnv* env = getJniEnv();
 
@@ -722,7 +759,7 @@
 
     clock = translateGnssClock(env, &data.clock);
     measurementArray = translateGnssMeasurements(
-        env, data.measurements.data(), data.measurementCount);
+        env, data.measurements.data(), NULL, data.measurements.size());
     setMeasurementData(env, clock, measurementArray);
 
     env->DeleteLocalRef(clock);
@@ -730,10 +767,27 @@
     return Void();
 }
 
-jobject GnssMeasurementCallback::translateGnssMeasurement(
-        JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement) {
-    JavaObject object(env, "android/location/GnssMeasurement");
+Return<void> GnssMeasurementCallback::GnssMeasurementCb(
+        const IGnssMeasurementCallback_V1_0::GnssData& data) {
+    JNIEnv* env = getJniEnv();
 
+    jobject clock;
+    jobjectArray measurementArray;
+
+    clock = translateGnssClock(env, &data.clock);
+    measurementArray = translateGnssMeasurements(
+        env, NULL, data.measurements.data(), data.measurementCount);
+    setMeasurementData(env, clock, measurementArray);
+
+    env->DeleteLocalRef(clock);
+    env->DeleteLocalRef(measurementArray);
+    return Void();
+}
+
+// preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
+void GnssMeasurementCallback::translateGnssMeasurement_V1_0(
+        JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurement,
+        JavaObject object) {
     uint32_t flags = static_cast<uint32_t>(measurement->flags);
 
     SET(Svid, static_cast<int32_t>(measurement->svid));
@@ -757,13 +811,8 @@
         SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
     }
 
-    if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE)) {
-        SET(CarrierPhase, measurement->carrierPhase);
-    }
-
-    if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY)) {
-        SET(CarrierPhaseUncertainty, measurement->carrierPhaseUncertainty);
-    }
+    // Intentionally not copying deprecated fields of carrierCycles,
+    // carrierPhase, carrierPhaseUncertainty
 
     SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
 
@@ -774,8 +823,6 @@
     if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL)) {
         SET(AutomaticGainControlLevelInDb, measurement->agcLevelDb);
     }
-
-    return object.get();
 }
 
 jobject GnssMeasurementCallback::translateGnssClock(
@@ -818,8 +865,9 @@
 }
 
 jobjectArray GnssMeasurementCallback::translateGnssMeasurements(JNIEnv* env,
-                                       const IGnssMeasurementCallback::GnssMeasurement*
-                                       measurements, size_t count) {
+         const IGnssMeasurementCallback::GnssMeasurement* measurements,
+         const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurements_v1_0,
+         size_t count) {
     if (count == 0) {
         return NULL;
     }
@@ -831,11 +879,18 @@
             NULL /* initialElement */);
 
     for (uint16_t i = 0; i < count; ++i) {
-        jobject gnssMeasurement = translateGnssMeasurement(
-            env,
-            &measurements[i]);
-        env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
-        env->DeleteLocalRef(gnssMeasurement);
+        JavaObject object(env, "android/location/GnssMeasurement");
+        if (measurements != NULL) {
+            translateGnssMeasurement_V1_0(env, &(measurements[i].v1_0), object);
+
+            // Set the V1_1 flag
+            SET(AccumulatedDeltaRangeState,
+                    static_cast<int32_t>(measurements[i].accumulatedDeltaRangeState));
+        } else {
+            translateGnssMeasurement_V1_0(env, &(measurements_v1_0[i]), object);
+        }
+
+        env->SetObjectArrayElement(gnssMeasurementArray, i, object.get());
     }
 
     env->DeleteLocalRef(gnssMeasurementClass);
@@ -1063,7 +1118,7 @@
     method_reportLocation = env->GetMethodID(clazz, "reportLocation",
             "(ZLandroid/location/Location;)V");
     method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
-    method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
+    method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F)V");
     method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
     method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
     method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
@@ -1369,49 +1424,6 @@
     }
 }
 
-/*
- * This enum is used by the read_sv_status method to combine the svid,
- * constellation and svFlag fields.
- */
-enum ShiftWidth: uint8_t {
-    SVID_SHIFT_WIDTH = 8,
-    CONSTELLATION_TYPE_SHIFT_WIDTH = 4
-};
-
-static jint android_location_GnssLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */,
-        jintArray svidWithFlagArray, jfloatArray cn0Array, jfloatArray elevArray,
-        jfloatArray azumArray, jfloatArray carrierFreqArray) {
-    /*
-     * This method should only be called from within a call to reportSvStatus.
-     */
-    jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
-    jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
-    jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
-    jfloat* azim = env->GetFloatArrayElements(azumArray, 0);
-    jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
-
-    /*
-     * Read GNSS SV info.
-     */
-    for (size_t i = 0; i < GnssCallback::sGnssSvListSize; ++i) {
-        const IGnssCallback::GnssSvInfo& info = GnssCallback::sGnssSvList[i];
-        svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
-            (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
-            static_cast<uint32_t>(info.svFlag);
-        cn0s[i] = info.cN0Dbhz;
-        elev[i] = info.elevationDegrees;
-        azim[i] = info.azimuthDegrees;
-        carrierFreq[i] = info.carrierFrequencyHz;
-    }
-
-    env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
-    env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
-    env->ReleaseFloatArrayElements(elevArray, elev, 0);
-    env->ReleaseFloatArrayElements(azumArray, azim, 0);
-    env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
-    return static_cast<jint>(GnssCallback::sGnssSvListSize);
-}
-
 static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
         JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
     IAGnssRil::AGnssRefLocation location;
@@ -2057,9 +2069,6 @@
     {"native_delete_aiding_data",
             "(I)V",
             reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
-    {"native_read_sv_status",
-            "([I[F[F[F[F)I",
-            reinterpret_cast<void *>(android_location_GnssLocationProvider_read_sv_status)},
     {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
             android_location_GnssLocationProvider_read_nmea)},
     {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
index 3557dc9..4020a52 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
@@ -172,4 +172,8 @@
     public long forceSecurityLogs() {
         return 0;
     }
+
+    @Override
+    public void setDefaultSmsApplication(ComponentName admin, String packageName) {
+    }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 8753344..6a468b1 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -50,6 +50,8 @@
 import static android.app.admin.DevicePolicyManager.ID_TYPE_MEID;
 import static android.app.admin.DevicePolicyManager.ID_TYPE_SERIAL;
 import static android.app.admin.DevicePolicyManager.LEAVE_ALL_SYSTEM_APPS_ENABLED;
+import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_HOME;
+import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
 import static android.app.admin.DevicePolicyManager.PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER;
@@ -158,6 +160,7 @@
 import android.os.RemoteCallback;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
@@ -204,6 +207,7 @@
 import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.telephony.SmsApplication;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.FunctionalUtils.ThrowingRunnable;
@@ -217,6 +221,7 @@
 import com.android.server.devicepolicy.DevicePolicyManagerService.ActiveAdmin.TrustAgentInfo;
 import com.android.server.net.NetworkPolicyManagerInternal;
 import com.android.server.pm.UserRestrictionsUtils;
+import com.android.server.storage.DeviceStorageMonitorInternal;
 
 import com.google.android.collect.Sets;
 
@@ -8215,6 +8220,16 @@
     }
 
     @Override
+    public void setDefaultSmsApplication(ComponentName admin, String packageName) {
+        Preconditions.checkNotNull(admin, "ComponentName is null");
+        synchronized (this) {
+            getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+        }
+        mInjector.binderWithCleanCallingIdentity(() ->
+                SmsApplication.setDefaultApplication(packageName, mContext));
+    }
+
+    @Override
     public boolean setApplicationRestrictionsManagingPackage(ComponentName admin,
             String packageName) {
         try {
@@ -8871,13 +8886,40 @@
         final boolean demo = (flags & DevicePolicyManager.MAKE_USER_DEMO) != 0
                 && UserManager.isDeviceInDemoMode(mContext);
         final boolean leaveAllSystemAppsEnabled = (flags & LEAVE_ALL_SYSTEM_APPS_ENABLED) != 0;
+        final int targetSdkVersion;
+
         // Create user.
         UserHandle user = null;
         synchronized (this) {
             getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
 
+            final int callingUid = mInjector.binderGetCallingUid();
             final long id = mInjector.binderClearCallingIdentity();
             try {
+                targetSdkVersion = mInjector.getPackageManagerInternal().getUidTargetSdkVersion(
+                        callingUid);
+
+                // Return detail error code for checks inside
+                // UserManagerService.createUserInternalUnchecked.
+                DeviceStorageMonitorInternal deviceStorageMonitorInternal =
+                        LocalServices.getService(DeviceStorageMonitorInternal.class);
+                if (deviceStorageMonitorInternal.isMemoryLow()) {
+                    if (targetSdkVersion >= Build.VERSION_CODES.P) {
+                        throw new ServiceSpecificException(
+                                UserManager.USER_OPERATION_ERROR_LOW_STORAGE, "low device storage");
+                    } else {
+                        return null;
+                    }
+                }
+                if (!mUserManager.canAddMoreUsers()) {
+                    if (targetSdkVersion >= Build.VERSION_CODES.P) {
+                        throw new ServiceSpecificException(
+                                UserManager.USER_OPERATION_ERROR_MAX_USERS, "user limit reached");
+                    } else {
+                        return null;
+                    }
+                }
+
                 int userInfoFlags = 0;
                 if (ephemeral) {
                     userInfoFlags |= UserInfo.FLAG_EPHEMERAL;
@@ -8901,7 +8943,12 @@
             }
         }
         if (user == null) {
-            return null;
+            if (targetSdkVersion >= Build.VERSION_CODES.P) {
+                throw new ServiceSpecificException(UserManager.USER_OPERATION_ERROR_UNKNOWN,
+                        "failed to create user");
+            } else {
+                return null;
+            }
         }
 
         final int userHandle = user.getIdentifier();
@@ -8947,7 +8994,12 @@
             return user;
         } catch (Throwable re) {
             mUserManager.removeUser(userHandle);
-            return null;
+            if (targetSdkVersion >= Build.VERSION_CODES.P) {
+                throw new ServiceSpecificException(UserManager.USER_OPERATION_ERROR_UNKNOWN,
+                        re.getMessage());
+            } else {
+                return null;
+            }
         } finally {
             mInjector.binderRestoreCallingIdentity(id);
         }
@@ -9028,24 +9080,24 @@
         final int userId = userHandle.getIdentifier();
         if (isManagedProfile(userId)) {
             Log.w(LOG_TAG, "Managed profile cannot be started in background");
-            return DevicePolicyManager.USER_OPERATION_ERROR_MANAGED_PROFILE;
+            return UserManager.USER_OPERATION_ERROR_MANAGED_PROFILE;
         }
 
         final long id = mInjector.binderClearCallingIdentity();
         try {
             if (!mInjector.getActivityManagerInternal().canStartMoreUsers()) {
                 Log.w(LOG_TAG, "Cannot start more users in background");
-                return DevicePolicyManager.USER_OPERATION_ERROR_MAX_RUNNING_USERS;
+                return UserManager.USER_OPERATION_ERROR_MAX_RUNNING_USERS;
             }
 
             if (mInjector.getIActivityManager().startUserInBackground(userId)) {
-                return DevicePolicyManager.USER_OPERATION_SUCCESS;
+                return UserManager.USER_OPERATION_SUCCESS;
             } else {
-                return DevicePolicyManager.USER_OPERATION_ERROR_UNKNOWN;
+                return UserManager.USER_OPERATION_ERROR_UNKNOWN;
             }
         } catch (RemoteException e) {
             // Same process, should not happen.
-            return DevicePolicyManager.USER_OPERATION_ERROR_UNKNOWN;
+            return UserManager.USER_OPERATION_ERROR_UNKNOWN;
         } finally {
             mInjector.binderRestoreCallingIdentity(id);
         }
@@ -9063,7 +9115,7 @@
         final int userId = userHandle.getIdentifier();
         if (isManagedProfile(userId)) {
             Log.w(LOG_TAG, "Managed profile cannot be stopped");
-            return DevicePolicyManager.USER_OPERATION_ERROR_MANAGED_PROFILE;
+            return UserManager.USER_OPERATION_ERROR_MANAGED_PROFILE;
         }
 
         return stopUserUnchecked(userId);
@@ -9084,7 +9136,7 @@
 
         if (isManagedProfile(callingUserId)) {
             Log.w(LOG_TAG, "Managed profile cannot be logout");
-            return DevicePolicyManager.USER_OPERATION_ERROR_MANAGED_PROFILE;
+            return UserManager.USER_OPERATION_ERROR_MANAGED_PROFILE;
         }
 
         final long id = mInjector.binderClearCallingIdentity();
@@ -9092,11 +9144,11 @@
             if (!mInjector.getIActivityManager().switchUser(UserHandle.USER_SYSTEM)) {
                 Log.w(LOG_TAG, "Failed to switch to primary user");
                 // This should never happen as target user is UserHandle.USER_SYSTEM
-                return DevicePolicyManager.USER_OPERATION_ERROR_UNKNOWN;
+                return UserManager.USER_OPERATION_ERROR_UNKNOWN;
             }
         } catch (RemoteException e) {
             // Same process, should not happen.
-            return DevicePolicyManager.USER_OPERATION_ERROR_UNKNOWN;
+            return UserManager.USER_OPERATION_ERROR_UNKNOWN;
         } finally {
             mInjector.binderRestoreCallingIdentity(id);
         }
@@ -9109,15 +9161,15 @@
         try {
             switch (mInjector.getIActivityManager().stopUser(userId, true /*force*/, null)) {
                 case ActivityManager.USER_OP_SUCCESS:
-                    return DevicePolicyManager.USER_OPERATION_SUCCESS;
+                    return UserManager.USER_OPERATION_SUCCESS;
                 case ActivityManager.USER_OP_IS_CURRENT:
-                    return DevicePolicyManager.USER_OPERATION_ERROR_CURRENT_USER;
+                    return UserManager.USER_OPERATION_ERROR_CURRENT_USER;
                 default:
-                    return DevicePolicyManager.USER_OPERATION_ERROR_UNKNOWN;
+                    return UserManager.USER_OPERATION_ERROR_UNKNOWN;
             }
         } catch (RemoteException e) {
             // Same process, should not happen.
-            return DevicePolicyManager.USER_OPERATION_ERROR_UNKNOWN;
+            return UserManager.USER_OPERATION_ERROR_UNKNOWN;
         } finally {
             mInjector.binderRestoreCallingIdentity(id);
         }
@@ -9817,6 +9869,13 @@
     @Override
     public void setLockTaskFeatures(ComponentName who, int flags) {
         Preconditions.checkNotNull(who, "ComponentName is null");
+
+        // Throw if Overview is used without Home.
+        boolean hasHome = (flags & LOCK_TASK_FEATURE_HOME) != 0;
+        boolean hasOverview = (flags & LOCK_TASK_FEATURE_OVERVIEW) != 0;
+        Preconditions.checkArgument(hasHome || !hasOverview,
+                "Cannot use LOCK_TASK_FEATURE_OVERVIEW without LOCK_TASK_FEATURE_HOME");
+
         final int userHandle = mInjector.userHandleGetCallingUserId();
         synchronized (this) {
             enforceCanCallLockTaskLocked(who);
@@ -10410,7 +10469,8 @@
         public CharSequence getPrintingDisabledReasonForUser(@UserIdInt int userId) {
             synchronized (DevicePolicyManagerService.this) {
                 DevicePolicyData policy = getUserData(userId);
-                if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_PRINTING)) {
+                if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_PRINTING,
+                        UserHandle.of(userId))) {
                     Log.e(LOG_TAG, "printing is enabled");
                     return null;
                 }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 61c8b79..5b5de0e 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1088,8 +1088,8 @@
 
             traceBeginAndSlog("StartNetworkPolicyManagerService");
             try {
-                networkPolicy = new NetworkPolicyManagerService(context,
-                    mActivityManagerService, networkStats, networkManagement);
+                networkPolicy = new NetworkPolicyManagerService(context, mActivityManagerService,
+                        networkManagement);
                 ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy);
             } catch (Throwable e) {
                 reportWtf("starting NetworkPolicy Service", e);
@@ -1270,7 +1270,8 @@
 
             if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_USB_HOST)
                 || mPackageManager.hasSystemFeature(
-                PackageManager.FEATURE_USB_ACCESSORY)) {
+                PackageManager.FEATURE_USB_ACCESSORY)
+                || isEmulator) {
                 // Manage USB host and device support
                 traceBeginAndSlog("StartUsbService");
                 mSystemServiceManager.startService(USB_SERVICE_CLASS);
diff --git a/services/net/java/android/net/ip/IpClient.java b/services/net/java/android/net/ip/IpClient.java
index d3a97b3..1f370a5 100644
--- a/services/net/java/android/net/ip/IpClient.java
+++ b/services/net/java/android/net/ip/IpClient.java
@@ -72,6 +72,7 @@
 import java.util.List;
 import java.util.Set;
 import java.util.StringJoiner;
+import java.util.concurrent.CountDownLatch;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
@@ -100,6 +101,11 @@
 
     /**
      * Callbacks for handling IpClient events.
+     *
+     * These methods are called by IpClient on its own thread. Implementations
+     * of this class MUST NOT carry out long-running computations or hold locks
+     * for which there might be contention with other code calling public
+     * methods of the same IpClient instance.
      */
     public static class Callback {
         // In order to receive onPreDhcpAction(), call #withPreDhcpAction()
@@ -545,6 +551,7 @@
     private final String mClatInterfaceName;
     @VisibleForTesting
     protected final Callback mCallback;
+    private final CountDownLatch mShutdownLatch;
     private final INetworkManagementService mNwService;
     private final NetlinkTracker mNetlinkTracker;
     private final WakeupMessage mProvisioningTimeoutAlarm;
@@ -597,6 +604,7 @@
         mInterfaceName = ifName;
         mClatInterfaceName = CLAT_PREFIX + ifName;
         mCallback = new LoggingCallbackWrapper(callback);
+        mShutdownLatch = new CountDownLatch(1);
         mNwService = nwService;
 
         mLog = new SharedLog(MAX_LOG_RECORDS, mTag);
@@ -704,6 +712,7 @@
     @Override
     protected void onQuitting() {
         mCallback.onQuit();
+        mShutdownLatch.countDown();
     }
 
     // Shut down this IpClient instance altogether.
@@ -712,6 +721,17 @@
         sendMessage(CMD_TERMINATE_AFTER_STOP);
     }
 
+    // In order to avoid deadlock, this method MUST NOT be called on the
+    // IpClient instance's thread. This prohibition includes code executed by
+    // when methods on the passed-in IpClient.Callback instance are called.
+    public void awaitShutdown() {
+        try {
+            mShutdownLatch.await();
+        } catch (InterruptedException e) {
+            mLog.e("Interrupted while awaiting shutdown: " + e);
+        }
+    }
+
     public static ProvisioningConfiguration.Builder buildProvisioningConfiguration() {
         return new ProvisioningConfiguration.Builder();
     }
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index e8620ed..83a125d 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -718,7 +718,8 @@
         }
 
         private boolean isPrintingEnabled() {
-            return !mUserManager.hasUserRestriction(UserManager.DISALLOW_PRINTING);
+            return !mUserManager.hasUserRestriction(UserManager.DISALLOW_PRINTING,
+                    Binder.getCallingUserHandle());
         }
 
         private void dump(@NonNull DualDumpOutputStream dumpStream,
diff --git a/services/print/java/com/android/server/print/RemotePrintService.java b/services/print/java/com/android/server/print/RemotePrintService.java
index f72d8ee..d4cbe7b 100644
--- a/services/print/java/com/android/server/print/RemotePrintService.java
+++ b/services/print/java/com/android/server/print/RemotePrintService.java
@@ -18,6 +18,7 @@
 
 import static com.android.internal.print.DumpUtils.writePrinterId;
 import static com.android.internal.util.dump.DumpUtils.writeComponentName;
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
 
 import android.annotation.FloatRange;
 import android.annotation.NonNull;
@@ -33,8 +34,6 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.IBinder.DeathRecipient;
-import android.os.Looper;
-import android.os.Message;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -86,8 +85,6 @@
 
     private final RemotePrintServiceClient mPrintServiceClient;
 
-    private final Handler mHandler;
-
     private IPrintService mPrintService;
 
     private boolean mBinding;
@@ -128,7 +125,6 @@
         mIntent = new Intent().setComponent(mComponentName);
         mUserId = userId;
         mSpooler = spooler;
-        mHandler = new MyHandler(context.getMainLooper());
         mPrintServiceClient = new RemotePrintServiceClient(this);
     }
 
@@ -137,7 +133,8 @@
     }
 
     public void destroy() {
-        mHandler.sendEmptyMessage(MyHandler.MSG_DESTROY);
+        Handler.getMain().sendMessage(obtainMessage(
+                RemotePrintService::handleDestroy, this));
     }
 
     private void handleDestroy() {
@@ -163,7 +160,8 @@
 
     @Override
     public void binderDied() {
-        mHandler.sendEmptyMessage(MyHandler.MSG_BINDER_DIED);
+        Handler.getMain().sendMessage(obtainMessage(
+                RemotePrintService::handleBinderDied, this));
     }
 
     private void handleBinderDied() {
@@ -177,7 +175,8 @@
     }
 
     public void onAllPrintJobsHandled() {
-        mHandler.sendEmptyMessage(MyHandler.MSG_ON_ALL_PRINT_JOBS_HANDLED);
+        Handler.getMain().sendMessage(obtainMessage(
+                RemotePrintService::handleOnAllPrintJobsHandled, this));
     }
 
     private void handleOnAllPrintJobsHandled() {
@@ -209,8 +208,8 @@
     }
 
     public void onRequestCancelPrintJob(PrintJobInfo printJob) {
-        mHandler.obtainMessage(MyHandler.MSG_ON_REQUEST_CANCEL_PRINT_JOB,
-                printJob).sendToTarget();
+        Handler.getMain().sendMessage(obtainMessage(
+                RemotePrintService::handleRequestCancelPrintJob, this, printJob));
     }
 
     private void handleRequestCancelPrintJob(final PrintJobInfo printJob) {
@@ -235,8 +234,8 @@
     }
 
     public void onPrintJobQueued(PrintJobInfo printJob) {
-        mHandler.obtainMessage(MyHandler.MSG_ON_PRINT_JOB_QUEUED,
-                printJob).sendToTarget();
+        Handler.getMain().sendMessage(obtainMessage(
+                RemotePrintService::handleOnPrintJobQueued, this, printJob));
     }
 
     private void handleOnPrintJobQueued(final PrintJobInfo printJob) {
@@ -262,7 +261,8 @@
     }
 
     public void createPrinterDiscoverySession() {
-        mHandler.sendEmptyMessage(MyHandler.MSG_CREATE_PRINTER_DISCOVERY_SESSION);
+        Handler.getMain().sendMessage(obtainMessage(
+                RemotePrintService::handleCreatePrinterDiscoverySession, this));
     }
 
     private void handleCreatePrinterDiscoverySession() {
@@ -288,7 +288,8 @@
     }
 
     public void destroyPrinterDiscoverySession() {
-        mHandler.sendEmptyMessage(MyHandler.MSG_DESTROY_PRINTER_DISCOVERY_SESSION);
+        Handler.getMain().sendMessage(obtainMessage(
+                RemotePrintService::handleDestroyPrinterDiscoverySession, this));
     }
 
     private void handleDestroyPrinterDiscoverySession() {
@@ -325,8 +326,8 @@
     }
 
     public void startPrinterDiscovery(List<PrinterId> priorityList) {
-        mHandler.obtainMessage(MyHandler.MSG_START_PRINTER_DISCOVERY,
-                priorityList).sendToTarget();
+        Handler.getMain().sendMessage(obtainMessage(
+                RemotePrintService::handleStartPrinterDiscovery, this, priorityList));
     }
 
     private void handleStartPrinterDiscovery(final List<PrinterId> priorityList) {
@@ -356,7 +357,8 @@
     }
 
     public void stopPrinterDiscovery() {
-        mHandler.sendEmptyMessage(MyHandler.MSG_STOP_PRINTER_DISCOVERY);
+        Handler.getMain().sendMessage(obtainMessage(
+                RemotePrintService::handleStopPrinterDiscovery, this));
     }
 
     private void handleStopPrinterDiscovery() {
@@ -387,8 +389,8 @@
     }
 
     public void validatePrinters(List<PrinterId> printerIds) {
-        mHandler.obtainMessage(MyHandler.MSG_VALIDATE_PRINTERS,
-                printerIds).sendToTarget();
+        Handler.getMain().sendMessage(obtainMessage(
+                RemotePrintService::handleValidatePrinters, this, printerIds));
     }
 
     private void handleValidatePrinters(final List<PrinterId> printerIds) {
@@ -413,8 +415,8 @@
     }
 
     public void startPrinterStateTracking(@NonNull PrinterId printerId) {
-        mHandler.obtainMessage(MyHandler.MSG_START_PRINTER_STATE_TRACKING,
-                printerId).sendToTarget();
+        Handler.getMain().sendMessage(obtainMessage(
+                RemotePrintService::handleStartPrinterStateTracking, this, printerId));
     }
 
     /**
@@ -424,8 +426,8 @@
      * @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon
      */
     public void requestCustomPrinterIcon(@NonNull PrinterId printerId) {
-        mHandler.obtainMessage(MyHandler.MSG_REQUEST_CUSTOM_PRINTER_ICON,
-                printerId).sendToTarget();
+        Handler.getMain().sendMessage(obtainMessage(
+                RemotePrintService::handleRequestCustomPrinterIcon, this, printerId));
     }
 
     /**
@@ -481,8 +483,8 @@
     }
 
     public void stopPrinterStateTracking(PrinterId printerId) {
-        mHandler.obtainMessage(MyHandler.MSG_STOP_PRINTER_STATE_TRACKING,
-                printerId).sendToTarget();
+        Handler.getMain().sendMessage(obtainMessage(
+                RemotePrintService::handleStopPrinterStateTracking, this, printerId));
     }
 
     private void handleStopPrinterStateTracking(final PrinterId printerId) {
@@ -672,96 +674,6 @@
         }
     }
 
-    private final class MyHandler extends Handler {
-        public static final int MSG_CREATE_PRINTER_DISCOVERY_SESSION = 1;
-        public static final int MSG_DESTROY_PRINTER_DISCOVERY_SESSION = 2;
-        public static final int MSG_START_PRINTER_DISCOVERY = 3;
-        public static final int MSG_STOP_PRINTER_DISCOVERY = 4;
-        public static final int MSG_VALIDATE_PRINTERS = 5;
-        public static final int MSG_START_PRINTER_STATE_TRACKING = 6;
-        public static final int MSG_STOP_PRINTER_STATE_TRACKING = 7;
-        public static final int MSG_ON_ALL_PRINT_JOBS_HANDLED = 8;
-        public static final int MSG_ON_REQUEST_CANCEL_PRINT_JOB = 9;
-        public static final int MSG_ON_PRINT_JOB_QUEUED = 10;
-        public static final int MSG_DESTROY = 11;
-        public static final int MSG_BINDER_DIED = 12;
-        public static final int MSG_REQUEST_CUSTOM_PRINTER_ICON = 13;
-
-        public MyHandler(Looper looper) {
-            super(looper, null, false);
-        }
-
-        @Override
-        @SuppressWarnings("unchecked")
-        public void handleMessage(Message message) {
-            if (mDestroyed) {
-                Slog.w(LOG_TAG, "Not handling " + message + " as service for " + mComponentName
-                        + " is already destroyed");
-                return;
-            }
-            switch (message.what) {
-                case MSG_CREATE_PRINTER_DISCOVERY_SESSION: {
-                    handleCreatePrinterDiscoverySession();
-                } break;
-
-                case MSG_DESTROY_PRINTER_DISCOVERY_SESSION: {
-                    handleDestroyPrinterDiscoverySession();
-                } break;
-
-                case MSG_START_PRINTER_DISCOVERY: {
-                    List<PrinterId> priorityList = (ArrayList<PrinterId>) message.obj;
-                    handleStartPrinterDiscovery(priorityList);
-                } break;
-
-                case MSG_STOP_PRINTER_DISCOVERY: {
-                    handleStopPrinterDiscovery();
-                } break;
-
-                case MSG_VALIDATE_PRINTERS: {
-                    List<PrinterId> printerIds = (List<PrinterId>) message.obj;
-                    handleValidatePrinters(printerIds);
-                } break;
-
-                case MSG_START_PRINTER_STATE_TRACKING: {
-                    PrinterId printerId = (PrinterId) message.obj;
-                    handleStartPrinterStateTracking(printerId);
-                } break;
-
-                case MSG_STOP_PRINTER_STATE_TRACKING: {
-                    PrinterId printerId = (PrinterId) message.obj;
-                    handleStopPrinterStateTracking(printerId);
-                } break;
-
-                case MSG_ON_ALL_PRINT_JOBS_HANDLED: {
-                    handleOnAllPrintJobsHandled();
-                } break;
-
-                case MSG_ON_REQUEST_CANCEL_PRINT_JOB: {
-                    PrintJobInfo printJob = (PrintJobInfo) message.obj;
-                    handleRequestCancelPrintJob(printJob);
-                } break;
-
-                case MSG_ON_PRINT_JOB_QUEUED: {
-                    PrintJobInfo printJob = (PrintJobInfo) message.obj;
-                    handleOnPrintJobQueued(printJob);
-                } break;
-
-                case MSG_DESTROY: {
-                    handleDestroy();
-                } break;
-
-                case MSG_BINDER_DIED: {
-                    handleBinderDied();
-                } break;
-
-                case MSG_REQUEST_CUSTOM_PRINTER_ICON: {
-                    PrinterId printerId = (PrinterId) message.obj;
-                    handleRequestCustomPrinterIcon(printerId);
-                } break;
-            }
-        }
-    }
-
     private static final class RemotePrintServiceClient extends IPrintServiceClient.Stub {
         private final WeakReference<RemotePrintService> mWeakService;
 
diff --git a/services/print/java/com/android/server/print/UserState.java b/services/print/java/com/android/server/print/UserState.java
index 84c1bb2..62185d7 100644
--- a/services/print/java/com/android/server/print/UserState.java
+++ b/services/print/java/com/android/server/print/UserState.java
@@ -38,7 +38,6 @@
 import android.content.pm.ResolveInfo;
 import android.graphics.drawable.Icon;
 import android.net.Uri;
-import android.os.AsyncTask;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
@@ -46,7 +45,6 @@
 import android.os.IBinder.DeathRecipient;
 import android.os.IInterface;
 import android.os.Looper;
-import android.os.Message;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -82,6 +80,7 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.dump.DualDumpOutputStream;
+import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.print.RemotePrintService.PrintServiceCallbacks;
 import com.android.server.print.RemotePrintServiceRecommendationService
         .RemotePrintServiceRecommendationServiceCallbacks;
@@ -94,6 +93,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.IntSupplier;
 
 /**
  * Represents the print state for a user.
@@ -135,8 +135,6 @@
 
     private final RemotePrintSpooler mSpooler;
 
-    private final Handler mHandler;
-
     private PrinterDiscoverySessionMediator mPrinterDiscoverySession;
 
     private List<PrintJobStateChangeListenerRecord> mPrintJobStateChangeListenerRecords;
@@ -162,7 +160,6 @@
         mUserId = userId;
         mLock = lock;
         mSpooler = new RemotePrintSpooler(context, userId, lowPriority, this);
-        mHandler = new UserStateHandler(context.getMainLooper());
 
         synchronized (mLock) {
             readInstalledPrintServicesLocked();
@@ -173,9 +170,7 @@
         // Some print services might have gotten installed before the User State came up
         prunePrintServices();
 
-        synchronized (mLock) {
-            onConfigurationChangedLocked();
-        }
+        onConfigurationChanged();
     }
 
     public void increasePriority() {
@@ -236,15 +231,6 @@
             return null;
         }
 
-        // Spin the spooler to add the job and show the config UI.
-        new AsyncTask<Void, Void, Void>() {
-            @Override
-            protected Void doInBackground(Void... params) {
-                mSpooler.createPrintJob(printJob);
-                return null;
-            }
-        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
-
         final long identity = Binder.clearCallingIdentity();
         try {
             Intent intent = new Intent(PrintManager.ACTION_PRINT_DIALOG);
@@ -705,18 +691,22 @@
     @Override
     public void onPrintJobStateChanged(PrintJobInfo printJob) {
         mPrintJobForAppCache.onPrintJobStateChanged(printJob);
-        mHandler.obtainMessage(UserStateHandler.MSG_DISPATCH_PRINT_JOB_STATE_CHANGED,
-                printJob.getAppId(), 0, printJob.getId()).sendToTarget();
+        Handler.getMain().sendMessage(obtainMessage(
+                UserState::handleDispatchPrintJobStateChanged,
+                this, printJob.getId(),
+                PooledLambda.obtainSupplier(printJob.getAppId()).recycleOnUse()));
     }
 
     public void onPrintServicesChanged() {
-        mHandler.obtainMessage(UserStateHandler.MSG_DISPATCH_PRINT_SERVICES_CHANGED).sendToTarget();
+        Handler.getMain().sendMessage(obtainMessage(
+                UserState::handleDispatchPrintServicesChanged, this));
     }
 
     @Override
     public void onPrintServiceRecommendationsUpdated(List<RecommendationInfo> recommendations) {
-        mHandler.obtainMessage(UserStateHandler.MSG_DISPATCH_PRINT_SERVICES_RECOMMENDATIONS_UPDATED,
-                0, 0, recommendations).sendToTarget();
+        Handler.getMain().sendMessage(obtainMessage(
+                UserState::handleDispatchPrintServiceRecommendationsUpdated,
+                this, recommendations));
     }
 
     @Override
@@ -781,8 +771,8 @@
             mActiveServices.remove(service.getComponentName());
 
             // The service might need to be restarted if it died because of an update
-            mHandler.sendMessageDelayed(
-                    mHandler.obtainMessage(UserStateHandler.MSG_CHECK_CONFIG_CHANGED),
+            Handler.getMain().sendMessageDelayed(obtainMessage(
+                    UserState::onConfigurationChanged, this),
                     SERVICE_RESTART_DELAY_MILLIS);
 
             // No session - nothing to do.
@@ -1122,24 +1112,26 @@
         }
     }
 
-    private void handleDispatchPrintJobStateChanged(PrintJobId printJobId, int appId) {
+    private void handleDispatchPrintJobStateChanged(
+            PrintJobId printJobId, IntSupplier appIdSupplier) {
+        int appId = appIdSupplier.getAsInt();
         final List<PrintJobStateChangeListenerRecord> records;
         synchronized (mLock) {
             if (mPrintJobStateChangeListenerRecords == null) {
                 return;
             }
-            records = new ArrayList<PrintJobStateChangeListenerRecord>(
-                    mPrintJobStateChangeListenerRecords);
+            records = new ArrayList<>(mPrintJobStateChangeListenerRecords);
         }
         final int recordCount = records.size();
         for (int i = 0; i < recordCount; i++) {
             PrintJobStateChangeListenerRecord record = records.get(i);
             if (record.appId == PrintManager.APP_ID_ANY
-                    || record.appId == appId)
-            try {
-                record.listener.onPrintJobStateChanged(printJobId);
-            } catch (RemoteException re) {
-                Log.e(LOG_TAG, "Error notifying for print job state change", re);
+                    || record.appId == appId) {
+                try {
+                    record.listener.onPrintJobStateChanged(printJobId);
+                } catch (RemoteException re) {
+                    Log.e(LOG_TAG, "Error notifying for print job state change", re);
+                }
             }
         }
     }
@@ -1187,38 +1179,9 @@
         }
     }
 
-    private final class UserStateHandler extends Handler {
-        public static final int MSG_DISPATCH_PRINT_JOB_STATE_CHANGED = 1;
-        public static final int MSG_DISPATCH_PRINT_SERVICES_CHANGED = 2;
-        public static final int MSG_DISPATCH_PRINT_SERVICES_RECOMMENDATIONS_UPDATED = 3;
-        public static final int MSG_CHECK_CONFIG_CHANGED = 4;
-
-        public UserStateHandler(Looper looper) {
-            super(looper, null, false);
-        }
-
-        @Override
-        public void handleMessage(Message message) {
-            switch (message.what) {
-                case MSG_DISPATCH_PRINT_JOB_STATE_CHANGED:
-                    PrintJobId printJobId = (PrintJobId) message.obj;
-                    final int appId = message.arg1;
-                    handleDispatchPrintJobStateChanged(printJobId, appId);
-                    break;
-                case MSG_DISPATCH_PRINT_SERVICES_CHANGED:
-                    handleDispatchPrintServicesChanged();
-                    break;
-                case MSG_DISPATCH_PRINT_SERVICES_RECOMMENDATIONS_UPDATED:
-                    handleDispatchPrintServiceRecommendationsUpdated(
-                            (List<RecommendationInfo>) message.obj);
-                    break;
-                case MSG_CHECK_CONFIG_CHANGED:
-                    synchronized (mLock) {
-                        onConfigurationChangedLocked();
-                    }
-                default:
-                    // not reached
-            }
+    private void onConfigurationChanged() {
+        synchronized (mLock) {
+            onConfigurationChangedLocked();
         }
     }
 
diff --git a/services/robotests/Android.mk b/services/robotests/Android.mk
index d825533..cd8163d 100644
--- a/services/robotests/Android.mk
+++ b/services/robotests/Android.mk
@@ -58,14 +58,14 @@
 LOCAL_SRC_FILES := \
     $(call all-java-files-under, src) \
     $(call all-Iaidl-files-under, $(INTERNAL_BACKUP)) \
+    $(call all-java-files-under, ../../core/java/android/app/backup) \
+    $(call all-Iaidl-files-under, ../../core/java/android/app/backup) \
     ../../core/java/android/content/pm/PackageInfo.java \
-    ../../core/java/android/app/backup/BackupAgent.java \
-    ../../core/java/android/app/backup/BackupDataOutput.java \
-    ../../core/java/android/app/backup/FullBackupDataOutput.java \
     ../../core/java/android/app/IBackupAgent.aidl
 
 LOCAL_AIDL_INCLUDES := \
     $(call all-Iaidl-files-under, $(INTERNAL_BACKUP)) \
+    $(call all-Iaidl-files-under, ../../core/java/android/app/backup) \
     ../../core/java/android/app/IBackupAgent.aidl
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
diff --git a/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java b/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
index d0e6658..f603a09 100644
--- a/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
+++ b/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
@@ -19,6 +19,7 @@
 import static com.android.server.backup.testing.BackupManagerServiceTestUtils.createBackupWakeLock;
 import static com.android.server.backup.testing.BackupManagerServiceTestUtils.setUpBackupManagerServiceBasics;
 import static com.android.server.backup.testing.BackupManagerServiceTestUtils.startBackupThreadAndGetLooper;
+
 import static com.android.server.backup.testing.TransportData.backupTransport;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -48,7 +49,6 @@
 import android.app.backup.BackupDataOutput;
 import android.app.backup.BackupManager;
 import android.app.backup.BackupTransport;
-import android.app.backup.FullBackupDataOutput;
 import android.app.backup.IBackupManager;
 import android.app.backup.IBackupManagerMonitor;
 import android.app.backup.IBackupObserver;
@@ -76,11 +76,11 @@
 import com.android.server.testing.FrameworkRobolectricTestRunner;
 import com.android.server.testing.SystemLoaderClasses;
 import com.android.server.testing.SystemLoaderPackages;
-import com.android.server.testing.shadows.FrameworkShadowPackageManager;
 import com.android.server.testing.shadows.ShadowBackupDataInput;
 import com.android.server.testing.shadows.ShadowBackupDataOutput;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentMatcher;
@@ -90,7 +90,6 @@
 import org.mockito.stubbing.Answer;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
-import org.robolectric.shadow.api.Shadow;
 import org.robolectric.shadows.ShadowLooper;
 import org.robolectric.shadows.ShadowPackageManager;
 import org.robolectric.shadows.ShadowQueuedWork;
@@ -105,22 +104,10 @@
 @Config(
     manifest = Config.NONE,
     sdk = 26,
-    shadows = {
-        FrameworkShadowPackageManager.class,
-        ShadowBackupDataInput.class,
-        ShadowBackupDataOutput.class,
-        ShadowQueuedWork.class
-    }
+    shadows = {ShadowBackupDataInput.class, ShadowBackupDataOutput.class, ShadowQueuedWork.class}
 )
-@SystemLoaderPackages({"com.android.server.backup"})
-@SystemLoaderClasses({
-    BackupDataOutput.class,
-    FullBackupDataOutput.class,
-    BackupAgent.class,
-    IBackupTransport.class,
-    IBackupAgent.class,
-    PackageInfo.class
-})
+@SystemLoaderPackages({"com.android.server.backup", "android.app.backup"})
+@SystemLoaderClasses({IBackupTransport.class, IBackupAgent.class, PackageInfo.class})
 @Presubmit
 public class PerformBackupTaskTest {
     private static final String PACKAGE_1 = "com.example.package1";
@@ -154,7 +141,7 @@
         assertThat(dataDir.mkdir()).isTrue();
 
         PackageManager packageManager = application.getPackageManager();
-        mShadowPackageManager = Shadow.extract(packageManager);
+        mShadowPackageManager = shadowOf(packageManager);
 
         mWakeLock = createBackupWakeLock(application);
 
@@ -496,8 +483,9 @@
     }
 
     // TODO: Giving NPE at PerformBackupTask:524 because mCurrentPackage is null (PackageManager
-    // rightfully threw NameNotFoundException). Uncomment @Test when fixed.
-    // @Test
+    // rightfully threw NameNotFoundException). Remove @Ignore when fixed.
+    @Ignore
+    @Test
     public void testRunTask_whenAgentUnknown() throws Exception {
         // Not calling setUpAgent()
         TransportMock transportMock = setUpTransport(mTransport);
@@ -586,6 +574,7 @@
         return task;
     }
 
+    /** Matches {@link PackageInfo} whose package name is {@code packageName}. */
     private static ArgumentMatcher<PackageInfo> packageInfo(String packageName) {
         // We have to test for packageInfo nulity because of Mockito's own stubbing with argThat().
         // E.g. if you do:
diff --git a/services/robotests/src/com/android/server/backup/TransportManagerTest.java b/services/robotests/src/com/android/server/backup/TransportManagerTest.java
index 32697bd..7d1b6c86 100644
--- a/services/robotests/src/com/android/server/backup/TransportManagerTest.java
+++ b/services/robotests/src/com/android/server/backup/TransportManagerTest.java
@@ -30,7 +30,7 @@
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
-import static org.robolectric.shadow.api.Shadow.extract;
+import static org.robolectric.Shadows.shadowOf;
 import static org.testng.Assert.expectThrows;
 
 import static java.util.Arrays.asList;
@@ -42,6 +42,7 @@
 
 import android.annotation.Nullable;
 import android.app.backup.BackupManager;
+import android.app.backup.BackupTransport;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -58,7 +59,6 @@
 import com.android.server.testing.FrameworkRobolectricTestRunner;
 import com.android.server.testing.SystemLoaderPackages;
 import com.android.server.testing.shadows.FrameworkShadowContextImpl;
-import com.android.server.testing.shadows.FrameworkShadowPackageManager;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -79,7 +79,7 @@
 @Config(
     manifest = Config.NONE,
     sdk = 26,
-    shadows = {FrameworkShadowPackageManager.class, FrameworkShadowContextImpl.class}
+    shadows = {FrameworkShadowContextImpl.class}
 )
 @SystemLoaderPackages({"com.android.server.backup"})
 @Presubmit
@@ -87,18 +87,11 @@
     private static final String PACKAGE_A = "some.package.a";
     private static final String PACKAGE_B = "some.package.b";
 
-    /**
-     * GMSCore depends on this constant so we define it here on top of the definition in {@link
-     * TransportManager} to verify this extra is passed
-     */
-    private static final String EXTRA_TRANSPORT_REGISTRATION = "transport_registration";
-
     @Mock private OnTransportRegisteredListener mListener;
     @Mock private TransportClientManager mTransportClientManager;
     private TransportData mTransportA1;
     private TransportData mTransportA2;
     private TransportData mTransportB1;
-
     private ShadowPackageManager mShadowPackageManager;
     private Context mContext;
 
@@ -107,8 +100,7 @@
         MockitoAnnotations.initMocks(this);
 
         mContext = RuntimeEnvironment.application;
-        mShadowPackageManager =
-                (FrameworkShadowPackageManager) extract(mContext.getPackageManager());
+        mShadowPackageManager = shadowOf(mContext.getPackageManager());
 
         mTransportA1 = genericTransport(PACKAGE_A, "TransportFoo");
         mTransportA2 = genericTransport(PACKAGE_A, "TransportBar");
@@ -212,7 +204,8 @@
         verify(mTransportClientManager)
                 .getTransportClient(
                         eq(mTransportA1.getTransportComponent()),
-                        argThat(bundle -> bundle.getBoolean(EXTRA_TRANSPORT_REGISTRATION)),
+                        argThat(bundle ->
+                                bundle.getBoolean(BackupTransport.EXTRA_TRANSPORT_REGISTRATION)),
                         anyString());
     }
 
diff --git a/services/robotests/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java b/services/robotests/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java
index 4ac00f0..03792b1 100644
--- a/services/robotests/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java
+++ b/services/robotests/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java
@@ -25,8 +25,10 @@
 
 import static org.mockito.AdditionalMatchers.aryEq;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.doCallRealMethod;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static org.robolectric.Shadows.shadowOf;
@@ -37,8 +39,11 @@
 import android.app.backup.IRestoreObserver;
 import android.app.backup.IRestoreSession;
 import android.app.backup.RestoreSet;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
 import android.os.Looper;
 import android.os.PowerManager;
+import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
 
 import com.android.server.EventLogTags;
@@ -51,7 +56,9 @@
 import com.android.server.testing.FrameworkRobolectricTestRunner;
 import com.android.server.testing.SystemLoaderPackages;
 import com.android.server.testing.shadows.ShadowEventLog;
+import com.android.server.testing.shadows.ShadowPerformUnifiedRestoreTask;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -60,15 +67,25 @@
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.shadows.ShadowBinder;
 import org.robolectric.shadows.ShadowLooper;
+import org.robolectric.shadows.ShadowPackageManager;
+
+import java.util.ArrayDeque;
 
 @RunWith(FrameworkRobolectricTestRunner.class)
-@Config(manifest = Config.NONE, sdk = 26, shadows = ShadowEventLog.class)
+@Config(
+    manifest = Config.NONE,
+    sdk = 26,
+    shadows = {ShadowEventLog.class, ShadowPerformUnifiedRestoreTask.class, ShadowBinder.class}
+)
 @SystemLoaderPackages({"com.android.server.backup"})
 @Presubmit
 public class ActiveRestoreSessionTest {
     private static final String PACKAGE_1 = "com.example.package1";
     private static final String PACKAGE_2 = "com.example.package2";
+    public static final long TOKEN_1 = 1L;
+    public static final long TOKEN_2 = 2L;
 
     @Mock private BackupManagerService mBackupManagerService;
     @Mock private TransportManager mTransportManager;
@@ -80,6 +97,7 @@
     private TransportData mTransport;
     private RestoreSet mRestoreSet1;
     private RestoreSet mRestoreSet2;
+    private ShadowPackageManager mShadowPackageManager;
 
     @Before
     public void setUp() throws Exception {
@@ -87,12 +105,14 @@
 
         mTransport = backupTransport();
 
-        mRestoreSet1 = new RestoreSet("name1", "device1", 1L);
-        mRestoreSet2 = new RestoreSet("name2", "device2", 2L);
+        mRestoreSet1 = new RestoreSet("name1", "device1", TOKEN_1);
+        mRestoreSet2 = new RestoreSet("name2", "device2", TOKEN_2);
 
         Application application = RuntimeEnvironment.application;
         mShadowApplication = shadowOf(application);
 
+        mShadowPackageManager = shadowOf(application.getPackageManager());
+
         Looper backupLooper = startBackupThreadAndGetLooper();
         mShadowBackupLooper = shadowOf(backupLooper);
         BackupHandler backupHandler = new BackupHandler(mBackupManagerService, backupLooper);
@@ -106,6 +126,12 @@
                 application.getPackageManager(),
                 backupHandler,
                 mWakeLock);
+        when(mBackupManagerService.getPendingRestores()).thenReturn(new ArrayDeque<>());
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        ShadowPerformUnifiedRestoreTask.reset();
     }
 
     @Test
@@ -193,12 +219,348 @@
         assertThat(mWakeLock.isHeld()).isFalse();
     }
 
+    @Test
+    public void testRestoreAll() throws Exception {
+        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
+        doCallRealMethod().when(mBackupManagerService).setRestoreInProgress(anyBoolean());
+        when(mBackupManagerService.isRestoreInProgress()).thenCallRealMethod();
+        TransportMock transportMock = setUpTransport(mTransport);
+        IRestoreSession restoreSession =
+                createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);
+
+        int result = restoreSession.restoreAll(TOKEN_1, mObserver, mMonitor);
+
+        mShadowBackupLooper.runToEndOfTasks();
+        assertThat(result).isEqualTo(0);
+        verify(mTransportManager)
+                .disposeOfTransportClient(eq(transportMock.transportClient), any());
+        assertThat(mWakeLock.isHeld()).isFalse();
+        assertThat(mBackupManagerService.isRestoreInProgress()).isFalse();
+        // Verify it created the task properly
+        ShadowPerformUnifiedRestoreTask shadowTask =
+                ShadowPerformUnifiedRestoreTask.getLastCreated();
+        assertThat(shadowTask.isFullSystemRestore()).isTrue();
+        assertThat(shadowTask.getFilterSet()).isNull();
+        assertThat(shadowTask.getPackage()).isNull();
+    }
+
+    @Test
+    public void testRestoreAll_whenNoRestoreSets() throws Exception {
+        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
+        setUpTransport(mTransport);
+        IRestoreSession restoreSession = createActiveRestoreSession(null, mTransport);
+
+        int result = restoreSession.restoreAll(TOKEN_1, mObserver, mMonitor);
+
+        assertThat(result).isEqualTo(-1);
+    }
+
+    @Test
+    public void testRestoreAll_whenSinglePackageSession() throws Exception {
+        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
+        setUpTransport(mTransport);
+        IRestoreSession restoreSession =
+                createActiveRestoreSessionWithRestoreSets(PACKAGE_1, mTransport, mRestoreSet1);
+
+        int result = restoreSession.restoreAll(TOKEN_1, mObserver, mMonitor);
+
+        assertThat(result).isEqualTo(-1);
+    }
+
+    @Test
+    public void testRestoreAll_whenSessionEnded() throws Exception {
+        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
+        setUpTransport(mTransport);
+        IRestoreSession restoreSession =
+                createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);
+        restoreSession.endRestoreSession();
+        mShadowBackupLooper.runToEndOfTasks();
+
+        expectThrows(
+                IllegalStateException.class,
+                () -> restoreSession.restoreAll(TOKEN_1, mObserver, mMonitor));
+    }
+
+    @Test
+    public void testRestoreAll_whenTransportNotRegistered() throws Exception {
+        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
+        setUpTransport(mTransport.unregistered());
+        IRestoreSession restoreSession =
+                createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);
+
+        int result = restoreSession.restoreAll(TOKEN_1, mObserver, mMonitor);
+
+        assertThat(result).isEqualTo(-1);
+    }
+
+    @Test
+    public void testRestoreAll_whenRestoreInProgress_addsToPendingRestores() throws Exception {
+        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
+        setUpTransport(mTransport);
+        when(mBackupManagerService.isRestoreInProgress()).thenReturn(true);
+        IRestoreSession restoreSession =
+                createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);
+
+        int result = restoreSession.restoreAll(TOKEN_1, mObserver, mMonitor);
+
+        mShadowBackupLooper.runToEndOfTasks();
+        assertThat(result).isEqualTo(0);
+        assertThat(mBackupManagerService.getPendingRestores()).hasSize(1);
+    }
+
+    @Test
+    public void testRestoreSome_for2Packages() throws Exception {
+        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
+        TransportMock transportMock = setUpTransport(mTransport);
+        IRestoreSession restoreSession =
+                createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);
+
+        int result =
+                restoreSession.restoreSome(
+                        TOKEN_1, mObserver, mMonitor, new String[] {PACKAGE_1, PACKAGE_2});
+
+        mShadowBackupLooper.runToEndOfTasks();
+        assertThat(result).isEqualTo(0);
+        verify(mTransportManager)
+                .disposeOfTransportClient(eq(transportMock.transportClient), any());
+        assertThat(mWakeLock.isHeld()).isFalse();
+        assertThat(mBackupManagerService.isRestoreInProgress()).isFalse();
+        ShadowPerformUnifiedRestoreTask shadowTask =
+                ShadowPerformUnifiedRestoreTask.getLastCreated();
+        assertThat(shadowTask.getFilterSet()).asList().containsExactly(PACKAGE_1, PACKAGE_2);
+        assertThat(shadowTask.getPackage()).isNull();
+    }
+
+    @Test
+    public void testRestoreSome_for2Packages_createsSystemRestoreTask() throws Exception {
+        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
+        setUpTransport(mTransport);
+        IRestoreSession restoreSession =
+                createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);
+
+        restoreSession.restoreSome(
+                TOKEN_1, mObserver, mMonitor, new String[] {PACKAGE_1, PACKAGE_2});
+
+        mShadowBackupLooper.runToEndOfTasks();
+        assertThat(ShadowPerformUnifiedRestoreTask.getLastCreated().isFullSystemRestore()).isTrue();
+    }
+
+    @Test
+    public void testRestoreSome_for1Package() throws Exception {
+        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
+        setUpTransport(mTransport);
+        IRestoreSession restoreSession =
+                createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);
+
+        restoreSession.restoreSome(TOKEN_1, mObserver, mMonitor, new String[] {PACKAGE_1});
+
+        mShadowBackupLooper.runToEndOfTasks();
+        ShadowPerformUnifiedRestoreTask shadowTask =
+                ShadowPerformUnifiedRestoreTask.getLastCreated();
+        assertThat(shadowTask.getFilterSet()).asList().containsExactly(PACKAGE_1);
+        assertThat(shadowTask.getPackage()).isNull();
+    }
+
+    @Test
+    public void testRestoreSome_for1Package_createsNonSystemRestoreTask() throws Exception {
+        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
+        setUpTransport(mTransport);
+        IRestoreSession restoreSession =
+                createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);
+
+        restoreSession.restoreSome(TOKEN_1, mObserver, mMonitor, new String[] {PACKAGE_1});
+
+        mShadowBackupLooper.runToEndOfTasks();
+        assertThat(ShadowPerformUnifiedRestoreTask.getLastCreated().isFullSystemRestore())
+                .isFalse();
+    }
+
+    @Test
+    public void testRestoreSome_whenNoRestoreSets() throws Exception {
+        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
+        setUpTransport(mTransport);
+        IRestoreSession restoreSession = createActiveRestoreSession(null, mTransport);
+
+        int result =
+                restoreSession.restoreSome(TOKEN_1, mObserver, mMonitor, new String[] {PACKAGE_1});
+
+        assertThat(result).isEqualTo(-1);
+    }
+
+    @Test
+    public void testRestoreSome_whenSinglePackageSession() throws Exception {
+        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
+        setUpTransport(mTransport);
+        IRestoreSession restoreSession =
+                createActiveRestoreSessionWithRestoreSets(PACKAGE_1, mTransport, mRestoreSet1);
+
+        int result =
+                restoreSession.restoreSome(TOKEN_1, mObserver, mMonitor, new String[] {PACKAGE_2});
+
+        assertThat(result).isEqualTo(-1);
+    }
+
+    @Test
+    public void testRestoreSome_whenSessionEnded() throws Exception {
+        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
+        setUpTransport(mTransport);
+        IRestoreSession restoreSession =
+                createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);
+        restoreSession.endRestoreSession();
+        mShadowBackupLooper.runToEndOfTasks();
+
+        expectThrows(
+                IllegalStateException.class,
+                () ->
+                        restoreSession.restoreSome(
+                                TOKEN_1, mObserver, mMonitor, new String[] {PACKAGE_1}));
+    }
+
+    @Test
+    public void testRestoreSome_whenTransportNotRegistered() throws Exception {
+        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
+        setUpTransport(mTransport.unregistered());
+        IRestoreSession restoreSession =
+                createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);
+
+        int result =
+                restoreSession.restoreSome(TOKEN_1, mObserver, mMonitor, new String[] {PACKAGE_1});
+
+        assertThat(result).isEqualTo(-1);
+    }
+
+    @Test
+    public void testRestorePackage_whenCallerIsPackage() throws Exception {
+        // No need for BACKUP permission in this case
+        mShadowApplication.denyPermissions(android.Manifest.permission.BACKUP);
+        ShadowBinder.setCallingUid(1);
+        setUpPackage(PACKAGE_1, /* uid */ 1);
+        when(mBackupManagerService.getAvailableRestoreToken(PACKAGE_1)).thenReturn(TOKEN_1);
+        TransportMock transportMock = setUpTransport(mTransport);
+        IRestoreSession restoreSession = createActiveRestoreSession(PACKAGE_1, mTransport);
+
+        int result = restoreSession.restorePackage(PACKAGE_1, mObserver, mMonitor);
+
+        mShadowBackupLooper.runToEndOfTasks();
+        assertThat(result).isEqualTo(0);
+        verify(mTransportManager)
+                .disposeOfTransportClient(eq(transportMock.transportClient), any());
+        assertThat(mWakeLock.isHeld()).isFalse();
+        assertThat(mBackupManagerService.isRestoreInProgress()).isFalse();
+        ShadowPerformUnifiedRestoreTask shadowTask =
+                ShadowPerformUnifiedRestoreTask.getLastCreated();
+        assertThat(shadowTask.isFullSystemRestore()).isFalse();
+        assertThat(shadowTask.getFilterSet()).isNull();
+        assertThat(shadowTask.getPackage().packageName).isEqualTo(PACKAGE_1);
+    }
+
+    @Test
+    public void testRestorePackage_whenPackageNullWhenCreated() throws Exception {
+        ShadowBinder.setCallingUid(1);
+        setUpPackage(PACKAGE_1, /* uid */ 1);
+        when(mBackupManagerService.getAvailableRestoreToken(PACKAGE_1)).thenReturn(TOKEN_1);
+        setUpTransport(mTransport);
+        IRestoreSession restoreSession = createActiveRestoreSession(null, mTransport);
+
+        int result = restoreSession.restorePackage(PACKAGE_1, mObserver, mMonitor);
+
+        mShadowBackupLooper.runToEndOfTasks();
+        assertThat(result).isEqualTo(0);
+    }
+
+    @Test
+    public void testRestorePackage_whenCallerIsNotPackageAndPermissionGranted() throws Exception {
+        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
+        ShadowBinder.setCallingUid(1);
+        setUpPackage(PACKAGE_1, /* uid */ 2);
+        when(mBackupManagerService.getAvailableRestoreToken(PACKAGE_1)).thenReturn(TOKEN_1);
+        setUpTransport(mTransport);
+        IRestoreSession restoreSession = createActiveRestoreSession(PACKAGE_1, mTransport);
+
+        int result = restoreSession.restorePackage(PACKAGE_1, mObserver, mMonitor);
+
+        mShadowBackupLooper.runToEndOfTasks();
+        assertThat(result).isEqualTo(0);
+    }
+
+    @Test
+    public void testRestorePackage_whenCallerIsNotPackageAndPermissionDenied() throws Exception {
+        mShadowApplication.denyPermissions(android.Manifest.permission.BACKUP);
+        ShadowBinder.setCallingUid(1);
+        setUpPackage(PACKAGE_1, /* uid */ 2);
+        when(mBackupManagerService.getAvailableRestoreToken(PACKAGE_1)).thenReturn(TOKEN_1);
+        setUpTransport(mTransport);
+        IRestoreSession restoreSession = createActiveRestoreSession(PACKAGE_1, mTransport);
+
+        expectThrows(
+                SecurityException.class,
+                () -> restoreSession.restorePackage(PACKAGE_1, mObserver, mMonitor));
+    }
+
+    @Test
+    public void testRestorePackage_whenPackageNotFound() throws Exception {
+        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
+        setUpPackage(PACKAGE_1, /* uid */ 1);
+        setUpTransport(mTransport);
+        IRestoreSession restoreSession = createActiveRestoreSession(null, mTransport);
+
+        int result = restoreSession.restorePackage(PACKAGE_2, mObserver, mMonitor);
+
+        assertThat(result).isEqualTo(-1);
+    }
+
+    @Test
+    public void testRestorePackage_whenSessionEnded() throws Exception {
+        ShadowBinder.setCallingUid(1);
+        setUpPackage(PACKAGE_1, /* uid */ 1);
+        setUpTransport(mTransport);
+        IRestoreSession restoreSession = createActiveRestoreSession(null, mTransport);
+        restoreSession.endRestoreSession();
+        mShadowBackupLooper.runToEndOfTasks();
+
+        expectThrows(
+                IllegalStateException.class,
+                () -> restoreSession.restorePackage(PACKAGE_1, mObserver, mMonitor));
+    }
+
+    @Test
+    public void testRestorePackage_whenTransportNotRegistered() throws Exception {
+        ShadowBinder.setCallingUid(1);
+        setUpPackage(PACKAGE_1, /* uid */ 1);
+        setUpTransport(mTransport.unregistered());
+        IRestoreSession restoreSession = createActiveRestoreSession(null, mTransport);
+
+        int result = restoreSession.restorePackage(PACKAGE_1, mObserver, mMonitor);
+
+        assertThat(result).isEqualTo(-1);
+    }
+
+    // TODO: Create a builder for PackageInfo/ApplicationInfo and unify usage with
+    //       TransportManagerTest
+    private void setUpPackage(String packageName, int uid) {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.packageName = packageName;
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.uid = uid;
+        mShadowPackageManager.addPackage(packageInfo);
+    }
+
     private IRestoreSession createActiveRestoreSession(
             String packageName, TransportData transport) {
         return new ActiveRestoreSession(
                 mBackupManagerService, packageName, transport.transportName);
     }
 
+    private IRestoreSession createActiveRestoreSessionWithRestoreSets(
+            String packageName, TransportData transport, RestoreSet... restoreSets)
+            throws RemoteException {
+        ActiveRestoreSession restoreSession =
+                new ActiveRestoreSession(
+                        mBackupManagerService, packageName, transport.transportName);
+        restoreSession.setRestoreSets(restoreSets);
+        return restoreSession;
+    }
+
     private TransportMock setUpTransport(TransportData transport) throws Exception {
         return TransportTestUtils.setUpTransport(mTransportManager, transport);
     }
diff --git a/services/robotests/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java b/services/robotests/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
index 3c0234b..c210fde 100644
--- a/services/robotests/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
+++ b/services/robotests/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
@@ -34,8 +34,9 @@
 
 import java.lang.Thread.UncaughtExceptionHandler;
 
+/** Test utils for {@link BackupManagerService} and friends. */
 public class BackupManagerServiceTestUtils {
-    /** Sets up a basic mocks for {@link BackupManagerService} */
+    /** Sets up basic mocks for {@link BackupManagerService}. */
     public static void setUpBackupManagerServiceBasics(
             BackupManagerService backupManagerService,
             Context context,
diff --git a/services/robotests/src/com/android/server/backup/testing/TransportTestUtils.java b/services/robotests/src/com/android/server/backup/testing/TransportTestUtils.java
index 565c7e6..c00a61d 100644
--- a/services/robotests/src/com/android/server/backup/testing/TransportTestUtils.java
+++ b/services/robotests/src/com/android/server/backup/testing/TransportTestUtils.java
@@ -115,6 +115,7 @@
                     .thenReturn(transportDirName);
             when(transportManager.getTransportDirName(eq(transportComponent)))
                     .thenReturn(transportDirName);
+            when(transportManager.isTransportRegistered(eq(transportName))).thenReturn(true);
             // TODO: Mock rest of description methods
         } else {
             // Transport not registered
@@ -127,6 +128,7 @@
                     .thenThrow(TransportNotRegisteredException.class);
             when(transportManager.getTransportDirName(eq(transportComponent)))
                     .thenThrow(TransportNotRegisteredException.class);
+            when(transportManager.isTransportRegistered(eq(transportName))).thenReturn(false);
         }
         return transportMock;
     }
diff --git a/services/robotests/src/com/android/server/testing/shadows/FrameworkShadowPackageManager.java b/services/robotests/src/com/android/server/testing/shadows/FrameworkShadowPackageManager.java
deleted file mode 100644
index 5cdbe7f..0000000
--- a/services/robotests/src/com/android/server/testing/shadows/FrameworkShadowPackageManager.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.testing.shadows;
-
-import android.app.ApplicationPackageManager;
-import android.content.Intent;
-import android.content.pm.ResolveInfo;
-import java.util.List;
-import org.robolectric.annotation.Implements;
-import org.robolectric.shadows.ShadowApplicationPackageManager;
-
-/** Extension of ShadowApplicationPackageManager */
-@Implements(value = ApplicationPackageManager.class, inheritImplementationMethods = true)
-public class FrameworkShadowPackageManager extends ShadowApplicationPackageManager {
-    @Override
-    public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
-        return queryIntentServices(intent, flags);
-    }
-}
diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowPerformUnifiedRestoreTask.java b/services/robotests/src/com/android/server/testing/shadows/ShadowPerformUnifiedRestoreTask.java
new file mode 100644
index 0000000..0f93c7a
--- /dev/null
+++ b/services/robotests/src/com/android/server/testing/shadows/ShadowPerformUnifiedRestoreTask.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.testing.shadows;
+
+import android.annotation.Nullable;
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IRestoreObserver;
+import android.content.pm.PackageInfo;
+
+import com.android.server.backup.BackupManagerService;
+import com.android.server.backup.internal.OnTaskFinishedListener;
+import com.android.server.backup.restore.PerformUnifiedRestoreTask;
+import com.android.server.backup.transport.TransportClient;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+@Implements(PerformUnifiedRestoreTask.class)
+public class ShadowPerformUnifiedRestoreTask {
+    @Nullable private static ShadowPerformUnifiedRestoreTask sLastShadow;
+
+    /**
+     * Retrieves the shadow for the last {@link PerformUnifiedRestoreTask} object created.
+     *
+     * @return The shadow or {@code null} if no object created since last {@link #reset()}.
+     */
+    @Nullable
+    public static ShadowPerformUnifiedRestoreTask getLastCreated() {
+        return sLastShadow;
+    }
+
+    public static void reset() {
+        sLastShadow = null;
+    }
+
+    private BackupManagerService mBackupManagerService;
+    @Nullable private PackageInfo mPackage;
+    private boolean mIsFullSystemRestore;
+    @Nullable private String[] mFilterSet;
+    private OnTaskFinishedListener mListener;
+
+    @Implementation
+    public void __constructor__(
+            BackupManagerService backupManagerService,
+            TransportClient transportClient,
+            IRestoreObserver observer,
+            IBackupManagerMonitor monitor,
+            long restoreSetToken,
+            @Nullable PackageInfo targetPackage,
+            int pmToken,
+            boolean isFullSystemRestore,
+            @Nullable String[] filterSet,
+            OnTaskFinishedListener listener) {
+        mBackupManagerService = backupManagerService;
+        mPackage = targetPackage;
+        mIsFullSystemRestore = isFullSystemRestore;
+        mFilterSet = filterSet;
+        mListener = listener;
+        sLastShadow = this;
+    }
+
+    @Implementation
+    public void execute() {
+        mBackupManagerService.setRestoreInProgress(false);
+        mListener.onFinished("ShadowPerformUnifiedRestoreTask.execute()");
+    }
+
+    public PackageInfo getPackage() {
+        return mPackage;
+    }
+
+    public String[] getFilterSet() {
+        return mFilterSet;
+    }
+
+    public boolean isFullSystemRestore() {
+        return mIsFullSystemRestore;
+    }
+}
diff --git a/services/tests/servicestests/Android.mk b/services/tests/servicestests/Android.mk
index b3fac48..356e64b 100644
--- a/services/tests/servicestests/Android.mk
+++ b/services/tests/servicestests/Android.mk
@@ -42,6 +42,7 @@
     android.test.base android.test.runner \
 
 LOCAL_PACKAGE_NAME := FrameworksServicesTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_COMPATIBILITY_SUITE := device-tests
 
 LOCAL_CERTIFICATE := platform
diff --git a/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java b/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java
index 90db2a3..b62f1ce 100644
--- a/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java
@@ -15,6 +15,9 @@
  */
 package com.android.server;
 
+import static android.app.usage.UsageStatsManager.REASON_MAIN_DEFAULT;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_USAGE;
+
 import static com.android.server.AppStateTracker.TARGET_OP;
 
 import static org.junit.Assert.assertEquals;
@@ -72,6 +75,7 @@
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.mockito.stubbing.Answer;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -187,6 +191,9 @@
 
     private final HashMap<String, Integer> mGlobalSettings = new HashMap<>();
 
+    private Answer<List<PackageOps>> mGetPackagesForOps =
+            inv -> new ArrayList<PackageOps>();
+
     @Before
     public void setUp() {
         mMainHandler = new Handler(Looper.getMainLooper());
@@ -226,7 +233,7 @@
                 .thenAnswer(inv -> getPowerSaveState());
         when(mMockAppOpsManager.getPackagesForOps(
                 any(int[].class)
-                )).thenAnswer(inv -> new ArrayList<AppOpsManager.PackageOps>());
+                )).thenAnswer(mGetPackagesForOps);
 
         mMockContentResolver = new MockContentResolver();
         when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver);
@@ -612,7 +619,7 @@
 
         // Exempt package 2 on user-10.
         mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 10, false,
-                UsageStatsManager.STANDBY_BUCKET_EXEMPTED);
+                UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT);
 
         areRestricted(instance, UID_1, PACKAGE_1, JOBS_AND_ALARMS);
         areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
@@ -624,7 +631,7 @@
 
         // Exempt package 1 on user-0.
         mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_1, /*user=*/ 0, false,
-                UsageStatsManager.STANDBY_BUCKET_EXEMPTED);
+                UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT);
 
         areRestricted(instance, UID_1, PACKAGE_1, NONE);
         areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
@@ -632,7 +639,7 @@
 
         // Unexempt package 2 on user-10.
         mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 10, false,
-                UsageStatsManager.STANDBY_BUCKET_ACTIVE);
+                UsageStatsManager.STANDBY_BUCKET_ACTIVE, REASON_MAIN_USAGE);
 
         areRestricted(instance, UID_1, PACKAGE_1, NONE);
         areRestricted(instance, UID_2, PACKAGE_2, JOBS_AND_ALARMS);
@@ -644,9 +651,9 @@
         mPowerSaveObserver.accept(getPowerSaveState());
 
         mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_1, /*user=*/ 0, false,
-                UsageStatsManager.STANDBY_BUCKET_EXEMPTED);
+                UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT);
         mAppIdleStateChangeListener.onAppIdleStateChanged(PACKAGE_2, /*user=*/ 0, false,
-                UsageStatsManager.STANDBY_BUCKET_EXEMPTED);
+                UsageStatsManager.STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT);
 
         setAppOps(UID_1, PACKAGE_1, true);
 
@@ -657,6 +664,7 @@
         areRestrictedWithExemption(instance, UID_2, PACKAGE_2, NONE);
     }
 
+    @Test
     public void loadPersistedAppOps() throws Exception {
         final AppStateTrackerTestable instance = newInstance();
 
@@ -700,6 +708,13 @@
 
         ops.add(new PackageOps(PACKAGE_3, UID_10_3, entries));
 
+        mGetPackagesForOps = inv -> {
+            final int[] arg = (int[]) inv.getArgument(0);
+            assertEquals(1, arg.length);
+            assertEquals(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, arg[0]);
+            return ops;
+        };
+
         callStart(instance);
 
         assertFalse(instance.isRunAnyInBackgroundAppOpsAllowed(UID_1, PACKAGE_1));
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index e1b4422..d31d550 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -26,6 +26,9 @@
 import static android.net.NetworkPolicyManager.POLICY_NONE;
 import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
 import static android.net.NetworkPolicyManager.uidPoliciesToString;
+import static android.net.NetworkStats.IFACE_ALL;
+import static android.net.NetworkStats.SET_ALL;
+import static android.net.NetworkStats.TAG_ALL;
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
 import static android.net.TrafficStats.MB_IN_BYTES;
 import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
@@ -42,8 +45,6 @@
 import static com.android.server.net.NetworkPolicyManagerService.TYPE_RAPID;
 import static com.android.server.net.NetworkPolicyManagerService.TYPE_WARNING;
 
-import static com.google.common.truth.Truth.assertThat;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -86,7 +87,6 @@
 import android.net.IConnectivityManager;
 import android.net.INetworkManagementEventObserver;
 import android.net.INetworkPolicyListener;
-import android.net.INetworkStatsService;
 import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkCapabilities;
@@ -105,6 +105,7 @@
 import android.os.PowerSaveState;
 import android.os.RemoteException;
 import android.os.SimpleClock;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
@@ -125,6 +126,7 @@
 import com.android.internal.util.test.BroadcastInterceptingContext.FutureIntent;
 import com.android.server.net.NetworkPolicyManagerInternal;
 import com.android.server.net.NetworkPolicyManagerService;
+import com.android.server.net.NetworkStatsManagerInternal;
 
 import libcore.io.IoUtils;
 import libcore.io.Streams;
@@ -214,7 +216,6 @@
     private String mNetpolicyXml;
 
     private @Mock IActivityManager mActivityManager;
-    private @Mock INetworkStatsService mStatsService;
     private @Mock INetworkManagementService mNetworkManager;
     private @Mock IConnectivityManager mConnManager;
     private @Mock NotificationManager mNotifManager;
@@ -224,7 +225,8 @@
     private @Mock CarrierConfigManager mCarrierConfigManager;
     private @Mock TelephonyManager mTelephonyManager;
 
-    private static ActivityManagerInternal mActivityManagerInternal;
+    private ActivityManagerInternal mActivityManagerInternal;
+    private NetworkStatsManagerInternal mStatsService;
 
     private IUidObserver mUidObserver;
     private INetworkManagementEventObserver mNetworkObserver;
@@ -264,6 +266,8 @@
     private static final int UID_F = UserHandle.getUid(USER_ID, APP_ID_F);
 
     private static final String PKG_NAME_A = "name.is.A,pkg.A";
+    private static final String PKG_NAME_B = "name.is.B,pkg.B";
+    private static final String PKG_NAME_C = "name.is.C,pkg.C";
 
     public final @Rule NetPolicyMethodRule mNetPolicyXmlRule = new NetPolicyMethodRule();
 
@@ -287,6 +291,8 @@
                 .setBatterySaverEnabled(false).build();
         final PowerManagerInternal pmInternal = addLocalServiceMock(PowerManagerInternal.class);
         when(pmInternal.getLowPowerState(anyInt())).thenReturn(state);
+
+        mStatsService = addLocalServiceMock(NetworkStatsManagerInternal.class);
     }
 
     @Before
@@ -347,7 +353,7 @@
                 eq(ActivityManager.PROCESS_STATE_UNKNOWN), isNull(String.class));
 
         mFutureIntent = newRestrictBackgroundChangedFuture();
-        mService = new NetworkPolicyManagerService(mServiceContext, mActivityManager, mStatsService,
+        mService = new NetworkPolicyManagerService(mServiceContext, mActivityManager,
                 mNetworkManager, mIpm, mClock, mPolicyDir, true);
         mService.bindConnectivityManager(mConnManager);
         mPolicyListener = new NetworkPolicyListenerAnswer(mService);
@@ -375,6 +381,14 @@
         when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
                 .thenReturn(new ApplicationInfo());
         when(mPackageManager.getPackagesForUid(UID_A)).thenReturn(new String[] {PKG_NAME_A});
+        when(mPackageManager.getPackagesForUid(UID_B)).thenReturn(new String[] {PKG_NAME_B});
+        when(mPackageManager.getPackagesForUid(UID_C)).thenReturn(new String[] {PKG_NAME_C});
+        when(mPackageManager.getApplicationInfo(eq(PKG_NAME_A), anyInt()))
+                .thenReturn(buildApplicationInfo(PKG_NAME_A));
+        when(mPackageManager.getApplicationInfo(eq(PKG_NAME_B), anyInt()))
+                .thenReturn(buildApplicationInfo(PKG_NAME_B));
+        when(mPackageManager.getApplicationInfo(eq(PKG_NAME_C), anyInt()))
+                .thenReturn(buildApplicationInfo(PKG_NAME_C));
         when(mNetworkManager.isBandwidthControlEnabled()).thenReturn(true);
         when(mNetworkManager.setDataSaverModeEnabled(anyBoolean())).thenReturn(true);
 
@@ -409,6 +423,7 @@
         LocalServices.removeServiceForTest(PowerManagerInternal.class);
         LocalServices.removeServiceForTest(DeviceIdleController.LocalService.class);
         LocalServices.removeServiceForTest(UsageStatsManagerInternal.class);
+        LocalServices.removeServiceForTest(NetworkStatsManagerInternal.class);
     }
 
     @After
@@ -515,7 +530,7 @@
         mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
 
         // RestrictBackground should be on even though battery saver want to turn it off
-        assertThat(mService.getRestrictBackground()).isTrue();
+        assertTrue(mService.getRestrictBackground());
 
         PowerSaveState stateOff = new PowerSaveState.Builder()
                 .setGlobalBatterySaverEnabled(false)
@@ -524,7 +539,7 @@
         mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
 
         // RestrictBackground should be on, following its previous state
-        assertThat(mService.getRestrictBackground()).isTrue();
+        assertTrue(mService.getRestrictBackground());
     }
 
     @Test
@@ -539,7 +554,7 @@
         mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
 
         // RestrictBackground should be turned on because of battery saver
-        assertThat(mService.getRestrictBackground()).isTrue();
+        assertTrue(mService.getRestrictBackground());
 
         PowerSaveState stateOff = new PowerSaveState.Builder()
                 .setGlobalBatterySaverEnabled(false)
@@ -548,7 +563,7 @@
         mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
 
         // RestrictBackground should be off, following its previous state
-        assertThat(mService.getRestrictBackground()).isFalse();
+        assertFalse(mService.getRestrictBackground());
     }
 
     @Test
@@ -562,7 +577,7 @@
         mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
 
         // RestrictBackground should still be on
-        assertThat(mService.getRestrictBackground()).isTrue();
+        assertTrue(mService.getRestrictBackground());
 
         // User turns off RestrictBackground manually
         setRestrictBackground(false);
@@ -571,7 +586,7 @@
         mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
 
         // RestrictBackground should be off because user changes it manually
-        assertThat(mService.getRestrictBackground()).isFalse();
+        assertFalse(mService.getRestrictBackground());
     }
 
     private void removeRestrictBackgroundWhitelist(boolean expectIntent) throws Exception {
@@ -974,6 +989,7 @@
     public void testNotificationWarningLimitSnooze() throws Exception {
         // Create a place to store fake usage
         final NetworkStatsHistory history = new NetworkStatsHistory(TimeUnit.HOURS.toMillis(1));
+        final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
         when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
                 .thenAnswer(new Answer<Long>() {
                     @Override
@@ -983,6 +999,13 @@
                         return entry.rxBytes + entry.txBytes;
                     }
                 });
+        when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong()))
+                .thenAnswer(new Answer<NetworkStats>() {
+                    @Override
+                    public NetworkStats answer(InvocationOnMock invocation) throws Throwable {
+                        return stats;
+                    }
+                });
 
         // Get active mobile network in place
         expectMobileDefaults();
@@ -1003,7 +1026,7 @@
 
         // Normal usage means no notification
         {
-            history.removeBucketsBefore(Long.MAX_VALUE);
+            history.clear();
             history.recordData(start, end,
                     new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(360), 0L, 0L, 0L, 0));
 
@@ -1020,7 +1043,7 @@
 
         // Push over warning
         {
-            history.removeBucketsBefore(Long.MAX_VALUE);
+            history.clear();
             history.recordData(start, end,
                     new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1799), 0L, 0L, 0L, 0));
 
@@ -1038,7 +1061,7 @@
 
         // Push over limit
         {
-            history.removeBucketsBefore(Long.MAX_VALUE);
+            history.clear();
             history.recordData(start, end,
                     new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1810), 0L, 0L, 0L, 0));
 
@@ -1073,6 +1096,7 @@
     public void testNotificationRapid() throws Exception {
         // Create a place to store fake usage
         final NetworkStatsHistory history = new NetworkStatsHistory(TimeUnit.HOURS.toMillis(1));
+        final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
         when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
                 .thenAnswer(new Answer<Long>() {
                     @Override
@@ -1082,6 +1106,13 @@
                         return entry.rxBytes + entry.txBytes;
                     }
                 });
+        when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong()))
+                .thenAnswer(new Answer<NetworkStats>() {
+                    @Override
+                    public NetworkStats answer(InvocationOnMock invocation) throws Throwable {
+                        return stats;
+                    }
+                });
 
         // Get active mobile network in place
         expectMobileDefaults();
@@ -1102,7 +1133,7 @@
 
         // Using 20% data in 20% time is normal
         {
-            history.removeBucketsBefore(Long.MAX_VALUE);
+            history.clear();
             history.recordData(start, end,
                     new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(360), 0L, 0L, 0L, 0));
 
@@ -1111,16 +1142,58 @@
             verify(mNotifManager, never()).notifyAsUser(any(), anyInt(), any(), any());
         }
 
-        // Using 80% data in 20% time is alarming
+        // Using 80% data in 20% time is alarming; but spread equally among
+        // three UIDs means we get generic alert
         {
-            history.removeBucketsBefore(Long.MAX_VALUE);
+            history.clear();
             history.recordData(start, end,
                     new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1440), 0L, 0L, 0L, 0));
+            stats.clear();
+            stats.addValues(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
+                    DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
+            stats.addValues(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
+                    DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
+            stats.addValues(IFACE_ALL, UID_C, SET_ALL, TAG_ALL,
+                    DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
 
             reset(mNotifManager);
             mService.updateNetworks();
+
+            final ArgumentCaptor<Notification> notif = ArgumentCaptor.forClass(Notification.class);
             verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_RAPID),
-                    isA(Notification.class), eq(UserHandle.ALL));
+                    notif.capture(), eq(UserHandle.ALL));
+
+            final String text = notif.getValue().extras.getCharSequence(Notification.EXTRA_TEXT)
+                    .toString();
+            assertFalse(text.contains(PKG_NAME_A));
+            assertFalse(text.contains(PKG_NAME_B));
+            assertFalse(text.contains(PKG_NAME_C));
+        }
+
+        // Using 80% data in 20% time is alarming; but mostly done by one UID
+        // means we get specific alert
+        {
+            history.clear();
+            history.recordData(start, end,
+                    new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1440), 0L, 0L, 0L, 0));
+            stats.clear();
+            stats.addValues(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
+                    DataUnit.MEGABYTES.toBytes(960), 0, 0, 0, 0);
+            stats.addValues(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
+                    DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
+
+            reset(mNotifManager);
+            mService.updateNetworks();
+
+            final ArgumentCaptor<Notification> notif = ArgumentCaptor.forClass(Notification.class);
+            verify(mNotifManager, atLeastOnce()).notifyAsUser(any(), eq(TYPE_RAPID),
+                    notif.capture(), eq(UserHandle.ALL));
+
+            final String text = notif.getValue().extras.getCharSequence(Notification.EXTRA_TEXT)
+                    .toString();
+            assertTrue(text.contains(PKG_NAME_A));
+            assertFalse(text.contains(PKG_NAME_B));
+            assertFalse(text.contains(PKG_NAME_C));
         }
     }
 
@@ -1411,6 +1484,12 @@
                 true);
     }
 
+    private ApplicationInfo buildApplicationInfo(String label) {
+        final ApplicationInfo ai = new ApplicationInfo();
+        ai.nonLocalizedLabel = label;
+        return ai;
+    }
+
     private NetworkInfo buildNetworkInfo() {
         final NetworkInfo ni = new NetworkInfo(ConnectivityManager.TYPE_MOBILE,
                 TelephonyManager.NETWORK_TYPE_LTE, null, null);
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
index d3df924..a527e17 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
@@ -22,6 +22,8 @@
 import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
 import static android.view.Display.DEFAULT_DISPLAY;
 
+import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
+import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
 import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING;
 import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
 import static com.android.server.am.ActivityStack.ActivityState.STOPPED;
@@ -51,6 +53,7 @@
 
 import org.junit.runner.RunWith;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.mockito.invocation.InvocationOnMock;
 
@@ -108,8 +111,7 @@
         assertEquals(mStack.onActivityRemovedFromStackInvocationCount(), 0);
     }
 
-    // TODO: b/71582913
-    //@Test
+    @Test
     public void testPausingWhenVisibleFromStopped() throws Exception {
         final MutableBoolean pauseFound = new MutableBoolean(false);
         doAnswer((InvocationOnMock invocationOnMock) -> {
@@ -119,20 +121,20 @@
             }
             return null;
         }).when(mActivity.app.thread).scheduleTransaction(any());
-        mActivity.state = STOPPED;
+        mActivity.setState(STOPPED, "testPausingWhenVisibleFromStopped");
 
         mActivity.makeVisibleIfNeeded(null /* starting */);
 
-        assertEquals(mActivity.state, PAUSING);
+        assertTrue(mActivity.isState(PAUSING));
 
         assertTrue(pauseFound.value);
 
         // Make sure that the state does not change for current non-stopping states.
-        mActivity.state = INITIALIZING;
+        mActivity.setState(INITIALIZING, "testPausingWhenVisibleFromStopped");
 
         mActivity.makeVisibleIfNeeded(null /* starting */);
 
-        assertEquals(mActivity.state, INITIALIZING);
+        assertTrue(mActivity.isState(INITIALIZING));
     }
 
     @Test
@@ -159,7 +161,7 @@
         when(mService.mWindowManager.getNavBarPosition()).thenReturn(navBarPosition);
         mTask.getConfiguration().windowConfiguration.setAppBounds(taskBounds);
         mActivity.info.maxAspectRatio = aspectRatio;
-        mActivity.ensureActivityConfigurationLocked(
+        mActivity.ensureActivityConfiguration(
                 0 /* globalChanges */, false /* preserveWindow */);
         assertEquals(expectedActivityBounds, mActivity.getBounds());
     }
@@ -197,7 +199,7 @@
         record.canBeLaunchedOnDisplay(DEFAULT_DISPLAY);
 
 
-        verify(mService.mStackSupervisor, times(1)).canPlaceEntityOnDisplay(anyInt(), eq(expected), anyInt(), anyInt(),
-                eq(record.info));
+        verify(mService.mStackSupervisor, times(1)).canPlaceEntityOnDisplay(anyInt(), eq(expected),
+                anyInt(), anyInt(), eq(record.info));
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
index ce3528b..c62820e 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
@@ -408,6 +408,10 @@
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
         final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(display,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final TestActivityStack fullscreenStack3 = createStackForShouldBeVisibleTest(display,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final TestActivityStack fullscreenStack4 = createStackForShouldBeVisibleTest(display,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
         final TestActivityStack homeStack = createStackForShouldBeVisibleTest(display,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
 
@@ -415,6 +419,10 @@
         assertTrue(display.getStackAboveHome() == fullscreenStack1);
         display.moveHomeStackBehindStack(fullscreenStack2);
         assertTrue(display.getStackAboveHome() == fullscreenStack2);
+        display.moveHomeStackBehindStack(fullscreenStack4);
+        assertTrue(display.getStackAboveHome() == fullscreenStack4);
+        display.moveHomeStackBehindStack(fullscreenStack2);
+        assertTrue(display.getStackAboveHome() == fullscreenStack2);
     }
 
     private <T extends ActivityStack> T createStackForShouldBeVisibleTest(
diff --git a/services/tests/servicestests/src/com/android/server/appops/AppOpsServiceTest.java b/services/tests/servicestests/src/com/android/server/appops/AppOpsServiceTest.java
new file mode 100644
index 0000000..ad21a78
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/appops/AppOpsServiceTest.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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;
+
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.MODE_ERRORED;
+import static android.app.AppOpsManager.OP_READ_SMS;
+import static android.app.AppOpsManager.OP_WRITE_SMS;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.app.AppOpsManager.OpEntry;
+import android.app.AppOpsManager.PackageOps;
+import android.content.Context;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Process;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Unit tests for AppOpsService. Covers functionality that is difficult to test using CTS tests
+ * or for which we can write more detailed unit tests than CTS tests (because the internal APIs are
+ * more finegrained data than the public ones).
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AppOpsServiceTest {
+
+    private static final String TAG = AppOpsServiceTest.class.getSimpleName();
+    // State will be persisted into this XML file.
+    private static final String APP_OPS_FILENAME = "appops-service-test.xml";
+
+    private File mAppOpsFile;
+    private Context mContext;
+    private Handler mHandler;
+    private AppOpsService mAppOpsService;
+    private String mMyPackageName;
+    private int mMyUid;
+    private long mTestStartMillis;
+
+    @Before
+    public void setUp() {
+        mContext = InstrumentationRegistry.getTargetContext();
+        mAppOpsFile = new File(mContext.getFilesDir(), APP_OPS_FILENAME);
+        if (mAppOpsFile.exists()) {
+            // Start with a clean state (persisted into XML).
+            mAppOpsFile.delete();
+        }
+
+        HandlerThread handlerThread = new HandlerThread(TAG);
+        handlerThread.start();
+        mHandler = new Handler(handlerThread.getLooper());
+        mMyPackageName = mContext.getOpPackageName();
+        mMyUid = Process.myUid();
+
+        mAppOpsService = new AppOpsService(mAppOpsFile, mHandler);
+        mAppOpsService.mContext = mContext;
+        mTestStartMillis = System.currentTimeMillis();
+    }
+
+    @Test
+    public void testGetOpsForPackage_noOpsLogged() {
+        assertThat(getLoggedOps()).isNull();
+    }
+
+    @Test
+    public void testNoteOperationAndGetOpsForPackage() {
+        mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED);
+        mAppOpsService.setMode(OP_WRITE_SMS, mMyUid, mMyPackageName, MODE_ERRORED);
+
+        // Note an op that's allowed.
+        mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName);
+        List<PackageOps> loggedOps = getLoggedOps();
+        assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
+
+        // Note another op that's not allowed.
+        mAppOpsService.noteOperation(OP_WRITE_SMS, mMyUid, mMyPackageName);
+        loggedOps = getLoggedOps();
+        assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
+        assertContainsOp(loggedOps, OP_WRITE_SMS, -1, mTestStartMillis, MODE_ERRORED);
+    }
+
+    // Tests the dumping and restoring of the in-memory state to/from XML.
+    @Test
+    public void testStatePersistence() {
+        mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED);
+        mAppOpsService.setMode(OP_WRITE_SMS, mMyUid, mMyPackageName, MODE_ERRORED);
+        mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName);
+        mAppOpsService.noteOperation(OP_WRITE_SMS, mMyUid, mMyPackageName);
+        mAppOpsService.writeState();
+
+        // Create a new app ops service, and initialize its state from XML.
+        mAppOpsService = new AppOpsService(mAppOpsFile, mHandler);
+        mAppOpsService.mContext = mContext;
+        mAppOpsService.readState();
+
+        // Query the state of the 2nd service.
+        List<PackageOps> loggedOps = getLoggedOps();
+        assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
+        assertContainsOp(loggedOps, OP_WRITE_SMS, -1, mTestStartMillis, MODE_ERRORED);
+    }
+
+    // Tests that ops are persisted during shutdown.
+    @Test
+    public void testShutdown() {
+        mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED);
+        mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName);
+        mAppOpsService.shutdown();
+
+        // Create a new app ops service, and initialize its state from XML.
+        mAppOpsService = new AppOpsService(mAppOpsFile, mHandler);
+        mAppOpsService.mContext = mContext;
+        mAppOpsService.readState();
+
+        // Query the state of the 2nd service.
+        List<PackageOps> loggedOps = getLoggedOps();
+        assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
+    }
+
+    @Test
+    public void testGetOpsForPackage() {
+        mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED);
+        mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName);
+
+        // Query all ops
+        List<PackageOps> loggedOps = mAppOpsService.getOpsForPackage(
+                mMyUid, mMyPackageName, null /* all ops */);
+        assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
+
+        // Query specific ops
+        loggedOps = mAppOpsService.getOpsForPackage(
+                mMyUid, mMyPackageName, new int[]{OP_READ_SMS, OP_WRITE_SMS});
+        assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
+
+        // Query unknown UID
+        loggedOps = mAppOpsService.getOpsForPackage(mMyUid + 1, mMyPackageName, null /* all ops */);
+        assertThat(loggedOps).isNull();
+
+        // Query unknown package name
+        loggedOps = mAppOpsService.getOpsForPackage(mMyUid, "fake.package", null /* all ops */);
+        assertThat(loggedOps).isNull();
+
+        // Query op code that's not been logged
+        loggedOps = mAppOpsService.getOpsForPackage(mMyUid, mMyPackageName,
+                new int[]{OP_WRITE_SMS});
+        assertThat(loggedOps).isNull();
+    }
+
+    @Test
+    public void testPackageRemoved() {
+        mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED);
+        mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName);
+
+        List<PackageOps> loggedOps = getLoggedOps();
+        assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
+
+        mAppOpsService.packageRemoved(mMyUid, mMyPackageName);
+        assertThat(getLoggedOps()).isNull();
+    }
+
+    @Test
+    public void testUidRemoved() {
+        mAppOpsService.setMode(OP_READ_SMS, mMyUid, mMyPackageName, MODE_ALLOWED);
+        mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, mMyPackageName);
+
+        List<PackageOps> loggedOps = getLoggedOps();
+        assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
+
+        mAppOpsService.uidRemoved(mMyUid);
+        assertThat(getLoggedOps()).isNull();
+    }
+
+    private List<PackageOps> getLoggedOps() {
+        return mAppOpsService.getOpsForPackage(mMyUid, mMyPackageName, null /* all ops */);
+    }
+
+    private void assertContainsOp(List<PackageOps> loggedOps, int opCode, long minMillis,
+            long minRejectMillis, int mode) {
+
+        boolean opLogged = false;
+        for (PackageOps pkgOps : loggedOps) {
+            assertWithMessage("Unexpected UID").that(mMyUid).isEqualTo(pkgOps.getUid());
+            assertWithMessage("Unexpected package name").that(mMyPackageName).isEqualTo(
+                    pkgOps.getPackageName());
+
+            for (OpEntry opEntry : pkgOps.getOps()) {
+                if (opCode != opEntry.getOp()) {
+                    continue;
+                }
+                opLogged = true;
+
+                assertWithMessage("Unexpected mode").that(mode).isEqualTo(opEntry.getMode());
+                if (minMillis > 0) {
+                    assertWithMessage("Unexpected timestamp")
+                            .that(opEntry.getTime()).isAtLeast(minMillis);
+                }
+                if (minRejectMillis > 0) {
+                    assertWithMessage("Unexpected rejection timestamp")
+                            .that(opEntry.getRejectTime()).isAtLeast(minRejectMillis);
+                }
+            }
+        }
+        assertWithMessage("Op was not logged").that(opLogged).isTrue();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java
index 86c83d6..8ccacb8 100644
--- a/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java
@@ -18,9 +18,14 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.Signature;
 import android.os.Process;
 import android.platform.test.annotations.Presubmit;
@@ -30,6 +35,7 @@
 import com.android.server.backup.BackupManagerService;
 import com.android.server.backup.testutils.PackageManagerStub;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -45,7 +51,14 @@
     private static final Signature SIGNATURE_3 = generateSignature((byte) 3);
     private static final Signature SIGNATURE_4 = generateSignature((byte) 4);
 
-    private final PackageManagerStub mPackageManagerStub = new PackageManagerStub();
+    private PackageManagerStub mPackageManagerStub;
+    private PackageManagerInternal mMockPackageManagerInternal;
+
+    @Before
+    public void setUp() throws Exception {
+        mPackageManagerStub = new PackageManagerStub();
+        mMockPackageManagerInternal = mock(PackageManagerInternal.class);
+    }
 
     @Test
     public void appIsEligibleForBackup_backupNotAllowed_returnsFalse() throws Exception {
@@ -358,7 +371,8 @@
 
     @Test
     public void signaturesMatch_targetIsNull_returnsFalse() throws Exception {
-        boolean result = AppBackupUtils.signaturesMatch(new Signature[] {SIGNATURE_1}, null);
+        boolean result = AppBackupUtils.signaturesMatch(new Signature[] {SIGNATURE_1}, null,
+                mMockPackageManagerInternal);
 
         assertThat(result).isFalse();
     }
@@ -369,7 +383,8 @@
         packageInfo.applicationInfo = new ApplicationInfo();
         packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
 
-        boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo);
+        boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo,
+                mMockPackageManagerInternal);
 
         assertThat(result).isTrue();
     }
@@ -378,10 +393,11 @@
     public void signaturesMatch_disallowsUnsignedApps_storedSignatureNull_returnsFalse()
             throws Exception {
         PackageInfo packageInfo = new PackageInfo();
-        packageInfo.signatures = new Signature[] {SIGNATURE_1};
+        packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}};
         packageInfo.applicationInfo = new ApplicationInfo();
 
-        boolean result = AppBackupUtils.signaturesMatch(null, packageInfo);
+        boolean result = AppBackupUtils.signaturesMatch(null, packageInfo,
+                mMockPackageManagerInternal);
 
         assertThat(result).isFalse();
     }
@@ -390,10 +406,11 @@
     public void signaturesMatch_disallowsUnsignedApps_storedSignatureEmpty_returnsFalse()
             throws Exception {
         PackageInfo packageInfo = new PackageInfo();
-        packageInfo.signatures = new Signature[] {SIGNATURE_1};
+        packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}};
         packageInfo.applicationInfo = new ApplicationInfo();
 
-        boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo);
+        boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo,
+                mMockPackageManagerInternal);
 
         assertThat(result).isFalse();
     }
@@ -404,11 +421,11 @@
     signaturesMatch_disallowsUnsignedApps_targetSignatureEmpty_returnsFalse()
             throws Exception {
         PackageInfo packageInfo = new PackageInfo();
-        packageInfo.signatures = new Signature[0];
+        packageInfo.signingCertificateHistory = new Signature[0][0];
         packageInfo.applicationInfo = new ApplicationInfo();
 
-        boolean result = AppBackupUtils.signaturesMatch(new Signature[] {SIGNATURE_1},
-                packageInfo);
+        boolean result = AppBackupUtils.signaturesMatch(new Signature[] {SIGNATURE_1}, packageInfo,
+                mMockPackageManagerInternal);
 
         assertThat(result).isFalse();
     }
@@ -418,11 +435,11 @@
     signaturesMatch_disallowsUnsignedApps_targetSignatureNull_returnsFalse()
             throws Exception {
         PackageInfo packageInfo = new PackageInfo();
-        packageInfo.signatures = null;
+        packageInfo.signingCertificateHistory = null;
         packageInfo.applicationInfo = new ApplicationInfo();
 
-        boolean result = AppBackupUtils.signaturesMatch(new Signature[] {SIGNATURE_1},
-                packageInfo);
+        boolean result = AppBackupUtils.signaturesMatch(new Signature[] {SIGNATURE_1}, packageInfo,
+                mMockPackageManagerInternal);
 
         assertThat(result).isFalse();
     }
@@ -431,10 +448,11 @@
     public void signaturesMatch_disallowsUnsignedApps_bothSignaturesNull_returnsFalse()
             throws Exception {
         PackageInfo packageInfo = new PackageInfo();
-        packageInfo.signatures = null;
+        packageInfo.signingCertificateHistory = null;
         packageInfo.applicationInfo = new ApplicationInfo();
 
-        boolean result = AppBackupUtils.signaturesMatch(null, packageInfo);
+        boolean result = AppBackupUtils.signaturesMatch(null, packageInfo,
+                mMockPackageManagerInternal);
 
         assertThat(result).isFalse();
     }
@@ -443,10 +461,11 @@
     public void signaturesMatch_disallowsUnsignedApps_bothSignaturesEmpty_returnsFalse()
             throws Exception {
         PackageInfo packageInfo = new PackageInfo();
-        packageInfo.signatures = new Signature[0];
+        packageInfo.signingCertificateHistory = new Signature[0][0];
         packageInfo.applicationInfo = new ApplicationInfo();
 
-        boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo);
+        boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo,
+                mMockPackageManagerInternal);
 
         assertThat(result).isFalse();
     }
@@ -458,11 +477,14 @@
         Signature signature3Copy = new Signature(SIGNATURE_3.toByteArray());
 
         PackageInfo packageInfo = new PackageInfo();
-        packageInfo.signatures = new Signature[]{SIGNATURE_1, SIGNATURE_2, SIGNATURE_3};
+        packageInfo.signingCertificateHistory = new Signature[][] {
+                {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}
+        };
         packageInfo.applicationInfo = new ApplicationInfo();
 
         boolean result = AppBackupUtils.signaturesMatch(
-                new Signature[]{signature3Copy, signature1Copy, signature2Copy}, packageInfo);
+                new Signature[] {signature3Copy, signature1Copy, signature2Copy}, packageInfo,
+                mMockPackageManagerInternal);
 
         assertThat(result).isTrue();
     }
@@ -473,11 +495,14 @@
         Signature signature2Copy = new Signature(SIGNATURE_2.toByteArray());
 
         PackageInfo packageInfo = new PackageInfo();
-        packageInfo.signatures = new Signature[]{SIGNATURE_1, SIGNATURE_2, SIGNATURE_3};
+        packageInfo.signingCertificateHistory = new Signature[][] {
+                {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}
+        };
         packageInfo.applicationInfo = new ApplicationInfo();
 
         boolean result = AppBackupUtils.signaturesMatch(
-                new Signature[]{signature2Copy, signature1Copy}, packageInfo);
+                new Signature[]{signature2Copy, signature1Copy}, packageInfo,
+                mMockPackageManagerInternal);
 
         assertThat(result).isTrue();
     }
@@ -488,11 +513,14 @@
         Signature signature2Copy = new Signature(SIGNATURE_2.toByteArray());
 
         PackageInfo packageInfo = new PackageInfo();
-        packageInfo.signatures = new Signature[]{signature1Copy, signature2Copy};
+        packageInfo.signingCertificateHistory = new Signature[][] {
+                {signature1Copy, signature2Copy}
+        };
         packageInfo.applicationInfo = new ApplicationInfo();
 
         boolean result = AppBackupUtils.signaturesMatch(
-                new Signature[]{SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}, packageInfo);
+                new Signature[]{SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}, packageInfo,
+                mMockPackageManagerInternal);
 
         assertThat(result).isFalse();
     }
@@ -503,11 +531,76 @@
         Signature signature2Copy = new Signature(SIGNATURE_2.toByteArray());
 
         PackageInfo packageInfo = new PackageInfo();
-        packageInfo.signatures = new Signature[]{SIGNATURE_1, SIGNATURE_2, SIGNATURE_3};
+        packageInfo.signingCertificateHistory = new Signature[][] {
+                {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}
+        };
         packageInfo.applicationInfo = new ApplicationInfo();
 
         boolean result = AppBackupUtils.signaturesMatch(
-                new Signature[]{signature1Copy, signature2Copy, SIGNATURE_4}, packageInfo);
+                new Signature[]{signature1Copy, signature2Copy, SIGNATURE_4}, packageInfo,
+                mMockPackageManagerInternal);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void signaturesMatch_singleStoredSignatureNoRotation_returnsTrue()
+            throws Exception {
+        Signature signature1Copy = new Signature(SIGNATURE_1.toByteArray());
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.packageName = "test";
+        packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}};
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(signature1Copy,
+                packageInfo.packageName);
+
+        boolean result = AppBackupUtils.signaturesMatch(new Signature[] {signature1Copy},
+                packageInfo, mMockPackageManagerInternal);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void signaturesMatch_singleStoredSignatureWithRotationAssumeDataCapability_returnsTrue()
+            throws Exception {
+        Signature signature1Copy = new Signature(SIGNATURE_1.toByteArray());
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.packageName = "test";
+        packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}, {SIGNATURE_2}};
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        // we know signature1Copy is in history, and we want to assume it has
+        // SigningDetails.CertCapabilities.INSTALLED_DATA capability
+        doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(signature1Copy,
+                packageInfo.packageName);
+
+        boolean result = AppBackupUtils.signaturesMatch(new Signature[] {signature1Copy},
+                packageInfo, mMockPackageManagerInternal);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void
+            signaturesMatch_singleStoredSignatureWithRotationAssumeNoDataCapability_returnsFalse()
+            throws Exception {
+        Signature signature1Copy = new Signature(SIGNATURE_1.toByteArray());
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.packageName = "test";
+        packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}, {SIGNATURE_2}};
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        // we know signature1Copy is in history, but we want to assume it does not have
+        // SigningDetails.CertCapabilities.INSTALLED_DATA capability
+        doReturn(false).when(mMockPackageManagerInternal).isDataRestoreSafe(signature1Copy,
+                packageInfo.packageName);
+
+        boolean result = AppBackupUtils.signaturesMatch(new Signature[] {signature1Copy},
+                packageInfo, mMockPackageManagerInternal);
 
         assertThat(result).isFalse();
     }
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
index 0cdf04b..5f052ce 100644
--- a/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
@@ -28,6 +28,9 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.verifyZeroInteractions;
@@ -37,6 +40,7 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.Signature;
 import android.os.Bundle;
 import android.os.Process;
@@ -79,6 +83,7 @@
 
     @Mock private BytesReadListener mBytesReadListenerMock;
     @Mock private IBackupManagerMonitor mBackupManagerMonitorMock;
+    @Mock private PackageManagerInternal mMockPackageManagerInternal;
 
     private final PackageManagerStub mPackageManagerStub = new PackageManagerStub();
     private Context mContext;
@@ -139,7 +144,8 @@
         Signature[] signatures = tarBackupReader.readAppManifestAndReturnSignatures(
                 fileMetadata);
         RestorePolicy restorePolicy = tarBackupReader.chooseRestorePolicy(
-                mPackageManagerStub, false /* allowApks */, fileMetadata, signatures);
+                mPackageManagerStub, false /* allowApks */, fileMetadata, signatures,
+                mMockPackageManagerInternal);
 
         assertThat(restorePolicy).isEqualTo(RestorePolicy.IGNORE);
         assertThat(fileMetadata.packageName).isEqualTo(TEST_PACKAGE_NAME);
@@ -152,7 +158,8 @@
         signatures = tarBackupReader.readAppManifestAndReturnSignatures(
                 fileMetadata);
         restorePolicy = tarBackupReader.chooseRestorePolicy(
-                mPackageManagerStub, false /* allowApks */, fileMetadata, signatures);
+                mPackageManagerStub, false /* allowApks */, fileMetadata, signatures,
+                mMockPackageManagerInternal);
 
         assertThat(restorePolicy).isEqualTo(RestorePolicy.IGNORE);
         assertThat(fileMetadata.packageName).isEqualTo(TEST_PACKAGE_NAME);
@@ -214,7 +221,8 @@
                 mBytesReadListenerMock, mBackupManagerMonitorMock);
 
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
-                true /* allowApks */, new FileMetadata(), null /* signatures */);
+                true /* allowApks */, new FileMetadata(), null /* signatures */,
+                mMockPackageManagerInternal);
 
         assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
         verifyZeroInteractions(mBackupManagerMonitorMock);
@@ -234,7 +242,8 @@
         PackageManagerStub.sPackageInfo = null;
 
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
-                true /* allowApks */, info, new Signature[0] /* signatures */);
+                true /* allowApks */, info, new Signature[0] /* signatures */,
+                mMockPackageManagerInternal);
 
         assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK);
         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
@@ -258,7 +267,8 @@
         PackageManagerStub.sPackageInfo = null;
 
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
-                true /* allowApks */, info, new Signature[0] /* signatures */);
+                true /* allowApks */, info, new Signature[0] /* signatures */,
+                mMockPackageManagerInternal);
 
         assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK);
         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
@@ -283,7 +293,8 @@
         PackageManagerStub.sPackageInfo = null;
 
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
-                false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */);
+                false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */,
+                mMockPackageManagerInternal);
 
         assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
@@ -307,7 +318,8 @@
         PackageManagerStub.sPackageInfo = packageInfo;
 
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
-                false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */);
+                false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */,
+                mMockPackageManagerInternal);
 
         assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
@@ -333,7 +345,8 @@
         PackageManagerStub.sPackageInfo = packageInfo;
 
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
-                false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */);
+                false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */,
+                mMockPackageManagerInternal);
 
         assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
@@ -358,11 +371,11 @@
         packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
         packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
         packageInfo.applicationInfo.backupAgentName = null;
-        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_2};
+        packageInfo.signingCertificateHistory = new Signature[][] {{FAKE_SIGNATURE_2}};
         PackageManagerStub.sPackageInfo = packageInfo;
 
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
-                false /* allowApks */, new FileMetadata(), signatures);
+                false /* allowApks */, new FileMetadata(), signatures, mMockPackageManagerInternal);
 
         assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
@@ -383,16 +396,19 @@
         Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
 
         PackageInfo packageInfo = new PackageInfo();
+        packageInfo.packageName = "test";
         packageInfo.applicationInfo = new ApplicationInfo();
         packageInfo.applicationInfo.flags |=
                 ApplicationInfo.FLAG_ALLOW_BACKUP | ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
         packageInfo.applicationInfo.uid = Process.SYSTEM_UID;
         packageInfo.applicationInfo.backupAgentName = "backup.agent";
-        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1};
+        packageInfo.signingCertificateHistory = new Signature[][] {{FAKE_SIGNATURE_1}};
         PackageManagerStub.sPackageInfo = packageInfo;
 
+        doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1,
+                packageInfo.packageName);
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
-                false /* allowApks */, new FileMetadata(), signatures);
+                false /* allowApks */, new FileMetadata(), signatures, mMockPackageManagerInternal);
 
         assertThat(policy).isEqualTo(RestorePolicy.ACCEPT);
         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
@@ -412,16 +428,19 @@
         Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
 
         PackageInfo packageInfo = new PackageInfo();
+        packageInfo.packageName = "test";
         packageInfo.applicationInfo = new ApplicationInfo();
         packageInfo.applicationInfo.flags |=
                 ApplicationInfo.FLAG_ALLOW_BACKUP | ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
         packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
         packageInfo.applicationInfo.backupAgentName = null;
-        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1};
+        packageInfo.signingCertificateHistory = new Signature[][] {{FAKE_SIGNATURE_1}};
         PackageManagerStub.sPackageInfo = packageInfo;
 
+        doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1,
+                packageInfo.packageName);
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
-                false /* allowApks */, new FileMetadata(), signatures);
+                false /* allowApks */, new FileMetadata(), signatures, mMockPackageManagerInternal);
 
         assertThat(policy).isEqualTo(RestorePolicy.ACCEPT);
         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
@@ -444,17 +463,20 @@
         info.version = 1;
 
         PackageInfo packageInfo = new PackageInfo();
+        packageInfo.packageName = "test";
         packageInfo.applicationInfo = new ApplicationInfo();
         packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
         packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
         packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
         packageInfo.applicationInfo.backupAgentName = null;
-        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1};
+        packageInfo.signingCertificateHistory = new Signature[][] {{FAKE_SIGNATURE_1}};
         packageInfo.versionCode = 2;
         PackageManagerStub.sPackageInfo = packageInfo;
 
+        doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1,
+                packageInfo.packageName);
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
-                false /* allowApks */, info, signatures);
+                false /* allowApks */, info, signatures, mMockPackageManagerInternal);
 
         assertThat(policy).isEqualTo(RestorePolicy.ACCEPT);
         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
@@ -479,17 +501,20 @@
         info.hasApk = true;
 
         PackageInfo packageInfo = new PackageInfo();
+        packageInfo.packageName = "test";
         packageInfo.applicationInfo = new ApplicationInfo();
         packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
         packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
         packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
         packageInfo.applicationInfo.backupAgentName = null;
-        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1};
+        packageInfo.signingCertificateHistory = new Signature[][] {{FAKE_SIGNATURE_1}};
         packageInfo.versionCode = 1;
         PackageManagerStub.sPackageInfo = packageInfo;
 
+        doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1,
+                packageInfo.packageName);
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
-                true /* allowApks */, info, signatures);
+                true /* allowApks */, info, signatures, mMockPackageManagerInternal);
 
         assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK);
         verifyNoMoreInteractions(mBackupManagerMonitorMock);
@@ -510,17 +535,20 @@
         info.version = 2;
 
         PackageInfo packageInfo = new PackageInfo();
+        packageInfo.packageName = "test";
         packageInfo.applicationInfo = new ApplicationInfo();
         packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
         packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
         packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
         packageInfo.applicationInfo.backupAgentName = null;
-        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1};
+        packageInfo.signingCertificateHistory = new Signature[][] {{FAKE_SIGNATURE_1}};
         packageInfo.versionCode = 1;
         PackageManagerStub.sPackageInfo = packageInfo;
 
+        doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1,
+                packageInfo.packageName);
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
-                false /* allowApks */, info, signatures);
+                false /* allowApks */, info, signatures, mMockPackageManagerInternal);
 
         assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
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 00a85a5..f58766f 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -94,7 +94,6 @@
 
 import org.hamcrest.BaseMatcher;
 import org.hamcrest.Description;
-import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
@@ -3765,19 +3764,22 @@
         // The DO can still set lock task packages
         final String[] doPackages = {"doPackage1", "doPackage2"};
         final int flags = DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS
-                | DevicePolicyManager.LOCK_TASK_FEATURE_RECENTS;
+                | DevicePolicyManager.LOCK_TASK_FEATURE_HOME
+                | DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW;
         verifyCanSetLockTask(DpmMockContext.CALLER_SYSTEM_USER_UID, UserHandle.USER_SYSTEM, admin1, doPackages, flags);
 
         final String[] secondaryPoPackages = {"secondaryPoPackage1", "secondaryPoPackage2"};
         final int secondaryPoFlags = DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS
-                | DevicePolicyManager.LOCK_TASK_FEATURE_RECENTS;
+                | DevicePolicyManager.LOCK_TASK_FEATURE_HOME
+                | DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW;
         verifyCanNotSetLockTask(DpmMockContext.CALLER_UID, admin3, secondaryPoPackages, secondaryPoFlags);
 
         // Managed profile is unaffiliated - shouldn't be able to setLockTaskPackages.
         mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
         final String[] poPackages = {"poPackage1", "poPackage2"};
         final int poFlags = DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS
-                | DevicePolicyManager.LOCK_TASK_FEATURE_RECENTS;
+                | DevicePolicyManager.LOCK_TASK_FEATURE_HOME
+                | DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW;
         verifyCanNotSetLockTask(MANAGED_PROFILE_ADMIN_UID, adminDifferentPackage, poPackages, poFlags);
 
         // Setting same affiliation ids
@@ -3820,7 +3822,8 @@
 
         final String[] poPackages = {"poPackage1", "poPackage2"};
         final int poFlags = DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS
-                | DevicePolicyManager.LOCK_TASK_FEATURE_RECENTS;
+                | DevicePolicyManager.LOCK_TASK_FEATURE_HOME
+                | DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW;
         verifyCanSetLockTask(DpmMockContext.CALLER_UID, DpmMockContext.CALLER_USER_HANDLE, admin1,
                 poPackages, poFlags);
 
@@ -3836,10 +3839,25 @@
         mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
         final String[] mpoPackages = {"poPackage1", "poPackage2"};
         final int mpoFlags = DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS
-                | DevicePolicyManager.LOCK_TASK_FEATURE_RECENTS;
+                | DevicePolicyManager.LOCK_TASK_FEATURE_HOME
+                | DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW;
         verifyCanNotSetLockTask(MANAGED_PROFILE_ADMIN_UID, adminDifferentPackage, mpoPackages, mpoFlags);
     }
 
+    public void testLockTaskFeatures_IllegalArgumentException() throws Exception {
+        // Setup a device owner.
+        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+        setupDeviceOwner();
+        // Lock task policy is updated when loading user data.
+        verifyLockTaskState(UserHandle.USER_SYSTEM);
+
+        final int flags = DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS
+                | DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW;
+        assertExpectException(IllegalArgumentException.class,
+                "Cannot use LOCK_TASK_FEATURE_OVERVIEW without LOCK_TASK_FEATURE_HOME",
+                () -> dpm.setLockTaskFeatures(admin1, flags));
+    }
+
     public void testIsDeviceManaged() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
index 501f966..b4f8474 100644
--- a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
@@ -338,6 +338,26 @@
         assertFalse(event.isDefaultBrightnessConfig);
         assertEquals(1.0, event.powerBrightnessFactor, FLOAT_DELTA);
         assertFalse(event.isUserSetBrightness);
+
+        // Pretend user 1 is a profile of user 0.
+        mInjector.mProfiles = new int[]{0, 1};
+        events = tracker.getEvents(0, true).getList();
+        // Both events should now be returned.
+        assertEquals(2, events.size());
+        BrightnessChangeEvent userZeroEvent;
+        BrightnessChangeEvent userOneEvent;
+        if (events.get(0).userId == 0) {
+            userZeroEvent = events.get(0);
+            userOneEvent = events.get(1);
+        } else {
+            userZeroEvent = events.get(1);
+            userOneEvent = events.get(0);
+        }
+        assertEquals(0, userZeroEvent.userId);
+        assertEquals("com.example.app", userZeroEvent.packageName);
+        assertEquals(1, userOneEvent.userId);
+        // Events from user 1 should have the package name redacted
+        assertNull(userOneEvent.packageName);
     }
 
     @Test
@@ -597,6 +617,7 @@
         Handler mHandler;
         boolean mIdleScheduled;
         boolean mInteractive = true;
+        int[] mProfiles;
 
         public TestInjector(Handler handler) {
             mHandler = handler;
@@ -682,6 +703,15 @@
         }
 
         @Override
+        public int[] getProfileIds(UserManager userManager, int userId) {
+            if (mProfiles != null) {
+                return mProfiles;
+            } else {
+                return new int[]{userId};
+            }
+        }
+
+        @Override
         public ActivityManager.StackInfo getFocusedStack() throws RemoteException {
             ActivityManager.StackInfo focusedStack = new ActivityManager.StackInfo();
             focusedStack.userId = 0;
@@ -689,15 +719,18 @@
             return focusedStack;
         }
 
+        @Override
         public void scheduleIdleJob(Context context) {
             // Don't actually schedule jobs during unit tests.
             mIdleScheduled = true;
         }
 
+        @Override
         public void cancelIdleJob(Context context) {
             mIdleScheduled = false;
         }
 
+        @Override
         public boolean isInteractive(Context context) {
             return mInteractive;
         }
diff --git a/services/tests/servicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java b/services/tests/servicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
index 35cba18..8874894 100644
--- a/services/tests/servicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
@@ -33,12 +33,14 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.os.Build;
+import android.os.Handler;
 import android.os.SystemClock;
 import android.support.test.runner.AndroidJUnit4;
 import android.util.DataUnit;
 
 import com.android.server.LocalServices;
 import com.android.server.job.JobSchedulerService;
+import com.android.server.job.JobSchedulerService.Constants;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -49,6 +51,8 @@
 
 @RunWith(AndroidJUnit4.class)
 public class ConnectivityControllerTest {
+    private Constants mConstants;
+
     @Before
     public void setUp() throws Exception {
         // Assume all packages are current SDK
@@ -65,23 +69,26 @@
                 Clock.fixed(SystemClock.uptimeMillisClock().instant(), ZoneOffset.UTC);
         JobSchedulerService.sElapsedRealtimeClock =
                 Clock.fixed(SystemClock.elapsedRealtimeClock().instant(), ZoneOffset.UTC);
+
+        // Assume default constants for now
+        mConstants = new Constants();
     }
 
     @Test
     public void testInsane() throws Exception {
-        final Network network = new Network(101);
+        final Network net = new Network(101);
         final JobInfo.Builder job = createJob()
                 .setEstimatedNetworkBytes(DataUnit.MEBIBYTES.toBytes(1))
                 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
 
         // Slow network is too slow
-        assertFalse(ConnectivityController.isSatisfied(createJobStatus(job), network,
+        assertFalse(ConnectivityController.isSatisfied(createJobStatus(job), net,
                 createCapabilities().setLinkUpstreamBandwidthKbps(1)
-                        .setLinkDownstreamBandwidthKbps(1)));
+                        .setLinkDownstreamBandwidthKbps(1), mConstants));
         // Fast network looks great
-        assertTrue(ConnectivityController.isSatisfied(createJobStatus(job), network,
+        assertTrue(ConnectivityController.isSatisfied(createJobStatus(job), net,
                 createCapabilities().setLinkUpstreamBandwidthKbps(1024)
-                        .setLinkDownstreamBandwidthKbps(1024)));
+                        .setLinkDownstreamBandwidthKbps(1024), mConstants));
     }
 
     @Test
@@ -95,19 +102,19 @@
 
         // Uncongested network is whenever
         {
-            final Network network = new Network(101);
-            final NetworkCapabilities capabilities = createCapabilities()
+            final Network net = new Network(101);
+            final NetworkCapabilities caps = createCapabilities()
                     .addCapability(NET_CAPABILITY_NOT_CONGESTED);
-            assertTrue(ConnectivityController.isSatisfied(early, network, capabilities));
-            assertTrue(ConnectivityController.isSatisfied(late, network, capabilities));
+            assertTrue(ConnectivityController.isSatisfied(early, net, caps, mConstants));
+            assertTrue(ConnectivityController.isSatisfied(late, net, caps, mConstants));
         }
 
         // Congested network is more selective
         {
-            final Network network = new Network(101);
-            final NetworkCapabilities capabilities = createCapabilities();
-            assertFalse(ConnectivityController.isSatisfied(early, network, capabilities));
-            assertTrue(ConnectivityController.isSatisfied(late, network, capabilities));
+            final Network net = new Network(101);
+            final NetworkCapabilities caps = createCapabilities();
+            assertFalse(ConnectivityController.isSatisfied(early, net, caps, mConstants));
+            assertTrue(ConnectivityController.isSatisfied(late, net, caps, mConstants));
         }
     }
 
@@ -126,25 +133,25 @@
 
         // Unmetered network is whenever
         {
-            final Network network = new Network(101);
-            final NetworkCapabilities capabilities = createCapabilities()
+            final Network net = new Network(101);
+            final NetworkCapabilities caps = createCapabilities()
                     .addCapability(NET_CAPABILITY_NOT_CONGESTED)
                     .addCapability(NET_CAPABILITY_NOT_METERED);
-            assertTrue(ConnectivityController.isSatisfied(early, network, capabilities));
-            assertTrue(ConnectivityController.isSatisfied(late, network, capabilities));
-            assertTrue(ConnectivityController.isSatisfied(earlyPrefetch, network, capabilities));
-            assertTrue(ConnectivityController.isSatisfied(latePrefetch, network, capabilities));
+            assertTrue(ConnectivityController.isSatisfied(early, net, caps, mConstants));
+            assertTrue(ConnectivityController.isSatisfied(late, net, caps, mConstants));
+            assertTrue(ConnectivityController.isSatisfied(earlyPrefetch, net, caps, mConstants));
+            assertTrue(ConnectivityController.isSatisfied(latePrefetch, net, caps, mConstants));
         }
 
         // Metered network is only when prefetching and late
         {
-            final Network network = new Network(101);
-            final NetworkCapabilities capabilities = createCapabilities()
+            final Network net = new Network(101);
+            final NetworkCapabilities caps = createCapabilities()
                     .addCapability(NET_CAPABILITY_NOT_CONGESTED);
-            assertFalse(ConnectivityController.isSatisfied(early, network, capabilities));
-            assertFalse(ConnectivityController.isSatisfied(late, network, capabilities));
-            assertFalse(ConnectivityController.isSatisfied(earlyPrefetch, network, capabilities));
-            assertTrue(ConnectivityController.isSatisfied(latePrefetch, network, capabilities));
+            assertFalse(ConnectivityController.isSatisfied(early, net, caps, mConstants));
+            assertFalse(ConnectivityController.isSatisfied(late, net, caps, mConstants));
+            assertFalse(ConnectivityController.isSatisfied(earlyPrefetch, net, caps, mConstants));
+            assertTrue(ConnectivityController.isSatisfied(latePrefetch, net, caps, mConstants));
         }
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGeneratorTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGeneratorTest.java
index 8a461ac..fd8b319 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGeneratorTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGeneratorTest.java
@@ -39,6 +39,7 @@
 import java.io.File;
 import java.nio.charset.StandardCharsets;
 import java.security.KeyStore;
+import java.util.Random;
 
 import javax.crypto.Cipher;
 import javax.crypto.KeyGenerator;
@@ -51,7 +52,7 @@
     private static final int TEST_GENERATION_ID = 3;
     private static final String ANDROID_KEY_STORE_PROVIDER = "AndroidKeyStore";
     private static final String KEY_ALGORITHM = "AES";
-    private static final int KEY_SIZE_BYTES = 32;
+    private static final int KEY_SIZE_BYTES = RecoverableKeyGenerator.KEY_SIZE_BITS / Byte.SIZE;
     private static final String KEY_WRAP_ALGORITHM = "AES/GCM/NoPadding";
     private static final String TEST_ALIAS = "karlin";
     private static final String WRAPPING_KEY_ALIAS = "RecoverableKeyGeneratorTestWrappingKey";
@@ -71,7 +72,7 @@
         mDatabaseFile = context.getDatabasePath(DATABASE_FILE_NAME);
         mRecoverableKeyStoreDb = RecoverableKeyStoreDb.newInstance(context);
 
-        AndroidKeyStoreSecretKey platformKey = generateAndroidKeyStoreKey();
+        AndroidKeyStoreSecretKey platformKey = generatePlatformKey();
         mPlatformKey = new PlatformEncryptionKey(TEST_GENERATION_ID, platformKey);
         mDecryptKey = new PlatformDecryptionKey(TEST_GENERATION_ID, platformKey);
         mRecoverableKeyGenerator = RecoverableKeyGenerator.newInstance(mRecoverableKeyStoreDb);
@@ -117,7 +118,21 @@
         assertArrayEquals(rawMaterial, unwrappedMaterial);
     }
 
-    private AndroidKeyStoreSecretKey generateAndroidKeyStoreKey() throws Exception {
+    @Test
+    public void importKey_storesTheWrappedVersionOfTheRawMaterial() throws Exception {
+        byte[] rawMaterial = randomBytes(KEY_SIZE_BYTES);
+        mRecoverableKeyGenerator.importKey(
+                mPlatformKey, TEST_USER_ID, KEYSTORE_UID_SELF, TEST_ALIAS, rawMaterial);
+
+        WrappedKey wrappedKey = mRecoverableKeyStoreDb.getKey(KEYSTORE_UID_SELF, TEST_ALIAS);
+        Cipher cipher = Cipher.getInstance(KEY_WRAP_ALGORITHM);
+        cipher.init(Cipher.DECRYPT_MODE, mDecryptKey.getKey(),
+                new GCMParameterSpec(GCM_TAG_LENGTH_BITS, wrappedKey.getNonce()));
+        byte[] unwrappedMaterial = cipher.doFinal(wrappedKey.getKeyMaterial());
+        assertArrayEquals(rawMaterial, unwrappedMaterial);
+    }
+
+    private AndroidKeyStoreSecretKey generatePlatformKey() throws Exception {
         KeyGenerator keyGenerator = KeyGenerator.getInstance(
                 KEY_ALGORITHM,
                 ANDROID_KEY_STORE_PROVIDER);
@@ -132,4 +147,10 @@
     private static byte[] getUtf8Bytes(String s) {
         return s.getBytes(StandardCharsets.UTF_8);
     }
+
+    private static byte[] randomBytes(int n) {
+        byte[] bytes = new byte[n];
+        new Random().nextBytes(bytes);
+        return bytes;
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
index 8bd0df4..e6a36c6 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
@@ -45,6 +45,7 @@
 import android.security.keystore.KeyProperties;
 import android.security.keystore.recovery.KeyDerivationParams;
 import android.security.keystore.recovery.KeyChainProtectionParams;
+import android.security.keystore.recovery.RecoveryCertPath;
 import android.security.keystore.recovery.WrappedApplicationKey;
 import android.support.test.filters.SmallTest;
 import android.support.test.InstrumentationRegistry;
@@ -67,6 +68,10 @@
 
 import java.io.File;
 import java.nio.charset.StandardCharsets;
+import java.security.cert.CertPath;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
 import java.util.concurrent.Executors;
 import java.util.Map;
 import java.util.Random;
@@ -127,6 +132,7 @@
     private static final String TEST_ALIAS = "nick";
     private static final String TEST_ALIAS2 = "bob";
     private static final int RECOVERABLE_KEY_SIZE_BYTES = 32;
+    private static final int APPLICATION_KEY_SIZE_BYTES = 32;
     private static final int GENERATION_ID = 1;
     private static final byte[] NONCE = getUtf8Bytes("nonce");
     private static final byte[] KEY_MATERIAL = getUtf8Bytes("keymaterial");
@@ -204,6 +210,39 @@
     }
 
     @Test
+    public void importKey_storesTheKey() throws Exception {
+        int uid = Binder.getCallingUid();
+        int userId = UserHandle.getCallingUserId();
+        byte[] keyMaterial = randomBytes(APPLICATION_KEY_SIZE_BYTES);
+
+        mRecoverableKeyStoreManager.importKey(TEST_ALIAS, keyMaterial);
+
+        assertThat(mRecoverableKeyStoreDb.getKey(uid, TEST_ALIAS)).isNotNull();
+        assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isTrue();
+    }
+
+    @Test
+    public void importKey_throwsIfInvalidLength() throws Exception {
+        byte[] keyMaterial = randomBytes(APPLICATION_KEY_SIZE_BYTES - 1);
+        try {
+            mRecoverableKeyStoreManager.importKey(TEST_ALIAS, keyMaterial);
+            fail("should have thrown");
+        } catch (ServiceSpecificException e) {
+            assertThat(e.getMessage()).contains("not contain 256 bits");
+        }
+    }
+
+    @Test
+    public void importKey_throwsIfNullKey() throws Exception {
+        try {
+            mRecoverableKeyStoreManager.importKey(TEST_ALIAS, /*keyBytes=*/ null);
+            fail("should have thrown");
+        } catch (ServiceSpecificException e) {
+            assertThat(e.getMessage()).contains("not contain 256 bits");
+        }
+    }
+
+    @Test
     public void removeKey_removesAKey() throws Exception {
         int uid = Binder.getCallingUid();
         mRecoverableKeyStoreManager.generateAndStoreKey(TEST_ALIAS);
@@ -238,7 +277,7 @@
     }
 
     @Test
-    public void initRecoveryService_succeeds() throws Exception {
+    public void initRecoveryService_succeedsWithCertFile() throws Exception {
         int uid = Binder.getCallingUid();
         int userId = UserHandle.getCallingUserId();
         long certSerial = 1000L;
@@ -335,6 +374,46 @@
     }
 
     @Test
+    public void startRecoverySessionWithCertPath_storesTheSessionInfo() throws Exception {
+        mRecoverableKeyStoreManager.startRecoverySessionWithCertPath(
+                TEST_SESSION_ID,
+                RecoveryCertPath.createRecoveryCertPath(TestData.CERT_PATH_1),
+                TEST_VAULT_PARAMS,
+                TEST_VAULT_CHALLENGE,
+                ImmutableList.of(
+                        new KeyChainProtectionParams(
+                                TYPE_LOCKSCREEN,
+                                UI_FORMAT_PASSWORD,
+                                KeyDerivationParams.createSha256Params(TEST_SALT),
+                                TEST_SECRET)));
+
+        assertEquals(1, mRecoverySessionStorage.size());
+        RecoverySessionStorage.Entry entry =
+                mRecoverySessionStorage.get(Binder.getCallingUid(), TEST_SESSION_ID);
+        assertArrayEquals(TEST_SECRET, entry.getLskfHash());
+        assertEquals(KEY_CLAIMANT_LENGTH_BYTES, entry.getKeyClaimant().length);
+    }
+
+    @Test
+    public void startRecoverySessionWithCertPath_checksPermissionFirst() throws Exception {
+        mRecoverableKeyStoreManager.startRecoverySessionWithCertPath(
+                TEST_SESSION_ID,
+                RecoveryCertPath.createRecoveryCertPath(TestData.CERT_PATH_1),
+                TEST_VAULT_PARAMS,
+                TEST_VAULT_CHALLENGE,
+                ImmutableList.of(
+                        new KeyChainProtectionParams(
+                                TYPE_LOCKSCREEN,
+                                UI_FORMAT_PASSWORD,
+                                KeyDerivationParams.createSha256Params(TEST_SALT),
+                                TEST_SECRET)));
+
+        verify(mMockContext, times(2))
+                .enforceCallingOrSelfPermission(
+                        eq(Manifest.permission.RECOVER_KEYSTORE), any());
+    }
+
+    @Test
     public void startRecoverySession_storesTheSessionInfo() throws Exception {
         mRecoverableKeyStoreManager.startRecoverySession(
                 TEST_SESSION_ID,
@@ -432,6 +511,90 @@
     }
 
     @Test
+    public void startRecoverySessionWithCertPath_throwsIfBadNumberOfSecrets() throws Exception {
+        try {
+            mRecoverableKeyStoreManager.startRecoverySessionWithCertPath(
+                    TEST_SESSION_ID,
+                    RecoveryCertPath.createRecoveryCertPath(TestData.CERT_PATH_1),
+                    TEST_VAULT_PARAMS,
+                    TEST_VAULT_CHALLENGE,
+                    ImmutableList.of());
+            fail("should have thrown");
+        } catch (UnsupportedOperationException e) {
+            assertThat(e.getMessage()).startsWith(
+                    "Only a single KeyChainProtectionParams is supported");
+        }
+    }
+
+    @Test
+    public void startRecoverySessionWithCertPath_throwsIfPublicKeysMismatch() throws Exception {
+        byte[] vaultParams = TEST_VAULT_PARAMS.clone();
+        vaultParams[1] ^= (byte) 1;  // Flip 1 bit
+        try {
+            mRecoverableKeyStoreManager.startRecoverySessionWithCertPath(
+                    TEST_SESSION_ID,
+                    RecoveryCertPath.createRecoveryCertPath(TestData.CERT_PATH_1),
+                    vaultParams,
+                    TEST_VAULT_CHALLENGE,
+                    ImmutableList.of(
+                            new KeyChainProtectionParams(
+                                    TYPE_LOCKSCREEN,
+                                    UI_FORMAT_PASSWORD,
+                                    KeyDerivationParams.createSha256Params(TEST_SALT),
+                                    TEST_SECRET)));
+            fail("should have thrown");
+        } catch (ServiceSpecificException e) {
+            assertThat(e.getMessage()).contains("do not match");
+        }
+    }
+
+    @Test
+    public void startRecoverySessionWithCertPath_throwsIfEmptyCertPath() throws Exception {
+        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+        CertPath emptyCertPath = certFactory.generateCertPath(new ArrayList<X509Certificate>());
+        try {
+            mRecoverableKeyStoreManager.startRecoverySessionWithCertPath(
+                    TEST_SESSION_ID,
+                    RecoveryCertPath.createRecoveryCertPath(emptyCertPath),
+                    TEST_VAULT_PARAMS,
+                    TEST_VAULT_CHALLENGE,
+                    ImmutableList.of(
+                            new KeyChainProtectionParams(
+                                    TYPE_LOCKSCREEN,
+                                    UI_FORMAT_PASSWORD,
+                                    KeyDerivationParams.createSha256Params(TEST_SALT),
+                                    TEST_SECRET)));
+            fail("should have thrown");
+        } catch (ServiceSpecificException e) {
+            assertThat(e.getMessage()).contains("empty");
+        }
+    }
+
+    @Test
+    public void startRecoverySessionWithCertPath_throwsIfInvalidCertPath() throws Exception {
+        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+        CertPath shortCertPath = certFactory.generateCertPath(
+                TestData.CERT_PATH_1.getCertificates()
+                        .subList(0, TestData.CERT_PATH_1.getCertificates().size() - 1));
+        try {
+            mRecoverableKeyStoreManager.startRecoverySessionWithCertPath(
+                    TEST_SESSION_ID,
+                    RecoveryCertPath.createRecoveryCertPath(shortCertPath),
+                    TEST_VAULT_PARAMS,
+                    TEST_VAULT_CHALLENGE,
+                    ImmutableList.of(
+                            new KeyChainProtectionParams(
+                                    TYPE_LOCKSCREEN,
+                                    UI_FORMAT_PASSWORD,
+                                    KeyDerivationParams.createSha256Params(TEST_SALT),
+                                    TEST_SECRET)));
+            fail("should have thrown");
+        } catch (ServiceSpecificException e) {
+            // expected
+        }
+    }
+
+    @Test
     public void recoverKeys_throwsIfNoSessionIsPresent() throws Exception {
         try {
             mRecoverableKeyStoreManager.recoverKeys(
@@ -639,7 +802,7 @@
     }
 
     @Test
-    public void setRecoveryStatus_forOneAlias() throws Exception {
+    public void setRecoveryStatus() throws Exception {
         int userId = UserHandle.getCallingUserId();
         int uid = Binder.getCallingUid();
         int status = 100;
@@ -648,59 +811,16 @@
         WrappedKey wrappedKey = new WrappedKey(NONCE, KEY_MATERIAL, GENERATION_ID, status);
         mRecoverableKeyStoreDb.insertKey(userId, uid, alias, wrappedKey);
         Map<String, Integer> statuses =
-                mRecoverableKeyStoreManager.getRecoveryStatus(/*packageName=*/ null);
+                mRecoverableKeyStoreManager.getRecoveryStatus();
         assertThat(statuses).hasSize(1);
         assertThat(statuses).containsEntry(alias, status);
 
-        mRecoverableKeyStoreManager.setRecoveryStatus(
-                /*packageName=*/ null, new String[] {alias}, status2);
-        statuses = mRecoverableKeyStoreManager.getRecoveryStatus(/*packageName=*/ null);
+        mRecoverableKeyStoreManager.setRecoveryStatus(alias, status2);
+        statuses = mRecoverableKeyStoreManager.getRecoveryStatus();
         assertThat(statuses).hasSize(1);
         assertThat(statuses).containsEntry(alias, status2); // updated
     }
 
-    @Test
-    public void setRecoveryStatus_for2Aliases() throws Exception {
-        int userId = UserHandle.getCallingUserId();
-        int uid = Binder.getCallingUid();
-        int status = 100;
-        int status2 = 200;
-        int status3 = 300;
-        String alias = "key1";
-        String alias2 = "key2";
-        WrappedKey wrappedKey = new WrappedKey(NONCE, KEY_MATERIAL, GENERATION_ID, status);
-        mRecoverableKeyStoreDb.insertKey(userId, uid, alias, wrappedKey);
-        mRecoverableKeyStoreDb.insertKey(userId, uid, alias2, wrappedKey);
-        Map<String, Integer> statuses =
-                mRecoverableKeyStoreManager.getRecoveryStatus(/*packageName=*/ null);
-        assertThat(statuses).hasSize(2);
-        assertThat(statuses).containsEntry(alias, status);
-        assertThat(statuses).containsEntry(alias2, status);
-
-        mRecoverableKeyStoreManager.setRecoveryStatus(
-                /*packageName=*/ null, /*aliases=*/ null, status2);
-        statuses = mRecoverableKeyStoreManager.getRecoveryStatus(/*packageName=*/ null);
-        assertThat(statuses).hasSize(2);
-        assertThat(statuses).containsEntry(alias, status2); // updated
-        assertThat(statuses).containsEntry(alias2, status2); // updated
-
-        mRecoverableKeyStoreManager.setRecoveryStatus(
-                /*packageName=*/ null, new String[] {alias2}, status3);
-
-        statuses = mRecoverableKeyStoreManager.getRecoveryStatus(/*packageName=*/ null);
-        assertThat(statuses).hasSize(2);
-        assertThat(statuses).containsEntry(alias, status2);
-        assertThat(statuses).containsEntry(alias2, status3); // updated
-
-        mRecoverableKeyStoreManager.setRecoveryStatus(
-                /*packageName=*/ null, new String[] {alias, alias2}, status);
-
-        statuses = mRecoverableKeyStoreManager.getRecoveryStatus(/*packageName=*/ null);
-        assertThat(statuses).hasSize(2);
-        assertThat(statuses).containsEntry(alias, status); // updated
-        assertThat(statuses).containsEntry(alias2, status); // updated
-    }
-
     private static byte[] encryptedApplicationKey(
             SecretKey recoveryKey, byte[] applicationKey) throws Exception {
         return KeySyncUtils.encryptKeysWithRecoveryKey(recoveryKey, ImmutableMap.of(
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/certificate/CertUtilsTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/certificate/CertUtilsTest.java
index d08dab4..9279698 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/certificate/CertUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/certificate/CertUtilsTest.java
@@ -30,8 +30,10 @@
 import java.security.KeyPairGenerator;
 import java.security.PublicKey;
 import java.security.cert.CertPath;
+import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.security.spec.ECGenParameterSpec;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Base64;
 import java.util.Collections;
@@ -317,6 +319,42 @@
     }
 
     @Test
+    public void validateCertPath_succeeds() throws Exception {
+        X509Certificate rootCert = TestData.ROOT_CA_TRUSTED;
+        List<X509Certificate> intermediateCerts =
+                Arrays.asList(TestData.INTERMEDIATE_CA_1, TestData.INTERMEDIATE_CA_2);
+        X509Certificate leafCert = TestData.LEAF_CERT_2;
+        CertPath certPath =
+                CertUtils.buildCertPath(
+                        CertUtils.buildPkixParams(
+                                TestData.DATE_ALL_CERTS_VALID, rootCert, intermediateCerts,
+                                leafCert));
+        CertUtils.validateCertPath(
+                TestData.DATE_ALL_CERTS_VALID, TestData.ROOT_CA_TRUSTED, certPath);
+    }
+
+    @Test
+    public void validateCertPath_throwsIfEmptyCertPath() throws Exception {
+        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+        CertPath emptyCertPath = certFactory.generateCertPath(new ArrayList<X509Certificate>());
+        CertValidationException expected =
+                expectThrows(
+                        CertValidationException.class,
+                        () -> CertUtils.validateCertPath(TestData.DATE_ALL_CERTS_VALID,
+                                TestData.ROOT_CA_TRUSTED, emptyCertPath));
+        assertThat(expected.getMessage()).contains("empty");
+    }
+
+    @Test
+    public void validateCertPath_throwsIfNotValidated() throws Exception {
+        assertThrows(
+                CertValidationException.class,
+                () -> CertUtils.validateCertPath(TestData.DATE_ALL_CERTS_VALID,
+                        TestData.ROOT_CA_DIFFERENT_COMMON_NAME,
+                        com.android.server.locksettings.recoverablekeystore.TestData.CERT_PATH_1));
+    }
+
+    @Test
     public void validateCert_succeeds() throws Exception {
         X509Certificate rootCert = TestData.ROOT_CA_TRUSTED;
         List<X509Certificate> intermediateCerts =
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/PersistentKeyChainSnapshotTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/PersistentKeyChainSnapshotTest.java
index 17a4d34..180345c 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/PersistentKeyChainSnapshotTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/PersistentKeyChainSnapshotTest.java
@@ -27,7 +27,6 @@
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -45,7 +44,6 @@
             .getBytes(StandardCharsets.UTF_8);
     private static final byte[] KEY_MATERIAL = "app_key_data".getBytes(StandardCharsets.UTF_8);
     private static final byte[] PUBLIC_KEY = "public_key_data".getBytes(StandardCharsets.UTF_8);
-    private static final byte[] ACCOUNT = "test_account".getBytes(StandardCharsets.UTF_8);
     private static final byte[] SALT = "salt".getBytes(StandardCharsets.UTF_8);
     private static final int SNAPSHOT_VERSION = 2;
     private static final int MAX_ATTEMPTS = 10;
@@ -130,7 +128,6 @@
         WrappedApplicationKey entry = new WrappedApplicationKey.Builder()
                 .setAlias(ALIAS)
                 .setEncryptedKeyMaterial(KEY_MATERIAL)
-                .setAccount(ACCOUNT)
                 .build();
         writer.writeKeyEntry(entry);
 
@@ -142,7 +139,6 @@
         WrappedApplicationKey copy = reader.readKeyEntry();
         assertThat(copy.getAlias()).isEqualTo(ALIAS);
         assertThat(copy.getEncryptedKeyMaterial()).isEqualTo(KEY_MATERIAL);
-        assertThat(copy.getAccount()).isEqualTo(ACCOUNT);
 
         assertThrows(
                 IOException.class,
@@ -194,7 +190,6 @@
         appKeysList.add(new WrappedApplicationKey.Builder()
                 .setAlias(ALIAS)
                 .setEncryptedKeyMaterial(KEY_MATERIAL)
-                .setAccount(ACCOUNT)
                 .build());
 
         KeyChainSnapshot snapshot =  new KeyChainSnapshot.Builder()
@@ -256,12 +251,10 @@
         appKeysList.add(new WrappedApplicationKey.Builder()
                 .setAlias(ALIAS)
                 .setEncryptedKeyMaterial(KEY_MATERIAL)
-                .setAccount(ACCOUNT)
                 .build());
         appKeysList.add(new WrappedApplicationKey.Builder()
                 .setAlias(ALIAS2)
                 .setEncryptedKeyMaterial(KEY_MATERIAL)
-                .setAccount(ACCOUNT)
                 .build());
 
 
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java
index 609faa4..dfb2dbf 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java
@@ -28,7 +28,7 @@
 import org.junit.runner.RunWith;
 
 import android.content.Context;
-import android.security.keystore.RecoveryController;
+import android.security.keystore.recovery.RecoveryController;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 8cf575e..4ca1647 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -289,6 +289,12 @@
         }
 
         @Override
+        int injectBinderCallingPid() {
+            // Note it's not used in tests, so just return a "random" value.
+            return mInjectedCallingUid * 123;
+        }
+
+        @Override
         int injectGetPackageUid(String packageName, int userId) {
             return getInjectedPackageInfo(packageName, userId, false).applicationInfo.uid;
         }
@@ -325,6 +331,11 @@
         }
 
         @Override
+        boolean injectHasUnlimitedShortcutsApiCallsPermission(int callingPid, int callingUid) {
+            return mInjectHasUnlimitedShortcutsApiCallsPermission;
+        }
+
+        @Override
         ComponentName getDefaultLauncher(@UserIdInt int userId) {
             final ComponentName activity = mDefaultLauncher.get(userId);
             if (activity != null) {
@@ -519,6 +530,12 @@
         }
 
         @Override
+        int injectBinderCallingPid() {
+            // Note it's not used in tests, so just return a "random" value.
+            return mInjectedCallingUid * 123;
+        }
+
+        @Override
         long injectClearCallingIdentity() {
             final int prevCallingUid = mInjectedCallingUid;
             mInjectedCallingUid = Process.SYSTEM_UID;
@@ -705,6 +722,8 @@
 
     protected boolean mInjectCheckAccessShortcutsPermission = false;
 
+    protected boolean mInjectHasUnlimitedShortcutsApiCallsPermission = false;
+
     static {
         QUERY_ALL.setQueryFlags(
                 ShortcutQuery.FLAG_GET_ALL_KINDS);
@@ -1207,7 +1226,7 @@
     }
 
     /**
-     * This controls {@link ShortcutService#hasShortcutHostPermission(String, int)}, but
+     * This controls {@link ShortcutService#hasShortcutHostPermission}, but
      * not {@link ShortcutService#getDefaultLauncher(int)}.  To control the later, use
      * {@link #setDefaultLauncher(int, ComponentName)}.
      */
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index 857925b..845e05d 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -366,7 +366,38 @@
         });
     }
 
-    public void testPublishWithNoActivity() {
+    public void testUnlimitedCalls() {
+        setCaller(CALLING_PACKAGE_1, USER_0);
+
+        final ShortcutInfo si1 = makeShortcut("shortcut1");
+
+        assertEquals(3, mManager.getRemainingCallCount());
+
+        assertTrue(mManager.setDynamicShortcuts(list(si1)));
+        assertEquals(2, mManager.getRemainingCallCount());
+
+        assertTrue(mManager.addDynamicShortcuts(list(si1)));
+        assertEquals(1, mManager.getRemainingCallCount());
+
+        assertTrue(mManager.updateShortcuts(list(si1)));
+        assertEquals(0, mManager.getRemainingCallCount());
+
+        // Unlimited now.
+        mInjectHasUnlimitedShortcutsApiCallsPermission = true;
+
+        assertEquals(3, mManager.getRemainingCallCount());
+
+        assertTrue(mManager.setDynamicShortcuts(list(si1)));
+        assertEquals(3, mManager.getRemainingCallCount());
+
+        assertTrue(mManager.addDynamicShortcuts(list(si1)));
+        assertEquals(3, mManager.getRemainingCallCount());
+
+        assertTrue(mManager.updateShortcuts(list(si1)));
+        assertEquals(3, mManager.getRemainingCallCount());
+    }
+
+   public void testPublishWithNoActivity() {
         // If activity is not explicitly set, use the default one.
 
         mRunningUsers.put(USER_10, true);
diff --git a/services/tests/servicestests/src/com/android/server/pm/backup/BackupUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/backup/BackupUtilsTest.java
index c016e61..a0cefbf 100644
--- a/services/tests/servicestests/src/com/android/server/pm/backup/BackupUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/backup/BackupUtilsTest.java
@@ -15,73 +15,298 @@
  */
 package com.android.server.pm.backup;
 
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.PackageParser.Package;
 import android.content.pm.Signature;
-import android.test.AndroidTestCase;
 import android.test.MoreAsserts;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
 
 import com.android.server.backup.BackupUtils;
 
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 
 @SmallTest
-public class BackupUtilsTest extends AndroidTestCase {
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class BackupUtilsTest {
 
-    private Signature[] genSignatures(String... signatures) {
-        final Signature[] sigs = new Signature[signatures.length];
-        for (int i = 0; i < signatures.length; i++){
-            sigs[i] = new Signature(signatures[i].getBytes());
-        }
-        return sigs;
+    private static final Signature SIGNATURE_1 = generateSignature((byte) 1);
+    private static final Signature SIGNATURE_2 = generateSignature((byte) 2);
+    private static final Signature SIGNATURE_3 = generateSignature((byte) 3);
+    private static final Signature SIGNATURE_4 = generateSignature((byte) 4);
+    private static final byte[] SIGNATURE_HASH_1 = BackupUtils.hashSignature(SIGNATURE_1);
+    private static final byte[] SIGNATURE_HASH_2 = BackupUtils.hashSignature(SIGNATURE_2);
+    private static final byte[] SIGNATURE_HASH_3 = BackupUtils.hashSignature(SIGNATURE_3);
+    private static final byte[] SIGNATURE_HASH_4 = BackupUtils.hashSignature(SIGNATURE_4);
+
+    private PackageManagerInternal mMockPackageManagerInternal;
+
+    @Before
+    public void setUp() throws Exception {
+        mMockPackageManagerInternal = mock(PackageManagerInternal.class);
     }
 
-    private PackageInfo genPackage(String... signatures) {
-        final PackageInfo pi = new PackageInfo();
-        pi.packageName = "package";
-        pi.applicationInfo = new ApplicationInfo();
-        pi.signatures = genSignatures(signatures);
+    @Test
+    public void signaturesMatch_targetIsNull_returnsFalse() throws Exception {
+        ArrayList<byte[]> storedSigHashes = new ArrayList<>();
+        storedSigHashes.add(SIGNATURE_HASH_1);
+        boolean result = BackupUtils.signaturesMatch(storedSigHashes, null,
+                mMockPackageManagerInternal);
 
-        return pi;
+        assertThat(result).isFalse();
     }
 
-    public void testSignaturesMatch() {
-        final ArrayList<byte[]> stored1 = BackupUtils.hashSignatureArray(Arrays.asList(
-                "abc".getBytes()));
-        final ArrayList<byte[]> stored2 = BackupUtils.hashSignatureArray(Arrays.asList(
-                "abc".getBytes(), "def".getBytes()));
+    @Test
+    public void signaturesMatch_systemApplication_returnsTrue() throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
 
-        PackageInfo pi;
+        ArrayList<byte[]> storedSigHashes = new ArrayList<>();
+        storedSigHashes.add(SIGNATURE_HASH_1);
+        boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo,
+                mMockPackageManagerInternal);
 
-        // False for null package.
-        assertFalse(BackupUtils.signaturesMatch(stored1, null));
-
-        // If it's a system app, signatures don't matter.
-        pi = genPackage("xyz");
-        pi.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
-        assertTrue(BackupUtils.signaturesMatch(stored1, pi));
-
-        // Non system apps.
-        assertTrue(BackupUtils.signaturesMatch(stored1, genPackage("abc")));
-
-        // Superset is okay.
-        assertTrue(BackupUtils.signaturesMatch(stored1, genPackage("abc", "xyz")));
-        assertTrue(BackupUtils.signaturesMatch(stored1, genPackage("xyz", "abc")));
-
-        assertFalse(BackupUtils.signaturesMatch(stored1, genPackage("xyz")));
-        assertFalse(BackupUtils.signaturesMatch(stored1, genPackage("xyz", "def")));
-
-        assertTrue(BackupUtils.signaturesMatch(stored2, genPackage("def", "abc")));
-        assertTrue(BackupUtils.signaturesMatch(stored2, genPackage("x", "def", "abc", "y")));
-
-        // Subset is not okay.
-        assertFalse(BackupUtils.signaturesMatch(stored2, genPackage("abc")));
-        assertFalse(BackupUtils.signaturesMatch(stored2, genPackage("def")));
+        assertThat(result).isTrue();
     }
 
+    @Test
+    public void signaturesMatch_disallowsUnsignedApps_storedSignatureNull_returnsFalse()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}};
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = BackupUtils.signaturesMatch(null, packageInfo,
+                mMockPackageManagerInternal);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void signaturesMatch_disallowsUnsignedApps_storedSignatureEmpty_returnsFalse()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}};
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        ArrayList<byte[]> storedSigHashes = new ArrayList<>();
+        boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo,
+                mMockPackageManagerInternal);
+
+        assertThat(result).isFalse();
+    }
+
+
+    @Test
+    public void
+    signaturesMatch_disallowsUnsignedApps_targetSignatureEmpty_returnsFalse()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signingCertificateHistory = new Signature[0][0];
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        ArrayList<byte[]> storedSigHashes = new ArrayList<>();
+        storedSigHashes.add(SIGNATURE_HASH_1);
+        boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo,
+                mMockPackageManagerInternal);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void
+    signaturesMatch_disallowsUnsignedApps_targetSignatureNull_returnsFalse()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signingCertificateHistory = null;
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        ArrayList<byte[]> storedSigHashes = new ArrayList<>();
+        storedSigHashes.add(SIGNATURE_HASH_1);
+        boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo,
+                mMockPackageManagerInternal);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void signaturesMatch_disallowsUnsignedApps_bothSignaturesNull_returnsFalse()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signingCertificateHistory = null;
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        boolean result = BackupUtils.signaturesMatch(null, packageInfo,
+                mMockPackageManagerInternal);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void signaturesMatch_disallowsUnsignedApps_bothSignaturesEmpty_returnsFalse()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signingCertificateHistory = new Signature[0][0];
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        ArrayList<byte[]> storedSigHashes = new ArrayList<>();
+        boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo,
+                mMockPackageManagerInternal);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void signaturesMatch_equalSignatures_returnsTrue() throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signingCertificateHistory = new Signature[][] {
+                {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}
+        };
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        ArrayList<byte[]> storedSigHashes = new ArrayList<>();
+        storedSigHashes.add(SIGNATURE_HASH_1);
+        storedSigHashes.add(SIGNATURE_HASH_2);
+        storedSigHashes.add(SIGNATURE_HASH_3);
+        boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo,
+                mMockPackageManagerInternal);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void signaturesMatch_extraSignatureInTarget_returnsTrue() throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signingCertificateHistory = new Signature[][] {
+                {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}
+        };
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        ArrayList<byte[]> storedSigHashes = new ArrayList<>();
+        storedSigHashes.add(SIGNATURE_HASH_1);
+        storedSigHashes.add(SIGNATURE_HASH_2);
+        boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo,
+                mMockPackageManagerInternal);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void signaturesMatch_extraSignatureInStored_returnsFalse() throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1, SIGNATURE_2}};
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        ArrayList<byte[]> storedSigHashes = new ArrayList<>();
+        storedSigHashes.add(SIGNATURE_HASH_1);
+        storedSigHashes.add(SIGNATURE_HASH_2);
+        storedSigHashes.add(SIGNATURE_HASH_3);
+        boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo,
+                mMockPackageManagerInternal);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void signaturesMatch_oneNonMatchingSignature_returnsFalse() throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.signingCertificateHistory = new Signature[][] {
+                {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}
+        };
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        ArrayList<byte[]> storedSigHashes = new ArrayList<>();
+        storedSigHashes.add(SIGNATURE_HASH_1);
+        storedSigHashes.add(SIGNATURE_HASH_2);
+        storedSigHashes.add(SIGNATURE_HASH_4);
+        boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo,
+                mMockPackageManagerInternal);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void signaturesMatch_singleStoredSignatureNoRotation_returnsTrue()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.packageName = "test";
+        packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}};
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(SIGNATURE_HASH_1,
+                packageInfo.packageName);
+
+        ArrayList<byte[]> storedSigHashes = new ArrayList<>();
+        storedSigHashes.add(SIGNATURE_HASH_1);
+        boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo,
+                mMockPackageManagerInternal);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void signaturesMatch_singleStoredSignatureWithRotationAssumeDataCapability_returnsTrue()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.packageName = "test";
+        packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}, {SIGNATURE_2}};
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        // we know SIGNATURE_1 is in history, and we want to assume it has
+        // SigningDetails.CertCapabilities.INSTALLED_DATA capability
+        doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(SIGNATURE_HASH_1,
+                packageInfo.packageName);
+
+        ArrayList<byte[]> storedSigHashes = new ArrayList<>();
+        storedSigHashes.add(SIGNATURE_HASH_1);
+        boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo,
+                mMockPackageManagerInternal);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void
+            signaturesMatch_singleStoredSignatureWithRotationAssumeNoDataCapability_returnsFalse()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.packageName = "test";
+        packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}, {SIGNATURE_2}};
+        packageInfo.applicationInfo = new ApplicationInfo();
+
+        // we know SIGNATURE_1 is in history, but we want to assume it does not have
+        // SigningDetails.CertCapabilities.INSTALLED_DATA capability
+        doReturn(false).when(mMockPackageManagerInternal).isDataRestoreSafe(SIGNATURE_HASH_1,
+                packageInfo.packageName);
+
+        ArrayList<byte[]> storedSigHashes = new ArrayList<>();
+        storedSigHashes.add(SIGNATURE_HASH_1);
+        boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo,
+                mMockPackageManagerInternal);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
     public void testHashSignature() {
         final byte[] sig1 = "abc".getBytes();
         final byte[] sig2 = "def".getBytes();
@@ -115,4 +340,10 @@
         MoreAsserts.assertEquals(hash2a, listA.get(1));
         MoreAsserts.assertEquals(hash2a, listB.get(1));
     }
+
+    private static Signature generateSignature(byte i) {
+        byte[] signatureBytes = new byte[256];
+        signatureBytes[0] = i;
+        return new Signature(signatureBytes);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/policy/FakeWindowState.java b/services/tests/servicestests/src/com/android/server/policy/FakeWindowState.java
index a628b7b..5de393c 100644
--- a/services/tests/servicestests/src/com/android/server/policy/FakeWindowState.java
+++ b/services/tests/servicestests/src/com/android/server/policy/FakeWindowState.java
@@ -79,11 +79,6 @@
     }
 
     @Override
-    public Point getShownPositionLw() {
-        return new Point(parentFrame.left, parentFrame.top);
-    }
-
-    @Override
     public Rect getDisplayFrameLw() {
         return displayFrame;
     }
diff --git a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java
index 293f9af..c6800be 100644
--- a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java
+++ b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java
@@ -77,6 +77,7 @@
         assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+        assertInsetBy(mAppWindow.displayFrame, 0, 0, 0, 0);
     }
 
     @Test
@@ -91,6 +92,7 @@
         assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.decorFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.displayFrame, 0, NAV_BAR_HEIGHT);
     }
 
     @Test
@@ -106,6 +108,7 @@
         assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.decorFrame, 0, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.displayFrame, 0, NAV_BAR_HEIGHT);
     }
 
     @Test
@@ -130,6 +133,7 @@
         assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+        assertInsetByTopBottom(mAppWindow.displayFrame, 0, 0);
     }
 
     @Test
@@ -146,6 +150,7 @@
         assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+        assertInsetByTopBottom(mAppWindow.displayFrame, STATUS_BAR_HEIGHT, 0);
     }
 
     @Test
@@ -162,6 +167,7 @@
         assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+        assertInsetBy(mAppWindow.displayFrame, 0, 0, 0, 0);
     }
 
     @Test
@@ -178,6 +184,7 @@
         assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+        assertInsetByTopBottom(mAppWindow.displayFrame, STATUS_BAR_HEIGHT, 0);
     }
 
     @Test
@@ -195,6 +202,7 @@
         assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
         assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+        assertInsetByTopBottom(mAppWindow.displayFrame, 0, 0);
     }
 
 
@@ -212,6 +220,7 @@
         assertInsetBy(mAppWindow.contentFrame,
                 DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
         assertInsetBy(mAppWindow.decorFrame, 0, 0, 0, 0);
+        assertInsetBy(mAppWindow.displayFrame, DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
     }
 
     @Test
@@ -228,6 +237,7 @@
         assertInsetBy(mAppWindow.contentFrame,
                 NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, DISPLAY_CUTOUT_HEIGHT, 0);
         assertInsetBy(mAppWindow.decorFrame, 0, 0, 0, 0);
+        assertInsetBy(mAppWindow.displayFrame, 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java
index 30ca9ca..1d4348c 100644
--- a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java
+++ b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java
@@ -77,7 +77,9 @@
     public void setUpBase() throws Exception {
         mContext = new TestContextWrapper(InstrumentationRegistry.getTargetContext());
         mContext.getResourceMocker().addOverride(
-                com.android.internal.R.dimen.status_bar_height, STATUS_BAR_HEIGHT);
+                com.android.internal.R.dimen.status_bar_height_portrait, STATUS_BAR_HEIGHT);
+        mContext.getResourceMocker().addOverride(
+                com.android.internal.R.dimen.status_bar_height_landscape, STATUS_BAR_HEIGHT);
         mContext.getResourceMocker().addOverride(
                 com.android.internal.R.dimen.navigation_bar_height, NAV_BAR_HEIGHT);
         mContext.getResourceMocker().addOverride(
diff --git a/services/tests/servicestests/src/com/android/server/timezone/RulesManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/timezone/RulesManagerServiceTest.java
index f5969f3..c252609 100644
--- a/services/tests/servicestests/src/com/android/server/timezone/RulesManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezone/RulesManagerServiceTest.java
@@ -41,6 +41,7 @@
 
 import libcore.io.IoUtils;
 
+import static com.android.server.timezone.RulesManagerService.REQUIRED_QUERY_PERMISSION;
 import static com.android.server.timezone.RulesManagerService.REQUIRED_UPDATER_PERMISSION;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -91,25 +92,25 @@
 
     @Test(expected = SecurityException.class)
     public void getRulesState_noCallerPermission() throws Exception {
-        configureCallerDoesNotHavePermission();
+        configureCallerDoesNotHaveQueryPermission();
         mRulesManagerService.getRulesState();
     }
 
     @Test(expected = SecurityException.class)
     public void requestInstall_noCallerPermission() throws Exception {
-        configureCallerDoesNotHavePermission();
+        configureCallerDoesNotHaveUpdatePermission();
         mRulesManagerService.requestInstall(null, null, null);
     }
 
     @Test(expected = SecurityException.class)
     public void requestUninstall_noCallerPermission() throws Exception {
-        configureCallerDoesNotHavePermission();
+        configureCallerDoesNotHaveUpdatePermission();
         mRulesManagerService.requestUninstall(null, null);
     }
 
     @Test(expected = SecurityException.class)
     public void requestNothing_noCallerPermission() throws Exception {
-        configureCallerDoesNotHavePermission();
+        configureCallerDoesNotHaveUpdatePermission();
         mRulesManagerService.requestNothing(null, true);
     }
 
@@ -916,12 +917,18 @@
                 .enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);
     }
 
-    private void configureCallerDoesNotHavePermission() {
+    private void configureCallerDoesNotHaveUpdatePermission() {
         doThrow(new SecurityException("Simulated permission failure"))
                 .when(mMockPermissionHelper)
                 .enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);
     }
 
+    private void configureCallerDoesNotHaveQueryPermission() {
+        doThrow(new SecurityException("Simulated permission failure"))
+                .when(mMockPermissionHelper)
+                .enforceCallerHasPermission(REQUIRED_QUERY_PERMISSION);
+    }
+
     private void configureStageInstallExpectation(int resultCode)
             throws Exception {
         when(mMockTimeZoneDistroInstaller.stageInstallWithErrorCode(any(TimeZoneDistro.class)))
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppIdleHistoryTests.java b/services/tests/servicestests/src/com/android/server/usage/AppIdleHistoryTests.java
index 7b06648..36504ac 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppIdleHistoryTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppIdleHistoryTests.java
@@ -16,10 +16,13 @@
 
 package com.android.server.usage;
 
-import static android.app.usage.UsageStatsManager.REASON_TIMEOUT;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_TIMEOUT;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_USAGE;
+import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_MOVE_TO_FOREGROUND;
 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE;
 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_FREQUENT;
 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE;
+import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -92,18 +95,18 @@
         AppIdleHistory aih = new AppIdleHistory(mStorageDir, 1000);
 
         aih.setAppStandbyBucket(PACKAGE_1, USER_ID, 1000, STANDBY_BUCKET_ACTIVE,
-                UsageStatsManager.REASON_USAGE);
+                REASON_MAIN_USAGE);
         // ACTIVE means not idle
         assertFalse(aih.isIdle(PACKAGE_1, USER_ID, 2000));
 
         aih.setAppStandbyBucket(PACKAGE_2, USER_ID, 2000, STANDBY_BUCKET_ACTIVE,
-                UsageStatsManager.REASON_USAGE);
+                REASON_MAIN_USAGE);
         aih.setAppStandbyBucket(PACKAGE_1, USER_ID, 3000, STANDBY_BUCKET_RARE,
-                REASON_TIMEOUT);
+                REASON_MAIN_TIMEOUT);
 
         assertEquals(aih.getAppStandbyBucket(PACKAGE_1, USER_ID, 3000), STANDBY_BUCKET_RARE);
         assertEquals(aih.getAppStandbyBucket(PACKAGE_2, USER_ID, 3000), STANDBY_BUCKET_ACTIVE);
-        assertEquals(aih.getAppStandbyReason(PACKAGE_1, USER_ID, 3000), REASON_TIMEOUT);
+        assertEquals(aih.getAppStandbyReason(PACKAGE_1, USER_ID, 3000), REASON_MAIN_TIMEOUT);
 
         // RARE is considered idle
         assertTrue(aih.isIdle(PACKAGE_1, USER_ID, 3000));
@@ -115,7 +118,7 @@
         aih = new AppIdleHistory(mStorageDir, 4000);
         assertEquals(aih.getAppStandbyBucket(PACKAGE_1, USER_ID, 5000), STANDBY_BUCKET_RARE);
         assertEquals(aih.getAppStandbyBucket(PACKAGE_2, USER_ID, 5000), STANDBY_BUCKET_ACTIVE);
-        assertEquals(aih.getAppStandbyReason(PACKAGE_1, USER_ID, 5000), REASON_TIMEOUT);
+        assertEquals(aih.getAppStandbyReason(PACKAGE_1, USER_ID, 5000), REASON_MAIN_TIMEOUT);
 
         assertTrue(aih.shouldInformListeners(PACKAGE_1, USER_ID, 5000, STANDBY_BUCKET_RARE));
         assertFalse(aih.shouldInformListeners(PACKAGE_1, USER_ID, 5000, STANDBY_BUCKET_RARE));
@@ -133,4 +136,18 @@
         assertEquals(1000, aih.getTimeSinceLastJobRun(PACKAGE_2, USER_ID, 7000));
         assertEquals(5000, aih.getTimeSinceLastJobRun(PACKAGE_1, USER_ID, 7000));
     }
+
+    public void testReason() throws Exception {
+        AppIdleHistory aih = new AppIdleHistory(mStorageDir, 1000);
+        aih.reportUsage(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
+                REASON_SUB_USAGE_MOVE_TO_FOREGROUND, 2000, 0);
+        assertEquals(REASON_MAIN_USAGE | REASON_SUB_USAGE_MOVE_TO_FOREGROUND,
+                aih.getAppStandbyReason(PACKAGE_1, USER_ID, 3000));
+        aih.setAppStandbyBucket(PACKAGE_1, USER_ID, 4000, STANDBY_BUCKET_WORKING_SET,
+                REASON_MAIN_TIMEOUT);
+        aih.writeAppIdleTimes(USER_ID);
+
+        aih = new AppIdleHistory(mStorageDir, 5000);
+        assertEquals(REASON_MAIN_TIMEOUT, aih.getAppStandbyReason(PACKAGE_1, USER_ID, 5000));
+    }
 }
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index cbbdca6..edf1f74 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -18,11 +18,11 @@
 
 import static android.app.usage.UsageEvents.Event.NOTIFICATION_SEEN;
 import static android.app.usage.UsageEvents.Event.USER_INTERACTION;
-import static android.app.usage.UsageStatsManager.REASON_DEFAULT;
-import static android.app.usage.UsageStatsManager.REASON_FORCED;
-import static android.app.usage.UsageStatsManager.REASON_PREDICTED;
-import static android.app.usage.UsageStatsManager.REASON_TIMEOUT;
-import static android.app.usage.UsageStatsManager.REASON_USAGE;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_DEFAULT;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_FORCED;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_PREDICTED;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_TIMEOUT;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_USAGE;
 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE;
 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_EXEMPTED;
 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_FREQUENT;
@@ -410,11 +410,11 @@
         setChargingState(mController, false);
         // Set it to timeout or usage, so that prediction can override it
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RARE,
-                REASON_TIMEOUT, 1 * HOUR_MS);
+                REASON_MAIN_TIMEOUT, 1 * HOUR_MS);
         assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController));
 
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
-                REASON_PREDICTED + ":CTS", 1 * HOUR_MS);
+                REASON_MAIN_PREDICTED, 1 * HOUR_MS);
         assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
 
         // Fast forward 12 hours
@@ -440,28 +440,28 @@
         setChargingState(mController, false);
         // Can force to NEVER
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_NEVER,
-                REASON_FORCED, 1 * HOUR_MS);
+                REASON_MAIN_FORCED, 1 * HOUR_MS);
         assertEquals(STANDBY_BUCKET_NEVER, getStandbyBucket(mController));
 
         // Prediction can't override FORCED reason
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
-                REASON_FORCED, 1 * HOUR_MS);
+                REASON_MAIN_FORCED, 1 * HOUR_MS);
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_WORKING_SET,
-                REASON_PREDICTED, 1 * HOUR_MS);
+                REASON_MAIN_PREDICTED, 1 * HOUR_MS);
         assertEquals(STANDBY_BUCKET_FREQUENT, getStandbyBucket(mController));
 
         // Prediction can't override NEVER
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_NEVER,
-                REASON_DEFAULT, 2 * HOUR_MS);
+                REASON_MAIN_DEFAULT, 2 * HOUR_MS);
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
-                REASON_PREDICTED, 2 * HOUR_MS);
+                REASON_MAIN_PREDICTED, 2 * HOUR_MS);
         assertEquals(STANDBY_BUCKET_NEVER, getStandbyBucket(mController));
 
         // Prediction can't set to NEVER
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
-                REASON_USAGE, 2 * HOUR_MS);
+                REASON_MAIN_USAGE, 2 * HOUR_MS);
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_NEVER,
-                REASON_PREDICTED, 2 * HOUR_MS);
+                REASON_MAIN_PREDICTED, 2 * HOUR_MS);
         assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
     }
 
@@ -474,7 +474,7 @@
 
         mInjector.mElapsedRealtime = 2000;
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
-                REASON_PREDICTED, mInjector.mElapsedRealtime);
+                REASON_MAIN_PREDICTED, mInjector.mElapsedRealtime);
         assertBucket(STANDBY_BUCKET_ACTIVE);
 
         // bucketing works after timeout
@@ -483,7 +483,7 @@
         assertBucket(STANDBY_BUCKET_WORKING_SET);
 
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
-                REASON_PREDICTED, mInjector.mElapsedRealtime);
+                REASON_MAIN_PREDICTED, mInjector.mElapsedRealtime);
         assertBucket(STANDBY_BUCKET_FREQUENT);
     }
 
@@ -498,15 +498,15 @@
         assertBucket(STANDBY_BUCKET_ACTIVE);
 
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_WORKING_SET,
-                REASON_PREDICTED, 1000);
+                REASON_MAIN_PREDICTED, 1000);
         assertBucket(STANDBY_BUCKET_ACTIVE);
 
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
-                REASON_PREDICTED, 2000 + mController.mStrongUsageTimeoutMillis);
+                REASON_MAIN_PREDICTED, 2000 + mController.mStrongUsageTimeoutMillis);
         assertBucket(STANDBY_BUCKET_WORKING_SET);
 
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
-                REASON_PREDICTED, 2000 + mController.mNotificationSeenTimeoutMillis);
+                REASON_MAIN_PREDICTED, 2000 + mController.mNotificationSeenTimeoutMillis);
         assertBucket(STANDBY_BUCKET_FREQUENT);
     }
 
@@ -527,18 +527,18 @@
         // Still in ACTIVE after first USER_INTERACTION times out
         mInjector.mElapsedRealtime = mController.mStrongUsageTimeoutMillis + 1000;
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
-                REASON_PREDICTED, mInjector.mElapsedRealtime);
+                REASON_MAIN_PREDICTED, mInjector.mElapsedRealtime);
         assertBucket(STANDBY_BUCKET_ACTIVE);
 
         // Both timed out, so NOTIFICATION_SEEN timeout should be effective
         mInjector.mElapsedRealtime = mController.mStrongUsageTimeoutMillis * 2 + 2000;
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
-                REASON_PREDICTED, mInjector.mElapsedRealtime);
+                REASON_MAIN_PREDICTED, mInjector.mElapsedRealtime);
         assertBucket(STANDBY_BUCKET_WORKING_SET);
 
         mInjector.mElapsedRealtime = mController.mNotificationSeenTimeoutMillis + 2000;
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RARE,
-                REASON_PREDICTED, mInjector.mElapsedRealtime);
+                REASON_MAIN_PREDICTED, mInjector.mElapsedRealtime);
         assertBucket(STANDBY_BUCKET_RARE);
     }
 
@@ -561,7 +561,7 @@
         // Predict to ACTIVE
         mInjector.mElapsedRealtime += 1000;
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
-                REASON_PREDICTED, mInjector.mElapsedRealtime);
+                REASON_MAIN_PREDICTED, mInjector.mElapsedRealtime);
         assertBucket(STANDBY_BUCKET_ACTIVE);
 
         // CheckIdleStates should not change the prediction
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
index b55c79b..79a9610 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
@@ -131,7 +131,6 @@
             assertNoStartingWindow(controller.getAppWindowToken(mDisplayContent));
 
             controller.getAppWindowToken(mDisplayContent).getParent().getParent().removeImmediately();
-            mDisplayContent.onPendingTransactionApplied();
         }
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimatorTest.java b/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimatorTest.java
index 64c3037..a120eba 100644
--- a/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimatorTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimatorTest.java
@@ -23,11 +23,11 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyZeroInteractions;
 
 import android.platform.test.annotations.Presubmit;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.SurfaceControl;
@@ -39,7 +39,6 @@
 import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
@@ -47,7 +46,6 @@
 import org.mockito.MockitoAnnotations;
 
 import java.util.ArrayList;
-import java.util.concurrent.CountDownLatch;
 
 /**
  * Test class for {@link SurfaceAnimatorTest}.
@@ -87,7 +85,7 @@
         callbackCaptor.getValue().onAnimationFinished(mSpec);
         assertNotAnimating(mAnimatable);
         assertTrue(mAnimatable.mFinishedCallbackCalled);
-        assertTrue(mAnimatable.mPendingDestroySurfaces.contains(mAnimatable.mLeash));
+        verify(mTransaction).destroy(eq(mAnimatable.mLeash));
         // TODO: Verify reparenting once we use mPendingTransaction to reparent it back
     }
 
@@ -97,7 +95,7 @@
         final SurfaceControl firstLeash = mAnimatable.mLeash;
         mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec2, true /* hidden */);
 
-        assertTrue(mAnimatable.mPendingDestroySurfaces.contains(firstLeash));
+        verify(mTransaction).destroy(eq(firstLeash));
         assertFalse(mAnimatable.mFinishedCallbackCalled);
 
         final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
@@ -124,7 +122,7 @@
         assertNotAnimating(mAnimatable);
         verify(mSpec).onAnimationCancelled(any());
         assertTrue(mAnimatable.mFinishedCallbackCalled);
-        assertTrue(mAnimatable.mPendingDestroySurfaces.contains(mAnimatable.mLeash));
+        verify(mTransaction).destroy(eq(mAnimatable.mLeash));
     }
 
     @Test
@@ -145,7 +143,7 @@
         verifyZeroInteractions(mSpec);
         assertNotAnimating(mAnimatable);
         assertTrue(mAnimatable.mFinishedCallbackCalled);
-        assertTrue(mAnimatable.mPendingDestroySurfaces.contains(mAnimatable.mLeash));
+        verify(mTransaction).destroy(eq(mAnimatable.mLeash));
     }
 
     @Test
@@ -161,11 +159,11 @@
         assertNotAnimating(mAnimatable);
         assertAnimating(mAnimatable2);
         assertEquals(leash, mAnimatable2.mSurfaceAnimator.mLeash);
-        assertFalse(mAnimatable.mPendingDestroySurfaces.contains(leash));
+        verify(mTransaction, never()).destroy(eq(leash));
         callbackCaptor.getValue().onAnimationFinished(mSpec);
         assertNotAnimating(mAnimatable2);
         assertTrue(mAnimatable2.mFinishedCallbackCalled);
-        assertTrue(mAnimatable2.mPendingDestroySurfaces.contains(leash));
+        verify(mTransaction).destroy(eq(leash));
     }
 
     private void assertAnimating(MyAnimatable animatable) {
@@ -182,7 +180,6 @@
 
         final SurfaceControl mParent;
         final SurfaceControl mSurface;
-        final ArrayList<SurfaceControl> mPendingDestroySurfaces = new ArrayList<>();
         final SurfaceAnimator mSurfaceAnimator;
         SurfaceControl mLeash;
         boolean mFinishedCallbackCalled;
@@ -198,7 +195,7 @@
                     .build();
             mFinishedCallbackCalled = false;
             mLeash = null;
-            mSurfaceAnimator = new SurfaceAnimator(this, mFinishedCallback, Runnable::run, sWm);
+            mSurfaceAnimator = new SurfaceAnimator(this, mFinishedCallback, sWm);
         }
 
         @Override
@@ -219,11 +216,6 @@
         }
 
         @Override
-        public void destroyAfterPendingTransaction(SurfaceControl surface) {
-            mPendingDestroySurfaces.add(surface);
-        }
-
-        @Override
         public Builder makeAnimationLeash() {
             return new SurfaceControl.Builder(mSession) {
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 0b99eaa..206ee7a 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -644,4 +644,8 @@
     public boolean canDismissBootAnimation() {
         return true;
     }
+
+    @Override
+    public void onScreenMagnificationStateChanged(boolean active) {
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/utils/RotationCacheTest.java b/services/tests/servicestests/src/com/android/server/wm/utils/RotationCacheTest.java
new file mode 100644
index 0000000..d3cf978
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/utils/RotationCacheTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.utils;
+
+import static android.util.Pair.create;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Pair;
+
+import com.android.server.wm.utils.RotationCache.RotationDependentComputation;
+
+import org.hamcrest.Matchers;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+public class RotationCacheTest {
+
+    private RotationCache<Object, Pair<Object, Integer>> mCache;
+    private boolean mComputationCalled;
+
+    @Before
+    public void setUp() throws Exception {
+        mComputationCalled = false;
+        mCache = new RotationCache<>((o, rot) -> {
+            mComputationCalled = true;
+            return create(o, rot);
+        });
+    }
+
+    @Test
+    public void getOrCompute_computes() throws Exception {
+        assertThat(mCache.getOrCompute("hello", 0), equalTo(create("hello", 0)));
+        assertThat(mCache.getOrCompute("hello", 1), equalTo(create("hello", 1)));
+        assertThat(mCache.getOrCompute("hello", 2), equalTo(create("hello", 2)));
+        assertThat(mCache.getOrCompute("hello", 3), equalTo(create("hello", 3)));
+    }
+
+    @Test
+    public void getOrCompute_sameParam_sameRot_hitsCache() throws Exception {
+        assertNotNull(mCache.getOrCompute("hello", 1));
+
+        mComputationCalled = false;
+        assertThat(mCache.getOrCompute("hello", 1), equalTo(create("hello", 1)));
+        assertThat(mComputationCalled, is(false));
+    }
+
+    @Test
+    public void getOrCompute_sameParam_hitsCache_forAllRots() throws Exception {
+        assertNotNull(mCache.getOrCompute("hello", 3));
+        assertNotNull(mCache.getOrCompute("hello", 2));
+        assertNotNull(mCache.getOrCompute("hello", 1));
+        assertNotNull(mCache.getOrCompute("hello", 0));
+
+        mComputationCalled = false;
+        assertThat(mCache.getOrCompute("hello", 1), equalTo(create("hello", 1)));
+        assertThat(mCache.getOrCompute("hello", 0), equalTo(create("hello", 0)));
+        assertThat(mCache.getOrCompute("hello", 2), equalTo(create("hello", 2)));
+        assertThat(mCache.getOrCompute("hello", 3), equalTo(create("hello", 3)));
+        assertThat(mComputationCalled, is(false));
+    }
+
+    @Test
+    public void getOrCompute_changingParam_recomputes() throws Exception {
+        assertNotNull(mCache.getOrCompute("hello", 1));
+
+        assertThat(mCache.getOrCompute("world", 1), equalTo(create("world", 1)));
+    }
+
+    @Test
+    public void getOrCompute_changingParam_clearsCacheForDifferentRots() throws Exception {
+        assertNotNull(mCache.getOrCompute("hello", 1));
+        assertNotNull(mCache.getOrCompute("world", 2));
+
+        mComputationCalled = false;
+        assertThat(mCache.getOrCompute("hello", 1), equalTo(create("hello", 1)));
+        assertThat(mComputationCalled, is(true));
+    }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/test-apps/ConnTestApp/Android.mk b/services/tests/servicestests/test-apps/ConnTestApp/Android.mk
index fbfa28a..18b8c2d 100644
--- a/services/tests/servicestests/test-apps/ConnTestApp/Android.mk
+++ b/services/tests/servicestests/test-apps/ConnTestApp/Android.mk
@@ -24,6 +24,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := ConnTestApp
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_CERTIFICATE := platform
 LOCAL_DEX_PREOPT := false
 LOCAL_PROGUARD_ENABLED := disabled
diff --git a/services/tests/uiservicestests/Android.mk b/services/tests/uiservicestests/Android.mk
index d7c3f7f..b98bc89 100644
--- a/services/tests/uiservicestests/Android.mk
+++ b/services/tests/uiservicestests/Android.mk
@@ -31,6 +31,7 @@
 LOCAL_DX_FLAGS := --multi-dex
 
 LOCAL_PACKAGE_NAME := FrameworksUiServicesTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_COMPATIBILITY_SUITE := device-tests
 
 LOCAL_CERTIFICATE := platform
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
index 9ebce71..354d2d5 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
@@ -161,8 +161,8 @@
         when(mTestIContentProvider.uncanonicalize(any(), eq(CANONICAL_SOUND_URI)))
                 .thenReturn(SOUND_URI);
 
-        mHelper = new RankingHelper(getContext(), mPm, mHandler, mUsageStats,
-                new String[] {ImportanceExtractor.class.getName()});
+        mHelper = new RankingHelper(getContext(), mPm, mHandler, mock(ZenModeHelper.class),
+                mUsageStats, new String[] {ImportanceExtractor.class.getName()});
 
         mNotiGroupGSortA = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                 .setContentTitle("A")
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeExtractorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeExtractorTest.java
new file mode 100644
index 0000000..faba6b6
--- /dev/null
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeExtractorTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.notification;
+
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.os.UserHandle;
+import android.service.notification.StatusBarNotification;
+
+import com.android.server.UiServiceTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class ZenModeExtractorTest extends UiServiceTestCase {
+
+    @Mock
+    ZenModeHelper mZenModeHelper;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void testExtractIntercepted() {
+        ZenModeExtractor extractor = new ZenModeExtractor();
+        extractor.setZenHelper(mZenModeHelper);
+        NotificationRecord r = generateRecord();
+
+        assertFalse(r.isIntercepted());
+
+        when(mZenModeHelper.shouldIntercept(any())).thenReturn(true);
+
+        extractor.process(r);
+
+        assertTrue(r.isIntercepted());
+    }
+
+    @Test
+    public void testExtractVisualDisturbancesNotIntercepted() {
+        ZenModeExtractor extractor = new ZenModeExtractor();
+        extractor.setZenHelper(mZenModeHelper);
+        NotificationRecord r = generateRecord();
+
+        when(mZenModeHelper.shouldIntercept(any())).thenReturn(false);
+        when(mZenModeHelper.shouldSuppressWhenScreenOff()).thenReturn(false);
+
+        extractor.process(r);
+
+        assertEquals(0, r.getSuppressedVisualEffects());
+    }
+
+    @Test
+    public void testExtractVisualDisturbancesIntercepted() {
+        ZenModeExtractor extractor = new ZenModeExtractor();
+        extractor.setZenHelper(mZenModeHelper);
+        NotificationRecord r = generateRecord();
+
+        when(mZenModeHelper.shouldIntercept(any())).thenReturn(true);
+        when(mZenModeHelper.shouldSuppressWhenScreenOff()).thenReturn(true);
+        when(mZenModeHelper.shouldSuppressWhenScreenOn()).thenReturn(true);
+
+        extractor.process(r);
+
+        assertEquals(NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF
+                | NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON,
+                r.getSuppressedVisualEffects());
+    }
+
+    private NotificationRecord generateRecord() {
+        NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
+        final Notification.Builder builder = new Notification.Builder(getContext())
+                .setContentTitle("foo")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon);
+        Notification n = builder.build();
+        StatusBarNotification sbn = new StatusBarNotification("", "", 0, "", 0,
+                0, n, UserHandle.ALL, null, System.currentTimeMillis());
+        return new NotificationRecord(getContext(), sbn, channel);
+    }
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java b/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java
index cfd155e..1052e8f 100644
--- a/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java
@@ -71,6 +71,7 @@
     private PinnedSliceState mPinnedSliceManager;
     private IContentProvider mIContentProvider;
     private ContentProvider mContentProvider;
+    private IBinder mToken = new Binder();
 
     @Before
     public void setup() {
@@ -108,7 +109,7 @@
         TestableLooper.get(this).processAllMessages();
 
         // When pinned for the first time, a pinned message should be sent.
-        mPinnedSliceManager.pin("pkg", FIRST_SPECS);
+        mPinnedSliceManager.pin("pkg", FIRST_SPECS, mToken);
         TestableLooper.get(this).processAllMessages();
 
         verify(mIContentProvider).call(anyString(), eq(SliceProvider.METHOD_PIN), eq(null),
@@ -119,112 +120,27 @@
     }
 
     @Test
-    public void testSendPinnedOnListen() throws RemoteException {
-        TestableLooper.get(this).processAllMessages();
-
-        // When a listener is added for the first time, a pinned message should be sent.
-        ISliceListener listener = mock(ISliceListener.class);
-        when(listener.asBinder()).thenReturn(new Binder());
-
-        mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
-                true);
-        TestableLooper.get(this).processAllMessages();
-
-        verify(mIContentProvider).call(anyString(), eq(SliceProvider.METHOD_PIN), eq(null),
-                argThat(b -> {
-                    assertEquals(TEST_URI, b.getParcelable(SliceProvider.EXTRA_BIND_URI));
-                    return true;
-                }));
-    }
-
-    @Test
-    public void testNoSendPinnedWithoutPermission() throws RemoteException {
-        TestableLooper.get(this).processAllMessages();
-
-        // When a listener is added for the first time, a pinned message should be sent.
-        ISliceListener listener = mock(ISliceListener.class);
-        when(listener.asBinder()).thenReturn(new Binder());
-
-        mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
-                false);
-        TestableLooper.get(this).processAllMessages();
-
-        verify(mIContentProvider, never()).call(anyString(), eq(SliceProvider.METHOD_PIN), eq(null),
-                any());
-    }
-
-    @Test
-    public void testSendUnpinnedOnDestroy() throws RemoteException {
-        TestableLooper.get(this).processAllMessages();
-        clearInvocations(mIContentProvider);
-
-        mPinnedSliceManager.pin("pkg", FIRST_SPECS);
-        mPinnedSliceManager.destroy();
-        TestableLooper.get(this).processAllMessages();
-
-        verify(mIContentProvider).call(anyString(), eq(SliceProvider.METHOD_UNPIN), eq(null),
-                argThat(b -> {
-                    assertEquals(TEST_URI, b.getParcelable(SliceProvider.EXTRA_BIND_URI));
-                    return true;
-                }));
-    }
-
-    @Test
     public void testPkgPin() {
         assertFalse(mPinnedSliceManager.hasPinOrListener());
 
-        mPinnedSliceManager.pin("pkg", FIRST_SPECS);
+        mPinnedSliceManager.pin("pkg", FIRST_SPECS, mToken);
         assertTrue(mPinnedSliceManager.hasPinOrListener());
 
-        assertTrue(mPinnedSliceManager.unpin("pkg"));
+        assertTrue(mPinnedSliceManager.unpin("pkg", mToken));
         assertFalse(mPinnedSliceManager.hasPinOrListener());
     }
 
     @Test
     public void testMultiPkgPin() {
+        IBinder t2 = new Binder();
         assertFalse(mPinnedSliceManager.hasPinOrListener());
 
-        mPinnedSliceManager.pin("pkg", FIRST_SPECS);
+        mPinnedSliceManager.pin("pkg", FIRST_SPECS, mToken);
         assertTrue(mPinnedSliceManager.hasPinOrListener());
-        mPinnedSliceManager.pin("pkg2", FIRST_SPECS);
+        mPinnedSliceManager.pin("pkg2", FIRST_SPECS, t2);
 
-        assertFalse(mPinnedSliceManager.unpin("pkg"));
-        assertTrue(mPinnedSliceManager.unpin("pkg2"));
-        assertFalse(mPinnedSliceManager.hasPinOrListener());
-    }
-
-    @Test
-    public void testListenerPin() {
-        ISliceListener listener = mock(ISliceListener.class);
-        when(listener.asBinder()).thenReturn(new Binder());
-        assertFalse(mPinnedSliceManager.hasPinOrListener());
-
-        mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
-                true);
-        assertTrue(mPinnedSliceManager.hasPinOrListener());
-
-        assertTrue(mPinnedSliceManager.removeSliceListener(listener));
-        assertFalse(mPinnedSliceManager.hasPinOrListener());
-    }
-
-    @Test
-    public void testMultiListenerPin() {
-        ISliceListener listener = mock(ISliceListener.class);
-        Binder value = new Binder();
-        when(listener.asBinder()).thenReturn(value);
-        ISliceListener listener2 = mock(ISliceListener.class);
-        Binder value2 = new Binder();
-        when(listener2.asBinder()).thenReturn(value2);
-        assertFalse(mPinnedSliceManager.hasPinOrListener());
-
-        mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
-                true);
-        assertTrue(mPinnedSliceManager.hasPinOrListener());
-        mPinnedSliceManager.addSliceListener(listener2, mContext.getPackageName(), FIRST_SPECS,
-                true);
-
-        assertFalse(mPinnedSliceManager.removeSliceListener(listener));
-        assertTrue(mPinnedSliceManager.removeSliceListener(listener2));
+        assertFalse(mPinnedSliceManager.unpin("pkg", mToken));
+        assertTrue(mPinnedSliceManager.unpin("pkg2", t2));
         assertFalse(mPinnedSliceManager.hasPinOrListener());
     }
 
@@ -236,8 +152,7 @@
         when(listener.asBinder()).thenReturn(binder);
         assertFalse(mPinnedSliceManager.hasPinOrListener());
 
-        mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
-                true);
+        mPinnedSliceManager.pin(mContext.getPackageName(), FIRST_SPECS, binder);
         assertTrue(mPinnedSliceManager.hasPinOrListener());
 
         ArgumentCaptor<DeathRecipient> arg = ArgumentCaptor.forClass(DeathRecipient.class);
@@ -246,79 +161,7 @@
         when(binder.isBinderAlive()).thenReturn(false);
         arg.getValue().binderDied();
 
-        verify(mSliceService).unlisten(eq(TEST_URI));
         verify(mSliceService).removePinnedSlice(eq(TEST_URI));
         assertFalse(mPinnedSliceManager.hasPinOrListener());
     }
-
-    @Test
-    public void testPkgListenerPin() {
-        ISliceListener listener = mock(ISliceListener.class);
-        when(listener.asBinder()).thenReturn(new Binder());
-        assertFalse(mPinnedSliceManager.hasPinOrListener());
-
-        mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
-                true);
-        assertTrue(mPinnedSliceManager.hasPinOrListener());
-        mPinnedSliceManager.pin("pkg", FIRST_SPECS);
-
-        assertFalse(mPinnedSliceManager.removeSliceListener(listener));
-        assertTrue(mPinnedSliceManager.unpin("pkg"));
-        assertFalse(mPinnedSliceManager.hasPinOrListener());
-    }
-
-    @Test
-    public void testBind() throws RemoteException {
-        TestableLooper.get(this).processAllMessages();
-        clearInvocations(mIContentProvider);
-
-        ISliceListener listener = mock(ISliceListener.class);
-        when(listener.asBinder()).thenReturn(new Binder());
-        Slice s = new Slice.Builder(TEST_URI).build();
-        Bundle b = new Bundle();
-        b.putParcelable(SliceProvider.EXTRA_SLICE, s);
-        when(mIContentProvider.call(anyString(), eq(SliceProvider.METHOD_SLICE), eq(null),
-                any())).thenReturn(b);
-
-        assertFalse(mPinnedSliceManager.hasPinOrListener());
-
-        mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
-                true);
-
-        mPinnedSliceManager.onChange();
-        TestableLooper.get(this).processAllMessages();
-
-        verify(mIContentProvider).call(anyString(), eq(SliceProvider.METHOD_SLICE), eq(null),
-                argThat(bundle -> {
-                    assertEquals(TEST_URI, bundle.getParcelable(SliceProvider.EXTRA_BIND_URI));
-                    return true;
-                }));
-        verify(listener).onSliceUpdated(eq(s));
-    }
-
-    @Test
-    public void testRecheckPackage() throws RemoteException {
-        TestableLooper.get(this).processAllMessages();
-
-        ISliceListener listener = mock(ISliceListener.class);
-        when(listener.asBinder()).thenReturn(new Binder());
-
-        mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
-                false);
-        TestableLooper.get(this).processAllMessages();
-
-        verify(mIContentProvider, never()).call(anyString(), eq(SliceProvider.METHOD_PIN), eq(null),
-                any());
-
-        when(mSliceService.checkAccess(any(), any(), anyInt(), anyInt()))
-                .thenReturn(PERMISSION_GRANTED);
-        mPinnedSliceManager.recheckPackage(mContext.getPackageName());
-        TestableLooper.get(this).processAllMessages();
-
-        verify(mIContentProvider).call(anyString(), eq(SliceProvider.METHOD_PIN), eq(null),
-                argThat(b -> {
-                    assertEquals(TEST_URI, b.getParcelable(SliceProvider.EXTRA_BIND_URI));
-                    return true;
-                }));
-    }
 }
\ No newline at end of file
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
index fe9ea7a..6fc3009 100644
--- a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
@@ -32,6 +32,8 @@
 import android.app.slice.SliceSpec;
 import android.content.pm.PackageManagerInternal;
 import android.net.Uri;
+import android.os.Binder;
+import android.os.IBinder;
 import android.os.RemoteException;
 import android.support.test.filters.SmallTest;
 import android.testing.AndroidTestingRunner;
@@ -59,6 +61,7 @@
 
     private SliceManagerService mService;
     private PinnedSliceState mCreatedSliceState;
+    private IBinder mToken = new Binder();
 
     @Before
     public void setup() {
@@ -77,43 +80,11 @@
     }
 
     @Test
-    public void testAddListenerCreatesPinned() throws RemoteException {
-        mService.addSliceListener(TEST_URI, "pkg", mock(ISliceListener.class), EMPTY_SPECS);
-        verify(mService, times(1)).createPinnedSlice(eq(TEST_URI));
-    }
-
-    @Test
-    public void testAddListenerCreatesOnePinned() throws RemoteException {
-        mService.addSliceListener(TEST_URI, "pkg", mock(ISliceListener.class), EMPTY_SPECS);
-        mService.addSliceListener(TEST_URI, "pkg", mock(ISliceListener.class), EMPTY_SPECS);
-        verify(mService, times(1)).createPinnedSlice(eq(TEST_URI));
-    }
-
-    @Test
-    public void testRemoveListenerDestroysPinned() throws RemoteException {
-        ISliceListener listener = mock(ISliceListener.class);
-        mService.addSliceListener(TEST_URI, "pkg", listener, EMPTY_SPECS);
-
-        when(mCreatedSliceState.removeSliceListener(eq(listener))).thenReturn(false);
-        mService.removeSliceListener(TEST_URI, "pkg", listener);
-        verify(mCreatedSliceState, never()).destroy();
-
-        when(mCreatedSliceState.removeSliceListener(eq(listener))).thenReturn(true);
-        mService.removeSliceListener(TEST_URI, "pkg", listener);
-        verify(mCreatedSliceState).destroy();
-    }
-
-    @Test(expected = IllegalStateException.class)
-    public void testUnrecognizedThrows() throws RemoteException {
-        mService.removeSliceListener(TEST_URI, "pkg", mock(ISliceListener.class));
-    }
-
-    @Test
     public void testAddPinCreatesPinned() throws RemoteException {
         doReturn("pkg").when(mService).getDefaultHome(anyInt());
 
-        mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS);
-        mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS);
+        mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken);
+        mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken);
         verify(mService, times(1)).createPinnedSlice(eq(TEST_URI));
     }
 
@@ -121,15 +92,11 @@
     public void testRemovePinDestroysPinned() throws RemoteException {
         doReturn("pkg").when(mService).getDefaultHome(anyInt());
 
-        mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS);
+        mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken);
 
-        when(mCreatedSliceState.unpin(eq("pkg"))).thenReturn(false);
-        mService.unpinSlice("pkg", TEST_URI);
+        when(mCreatedSliceState.unpin(eq("pkg"), eq(mToken))).thenReturn(false);
+        mService.unpinSlice("pkg", TEST_URI, mToken);
         verify(mCreatedSliceState, never()).destroy();
-
-        when(mCreatedSliceState.unpin(eq("pkg"))).thenReturn(true);
-        mService.unpinSlice("pkg", TEST_URI);
-        verify(mCreatedSliceState).destroy();
     }
 
 }
\ No newline at end of file
diff --git a/services/usage/java/com/android/server/usage/AppIdleHistory.java b/services/usage/java/com/android/server/usage/AppIdleHistory.java
index f26c2ae..fd28b65 100644
--- a/services/usage/java/com/android/server/usage/AppIdleHistory.java
+++ b/services/usage/java/com/android/server/usage/AppIdleHistory.java
@@ -16,15 +16,18 @@
 
 package com.android.server.usage;
 
-import static android.app.usage.UsageStatsManager.REASON_DEFAULT;
-import static android.app.usage.UsageStatsManager.REASON_FORCED;
-import static android.app.usage.UsageStatsManager.REASON_PREDICTED;
-import static android.app.usage.UsageStatsManager.REASON_USAGE;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_DEFAULT;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_FORCED;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_MASK;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_PREDICTED;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_USAGE;
+import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_USER_INTERACTION;
 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE;
 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_NEVER;
 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE;
 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET;
 
+import android.app.usage.AppStandbyInfo;
 import android.app.usage.UsageStatsManager;
 import android.os.SystemClock;
 import android.util.ArrayMap;
@@ -37,8 +40,6 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.LocalServices;
-import com.android.server.job.JobSchedulerInternal;
 
 import libcore.io.IoUtils;
 
@@ -53,8 +54,7 @@
 import java.io.FileReader;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.ArrayList;
 
 /**
  * Keeps track of recent active state changes in apps.
@@ -114,8 +114,10 @@
         // Standby bucket
         @UsageStatsManager.StandbyBuckets
         int currentBucket;
-        // Reason for setting the standby bucket. TODO: Switch to int.
-        String bucketingReason;
+        // Reason for setting the standby bucket. The value here is a combination of
+        // one of UsageStatsManager.REASON_MAIN_* and one (or none) of
+        // UsageStatsManager.REASON_SUB_*. Also see REASON_MAIN_MASK and REASON_SUB_MASK.
+        int bucketingReason;
         // In-memory only, last bucket for which the listeners were informed
         int lastInformedBucket;
         // The last time a job was run for this app, using elapsed timebase
@@ -214,13 +216,14 @@
      * @param appUsageHistory the usage record for the app being updated
      * @param packageName name of the app being updated, for logging purposes
      * @param newBucket the bucket to set the app to
+     * @param usageReason the sub-reason for usage, one of REASON_SUB_USAGE_*
      * @param elapsedRealtime mark as used time if non-zero
      * @param timeout set the timeout of the specified bucket, if non-zero. Can only be used
      *                with bucket values of ACTIVE and WORKING_SET.
      * @return
      */
     public AppUsageHistory reportUsage(AppUsageHistory appUsageHistory, String packageName,
-            int newBucket, long elapsedRealtime, long timeout) {
+            int newBucket, int usageReason, long elapsedRealtime, long timeout) {
         // Set the timeout if applicable
         if (timeout > elapsedRealtime) {
             // Convert to elapsed timebase
@@ -248,10 +251,10 @@
             if (DEBUG) {
                 Slog.d(TAG, "Moved " + packageName + " to bucket=" + appUsageHistory
                         .currentBucket
-                        + ", reason=" + appUsageHistory.bucketingReason);
+                        + ", reason=0x0" + Integer.toHexString(appUsageHistory.bucketingReason));
             }
         }
-        appUsageHistory.bucketingReason = REASON_USAGE;
+        appUsageHistory.bucketingReason = REASON_MAIN_USAGE | usageReason;
 
         return appUsageHistory;
     }
@@ -264,16 +267,17 @@
      * @param packageName
      * @param userId
      * @param newBucket the bucket to set the app to
-     * @param elapsedRealtime mark as used time if non-zero
+     * @param usageReason sub reason for usage
+     * @param nowElapsed mark as used time if non-zero
      * @param timeout set the timeout of the specified bucket, if non-zero. Can only be used
      *                with bucket values of ACTIVE and WORKING_SET.
      * @return
      */
     public AppUsageHistory reportUsage(String packageName, int userId, int newBucket,
-            long nowElapsed, long timeout) {
+            int usageReason, long nowElapsed, long timeout) {
         ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId);
         AppUsageHistory history = getPackageHistory(userHistory, packageName, nowElapsed, true);
-        return reportUsage(history, packageName, newBucket, nowElapsed, timeout);
+        return reportUsage(history, packageName, newBucket, usageReason, nowElapsed, timeout);
     }
 
     private ArrayMap<String, AppUsageHistory> getUserHistory(int userId) {
@@ -295,7 +299,7 @@
             appUsageHistory.lastUsedScreenTime = getScreenOnTime(elapsedRealtime);
             appUsageHistory.lastPredictedTime = getElapsedTime(0);
             appUsageHistory.currentBucket = STANDBY_BUCKET_NEVER;
-            appUsageHistory.bucketingReason = REASON_DEFAULT;
+            appUsageHistory.bucketingReason = REASON_MAIN_DEFAULT;
             appUsageHistory.lastInformedBucket = -1;
             appUsageHistory.lastJobRunTime = Long.MIN_VALUE; // long long time ago
             userHistory.put(packageName, appUsageHistory);
@@ -330,18 +334,18 @@
     }
 
     public void setAppStandbyBucket(String packageName, int userId, long elapsedRealtime,
-            int bucket, String reason) {
+            int bucket, int reason) {
         ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId);
         AppUsageHistory appUsageHistory =
                 getPackageHistory(userHistory, packageName, elapsedRealtime, true);
         appUsageHistory.currentBucket = bucket;
         appUsageHistory.bucketingReason = reason;
-        if (reason.startsWith(REASON_PREDICTED)) {
+        if ((reason & REASON_MAIN_MASK) == REASON_MAIN_PREDICTED) {
             appUsageHistory.lastPredictedTime = getElapsedTime(elapsedRealtime);
         }
         if (DEBUG) {
             Slog.d(TAG, "Moved " + packageName + " to bucket=" + appUsageHistory.currentBucket
-                    + ", reason=" + appUsageHistory.bucketingReason);
+                    + ", reason=0x0" + Integer.toHexString(appUsageHistory.bucketingReason));
         }
     }
 
@@ -384,23 +388,22 @@
         return appUsageHistory.currentBucket;
     }
 
-    public Map<String, Integer> getAppStandbyBuckets(int userId, long elapsedRealtime,
-            boolean appIdleEnabled) {
+    public ArrayList<AppStandbyInfo> getAppStandbyBuckets(int userId, boolean appIdleEnabled) {
         ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId);
         int size = userHistory.size();
-        HashMap<String, Integer> buckets = new HashMap<>(size);
+        ArrayList<AppStandbyInfo> buckets = new ArrayList<>(size);
         for (int i = 0; i < size; i++) {
-            buckets.put(userHistory.keyAt(i),
-                    appIdleEnabled ? userHistory.valueAt(i).currentBucket : STANDBY_BUCKET_ACTIVE);
+            buckets.add(new AppStandbyInfo(userHistory.keyAt(i),
+                    appIdleEnabled ? userHistory.valueAt(i).currentBucket : STANDBY_BUCKET_ACTIVE));
         }
         return buckets;
     }
 
-    public String getAppStandbyReason(String packageName, int userId, long elapsedRealtime) {
+    public int getAppStandbyReason(String packageName, int userId, long elapsedRealtime) {
         ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId);
         AppUsageHistory appUsageHistory =
                 getPackageHistory(userHistory, packageName, elapsedRealtime, false);
-        return appUsageHistory != null ? appUsageHistory.bucketingReason : null;
+        return appUsageHistory != null ? appUsageHistory.bucketingReason : 0;
     }
 
     public long getElapsedTime(long elapsedRealtime) {
@@ -414,11 +417,11 @@
                 elapsedRealtime, true);
         if (idle) {
             appUsageHistory.currentBucket = STANDBY_BUCKET_RARE;
-            appUsageHistory.bucketingReason = REASON_FORCED;
+            appUsageHistory.bucketingReason = REASON_MAIN_FORCED;
         } else {
             appUsageHistory.currentBucket = STANDBY_BUCKET_ACTIVE;
             // This is to pretend that the app was just used, don't freeze the state anymore.
-            appUsageHistory.bucketingReason = REASON_USAGE;
+            appUsageHistory.bucketingReason = REASON_MAIN_USAGE | REASON_SUB_USAGE_USER_INTERACTION;
         }
         return appUsageHistory.currentBucket;
     }
@@ -519,7 +522,7 @@
                         appUsageHistory.currentBucket = currentBucketString == null
                                 ? STANDBY_BUCKET_ACTIVE
                                 : Integer.parseInt(currentBucketString);
-                        appUsageHistory.bucketingReason =
+                        String bucketingReason =
                                 parser.getAttributeValue(null, ATTR_BUCKETING_REASON);
                         appUsageHistory.lastJobRunTime = getLongValue(parser,
                                 ATTR_LAST_RUN_JOB_TIME, Long.MIN_VALUE);
@@ -527,8 +530,13 @@
                                 ATTR_BUCKET_ACTIVE_TIMEOUT_TIME, 0L);
                         appUsageHistory.bucketWorkingSetTimeoutTime = getLongValue(parser,
                                 ATTR_BUCKET_WORKING_SET_TIMEOUT_TIME, 0L);
-                        if (appUsageHistory.bucketingReason == null) {
-                            appUsageHistory.bucketingReason = REASON_DEFAULT;
+                        appUsageHistory.bucketingReason = REASON_MAIN_DEFAULT;
+                        if (bucketingReason != null) {
+                            try {
+                                appUsageHistory.bucketingReason =
+                                        Integer.parseInt(bucketingReason, 16);
+                            } catch (NumberFormatException nfe) {
+                            }
                         }
                         appUsageHistory.lastInformedBucket = -1;
                         userHistory.put(packageName, appUsageHistory);
@@ -577,7 +585,8 @@
                         Long.toString(history.lastPredictedTime));
                 xml.attribute(null, ATTR_CURRENT_BUCKET,
                         Integer.toString(history.currentBucket));
-                xml.attribute(null, ATTR_BUCKETING_REASON, history.bucketingReason);
+                xml.attribute(null, ATTR_BUCKETING_REASON,
+                        Integer.toHexString(history.bucketingReason));
                 if (history.bucketActiveTimeoutTime > 0) {
                     xml.attribute(null, ATTR_BUCKET_ACTIVE_TIMEOUT_TIME, Long.toString(history
                             .bucketActiveTimeoutTime));
@@ -603,7 +612,7 @@
     }
 
     public void dump(IndentingPrintWriter idpw, int userId, String pkg) {
-        idpw.println("Package idle stats:");
+        idpw.println("App Standby States:");
         idpw.increaseIndent();
         ArrayMap<String, AppUsageHistory> userHistory = mIdleHistory.get(userId);
         final long elapsedRealtime = SystemClock.elapsedRealtime();
@@ -618,24 +627,25 @@
                 continue;
             }
             idpw.print("package=" + packageName);
-            idpw.print(" userId=" + userId);
-            idpw.print(" lastUsedElapsed=");
+            idpw.print(" u=" + userId);
+            idpw.print(" bucket=" + appUsageHistory.currentBucket
+                    + " reason="
+                    + UsageStatsManager.reasonToString(appUsageHistory.bucketingReason));
+            idpw.print(" used=");
             TimeUtils.formatDuration(totalElapsedTime - appUsageHistory.lastUsedElapsedTime, idpw);
-            idpw.print(" lastUsedScreenOn=");
+            idpw.print(" usedScr=");
             TimeUtils.formatDuration(screenOnTime - appUsageHistory.lastUsedScreenTime, idpw);
-            idpw.print(" lastPredictedTime=");
+            idpw.print(" lastPred=");
             TimeUtils.formatDuration(totalElapsedTime - appUsageHistory.lastPredictedTime, idpw);
-            idpw.print(" bucketActiveTimeoutTime=");
-            TimeUtils.formatDuration(totalElapsedTime - appUsageHistory.bucketActiveTimeoutTime,
+            idpw.print(" activeLeft=");
+            TimeUtils.formatDuration(appUsageHistory.bucketActiveTimeoutTime - totalElapsedTime,
                     idpw);
-            idpw.print(" bucketWorkingSetTimeoutTime=");
-            TimeUtils.formatDuration(totalElapsedTime - appUsageHistory.bucketWorkingSetTimeoutTime,
+            idpw.print(" wsLeft=");
+            TimeUtils.formatDuration(appUsageHistory.bucketWorkingSetTimeoutTime - totalElapsedTime,
                     idpw);
-            idpw.print(" lastJobRunTime=");
+            idpw.print(" lastJob=");
             TimeUtils.formatDuration(totalElapsedTime - appUsageHistory.lastJobRunTime, idpw);
             idpw.print(" idle=" + (isIdle(packageName, userId, elapsedRealtime) ? "y" : "n"));
-            idpw.print(" bucket=" + appUsageHistory.currentBucket
-                    + " reason=" + appUsageHistory.bucketingReason);
             idpw.println();
         }
         idpw.println();
diff --git a/services/usage/java/com/android/server/usage/AppStandbyController.java b/services/usage/java/com/android/server/usage/AppStandbyController.java
index c31809e..e836677 100644
--- a/services/usage/java/com/android/server/usage/AppStandbyController.java
+++ b/services/usage/java/com/android/server/usage/AppStandbyController.java
@@ -16,11 +16,20 @@
 
 package com.android.server.usage;
 
-import static android.app.usage.UsageStatsManager.REASON_DEFAULT;
-import static android.app.usage.UsageStatsManager.REASON_FORCED;
-import static android.app.usage.UsageStatsManager.REASON_PREDICTED;
-import static android.app.usage.UsageStatsManager.REASON_TIMEOUT;
-import static android.app.usage.UsageStatsManager.REASON_USAGE;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_DEFAULT;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_FORCED;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_MASK;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_PREDICTED;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_TIMEOUT;
+import static android.app.usage.UsageStatsManager.REASON_MAIN_USAGE;
+import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_ACTIVE_TIMEOUT;
+import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_MOVE_TO_BACKGROUND;
+import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_MOVE_TO_FOREGROUND;
+import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_NOTIFICATION_SEEN;
+import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_SYNC_ADAPTER;
+import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_SYSTEM_INTERACTION;
+import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_SYSTEM_UPDATE;
+import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_USER_INTERACTION;
 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE;
 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_EXEMPTED;
 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_FREQUENT;
@@ -33,6 +42,7 @@
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.AppGlobals;
+import android.app.usage.AppStandbyInfo;
 import android.app.usage.UsageStatsManager.StandbyBuckets;
 import android.app.usage.UsageEvents;
 import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
@@ -128,8 +138,8 @@
             STANDBY_BUCKET_RARE
     };
 
-    // Expiration time for predicted bucket
-    private static final long PREDICTION_TIMEOUT = 12 * ONE_HOUR;
+    /** Default expiration time for bucket prediction. After this, use thresholds to downgrade. */
+    private static final long DEFAULT_PREDICTION_TIMEOUT = 12 * ONE_HOUR;
 
     /**
      * Indicates the maximum wait time for admin data to be available;
@@ -186,6 +196,8 @@
     long mNotificationSeenTimeoutMillis;
     /** Minimum time a system update event should keep the buckets elevated. */
     long mSystemUpdateUsageTimeoutMillis;
+    /** Maximum time to wait for a prediction before using simple timeouts to downgrade buckets. */
+    long mPredictionTimeoutMillis;
 
     volatile boolean mAppIdleEnabled;
     boolean mAppIdleTempParoled;
@@ -222,24 +234,30 @@
         // Whether the bucket change is because the user has started interacting with the app
         boolean isUserInteraction;
 
-        StandbyUpdateRecord(String pkgName, int userId, int bucket, boolean isInteraction) {
+        // Reason for bucket change
+        int reason;
+
+        StandbyUpdateRecord(String pkgName, int userId, int bucket, int reason,
+                boolean isInteraction) {
             this.packageName = pkgName;
             this.userId = userId;
             this.bucket = bucket;
+            this.reason = reason;
             this.isUserInteraction = isInteraction;
         }
 
         public static StandbyUpdateRecord obtain(String pkgName, int userId,
-                int bucket, boolean isInteraction) {
+                int bucket, int reason, boolean isInteraction) {
             synchronized (sStandbyUpdatePool) {
                 final int size = sStandbyUpdatePool.size();
                 if (size < 1) {
-                    return new StandbyUpdateRecord(pkgName, userId, bucket, isInteraction);
+                    return new StandbyUpdateRecord(pkgName, userId, bucket, reason, isInteraction);
                 }
                 StandbyUpdateRecord r = sStandbyUpdatePool.remove(size - 1);
                 r.packageName = pkgName;
                 r.userId = userId;
                 r.bucket = bucket;
+                r.reason = reason;
                 r.isUserInteraction = isInteraction;
                 return r;
             }
@@ -338,10 +356,11 @@
                 if (!packageName.equals(providerPkgName)) {
                     synchronized (mAppIdleLock) {
                         AppUsageHistory appUsage = mAppIdleHistory.reportUsage(packageName, userId,
-                                STANDBY_BUCKET_ACTIVE, elapsedRealtime,
+                                STANDBY_BUCKET_ACTIVE, REASON_SUB_USAGE_SYNC_ADAPTER,
+                                elapsedRealtime,
                                 elapsedRealtime + mStrongUsageTimeoutMillis);
                         maybeInformListeners(packageName, userId, elapsedRealtime,
-                                appUsage.currentBucket, false);
+                                appUsage.currentBucket, appUsage.bucketingReason, false);
                     }
                 }
             } catch (PackageManager.NameNotFoundException e) {
@@ -496,50 +515,54 @@
         if (isSpecial) {
             synchronized (mAppIdleLock) {
                 mAppIdleHistory.setAppStandbyBucket(packageName, userId, elapsedRealtime,
-                        STANDBY_BUCKET_EXEMPTED, REASON_DEFAULT);
+                        STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT);
             }
             maybeInformListeners(packageName, userId, elapsedRealtime,
-                    STANDBY_BUCKET_EXEMPTED, false);
+                    STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT, false);
         } else {
             synchronized (mAppIdleLock) {
                 final AppIdleHistory.AppUsageHistory app =
                         mAppIdleHistory.getAppUsageHistory(packageName,
                         userId, elapsedRealtime);
-                String reason = app.bucketingReason;
+                int reason = app.bucketingReason;
+                final int oldMainReason = reason & REASON_MAIN_MASK;
 
                 // If the bucket was forced by the user/developer, leave it alone.
                 // A usage event will be the only way to bring it out of this forced state
-                if (REASON_FORCED.equals(app.bucketingReason)) {
+                if (oldMainReason == REASON_MAIN_FORCED) {
                     return;
                 }
                 final int oldBucket = app.currentBucket;
                 int newBucket = Math.max(oldBucket, STANDBY_BUCKET_ACTIVE); // Undo EXEMPTED
                 boolean predictionLate = false;
                 // Compute age-based bucket
-                if (REASON_DEFAULT.equals(app.bucketingReason)
-                        || REASON_USAGE.equals(app.bucketingReason)
-                        || REASON_TIMEOUT.equals(app.bucketingReason)
+                if (oldMainReason == REASON_MAIN_DEFAULT
+                        || oldMainReason == REASON_MAIN_USAGE
+                        || oldMainReason == REASON_MAIN_TIMEOUT
                         || (predictionLate = predictionTimedOut(app, elapsedRealtime))) {
                     newBucket = getBucketForLocked(packageName, userId,
                             elapsedRealtime);
                     if (DEBUG) {
                         Slog.d(TAG, "Evaluated AOSP newBucket = " + newBucket);
                     }
-                    reason = REASON_TIMEOUT;
+                    reason = REASON_MAIN_TIMEOUT;
                 }
                 // Check if the app is within one of the timeouts for forced bucket elevation
                 final long elapsedTimeAdjusted = mAppIdleHistory.getElapsedTime(elapsedRealtime);
                 if (newBucket >= STANDBY_BUCKET_ACTIVE
                         && app.bucketActiveTimeoutTime > elapsedTimeAdjusted) {
                     newBucket = STANDBY_BUCKET_ACTIVE;
-                    reason = REASON_USAGE;
+                    reason = app.bucketingReason;
                     if (DEBUG) {
                         Slog.d(TAG, "    Keeping at ACTIVE due to min timeout");
                     }
                 } else if (newBucket >= STANDBY_BUCKET_WORKING_SET
                         && app.bucketWorkingSetTimeoutTime > elapsedTimeAdjusted) {
                     newBucket = STANDBY_BUCKET_WORKING_SET;
-                    reason = REASON_USAGE;
+                    // If it was already there, keep the reason, else assume timeout to WS
+                    reason = (newBucket == oldBucket)
+                            ? app.bucketingReason
+                            : REASON_MAIN_USAGE | REASON_SUB_USAGE_ACTIVE_TIMEOUT;
                     if (DEBUG) {
                         Slog.d(TAG, "    Keeping at WORKING_SET due to min timeout");
                     }
@@ -552,43 +575,41 @@
                     mAppIdleHistory.setAppStandbyBucket(packageName, userId,
                             elapsedRealtime, newBucket, reason);
                     maybeInformListeners(packageName, userId, elapsedRealtime,
-                            newBucket, false);
+                            newBucket, reason, false);
                 }
             }
         }
     }
 
+    /** Returns true if there hasn't been a prediction for the app in a while. */
     private boolean predictionTimedOut(AppIdleHistory.AppUsageHistory app, long elapsedRealtime) {
-        return app.bucketingReason != null
-                && app.bucketingReason.startsWith(REASON_PREDICTED)
+        return (app.bucketingReason & REASON_MAIN_MASK) == REASON_MAIN_PREDICTED
                 && app.lastPredictedTime > 0
                 && mAppIdleHistory.getElapsedTime(elapsedRealtime)
-                    - app.lastPredictedTime > PREDICTION_TIMEOUT;
+                    - app.lastPredictedTime > mPredictionTimeoutMillis;
     }
 
-    private boolean hasBucketTimeoutPassed(AppIdleHistory.AppUsageHistory app,
-            long elapsedRealtime) {
-        final long elapsedTimeAdjusted = mAppIdleHistory.getElapsedTime(elapsedRealtime);
-        return app.bucketActiveTimeoutTime < elapsedTimeAdjusted
-                && app.bucketWorkingSetTimeoutTime < elapsedTimeAdjusted;
-    }
-
+    /** Inform listeners if the bucket has changed since it was last reported to listeners */
     private void maybeInformListeners(String packageName, int userId,
-            long elapsedRealtime, int bucket, boolean userStartedInteracting) {
+            long elapsedRealtime, int bucket, int reason, boolean userStartedInteracting) {
         synchronized (mAppIdleLock) {
-            // TODO: fold these into one call + lookup for efficiency if needed
             if (mAppIdleHistory.shouldInformListeners(packageName, userId,
                     elapsedRealtime, bucket)) {
-                StandbyUpdateRecord r = StandbyUpdateRecord.obtain(packageName, userId,
-                        bucket, userStartedInteracting);
+                final StandbyUpdateRecord r = StandbyUpdateRecord.obtain(packageName, userId,
+                        bucket, reason, userStartedInteracting);
                 if (DEBUG) Slog.d(TAG, "Standby bucket for " + packageName + "=" + bucket);
-                mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS,
-                        StandbyUpdateRecord.obtain(packageName, userId,
-                                bucket, userStartedInteracting)));
+                mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS, r));
             }
         }
     }
 
+    /**
+     * Evaluates next bucket based on time since last used and the bucketing thresholds.
+     * @param packageName the app
+     * @param userId the user
+     * @param elapsedRealtime as the name suggests, current elapsed time
+     * @return the bucket for the app, based on time since last used
+     */
     @GuardedBy("mAppIdleLock")
     @StandbyBuckets int getBucketForLocked(String packageName, int userId,
             long elapsedRealtime) {
@@ -674,17 +695,20 @@
                 final AppUsageHistory appHistory = mAppIdleHistory.getAppUsageHistory(
                         event.mPackage, userId, elapsedRealtime);
                 final int prevBucket = appHistory.currentBucket;
-                final String prevBucketReason = appHistory.bucketingReason;
+                final int prevBucketReason = appHistory.bucketingReason;
                 final long nextCheckTime;
+                final int subReason = usageEventToSubReason(event.mEventType);
+                final int reason = REASON_MAIN_USAGE | subReason;
                 if (event.mEventType == UsageEvents.Event.NOTIFICATION_SEEN) {
                     // Mild usage elevates to WORKING_SET but doesn't change usage time.
                     mAppIdleHistory.reportUsage(appHistory, event.mPackage,
-                            STANDBY_BUCKET_WORKING_SET,
+                            STANDBY_BUCKET_WORKING_SET, subReason,
                             0, elapsedRealtime + mNotificationSeenTimeoutMillis);
                     nextCheckTime = mNotificationSeenTimeoutMillis;
+
                 } else {
                     mAppIdleHistory.reportUsage(appHistory, event.mPackage,
-                            STANDBY_BUCKET_ACTIVE,
+                            STANDBY_BUCKET_ACTIVE, subReason,
                             elapsedRealtime, elapsedRealtime + mStrongUsageTimeoutMillis);
                     nextCheckTime = mStrongUsageTimeoutMillis;
                 }
@@ -694,9 +718,9 @@
                 final boolean userStartedInteracting =
                         appHistory.currentBucket == STANDBY_BUCKET_ACTIVE &&
                         prevBucket != appHistory.currentBucket &&
-                        prevBucketReason != REASON_USAGE;
+                        (prevBucketReason & REASON_MAIN_MASK) != REASON_MAIN_USAGE;
                 maybeInformListeners(event.mPackage, userId, elapsedRealtime,
-                        appHistory.currentBucket, userStartedInteracting);
+                        appHistory.currentBucket, reason, userStartedInteracting);
 
                 if (previouslyIdle) {
                     notifyBatteryStats(event.mPackage, userId, false);
@@ -705,6 +729,17 @@
         }
     }
 
+    private int usageEventToSubReason(int eventType) {
+        switch (eventType) {
+            case UsageEvents.Event.MOVE_TO_FOREGROUND: return REASON_SUB_USAGE_MOVE_TO_FOREGROUND;
+            case UsageEvents.Event.MOVE_TO_BACKGROUND: return REASON_SUB_USAGE_MOVE_TO_BACKGROUND;
+            case UsageEvents.Event.SYSTEM_INTERACTION: return REASON_SUB_USAGE_SYSTEM_INTERACTION;
+            case UsageEvents.Event.USER_INTERACTION: return REASON_SUB_USAGE_USER_INTERACTION;
+            case UsageEvents.Event.NOTIFICATION_SEEN: return REASON_SUB_USAGE_NOTIFICATION_SEEN;
+            default: return 0;
+        }
+    }
+
     /**
      * Forces the app's beginIdleTime and lastUsedTime to reflect idle or active. If idle,
      * then it rolls back the beginIdleTime and lastUsedTime to a point in time that's behind
@@ -730,7 +765,8 @@
                 userId, elapsedRealtime);
         // Inform listeners if necessary
         if (previouslyIdle != stillIdle) {
-            maybeInformListeners(packageName, userId, elapsedRealtime, standbyBucket, false);
+            maybeInformListeners(packageName, userId, elapsedRealtime, standbyBucket,
+                    REASON_MAIN_FORCED, false);
             if (!stillIdle) {
                 notifyBatteryStats(packageName, userId, idle);
             }
@@ -954,18 +990,18 @@
         }
     }
 
-    public Map<String, Integer> getAppStandbyBuckets(int userId, long elapsedRealtime) {
+    public List<AppStandbyInfo> getAppStandbyBuckets(int userId) {
         synchronized (mAppIdleLock) {
-            return mAppIdleHistory.getAppStandbyBuckets(userId, elapsedRealtime, mAppIdleEnabled);
+            return mAppIdleHistory.getAppStandbyBuckets(userId, mAppIdleEnabled);
         }
     }
 
     void setAppStandbyBucket(String packageName, int userId, @StandbyBuckets int newBucket,
-            String reason, long elapsedRealtime) {
+            int reason, long elapsedRealtime) {
         synchronized (mAppIdleLock) {
             AppIdleHistory.AppUsageHistory app = mAppIdleHistory.getAppUsageHistory(packageName,
                     userId, elapsedRealtime);
-            boolean predicted = reason != null && reason.startsWith(REASON_PREDICTED);
+            boolean predicted = (reason & REASON_MAIN_MASK) == REASON_MAIN_PREDICTED;
 
             // Don't allow changing bucket if higher than ACTIVE
             if (app.currentBucket < STANDBY_BUCKET_ACTIVE) return;
@@ -978,7 +1014,7 @@
             }
 
             // If the bucket was forced, don't allow prediction to override
-            if (app.bucketingReason.equals(REASON_FORCED) && predicted) return;
+            if ((app.bucketingReason & REASON_MAIN_MASK) == REASON_MAIN_FORCED && predicted) return;
 
             // If the bucket is required to stay in a higher state for a specified duration, don't
             // override unless the duration has passed
@@ -988,14 +1024,18 @@
                 if (newBucket > STANDBY_BUCKET_ACTIVE
                         && app.bucketActiveTimeoutTime > elapsedTimeAdjusted) {
                     newBucket = STANDBY_BUCKET_ACTIVE;
-                    reason = REASON_USAGE;
+                    reason = app.bucketingReason;
                     if (DEBUG) {
                         Slog.d(TAG, "    Keeping at ACTIVE due to min timeout");
                     }
                 } else if (newBucket > STANDBY_BUCKET_WORKING_SET
                         && app.bucketWorkingSetTimeoutTime > elapsedTimeAdjusted) {
                     newBucket = STANDBY_BUCKET_WORKING_SET;
-                    reason = REASON_USAGE;
+                    if (app.currentBucket != newBucket) {
+                        reason = REASON_MAIN_USAGE | REASON_SUB_USAGE_ACTIVE_TIMEOUT;
+                    } else {
+                        reason = app.bucketingReason;
+                    }
                     if (DEBUG) {
                         Slog.d(TAG, "    Keeping at WORKING_SET due to min timeout");
                     }
@@ -1005,7 +1045,7 @@
             mAppIdleHistory.setAppStandbyBucket(packageName, userId, elapsedRealtime, newBucket,
                     reason);
         }
-        maybeInformListeners(packageName, userId, elapsedRealtime, newBucket, false);
+        maybeInformListeners(packageName, userId, elapsedRealtime, newBucket, reason, false);
     }
 
     @VisibleForTesting
@@ -1105,11 +1145,12 @@
         return packageName != null && packageName.equals(activeScorer);
     }
 
-    void informListeners(String packageName, int userId, int bucket, boolean userInteraction) {
+    void informListeners(String packageName, int userId, int bucket, int reason,
+            boolean userInteraction) {
         final boolean idle = bucket >= STANDBY_BUCKET_RARE;
         synchronized (mPackageAccessListeners) {
             for (AppIdleStateChangeListener listener : mPackageAccessListeners) {
-                listener.onAppIdleStateChanged(packageName, userId, idle, bucket);
+                listener.onAppIdleStateChanged(packageName, userId, idle, bucket, reason);
                 if (userInteraction) {
                     listener.onUserInteractionStarted(packageName, userId);
                 }
@@ -1187,7 +1228,8 @@
                 if (pi.applicationInfo != null && pi.applicationInfo.isSystemApp()) {
                     // Mark app as used for 2 hours. After that it can timeout to whatever the
                     // past usage pattern was.
-                    mAppIdleHistory.reportUsage(packageName, userId, STANDBY_BUCKET_ACTIVE, 0,
+                    mAppIdleHistory.reportUsage(packageName, userId, STANDBY_BUCKET_ACTIVE,
+                            REASON_SUB_USAGE_SYSTEM_UPDATE, 0,
                             elapsedRealtime + mSystemUpdateUsageTimeoutMillis);
                 }
             }
@@ -1368,7 +1410,8 @@
             switch (msg.what) {
                 case MSG_INFORM_LISTENERS:
                     StandbyUpdateRecord r = (StandbyUpdateRecord) msg.obj;
-                    informListeners(r.packageName, r.userId, r.bucket, r.isUserInteraction);
+                    informListeners(r.packageName, r.userId, r.bucket, r.reason,
+                            r.isUserInteraction);
                     r.recycle();
                     break;
 
@@ -1476,7 +1519,7 @@
                 "notification_seen_duration";
         private static final String KEY_SYSTEM_UPDATE_HOLD_DURATION =
                 "system_update_usage_duration";
-
+        private static final String KEY_PREDICTION_TIMEOUT = "prediction_timeout";
 
         private final KeyValueListParser mParser = new KeyValueListParser(',');
 
@@ -1546,6 +1589,9 @@
                 mSystemUpdateUsageTimeoutMillis = mParser.getDurationMillis
                         (KEY_SYSTEM_UPDATE_HOLD_DURATION,
                                 COMPRESS_TIME ? 2 * ONE_MINUTE : 2 * ONE_HOUR);
+                mPredictionTimeoutMillis = mParser.getDurationMillis
+                        (KEY_PREDICTION_TIMEOUT,
+                                COMPRESS_TIME ? 10 * ONE_MINUTE : DEFAULT_PREDICTION_TIMEOUT);
             }
         }
 
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 3b0fd1f..69b2c63 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -20,6 +20,7 @@
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
 import android.app.IUidObserver;
+import android.app.usage.AppStandbyInfo;
 import android.app.usage.ConfigurationStats;
 import android.app.usage.IUsageStatsManager;
 import android.app.usage.UsageEvents;
@@ -98,6 +99,7 @@
     static final int MSG_REPORT_EVENT = 0;
     static final int MSG_FLUSH_TO_DISK = 1;
     static final int MSG_REMOVE_USER = 2;
+    static final int MSG_UID_STATE_CHANGED = 3;
 
     private final Object mLock = new Object();
     Handler mHandler;
@@ -119,10 +121,10 @@
             new UsageStatsManagerInternal.AppIdleStateChangeListener() {
                 @Override
                 public void onAppIdleStateChanged(String packageName, int userId, boolean idle,
-                        int bucket) {
+                        int bucket, int reason) {
                     Event event = new Event();
                     event.mEventType = Event.STANDBY_BUCKET_CHANGED;
-                    event.mBucket = bucket;
+                    event.mBucketAndReason = (bucket << 16) | (reason & 0xFFFF);
                     event.mPackage = packageName;
                     // This will later be converted to system time.
                     event.mTimeStamp = SystemClock.elapsedRealtime();
@@ -219,18 +221,7 @@
     private final IUidObserver mUidObserver = new IUidObserver.Stub() {
         @Override
         public void onUidStateChanged(int uid, int procState, long procStateSeq) {
-            final int newCounter = (procState <= ActivityManager.PROCESS_STATE_TOP) ? 0 : 1;
-            synchronized (mUidToKernelCounter) {
-                final int oldCounter = mUidToKernelCounter.get(uid, 0);
-                if (newCounter != oldCounter) {
-                    mUidToKernelCounter.put(uid, newCounter);
-                    try {
-                        FileUtils.stringToFile(KERNEL_COUNTER_FILE, uid + " " + newCounter);
-                    } catch (IOException e) {
-                        Slog.w(TAG, "Failed to update counter set: " + e);
-                    }
-                }
-            }
+            mHandler.obtainMessage(MSG_UID_STATE_CHANGED, uid, procState).sendToTarget();
         }
 
         @Override
@@ -560,6 +551,25 @@
                     onUserRemoved(msg.arg1);
                     break;
 
+                case MSG_UID_STATE_CHANGED: {
+                    final int uid = msg.arg1;
+                    final int procState = msg.arg2;
+
+                    final int newCounter = (procState <= ActivityManager.PROCESS_STATE_TOP) ? 0 : 1;
+                    synchronized (mUidToKernelCounter) {
+                        final int oldCounter = mUidToKernelCounter.get(uid, 0);
+                        if (newCounter != oldCounter) {
+                            mUidToKernelCounter.put(uid, newCounter);
+                            try {
+                                FileUtils.stringToFile(KERNEL_COUNTER_FILE, uid + " " + newCounter);
+                            } catch (IOException e) {
+                                Slog.w(TAG, "Failed to update counter set: " + e);
+                            }
+                        }
+                    }
+                    break;
+                }
+
                 default:
                     super.handleMessage(msg);
                     break;
@@ -740,9 +750,9 @@
                 throw re.rethrowFromSystemServer();
             }
             final boolean shellCaller = callingUid == 0 || callingUid == Process.SHELL_UID;
-            final String reason = shellCaller
-                    ? UsageStatsManager.REASON_FORCED
-                    : UsageStatsManager.REASON_PREDICTED + ":" + callingUid;
+            final int reason = shellCaller
+                    ? UsageStatsManager.REASON_MAIN_FORCED
+                    : UsageStatsManager.REASON_MAIN_PREDICTED;
             final long token = Binder.clearCallingIdentity();
             try {
                 // Caller cannot set their own standby state
@@ -758,7 +768,8 @@
         }
 
         @Override
-        public Map getAppStandbyBuckets(String callingPackageName, int userId) {
+        public ParceledListSlice<AppStandbyInfo> getAppStandbyBuckets(String callingPackageName,
+                int userId) {
             final int callingUid = Binder.getCallingUid();
             try {
                 userId = ActivityManager.getService().handleIncomingUser(
@@ -773,15 +784,17 @@
             }
             final long token = Binder.clearCallingIdentity();
             try {
-                return mAppStandby.getAppStandbyBuckets(userId,
-                        SystemClock.elapsedRealtime());
+                final List<AppStandbyInfo> standbyBucketList =
+                        mAppStandby.getAppStandbyBuckets(userId);
+                return (standbyBucketList == null) ? ParceledListSlice.emptyList()
+                        : new ParceledListSlice<>(standbyBucketList);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
-        public void setAppStandbyBuckets(Map appBuckets, int userId) {
+        public void setAppStandbyBuckets(ParceledListSlice appBuckets, int userId) {
             getContext().enforceCallingPermission(Manifest.permission.CHANGE_APP_IDLE_STATE,
                     "No permission to change app standby state");
 
@@ -794,16 +807,16 @@
                 throw re.rethrowFromSystemServer();
             }
             final boolean shellCaller = callingUid == 0 || callingUid == Process.SHELL_UID;
-            final String reason = shellCaller
-                    ? UsageStatsManager.REASON_FORCED
-                    : UsageStatsManager.REASON_PREDICTED + ":" + callingUid;
+            final int reason = shellCaller
+                    ? UsageStatsManager.REASON_MAIN_FORCED
+                    : UsageStatsManager.REASON_MAIN_PREDICTED;
             final long token = Binder.clearCallingIdentity();
             try {
                 final long elapsedRealtime = SystemClock.elapsedRealtime();
-                Map<String, Integer> buckets = (Map<String, Integer>) appBuckets;
-                for (Map.Entry<String, Integer> entry: buckets.entrySet()) {
-                    String packageName = entry.getKey();
-                    int bucket = entry.getValue();
+                List<AppStandbyInfo> bucketList = appBuckets.getList();
+                for (AppStandbyInfo bucketInfo : bucketList) {
+                    final String packageName = bucketInfo.mPackageName;
+                    final int bucket = bucketInfo.mStandbyBucket;
                     if (bucket < UsageStatsManager.STANDBY_BUCKET_ACTIVE
                             || bucket > UsageStatsManager.STANDBY_BUCKET_NEVER) {
                         throw new IllegalArgumentException(
diff --git a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
index d1ed599..5e7e80d 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
@@ -26,10 +26,7 @@
 import android.app.usage.UsageEvents;
 import android.app.usage.UsageStats;
 import android.content.res.Configuration;
-import android.text.TextUtils;
 import android.util.ArrayMap;
-import android.util.Log;
-import android.util.LogWriter;
 
 import java.io.IOException;
 import java.net.ProtocolException;
@@ -175,7 +172,7 @@
                 event.mShortcutId = (id != null) ? id.intern() : null;
                 break;
             case UsageEvents.Event.STANDBY_BUCKET_CHANGED:
-                event.mBucket = XmlUtils.readIntAttribute(parser, STANDBY_BUCKET_ATTR, 0);
+                event.mBucketAndReason = XmlUtils.readIntAttribute(parser, STANDBY_BUCKET_ATTR, 0);
                 break;
         }
 
@@ -281,8 +278,8 @@
                 }
                 break;
             case UsageEvents.Event.STANDBY_BUCKET_CHANGED:
-                if (event.mBucket != 0) {
-                    XmlUtils.writeIntAttribute(xml, STANDBY_BUCKET_ATTR, event.mBucket);
+                if (event.mBucketAndReason != 0) {
+                    XmlUtils.writeIntAttribute(xml, STANDBY_BUCKET_ATTR, event.mBucketAndReason);
                 }
         }
 
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index ec12da2..7f060b3 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -24,6 +24,7 @@
 import android.content.res.Configuration;
 import android.os.SystemClock;
 import android.content.Context;
+import android.text.format.DateFormat;
 import android.text.format.DateUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -46,7 +47,7 @@
 class UserUsageStatsService {
     private static final String TAG = "UsageStatsService";
     private static final boolean DEBUG = UsageStatsService.DEBUG;
-    private static final SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+    private static final SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd/HH:mm:ss");
     private static final int sDateFormatFlags =
             DateUtils.FORMAT_SHOW_DATE
             | DateUtils.FORMAT_SHOW_TIME
@@ -474,25 +475,25 @@
         mDatabase.checkinDailyFiles(new UsageStatsDatabase.CheckinAction() {
             @Override
             public boolean checkin(IntervalStats stats) {
-                printIntervalStats(pw, stats, false, null);
+                printIntervalStats(pw, stats, true, null);
                 return true;
             }
         });
     }
 
     void dump(IndentingPrintWriter pw, String pkg) {
-        // This is not a check-in, only dump in-memory stats.
+        printLast24HrEvents(pw, true, pkg);
         for (int interval = 0; interval < mCurrentStats.length; interval++) {
             pw.print("In-memory ");
             pw.print(intervalToString(interval));
             pw.println(" stats");
-            printIntervalStats(pw, mCurrentStats[interval], true, pkg);
+            printIntervalStats(pw, mCurrentStats[interval], false, pkg);
         }
     }
 
     private String formatDateTime(long dateTime, boolean pretty) {
         if (pretty) {
-            return "\"" + DateUtils.formatDateTime(mContext, dateTime, sDateFormatFlags) + "\"";
+            return "\"" + DateFormat.format("yyyy-MM-dd HH:mm:ss", dateTime).toString() + "\"";
         }
         return Long.toString(dateTime);
     }
@@ -504,8 +505,85 @@
         return Long.toString(elapsedTime);
     }
 
+
+    void printEvent(IndentingPrintWriter pw, UsageEvents.Event event, boolean prettyDates) {
+        pw.printPair("time", formatDateTime(event.mTimeStamp, prettyDates));
+        pw.printPair("type", eventToString(event.mEventType));
+        pw.printPair("package", event.mPackage);
+        if (event.mClass != null) {
+            pw.printPair("class", event.mClass);
+        }
+        if (event.mConfiguration != null) {
+            pw.printPair("config", Configuration.resourceQualifierString(event.mConfiguration));
+        }
+        if (event.mShortcutId != null) {
+            pw.printPair("shortcutId", event.mShortcutId);
+        }
+        if (event.mEventType == UsageEvents.Event.STANDBY_BUCKET_CHANGED) {
+            pw.printPair("standbyBucket", event.getStandbyBucket());
+            pw.printPair("reason", UsageStatsManager.reasonToString(event.getStandbyReason()));
+        }
+        pw.printHexPair("flags", event.mFlags);
+        pw.println();
+    }
+
+    void printLast24HrEvents(IndentingPrintWriter pw, boolean prettyDates, final String pkg) {
+        final long endTime = System.currentTimeMillis();
+        UnixCalendar yesterday = new UnixCalendar(endTime);
+        yesterday.addDays(-1);
+
+        final long beginTime = yesterday.getTimeInMillis();
+
+        List<UsageEvents.Event> events = queryStats(UsageStatsManager.INTERVAL_DAILY,
+                beginTime, endTime, new StatCombiner<UsageEvents.Event>() {
+                    @Override
+                    public void combine(IntervalStats stats, boolean mutable,
+                            List<UsageEvents.Event> accumulatedResult) {
+                        if (stats.events == null) {
+                            return;
+                        }
+
+                        final int startIndex = stats.events.closestIndexOnOrAfter(beginTime);
+                        if (startIndex < 0) {
+                            return;
+                        }
+
+                        final int size = stats.events.size();
+                        for (int i = startIndex; i < size; i++) {
+                            if (stats.events.keyAt(i) >= endTime) {
+                                return;
+                            }
+
+                            UsageEvents.Event event = stats.events.valueAt(i);
+                            if (pkg != null && !pkg.equals(event.mPackage)) {
+                                continue;
+                            }
+                            accumulatedResult.add(event);
+                        }
+                    }
+                });
+
+        pw.print("Last 24 hour events (");
+        if (prettyDates) {
+            pw.printPair("timeRange", "\"" + DateUtils.formatDateRange(mContext,
+                    beginTime, endTime, sDateFormatFlags) + "\"");
+        } else {
+            pw.printPair("beginTime", beginTime);
+            pw.printPair("endTime", endTime);
+        }
+        pw.println(")");
+        if (events != null) {
+            pw.increaseIndent();
+            for (UsageEvents.Event event : events) {
+                printEvent(pw, event, prettyDates);
+            }
+            pw.decreaseIndent();
+        }
+    }
+
     void printIntervalStats(IndentingPrintWriter pw, IntervalStats stats,
-            boolean prettyDates, String pkg) {
+            boolean checkin, String pkg) {
+        boolean prettyDates = !checkin;
         if (prettyDates) {
             pw.printPair("timeRange", "\"" + DateUtils.formatDateRange(mContext,
                     stats.beginTime, stats.endTime, sDateFormatFlags) + "\"");
@@ -578,35 +656,23 @@
             pw.decreaseIndent();
         }
 
-        pw.println("events");
-        pw.increaseIndent();
-        final TimeSparseArray<UsageEvents.Event> events = stats.events;
-        final int eventCount = events != null ? events.size() : 0;
-        for (int i = 0; i < eventCount; i++) {
-            final UsageEvents.Event event = events.valueAt(i);
-            if (pkg != null && !pkg.equals(event.mPackage)) {
-                continue;
+        // The last 24 hours of events is already printed in the non checkin dump
+        // No need to repeat here.
+        if (checkin) {
+            pw.println("events");
+            pw.increaseIndent();
+            final TimeSparseArray<UsageEvents.Event> events = stats.events;
+            final int eventCount = events != null ? events.size() : 0;
+            for (int i = 0; i < eventCount; i++) {
+                final UsageEvents.Event event = events.valueAt(i);
+                if (pkg != null && !pkg.equals(event.mPackage)) {
+                    continue;
+                }
+                printEvent(pw, event, prettyDates);
             }
-            pw.printPair("time", formatDateTime(event.mTimeStamp, prettyDates));
-            pw.printPair("type", eventToString(event.mEventType));
-            pw.printPair("package", event.mPackage);
-            if (event.mClass != null) {
-                pw.printPair("class", event.mClass);
-            }
-            if (event.mConfiguration != null) {
-                pw.printPair("config", Configuration.resourceQualifierString(event.mConfiguration));
-            }
-            if (event.mShortcutId != null) {
-                pw.printPair("shortcutId", event.mShortcutId);
-            }
-            if (event.mEventType == UsageEvents.Event.STANDBY_BUCKET_CHANGED) {
-                pw.printPair("standbyBucket", event.mBucket);
-            }
-            pw.printHexPair("flags", event.mFlags);
-            pw.println();
+            pw.decreaseIndent();
         }
         pw.decreaseIndent();
-        pw.decreaseIndent();
     }
 
     private static String intervalToString(int interval) {
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index a7fc470..ef0780a 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -1359,9 +1359,7 @@
                             UsbManager.USB_FUNCTION_NONE).equals(
                             getSystemProperty(USB_STATE_PROPERTY, UsbManager.USB_FUNCTION_NONE));
                 }
-                // Mask out adb, since it is stored in mAdbEnabled
-                mCurrentFunctions = UsbManager.usbFunctionsFromString(mCurrentFunctionsStr)
-                        & ~UsbManager.FUNCTION_ADB;
+                mCurrentFunctions = UsbManager.FUNCTION_NONE;
                 mCurrentUsbFunctionsReceived = true;
 
                 String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index ddb4f04..33da403 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -138,6 +138,7 @@
     }
 
     public void systemReady() {
+	mSystemReady = true;
         if (mProxy != null) {
             try {
                 mProxy.queryPortStatus();
@@ -146,7 +147,6 @@
                         "ServiceStart: Failed to query port status", e);
             }
         }
-        mSystemReady = true;
     }
 
     public UsbPort[] getPorts() {
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
index 297a6ea..956efc0 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
@@ -380,11 +380,10 @@
                 if (DEBUG) {
                     Log.d(TAG, "  type:0x" + Integer.toHexString(type));
                 }
-                if ((type >= UsbTerminalTypes.TERMINAL_IN_UNDEFINED
-                            && type <= UsbTerminalTypes.TERMINAL_IN_PROC_MIC_ARRAY)
-                        || (type >= UsbTerminalTypes.TERMINAL_BIDIR_UNDEFINED
-                            && type <= UsbTerminalTypes.TERMINAL_BIDIR_SKRPHONE_CANCEL)
-                        || (type == UsbTerminalTypes.TERMINAL_USB_STREAMING)) {
+                int terminalCategory = type & ~0xFF;
+                if (terminalCategory != UsbTerminalTypes.TERMINAL_USB_UNDEFINED
+                        && terminalCategory != UsbTerminalTypes.TERMINAL_OUT_UNDEFINED) {
+                    // If not explicitly a USB connection or output, it could be an input.
                     hasInput = true;
                     break;
                 }
@@ -419,10 +418,10 @@
                 if (DEBUG) {
                     Log.d(TAG, "  type:0x" + Integer.toHexString(type));
                 }
-                if ((type >= UsbTerminalTypes.TERMINAL_OUT_UNDEFINED
-                            && type <= UsbTerminalTypes.TERMINAL_OUT_LFSPEAKER)
-                        || (type >= UsbTerminalTypes.TERMINAL_BIDIR_UNDEFINED
-                            && type <= UsbTerminalTypes.TERMINAL_BIDIR_SKRPHONE_CANCEL)) {
+                int terminalCategory = type & ~0xFF;
+                if (terminalCategory != UsbTerminalTypes.TERMINAL_USB_UNDEFINED
+                        && terminalCategory != UsbTerminalTypes.TERMINAL_IN_UNDEFINED) {
+                    // If not explicitly a USB connection or input, it could be an output.
                     hasOutput = true;
                     break;
                 }
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbTerminalTypes.java b/services/usb/java/com/android/server/usb/descriptors/UsbTerminalTypes.java
index 9bd6cb9..cbb899e 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbTerminalTypes.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbTerminalTypes.java
@@ -24,6 +24,7 @@
     private static final String TAG = "UsbTerminalTypes";
 
     // USB
+    public static final int TERMINAL_USB_UNDEFINED   = 0x0100;
     public static final int TERMINAL_USB_STREAMING   = 0x0101;
 
     // Inputs
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
index 25c54b3..f4bb32d 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
@@ -34,6 +34,7 @@
 import android.hardware.soundtrigger.SoundTrigger.SoundModel;
 import android.hardware.soundtrigger.SoundTrigger.SoundModelEvent;
 import android.hardware.soundtrigger.SoundTriggerModule;
+import android.os.Binder;
 import android.os.DeadObjectException;
 import android.os.PowerManager;
 import android.os.PowerManager.ServiceType;
@@ -880,21 +881,26 @@
     }
 
     private void initializeTelephonyAndPowerStateListeners() {
-        // Get the current call state synchronously for the first recognition.
-        mCallActive = mTelephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE;
+        long token = Binder.clearCallingIdentity();
+        try {
+            // Get the current call state synchronously for the first recognition.
+            mCallActive = mTelephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE;
 
-        // Register for call state changes when the first call to start recognition occurs.
-        mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
+            // Register for call state changes when the first call to start recognition occurs.
+            mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
 
-        // Register for power saver mode changes when the first call to start recognition
-        // occurs.
-        if (mPowerSaveModeListener == null) {
-            mPowerSaveModeListener = new PowerSaveModeListener();
-            mContext.registerReceiver(mPowerSaveModeListener,
-                    new IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
+            // Register for power saver mode changes when the first call to start recognition
+            // occurs.
+            if (mPowerSaveModeListener == null) {
+                mPowerSaveModeListener = new PowerSaveModeListener();
+                mContext.registerReceiver(mPowerSaveModeListener,
+                        new IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
+            }
+            mIsPowerSaveMode = mPowerManager.getPowerSaveState(ServiceType.SOUND)
+                    .batterySaverEnabled;
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
-        mIsPowerSaveMode = mPowerManager.getPowerSaveState(ServiceType.SOUND)
-                .batterySaverEnabled;
     }
 
     // Sends an error callback to all models with a valid registered callback.
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 0c92c20..a79f2c9 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -422,6 +422,7 @@
         /**
          * Indicates the call used Assisted Dialing.
          * See also {@link Connection#PROPERTY_ASSISTED_DIALING_USED}
+         * @hide
          */
         public static final int PROPERTY_ASSISTED_DIALING_USED = 0x00000200;
 
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 26a2f1c..36333e4 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -35,7 +35,6 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
-import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.util.ArraySet;
@@ -407,6 +406,7 @@
 
     /**
      * Set by the framework to indicate that a connection is using assisted dialing.
+     * @hide
      */
     public static final int PROPERTY_ASSISTED_DIALING_USED = 1 << 9;
 
@@ -2553,19 +2553,6 @@
     }
 
     /**
-     * Adds a parcelable extra to this {@code Connection}.
-     *
-     * @param key The extra key.
-     * @param value The value.
-     * @hide
-     */
-    public final void putExtra(@NonNull String key, @NonNull Parcelable value) {
-        Bundle newExtras = new Bundle();
-        newExtras.putParcelable(key, value);
-        putExtras(newExtras);
-    }
-
-    /**
      * Removes extras from this {@code Connection}.
      *
      * @param keys The keys of the extras to remove.
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index a180da6..e456830 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -111,12 +111,6 @@
             "android.telecom.action.SHOW_RESPOND_VIA_SMS_SETTINGS";
 
     /**
-     * The {@link android.content.Intent} action used to show the assisted dialing settings.
-     */
-    public static final String ACTION_SHOW_ASSISTED_DIALING_SETTINGS =
-            "android.telecom.action.SHOW_ASSISTED_DIALING_SETTINGS";
-
-    /**
      * The {@link android.content.Intent} action used to show the settings page used to configure
      * {@link PhoneAccount} preferences.
      */
@@ -619,17 +613,12 @@
     /**
      * The boolean indicated by this extra controls whether or not a call is eligible to undergo
      * assisted dialing. This extra is stored under {@link #EXTRA_OUTGOING_CALL_EXTRAS}.
+     * @hide
      */
     public static final String EXTRA_USE_ASSISTED_DIALING =
             "android.telecom.extra.USE_ASSISTED_DIALING";
 
     /**
-     * The bundle indicated by this extra store information related to the assisted dialing action.
-     */
-    public static final String EXTRA_ASSISTED_DIALING_TRANSFORMATION_INFO =
-            "android.telecom.extra.ASSISTED_DIALING_TRANSFORMATION_INFO";
-
-    /**
      * The following 4 constants define how properties such as phone numbers and names are
      * displayed to the user.
      */
diff --git a/telecomm/java/android/telecom/TransformationInfo.java b/telecomm/java/android/telecom/TransformationInfo.java
deleted file mode 100755
index 3e848c6..0000000
--- a/telecomm/java/android/telecom/TransformationInfo.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telecom;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-/**
- * A container class to hold information related to the Assisted Dialing operation. All member
- * variables must be set when constructing a new instance of this class.
- */
-public final class TransformationInfo implements Parcelable {
-    private String mOriginalNumber;
-    private String mTransformedNumber;
-    private String mUserHomeCountryCode;
-    private String mUserRoamingCountryCode;
-    private int mTransformedNumberCountryCallingCode;
-
-    public TransformationInfo(String originalNumber,
-                              String transformedNumber,
-                              String userHomeCountryCode,
-                              String userRoamingCountryCode,
-                              int transformedNumberCountryCallingCode) {
-        String missing = "";
-        if (originalNumber == null) {
-            missing += " mOriginalNumber";
-        }
-        if (transformedNumber == null) {
-            missing += " mTransformedNumber";
-        }
-        if (userHomeCountryCode == null) {
-            missing += " mUserHomeCountryCode";
-        }
-        if (userRoamingCountryCode == null) {
-            missing += " mUserRoamingCountryCode";
-        }
-
-        if (!missing.isEmpty()) {
-            throw new IllegalStateException("Missing required properties:" + missing);
-        }
-        this.mOriginalNumber = originalNumber;
-        this.mTransformedNumber = transformedNumber;
-        this.mUserHomeCountryCode = userHomeCountryCode;
-        this.mUserRoamingCountryCode = userRoamingCountryCode;
-        this.mTransformedNumberCountryCallingCode = transformedNumberCountryCallingCode;
-    }
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeString(mOriginalNumber);
-        out.writeString(mTransformedNumber);
-        out.writeString(mUserHomeCountryCode);
-        out.writeString(mUserRoamingCountryCode);
-        out.writeInt(mTransformedNumberCountryCallingCode);
-    }
-
-    public static final Parcelable.Creator<TransformationInfo> CREATOR
-            = new Parcelable.Creator<TransformationInfo>() {
-        public TransformationInfo createFromParcel(Parcel in) {
-            return new TransformationInfo(in);
-        }
-
-        public TransformationInfo[] newArray(int size) {
-            return new TransformationInfo[size];
-        }
-    };
-
-    private TransformationInfo(Parcel in) {
-        mOriginalNumber = in.readString();
-        mTransformedNumber = in.readString();
-        mUserHomeCountryCode = in.readString();
-        mUserRoamingCountryCode = in.readString();
-        mTransformedNumberCountryCallingCode = in.readInt();
-    }
-
-    /**
-     * The original number that underwent Assisted Dialing.
-     */
-    public String getOriginalNumber() {
-        return mOriginalNumber;
-    }
-
-    /**
-     * The number after it underwent Assisted Dialing.
-     */
-    public String getTransformedNumber() {
-        return mTransformedNumber;
-    }
-
-    /**
-     * The user's home country code that was used when attempting to transform the number.
-     */
-    public String getUserHomeCountryCode() {
-        return mUserHomeCountryCode;
-    }
-
-    /**
-     * The users's roaming country code that was used when attempting to transform the number.
-     */
-    public String getUserRoamingCountryCode() {
-        return mUserRoamingCountryCode;
-    }
-
-    /**
-     * The country calling code that was used in the transformation.
-     */
-    public int getTransformedNumberCountryCallingCode() {
-        return mTransformedNumberCountryCallingCode;
-    }
-}
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index 63263bd..cb87d1f 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -1103,10 +1103,15 @@
                 "android.provider.Telephony.MMS_DOWNLOADED";
 
             /**
-             * Broadcast Action: A debug code has been entered in the dialer. These "secret codes"
-             * are used to activate developer menus by dialing certain codes. And they are of the
-             * form {@code *#*#&lt;code&gt;#*#*}. The intent will have the data URI:
-             * {@code android_secret_code://&lt;code&gt;}.
+             * Broadcast Action: A debug code has been entered in the dialer. This intent is
+             * broadcast by the system and OEM telephony apps may need to receive these broadcasts.
+             * These "secret codes" are used to activate developer menus by dialing certain codes.
+             * And they are of the form {@code *#*#&lt;code&gt;#*#*}. The intent will have the data
+             * URI: {@code android_secret_code://&lt;code&gt;}. It is possible that a manifest
+             * receiver would be woken up even if it is not currently running.
+             *
+             * <p>Requires {@code android.Manifest.permission#CONTROL_INCALL_EXPERIENCE} to
+             * send and receive.</p>
              */
             @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
             public static final String SECRET_CODE_ACTION =
@@ -2732,6 +2737,7 @@
          * This should be spread to other technologies,
          * but is currently only used for LTE (14) and eHRPD (13).
          * <P>Type: INTEGER</P>
+         * @deprecated this column is no longer supported, use {@link #NETWORK_TYPE_BITMASK} instead
          */
         @Deprecated
         public static final String BEARER = "bearer";
@@ -2744,13 +2750,14 @@
          * Bitmask for a radio tech R is (1 << (R - 1))
          * <P>Type: INTEGER</P>
          * @hide
+         * @deprecated this column is no longer supported, use {@link #NETWORK_TYPE_BITMASK} instead
          */
         @Deprecated
         public static final String BEARER_BITMASK = "bearer_bitmask";
 
         /**
          * Radio technology (network type) bitmask.
-         * To check what values can be contained, refer to
+         * To check what values can be contained, refer to the NETWORK_TYPE_ constants in
          * {@link android.telephony.TelephonyManager}.
          * Bitmask for a radio tech R is (1 << (R - 1))
          * <P>Type: INTEGER</P>
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 2d3d49c..96eb23d 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1704,13 +1704,6 @@
             "roaming_operator_string_array";
 
     /**
-     * Controls whether Assisted Dialing is enabled and the preference is shown. This feature
-     * transforms numbers when the user is roaming.
-     */
-    public static final String KEY_ASSISTED_DIALING_ENABLED_BOOL =
-            "assisted_dialing_enabled_bool";
-
-    /**
      * URL from which the proto containing the public key of the Carrier used for
      * IMSI encryption will be downloaded.
      * @hide
@@ -1822,7 +1815,14 @@
             "check_pricing_with_carrier_data_roaming_bool";
 
     /**
-     * List of thresholds of RSRP for determining the display level of LTE signal bar.
+     * A list of 4 LTE RSRP thresholds above which a signal level is considered POOR,
+     * MODERATE, GOOD, or EXCELLENT, to be used in SignalStrength reporting.
+     *
+     * Note that the min and max thresholds are fixed at -140 and -44, as explained in
+     * TS 136.133 9.1.4 - RSRP Measurement Report Mapping.
+     * <p>
+     * See SignalStrength#MAX_LTE_RSRP and SignalStrength#MIN_LTE_RSRP. Any signal level outside
+     * these boundaries is considered invalid.
      * @hide
      */
     public static final String KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY =
@@ -2131,7 +2131,6 @@
                 false);
         sDefaults.putStringArray(KEY_NON_ROAMING_OPERATOR_STRING_ARRAY, null);
         sDefaults.putStringArray(KEY_ROAMING_OPERATOR_STRING_ARRAY, null);
-        sDefaults.putBoolean(KEY_ASSISTED_DIALING_ENABLED_BOOL, true);
         sDefaults.putBoolean(KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, false);
         sDefaults.putBoolean(KEY_RTT_SUPPORTED_BOOL, false);
         sDefaults.putBoolean(KEY_DISABLE_CHARGE_INDICATION_BOOL, false);
@@ -2144,12 +2143,10 @@
         sDefaults.putBoolean(KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL, false);
         sDefaults.putIntArray(KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY,
                 new int[] {
-                        -140, /* SIGNAL_STRENGTH_NONE_OR_UNKNOWN */
                         -128, /* SIGNAL_STRENGTH_POOR */
                         -118, /* SIGNAL_STRENGTH_MODERATE */
                         -108, /* SIGNAL_STRENGTH_GOOD */
                         -98,  /* SIGNAL_STRENGTH_GREAT */
-                        -44
                 });
     }
 
diff --git a/telephony/java/android/telephony/LocationAccessPolicy.java b/telephony/java/android/telephony/LocationAccessPolicy.java
new file mode 100644
index 0000000..b362df9
--- /dev/null
+++ b/telephony/java/android/telephony/LocationAccessPolicy.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.telephony;
+
+import android.Manifest;
+import android.annotation.NonNull;
+import android.annotation.UserIdInt;
+import android.app.ActivityManager;
+import android.app.AppOpsManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.location.LocationManager;
+import android.os.Binder;
+import android.os.Build;
+import android.os.Process;
+import android.os.Trace;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.util.SparseBooleanArray;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Helper for performing location access checks.
+ * @hide
+ */
+public final class LocationAccessPolicy {
+    /**
+     * API to determine if the caller has permissions to get cell location.
+     *
+     * @param pkgName Package name of the application requesting access
+     * @param uid The uid of the package
+     * @param pid The pid of the package
+     * @return boolean true or false if permissions is granted
+     */
+    public static boolean canAccessCellLocation(@NonNull Context context, @NonNull String pkgName,
+            int uid, int pid) throws SecurityException {
+        Trace.beginSection("TelephonyLocationCheck");
+        try {
+            // Always allow the phone process to access location. This avoid breaking legacy code
+            // that rely on public-facing APIs to access cell location, and it doesn't create a
+            // info leak risk because the cell location is stored in the phone process anyway.
+            if (uid == Process.PHONE_UID) {
+                return true;
+            }
+
+            // We always require the location permission and also require the
+            // location mode to be on for non-legacy apps. Legacy apps are
+            // required to be in the foreground to at least mitigate the case
+            // where a legacy app the user is not using tracks their location.
+            // Granting ACCESS_FINE_LOCATION to an app automatically grants it
+            // ACCESS_COARSE_LOCATION.
+
+            if (context.checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION, pid, uid) ==
+                    PackageManager.PERMISSION_DENIED) {
+                return false;
+            }
+            final int opCode = AppOpsManager.permissionToOpCode(
+                    Manifest.permission.ACCESS_COARSE_LOCATION);
+            if (opCode != AppOpsManager.OP_NONE && context.getSystemService(AppOpsManager.class)
+                    .noteOpNoThrow(opCode, uid, pkgName) != AppOpsManager.MODE_ALLOWED) {
+                return false;
+            }
+            if (!isLocationModeEnabled(context, UserHandle.getUserId(uid))
+                    && !isLegacyForeground(context, pkgName, uid)) {
+                return false;
+            }
+            // If the user or profile is current, permission is granted.
+            // Otherwise, uid must have INTERACT_ACROSS_USERS_FULL permission.
+            return isCurrentProfile(context, uid) || checkInteractAcrossUsersFull(context);
+        } finally {
+            Trace.endSection();
+        }
+    }
+
+    private static boolean isLocationModeEnabled(@NonNull Context context, @UserIdInt int userId) {
+        int locationMode = Settings.Secure.getIntForUser(context.getContentResolver(),
+                Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF, userId);
+        return locationMode != Settings.Secure.LOCATION_MODE_OFF
+                && locationMode != Settings.Secure.LOCATION_MODE_SENSORS_ONLY;
+    }
+
+    private static boolean isLegacyForeground(@NonNull Context context, @NonNull String pkgName,
+            int uid) {
+        long token = Binder.clearCallingIdentity();
+        try {
+            return isLegacyVersion(context, pkgName) && isForegroundApp(context, uid);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    private static boolean isLegacyVersion(@NonNull Context context, @NonNull String pkgName) {
+        try {
+            if (context.getPackageManager().getApplicationInfo(pkgName, 0)
+                    .targetSdkVersion <= Build.VERSION_CODES.O) {
+                return true;
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            // In case of exception, assume known app (more strict checking)
+            // Note: This case will never happen since checkPackage is
+            // called to verify validity before checking app's version.
+        }
+        return false;
+    }
+
+    private static boolean isForegroundApp(@NonNull Context context, int uid) {
+        final ActivityManager am = context.getSystemService(ActivityManager.class);
+        return am.getUidImportance(uid) <= ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
+    }
+
+    private static boolean checkInteractAcrossUsersFull(@NonNull Context context) {
+        return context.checkCallingOrSelfPermission(
+                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
+                == PackageManager.PERMISSION_GRANTED;
+    }
+
+    private static boolean isCurrentProfile(@NonNull Context context, int uid) {
+        long token = Binder.clearCallingIdentity();
+        try {
+            final int currentUser = ActivityManager.getCurrentUser();
+            final int callingUserId = UserHandle.getUserId(uid);
+            if (callingUserId == currentUser) {
+                return true;
+            } else {
+                List<UserInfo> userProfiles = context.getSystemService(
+                        UserManager.class).getProfiles(currentUser);
+                for (UserInfo user : userProfiles) {
+                    if (user.id == callingUserId) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+}
diff --git a/telephony/java/android/telephony/MbmsDownloadSession.java b/telephony/java/android/telephony/MbmsDownloadSession.java
index da3d87b..ce1b80c 100644
--- a/telephony/java/android/telephony/MbmsDownloadSession.java
+++ b/telephony/java/android/telephony/MbmsDownloadSession.java
@@ -30,7 +30,6 @@
 import android.net.Uri;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.RemoteException;
 import android.telephony.mbms.DownloadStateCallback;
 import android.telephony.mbms.FileInfo;
@@ -53,6 +52,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -107,11 +107,8 @@
     /**
      * {@link Uri} extra that Android will attach to the intent supplied via
      * {@link android.telephony.mbms.DownloadRequest.Builder#setAppIntent(Intent)}
-     * Indicates the location of the successfully downloaded file within the temp file root set
-     * via {@link #setTempFileRootDirectory(File)}.
-     * While you may use this file in-place, it is highly encouraged that you move
-     * this file to a different location after receiving the download completion intent, as this
-     * file resides within the temp file directory.
+     * Indicates the location of the successfully downloaded file within the directory that the
+     * app provided via the builder.
      *
      * Will always be set to a non-null value if
      * {@link #EXTRA_MBMS_DOWNLOAD_RESULT} is set to {@link #RESULT_SUCCESSFUL}.
@@ -220,6 +217,8 @@
      */
     public static final int STATUS_PENDING_DOWNLOAD_WINDOW = 4;
 
+    private static final String DESTINATION_SANITY_CHECK_FILE_NAME = "destinationSanityCheckFile";
+
     private static AtomicBoolean sIsInitialized = new AtomicBoolean(false);
 
     private final Context mContext;
@@ -236,23 +235,20 @@
     private final Map<DownloadStateCallback, InternalDownloadStateCallback>
             mInternalDownloadCallbacks = new HashMap<>();
 
-    private MbmsDownloadSession(Context context, MbmsDownloadSessionCallback callback,
-            int subscriptionId, Handler handler) {
+    private MbmsDownloadSession(Context context, Executor executor, int subscriptionId,
+            MbmsDownloadSessionCallback callback) {
         mContext = context;
         mSubscriptionId = subscriptionId;
-        if (handler == null) {
-            handler = new Handler(Looper.getMainLooper());
-        }
-        mInternalCallback = new InternalDownloadSessionCallback(callback, handler);
+        mInternalCallback = new InternalDownloadSessionCallback(callback, executor);
     }
 
     /**
      * Create a new {@link MbmsDownloadSession} using the system default data subscription ID.
-     * See {@link #create(Context, MbmsDownloadSessionCallback, int, Handler)}
+     * See {@link #create(Context, Executor, int, MbmsDownloadSessionCallback)}
      */
     public static MbmsDownloadSession create(@NonNull Context context,
-            @NonNull MbmsDownloadSessionCallback callback, @NonNull Handler handler) {
-        return create(context, callback, SubscriptionManager.getDefaultSubscriptionId(), handler);
+            @NonNull Executor executor, @NonNull MbmsDownloadSessionCallback callback) {
+        return create(context, executor, SubscriptionManager.getDefaultSubscriptionId(), callback);
     }
 
     /**
@@ -279,24 +275,24 @@
      * {@link MbmsDownloadSession} that you received before calling this method again.
      *
      * @param context The instance of {@link Context} to use
-     * @param callback A callback to get asynchronous error messages and file service updates.
+     * @param executor The executor on which you wish to execute callbacks.
      * @param subscriptionId The data subscription ID to use
-     * @param handler The {@link Handler} on which callbacks should be enqueued.
+     * @param callback A callback to get asynchronous error messages and file service updates.
      * @return A new instance of {@link MbmsDownloadSession}, or null if an error occurred during
      * setup.
      */
     public static @Nullable MbmsDownloadSession create(@NonNull Context context,
-            final @NonNull MbmsDownloadSessionCallback callback,
-            int subscriptionId, @NonNull Handler handler) {
+            @NonNull Executor executor, int subscriptionId,
+            final @NonNull MbmsDownloadSessionCallback callback) {
         if (!sIsInitialized.compareAndSet(false, true)) {
             throw new IllegalStateException("Cannot have two active instances");
         }
         MbmsDownloadSession session =
-                new MbmsDownloadSession(context, callback, subscriptionId, handler);
+                new MbmsDownloadSession(context, executor, subscriptionId, callback);
         final int result = session.bindAndInitialize();
         if (result != MbmsErrors.SUCCESS) {
             sIsInitialized.set(false);
-            handler.post(new Runnable() {
+            executor.execute(new Runnable() {
                 @Override
                 public void run() {
                     callback.onError(result, null);
@@ -500,6 +496,10 @@
      * {@link MbmsDownloadSession#DEFAULT_TOP_LEVEL_TEMP_DIRECTORY} and store that as the temp
      * file root directory.
      *
+     * If the {@link DownloadRequest} has a destination that is not on the same filesystem as the
+     * temp file directory provided via {@link #getTempFileRootDirectory()}, an
+     * {@link IllegalArgumentException} will be thrown.
+     *
      * Asynchronous errors through the callback may include any error not specific to the
      * streaming use-case.
      * @param request The request that specifies what should be downloaded.
@@ -522,6 +522,8 @@
             setTempFileRootDirectory(tempRootDirectory);
         }
 
+        checkDownloadRequestDestination(request);
+
         try {
             int result = downloadService.download(request);
             if (result == MbmsErrors.SUCCESS) {
@@ -568,21 +570,21 @@
      * this method will throw an {@link IllegalArgumentException}.
      *
      * @param request The {@link DownloadRequest} that you want updates on.
+     * @param executor The {@link Executor} on which calls to {@code callback} should be executed.
      * @param callback The callback that should be called when the middleware has information to
      *                 share on the download.
-     * @param handler The {@link Handler} on which calls to {@code callback} should be enqueued on.
      * @return {@link MbmsErrors#SUCCESS} if the operation did not encounter a synchronous error,
      * and some other error code otherwise.
      */
     public int registerStateCallback(@NonNull DownloadRequest request,
-            @NonNull DownloadStateCallback callback, @NonNull Handler handler) {
+            @NonNull Executor executor, @NonNull DownloadStateCallback callback) {
         IMbmsDownloadService downloadService = mService.get();
         if (downloadService == null) {
             throw new IllegalStateException("Middleware not yet bound");
         }
 
         InternalDownloadStateCallback internalCallback =
-                new InternalDownloadStateCallback(callback, handler);
+                new InternalDownloadStateCallback(callback, executor);
 
         try {
             int result = downloadService.registerStateCallback(request, internalCallback,
@@ -604,7 +606,7 @@
 
     /**
      * Un-register a callback previously registered via
-     * {@link #registerStateCallback(DownloadRequest, DownloadStateCallback, Handler)}. After
+     * {@link #registerStateCallback(DownloadRequest, Executor, DownloadStateCallback)}. After
      * this method is called, no further callbacks will be enqueued on the {@link Handler}
      * provided upon registration, even if this method throws an exception.
      *
@@ -692,7 +694,7 @@
      * The state will be delivered as a callback via
      * {@link DownloadStateCallback#onStateUpdated(DownloadRequest, FileInfo, int)}. If no such
      * callback has been registered via
-     * {@link #registerStateCallback(DownloadRequest, DownloadStateCallback, Handler)}, this
+     * {@link #registerStateCallback(DownloadRequest, Executor, DownloadStateCallback)}, this
      * method will be a no-op.
      *
      * If the middleware has no record of the
@@ -775,7 +777,7 @@
      * instance of {@link MbmsDownloadSessionCallback}, but callbacks that have already been
      * enqueued will still be delivered.
      *
-     * It is safe to call {@link #create(Context, MbmsDownloadSessionCallback, int, Handler)} to
+     * It is safe to call {@link #create(Context, Executor, int, MbmsDownloadSessionCallback)} to
      * obtain another instance of {@link MbmsDownloadSession} immediately after this method
      * returns.
      *
@@ -831,6 +833,36 @@
         }
     }
 
+    private void checkDownloadRequestDestination(DownloadRequest request) {
+        File downloadRequestDestination = new File(request.getDestinationUri().getPath());
+        if (!downloadRequestDestination.isDirectory()) {
+            throw new IllegalArgumentException("The destination path must be a directory");
+        }
+        // Check if the request destination is okay to use by attempting to rename an empty
+        // file to there.
+        File testFile = new File(MbmsTempFileProvider.getEmbmsTempFileDir(mContext),
+                DESTINATION_SANITY_CHECK_FILE_NAME);
+        File testFileDestination = new File(downloadRequestDestination,
+                DESTINATION_SANITY_CHECK_FILE_NAME);
+
+        try {
+            if (!testFile.exists()) {
+                testFile.createNewFile();
+            }
+            if (!testFile.renameTo(testFileDestination)) {
+                throw new IllegalArgumentException("Destination provided in the download request " +
+                        "is invalid -- files in the temp file directory cannot be directly moved " +
+                        "there.");
+            }
+        } catch (IOException e) {
+            throw new IllegalStateException("Got IOException while testing out the destination: "
+                    + e);
+        } finally {
+            testFile.delete();
+            testFileDestination.delete();
+        }
+    }
+
     private File getDownloadRequestTokenPath(DownloadRequest request) {
         File tempFileLocation = MbmsUtils.getEmbmsTempFileDirForService(mContext,
                 request.getFileServiceId());
diff --git a/telephony/java/android/telephony/MbmsStreamingSession.java b/telephony/java/android/telephony/MbmsStreamingSession.java
index fb2ff7b..42c760d4 100644
--- a/telephony/java/android/telephony/MbmsStreamingSession.java
+++ b/telephony/java/android/telephony/MbmsStreamingSession.java
@@ -24,9 +24,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.ServiceConnection;
-import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.RemoteException;
 import android.telephony.mbms.InternalStreamingSessionCallback;
 import android.telephony.mbms.InternalStreamingServiceCallback;
@@ -42,6 +40,7 @@
 
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -89,14 +88,11 @@
     private int mSubscriptionId = INVALID_SUBSCRIPTION_ID;
 
     /** @hide */
-    private MbmsStreamingSession(Context context, MbmsStreamingSessionCallback callback,
-                    int subscriptionId, Handler handler) {
+    private MbmsStreamingSession(Context context, Executor executor, int subscriptionId,
+            MbmsStreamingSessionCallback callback) {
         mContext = context;
         mSubscriptionId = subscriptionId;
-        if (handler == null) {
-            handler = new Handler(Looper.getMainLooper());
-        }
-        mInternalCallback = new InternalStreamingSessionCallback(callback, handler);
+        mInternalCallback = new InternalStreamingSessionCallback(callback, executor);
     }
 
     /**
@@ -117,25 +113,25 @@
      * {@link MbmsStreamingSession} that you received before calling this method again.
      *
      * @param context The {@link Context} to use.
+     * @param executor The executor on which you wish to execute callbacks.
+     * @param subscriptionId The subscription ID to use.
      * @param callback A callback object on which you wish to receive results of asynchronous
      *                 operations.
-     * @param subscriptionId The subscription ID to use.
-     * @param handler The handler you wish to receive callbacks on.
      * @return An instance of {@link MbmsStreamingSession}, or null if an error occurred.
      */
     public static @Nullable MbmsStreamingSession create(@NonNull Context context,
-            final @NonNull MbmsStreamingSessionCallback callback, int subscriptionId,
-            @NonNull Handler handler) {
+            @NonNull Executor executor, int subscriptionId,
+            final @NonNull MbmsStreamingSessionCallback callback) {
         if (!sIsInitialized.compareAndSet(false, true)) {
             throw new IllegalStateException("Cannot create two instances of MbmsStreamingSession");
         }
-        MbmsStreamingSession session = new MbmsStreamingSession(context, callback,
-                subscriptionId, handler);
+        MbmsStreamingSession session = new MbmsStreamingSession(context, executor,
+                subscriptionId, callback);
 
         final int result = session.bindAndInitialize();
         if (result != MbmsErrors.SUCCESS) {
             sIsInitialized.set(false);
-            handler.post(new Runnable() {
+            executor.execute(new Runnable() {
                 @Override
                 public void run() {
                     callback.onError(result, null);
@@ -148,22 +144,22 @@
 
     /**
      * Create a new {@link MbmsStreamingSession} using the system default data subscription ID.
-     * See {@link #create(Context, MbmsStreamingSessionCallback, int, Handler)}.
+     * See {@link #create(Context, Executor, int, MbmsStreamingSessionCallback)}.
      */
     public static MbmsStreamingSession create(@NonNull Context context,
-            @NonNull MbmsStreamingSessionCallback callback, @NonNull Handler handler) {
-        return create(context, callback, SubscriptionManager.getDefaultSubscriptionId(), handler);
+            @NonNull Executor executor, @NonNull MbmsStreamingSessionCallback callback) {
+        return create(context, executor, SubscriptionManager.getDefaultSubscriptionId(), callback);
     }
 
     /**
      * Terminates this instance. Also terminates
      * any streaming services spawned from this instance as if
-     * {@link StreamingService#stopStreaming()} had been called on them. After this method returns,
+     * {@link StreamingService#close()} had been called on them. After this method returns,
      * no further callbacks originating from the middleware will be enqueued on the provided
      * instance of {@link MbmsStreamingSessionCallback}, but callbacks that have already been
      * enqueued will still be delivered.
      *
-     * It is safe to call {@link #create(Context, MbmsStreamingSessionCallback, int, Handler)} to
+     * It is safe to call {@link #create(Context, Executor, int, MbmsStreamingSessionCallback)} to
      * obtain another instance of {@link MbmsStreamingSession} immediately after this method
      * returns.
      *
@@ -237,20 +233,20 @@
      * {@link MbmsErrors.StreamingErrors}.
      *
      * @param serviceInfo The information about the service to stream.
+     * @param executor The executor on which you wish to execute callbacks for this stream.
      * @param callback A callback that'll be called when something about the stream changes.
-     * @param handler A handler that calls to {@code callback} should be called on.
      * @return An instance of {@link StreamingService} through which the stream can be controlled.
      *         May be {@code null} if an error occurred.
      */
     public @Nullable StreamingService startStreaming(StreamingServiceInfo serviceInfo,
-            StreamingServiceCallback callback, @NonNull Handler handler) {
+            @NonNull Executor executor, StreamingServiceCallback callback) {
         IMbmsStreamingService streamingService = mService.get();
         if (streamingService == null) {
             throw new IllegalStateException("Middleware not yet bound");
         }
 
         InternalStreamingServiceCallback serviceCallback = new InternalStreamingServiceCallback(
-                callback, handler);
+                callback, executor);
 
         StreamingService serviceForApp = new StreamingService(
                 mSubscriptionId, streamingService, this, serviceInfo, serviceCallback);
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index 0ee870a..0446925 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -372,7 +372,7 @@
                         break;
                     case LISTEN_PHYSICAL_CHANNEL_CONFIGURATION:
                         PhoneStateListener.this.onPhysicalChannelConfigurationChanged(
-                            (List<PhysicalChannelConfig>)msg.obj);
+                                (List<PhysicalChannelConfig>)msg.obj);
                         break;
                 }
             }
@@ -700,6 +700,10 @@
         public void onCarrierNetworkChange(boolean active) {
             send(LISTEN_CARRIER_NETWORK_CHANGE, 0, 0, active);
         }
+
+        public void onPhysicalChannelConfigurationChanged(List<PhysicalChannelConfig> configs) {
+            send(LISTEN_PHYSICAL_CHANNEL_CONFIGURATION, 0, 0, configs);
+        }
     }
 
     IPhoneStateListener callback = new IPhoneStateListenerStub(this);
diff --git a/telephony/java/android/telephony/PhysicalChannelConfig.java b/telephony/java/android/telephony/PhysicalChannelConfig.java
index 651d68d..ce444dd 100644
--- a/telephony/java/android/telephony/PhysicalChannelConfig.java
+++ b/telephony/java/android/telephony/PhysicalChannelConfig.java
@@ -27,8 +27,9 @@
  */
 public final class PhysicalChannelConfig implements Parcelable {
 
+    // TODO(b/72993578) consolidate these enums in a central location.
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef({CONNECTION_PRIMARY_SERVING, CONNECTION_SECONDARY_SERVING})
+    @IntDef({CONNECTION_PRIMARY_SERVING, CONNECTION_SECONDARY_SERVING, CONNECTION_UNKNOWN})
     public @interface ConnectionStatus {}
 
     /**
@@ -41,6 +42,9 @@
      */
     public static final int CONNECTION_SECONDARY_SERVING = 2;
 
+    /** Connection status is unknown. */
+    public static final int CONNECTION_UNKNOWN = Integer.MAX_VALUE;
+
     /**
      * Connection status of the cell.
      *
@@ -86,6 +90,7 @@
      *
      * @see #CONNECTION_PRIMARY_SERVING
      * @see #CONNECTION_SECONDARY_SERVING
+     * @see #CONNECTION_UNKNOWN
      *
      * @return Connection status of the cell
      */
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index ec348df..82a7450 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -178,7 +179,6 @@
 
     /**
      * Number of radio technologies for GSM, UMTS and CDMA.
-     * @hide
      */
     private static final int NEXT_RIL_RADIO_TECHNOLOGY = 20;
 
@@ -340,6 +340,8 @@
         mIsEmergencyOnly = s.mIsEmergencyOnly;
         mIsDataRoamingFromRegistration = s.mIsDataRoamingFromRegistration;
         mIsUsingCarrierAggregation = s.mIsUsingCarrierAggregation;
+        mChannelNumber = s.mChannelNumber;
+        mCellBandwidths = Arrays.copyOf(s.mCellBandwidths, s.mCellBandwidths.length);
         mLteEarfcnRsrpBoost = s.mLteEarfcnRsrpBoost;
         mNetworkRegistrationStates = new ArrayList<>(s.mNetworkRegistrationStates);
     }
@@ -1214,6 +1216,7 @@
     }
 
     /** @hide */
+    @TestApi
     public void setSystemAndNetworkId(int systemId, int networkId) {
         this.mSystemId = systemId;
         this.mNetworkId = networkId;
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index 778ca77..47a7d5f 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -62,7 +62,9 @@
      */
     public static final int INVALID = Integer.MAX_VALUE;
 
-    private static final int LTE_RSRP_THRESHOLDS_NUM = 6;
+    private static final int LTE_RSRP_THRESHOLDS_NUM = 4;
+    private static final int MAX_LTE_RSRP = -44;
+    private static final int MIN_LTE_RSRP = -140;
 
     /** Parameters reported by the Radio */
     private int mGsmSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5
@@ -86,7 +88,8 @@
                             // onSignalStrengthResult.
     private boolean mUseOnlyRsrpForLteLevel; // Use only RSRP for the number of LTE signal bar.
 
-    // The threshold of LTE RSRP for determining the display level of LTE signal bar.
+    // The threshold of LTE RSRP for determining the display level of LTE signal bar. Note that the
+    // min and max are fixed at MIN_LTE_RSRP (-140) and MAX_LTE_RSRP (-44).
     private int mLteRsrpThresholds[] = new int[LTE_RSRP_THRESHOLDS_NUM];
 
     /**
@@ -324,7 +327,8 @@
 
         // TS 36.214 Physical Layer Section 5.1.3, TS 36.331 RRC
         mLteSignalStrength = (mLteSignalStrength >= 0) ? mLteSignalStrength : 99;
-        mLteRsrp = ((mLteRsrp >= 44) && (mLteRsrp <= 140)) ? -mLteRsrp : SignalStrength.INVALID;
+        mLteRsrp = ((-mLteRsrp >= MIN_LTE_RSRP) && (-mLteRsrp <= MAX_LTE_RSRP)) ? -mLteRsrp
+                                : SignalStrength.INVALID;
         mLteRsrq = ((mLteRsrq >= 3) && (mLteRsrq <= 20)) ? -mLteRsrq : SignalStrength.INVALID;
         mLteRssnr = ((mLteRssnr >= -200) && (mLteRssnr <= 300)) ? mLteRssnr
                 : SignalStrength.INVALID;
@@ -740,24 +744,29 @@
      */
     public int getLteLevel() {
         /*
-         * TS 36.214 Physical Layer Section 5.1.3 TS 36.331 RRC RSSI = received
-         * signal + noise RSRP = reference signal dBm RSRQ = quality of signal
-         * dB= Number of Resource blocksxRSRP/RSSI SNR = gain=signal/noise ratio
-         * = -10log P1/P2 dB
+         * TS 36.214 Physical Layer Section 5.1.3
+         * TS 36.331 RRC
+         *
+         * RSSI = received signal + noise
+         * RSRP = reference signal dBm
+         * RSRQ = quality of signal dB = Number of Resource blocks*RSRP/RSSI
+         * SNR = gain = signal/noise ratio = -10log P1/P2 dB
          */
         int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, rsrpIconLevel = -1, snrIconLevel = -1;
 
-        if (mLteRsrp > mLteRsrpThresholds[5]) {
-            rsrpIconLevel = -1;
-        } else if (mLteRsrp >= (mLteRsrpThresholds[4] - mLteRsrpBoost)) {
-            rsrpIconLevel = SIGNAL_STRENGTH_GREAT;
+        if (mLteRsrp > MAX_LTE_RSRP || mLteRsrp < MIN_LTE_RSRP) {
+            if (mLteRsrp != INVALID) {
+                Log.wtf(LOG_TAG, "getLteLevel - invalid lte rsrp: mLteRsrp=" + mLteRsrp);
+            }
         } else if (mLteRsrp >= (mLteRsrpThresholds[3] - mLteRsrpBoost)) {
-            rsrpIconLevel = SIGNAL_STRENGTH_GOOD;
+            rsrpIconLevel = SIGNAL_STRENGTH_GREAT;
         } else if (mLteRsrp >= (mLteRsrpThresholds[2] - mLteRsrpBoost)) {
-            rsrpIconLevel = SIGNAL_STRENGTH_MODERATE;
+            rsrpIconLevel = SIGNAL_STRENGTH_GOOD;
         } else if (mLteRsrp >= (mLteRsrpThresholds[1] - mLteRsrpBoost)) {
+            rsrpIconLevel = SIGNAL_STRENGTH_MODERATE;
+        } else if (mLteRsrp >= (mLteRsrpThresholds[0] - mLteRsrpBoost)) {
             rsrpIconLevel = SIGNAL_STRENGTH_POOR;
-        } else if (mLteRsrp >= mLteRsrpThresholds[0]) {
+        } else {
             rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
         }
 
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 0874b86..8a3f138 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -395,6 +395,112 @@
     }
 
     /**
+     * Send a text based SMS with messaging options.
+     *
+     * @param destinationAddress the address to send the message to
+     * @param scAddress is the service center address or null to use
+     *  the current default SMSC
+     * @param text the body of the message to send
+     * @param sentIntent if not NULL this <code>PendingIntent</code> is
+     *  broadcast when the message is successfully sent, or failed.
+     *  The result code will be <code>Activity.RESULT_OK</code> for success,
+     *  or one of these errors:<br>
+     *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
+     *  <code>RESULT_ERROR_RADIO_OFF</code><br>
+     *  <code>RESULT_ERROR_NULL_PDU</code><br>
+     *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
+     *  the extra "errorCode" containing a radio technology specific value,
+     *  generally only useful for troubleshooting.<br>
+     *  The per-application based SMS control checks sentIntent. If sentIntent
+     *  is NULL the caller will be checked against all unknown applications,
+     *  which cause smaller number of SMS to be sent in checking period.
+     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
+     *  broadcast when the message is delivered to the recipient.  The
+     *  raw pdu of the status report is in the extended data ("pdu").
+     * @param priority Priority level of the message
+     *  Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1
+     *  ---------------------------------
+     *  PRIORITY      | Level of Priority
+     *  ---------------------------------
+     *      '00'      |     Normal
+     *      '01'      |     Interactive
+     *      '10'      |     Urgent
+     *      '11'      |     Emergency
+     *  ----------------------------------
+     *  Any Other values included Negative considered as Invalid Priority Indicator of the message.
+     * @param expectMore is a boolean to indicate the sending messages through same link or not.
+     * @param validityPeriod Validity Period of the message in mins.
+     *  Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1.
+     *  Validity Period(Minimum) -> 5 mins
+     *  Validity Period(Maximum) -> 635040 mins(i.e.63 weeks).
+     *  Any Other values included Negative considered as Invalid Validity Period of the message.
+     *
+     * @throws IllegalArgumentException if destinationAddress or text are empty
+     * {@hide}
+     */
+    public void sendTextMessage(
+            String destinationAddress, String scAddress, String text,
+            PendingIntent sentIntent, PendingIntent deliveryIntent,
+            int priority, boolean expectMore, int validityPeriod) {
+        sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
+                true /* persistMessage*/, priority, expectMore, validityPeriod);
+    }
+
+    private void sendTextMessageInternal(
+            String destinationAddress, String scAddress, String text,
+            PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage,
+            int priority, boolean expectMore, int validityPeriod) {
+        if (TextUtils.isEmpty(destinationAddress)) {
+            throw new IllegalArgumentException("Invalid destinationAddress");
+        }
+
+        if (TextUtils.isEmpty(text)) {
+            throw new IllegalArgumentException("Invalid message body");
+        }
+
+        if (priority < 0x00 || priority > 0x03) {
+            throw new IllegalArgumentException("Invalid priority");
+        }
+
+        if (validityPeriod < 0x05 || validityPeriod > 0x09b0a0) {
+            throw new IllegalArgumentException("Invalid validity period");
+        }
+
+        try {
+             ISms iccISms = getISmsServiceOrThrow();
+            if (iccISms != null) {
+                iccISms.sendTextForSubscriberWithOptions(getSubscriptionId(),
+                        ActivityThread.currentPackageName(), destinationAddress, scAddress, text,
+                        sentIntent, deliveryIntent, persistMessage,  priority, expectMore,
+                        validityPeriod);
+            }
+        } catch (RemoteException ex) {
+            // ignore it
+        }
+    }
+
+    /**
+     * Send a text based SMS without writing it into the SMS Provider.
+     *
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or the calling app has carrier
+     * privileges.
+     * </p>
+     *
+     * @see #sendTextMessage(String, String, String, PendingIntent,
+     * PendingIntent, int, boolean, int)
+     * @hide
+     */
+    public void sendTextMessageWithoutPersisting(
+            String destinationAddress, String scAddress, String text,
+            PendingIntent sentIntent, PendingIntent deliveryIntent, int priority,
+            boolean expectMore, int validityPeriod) {
+        sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
+                false /* persistMessage */, priority, expectMore, validityPeriod);
+    }
+
+    /**
+     *
      * Inject an SMS PDU into the android application framework.
      *
      * <p>Requires permission: {@link android.Manifest.permission#MODIFY_PHONE_STATE} or carrier
@@ -552,6 +658,140 @@
     }
 
     /**
+     * Send a multi-part text based SMS with messaging options. The callee should have already
+     * divided the message into correctly sized parts by calling
+     * <code>divideMessage</code>.
+     *
+     * <p class="note"><strong>Note:</strong> Using this method requires that your app has the
+     * {@link android.Manifest.permission#SEND_SMS} permission.</p>
+     *
+     * <p class="note"><strong>Note:</strong> Beginning with Android 4.4 (API level 19), if
+     * <em>and only if</em> an app is not selected as the default SMS app, the system automatically
+     * writes messages sent using this method to the SMS Provider (the default SMS app is always
+     * responsible for writing its sent messages to the SMS Provider). For information about
+     * how to behave as the default SMS app, see {@link android.provider.Telephony}.</p>
+     *
+     * @param destinationAddress the address to send the message to
+     * @param scAddress is the service center address or null to use
+     *   the current default SMSC
+     * @param parts an <code>ArrayList</code> of strings that, in order,
+     *   comprise the original message
+     * @param sentIntents if not null, an <code>ArrayList</code> of
+     *   <code>PendingIntent</code>s (one for each message part) that is
+     *   broadcast when the corresponding message part has been sent.
+     *   The result code will be <code>Activity.RESULT_OK</code> for success,
+     *   or one of these errors:<br>
+     *   <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
+     *   <code>RESULT_ERROR_RADIO_OFF</code><br>
+     *   <code>RESULT_ERROR_NULL_PDU</code><br>
+     *   For <code>RESULT_ERROR_GENERIC_FAILURE</code> each sentIntent may include
+     *   the extra "errorCode" containing a radio technology specific value,
+     *   generally only useful for troubleshooting.<br>
+     *   The per-application based SMS control checks sentIntent. If sentIntent
+     *   is NULL the caller will be checked against all unknown applications,
+     *   which cause smaller number of SMS to be sent in checking period.
+     * @param deliveryIntents if not null, an <code>ArrayList</code> of
+     *   <code>PendingIntent</code>s (one for each message part) that is
+     *   broadcast when the corresponding message part has been delivered
+     *   to the recipient.  The raw pdu of the status report is in the
+     *   extended data ("pdu").
+     * @param priority Priority level of the message
+     *  Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1
+     *  ---------------------------------
+     *  PRIORITY      | Level of Priority
+     *  ---------------------------------
+     *      '00'      |     Normal
+     *      '01'      |     Interactive
+     *      '10'      |     Urgent
+     *      '11'      |     Emergency
+     *  ----------------------------------
+     *  Any Other values included Negative considered as Invalid Priority Indicator of the message.
+     * @param expectMore is a boolean to indicate the sending messages through same link or not.
+     * @param validityPeriod Validity Period of the message in mins.
+     *  Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1.
+     *  Validity Period(Minimum) -> 5 mins
+     *  Validity Period(Maximum) -> 635040 mins(i.e.63 weeks).
+     *  Any Other values included Negative considered as Invalid Validity Period of the message.
+     *
+     * @throws IllegalArgumentException if destinationAddress or data are empty
+     * {@hide}
+     */
+    public void sendMultipartTextMessage(
+            String destinationAddress, String scAddress, ArrayList<String> parts,
+            ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents,
+            int priority, boolean expectMore, int validityPeriod) {
+        sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
+                deliveryIntents, true /* persistMessage*/);
+    }
+
+    private void sendMultipartTextMessageInternal(
+            String destinationAddress, String scAddress, List<String> parts,
+            List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents,
+            boolean persistMessage, int priority, boolean expectMore, int validityPeriod) {
+        if (TextUtils.isEmpty(destinationAddress)) {
+            throw new IllegalArgumentException("Invalid destinationAddress");
+        }
+        if (parts == null || parts.size() < 1) {
+            throw new IllegalArgumentException("Invalid message body");
+        }
+
+        if (priority < 0x00 || priority > 0x03) {
+            throw new IllegalArgumentException("Invalid priority");
+        }
+
+        if (validityPeriod < 0x05 || validityPeriod > 0x09b0a0) {
+            throw new IllegalArgumentException("Invalid validity period");
+        }
+
+        if (parts.size() > 1) {
+            try {
+                 ISms iccISms = getISmsServiceOrThrow();
+                if (iccISms != null) {
+                    iccISms.sendMultipartTextForSubscriberWithOptions(getSubscriptionId(),
+                            ActivityThread.currentPackageName(), destinationAddress, scAddress,
+                            parts, sentIntents, deliveryIntents, persistMessage, priority,
+                            expectMore, validityPeriod);
+                }
+            } catch (RemoteException ex) {
+                // ignore it
+            }
+        } else {
+            PendingIntent sentIntent = null;
+            PendingIntent deliveryIntent = null;
+            if (sentIntents != null && sentIntents.size() > 0) {
+                sentIntent = sentIntents.get(0);
+            }
+            if (deliveryIntents != null && deliveryIntents.size() > 0) {
+                deliveryIntent = deliveryIntents.get(0);
+            }
+            sendTextMessageInternal(destinationAddress, scAddress, parts.get(0),
+                    sentIntent, deliveryIntent, persistMessage, priority, expectMore,
+                    validityPeriod);
+        }
+    }
+
+    /**
+     * Send a multi-part text based SMS without writing it into the SMS Provider.
+     *
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or the calling app has carrier
+     * privileges.
+     * </p>
+     *
+     * @see #sendMultipartTextMessage(String, String, ArrayList, ArrayList,
+     * ArrayList, int, boolean, int)
+     * @hide
+     **/
+    public void sendMultipartTextMessageWithoutPersisting(
+            String destinationAddress, String scAddress, List<String> parts,
+            List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents,
+            int priority, boolean expectMore, int validityPeriod) {
+        sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
+                deliveryIntents, false /* persistMessage*/, priority, expectMore,
+                validityPeriod);
+    }
+
+   /**
      * Send a data based SMS to a specific application port.
      *
      * <p class="note"><strong>Note:</strong> Using this method requires that your app has the
@@ -1014,7 +1254,7 @@
      *   <code>getAllMessagesFromIcc</code>
      * @return <code>ArrayList</code> of <code>SmsMessage</code> objects.
      */
-    private static ArrayList<SmsMessage> createMessageListFromRawRecords(List<SmsRawData> records) {
+    private ArrayList<SmsMessage> createMessageListFromRawRecords(List<SmsRawData> records) {
         ArrayList<SmsMessage> messages = new ArrayList<SmsMessage>();
         if (records != null) {
             int count = records.size();
@@ -1022,7 +1262,8 @@
                 SmsRawData data = records.get(i);
                 // List contains all records, including "free" records (null)
                 if (data != null) {
-                    SmsMessage sms = SmsMessage.createFromEfRecord(i+1, data.getBytes());
+                    SmsMessage sms = SmsMessage.createFromEfRecord(i+1, data.getBytes(),
+                            getSubscriptionId());
                     if (sms != null) {
                         messages.add(sms);
                     }
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index 577ea7d..9d03b59 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -277,6 +277,31 @@
     }
 
     /**
+     * Create an SmsMessage from an SMS EF record.
+     *
+     * @param index Index of SMS record. This should be index in ArrayList
+     *              returned by SmsManager.getAllMessagesFromSim + 1.
+     * @param data Record data.
+     * @param subId Subscription Id of the SMS
+     * @return An SmsMessage representing the record.
+     *
+     * @hide
+     */
+    public static SmsMessage createFromEfRecord(int index, byte[] data, int subId) {
+        SmsMessageBase wrappedMessage;
+
+        if (isCdmaVoice(subId)) {
+            wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.createFromEfRecord(
+                    index, data);
+        } else {
+            wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.createFromEfRecord(
+                    index, data);
+        }
+
+        return wrappedMessage != null ? new SmsMessage(wrappedMessage) : null;
+    }
+
+    /**
      * Get the TP-Layer-Length for the given SMS-SUBMIT PDU Basically, the
      * length in bytes (not hex chars) less the SMSC header
      *
@@ -836,6 +861,7 @@
          int activePhone = TelephonyManager.getDefault().getCurrentPhoneType(subId);
          return (PHONE_TYPE_CDMA == activePhone);
    }
+
     /**
      * Decide if the carrier supports long SMS.
      * {@hide}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 11a1984..4a61437 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -613,9 +613,9 @@
      *                 onSubscriptionsChanged overridden.
      */
     public void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
-        String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
+        String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>";
         if (DBG) {
-            logd("register OnSubscriptionsChangedListener pkgForDebug=" + pkgForDebug
+            logd("register OnSubscriptionsChangedListener pkgName=" + pkgName
                     + " listener=" + listener);
         }
         try {
@@ -624,7 +624,7 @@
             ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
                     "telephony.registry"));
             if (tr != null) {
-                tr.addOnSubscriptionsChangedListener(pkgForDebug, listener.callback);
+                tr.addOnSubscriptionsChangedListener(pkgName, listener.callback);
             }
         } catch (RemoteException ex) {
             // Should not happen
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index fefc03d..af3a0bb 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -4054,6 +4054,9 @@
      * To unregister a listener, pass the listener object and set the
      * events argument to
      * {@link PhoneStateListener#LISTEN_NONE LISTEN_NONE} (0).
+     * Note: if you call this method while in the middle of a binder transaction, you <b>must</b>
+     * call {@link android.os.Binder#clearCallingIdentity()} before calling this method. A
+     * {@link SecurityException} will be thrown otherwise.
      *
      * @param listener The {@link PhoneStateListener} object to register
      *                 (or unregister)
@@ -4846,8 +4849,6 @@
             return;
         }
 
-        Rlog.d(TAG, "setTelephonyProperty: success phoneId=" + phoneId +
-                " property=" + property + " value: " + value + " propVal=" + propVal);
         SystemProperties.set(property, propVal);
     }
 
@@ -5280,6 +5281,24 @@
     }
 
     /**
+     * Determines if emergency calling is allowed for the MMTEL feature on the slot provided.
+     * @param slotIndex The SIM slot of the MMTEL feature
+     * @return true if emergency calling is allowed, false otherwise.
+     * @hide
+     */
+    public boolean isEmergencyMmTelAvailable(int slotIndex) {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.isEmergencyMmTelAvailable(slotIndex);
+            }
+        } catch (RemoteException e) {
+            Rlog.e(TAG, "isEmergencyMmTelAvailable, RemoteException: " + e.getMessage());
+        }
+        return false;
+    }
+
+    /**
      * Set IMS registration state
      *
      * @param Registration state
@@ -7182,18 +7201,16 @@
      *
      * @return Carrier id of the current subscription. Return {@link #UNKNOWN_CARRIER_ID} if the
      * subscription is unavailable or the carrier cannot be identified.
-     * @throws IllegalStateException if telephony service is unavailable.
      */
     public int getAndroidCarrierIdForSubscription() {
         try {
             ITelephony service = getITelephony();
-            return service.getSubscriptionCarrierId(getSubId());
+            if (service != null) {
+                return service.getSubscriptionCarrierId(getSubId());
+            }
         } catch (RemoteException ex) {
             // This could happen if binder process crashes.
             ex.rethrowAsRuntimeException();
-        } catch (NullPointerException ex) {
-            // This could happen before phone restarts due to crashing.
-            throw new IllegalStateException("Telephony service unavailable");
         }
         return UNKNOWN_CARRIER_ID;
     }
@@ -7209,18 +7226,16 @@
      *
      * @return Carrier name of the current subscription. Return {@code null} if the subscription is
      * unavailable or the carrier cannot be identified.
-     * @throws IllegalStateException if telephony service is unavailable.
      */
     public CharSequence getAndroidCarrierNameForSubscription() {
         try {
             ITelephony service = getITelephony();
-            return service.getSubscriptionCarrierName(getSubId());
+            if (service != null) {
+                return service.getSubscriptionCarrierName(getSubId());
+            }
         } catch (RemoteException ex) {
             // This could happen if binder process crashes.
             ex.rethrowAsRuntimeException();
-        } catch (NullPointerException ex) {
-            // This could happen before phone restarts due to crashing.
-            throw new IllegalStateException("Telephony service unavailable");
         }
         return null;
     }
@@ -7668,4 +7683,83 @@
             Log.e(TAG, "Error calling ITelephony#setUserDataEnabled", e);
         }
     }
+
+    /**
+     * In this mode, modem will not send specified indications when screen is off.
+     * @hide
+     */
+    public static final int INDICATION_UPDATE_MODE_NORMAL                   = 1;
+
+    /**
+     * In this mode, modem will still send specified indications when screen is off.
+     * @hide
+     */
+    public static final int INDICATION_UPDATE_MODE_IGNORE_SCREEN_OFF        = 2;
+
+    /** @hide */
+    @IntDef(prefix = { "INDICATION_UPDATE_MODE_" }, value = {
+            INDICATION_UPDATE_MODE_NORMAL,
+            INDICATION_UPDATE_MODE_IGNORE_SCREEN_OFF
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface IndicationUpdateMode{}
+
+    /**
+     * The indication for signal strength update.
+     * @hide
+     */
+    public static final int INDICATION_FILTER_SIGNAL_STRENGTH               = 0x1;
+
+    /**
+     * The indication for full network state update.
+     * @hide
+     */
+    public static final int INDICATION_FILTER_FULL_NETWORK_STATE            = 0x2;
+
+    /**
+     * The indication for data call dormancy changed update.
+     * @hide
+     */
+    public static final int INDICATION_FILTER_DATA_CALL_DORMANCY_CHANGED    = 0x4;
+
+    /** @hide */
+    @IntDef(flag = true, prefix = { "INDICATION_FILTER_" }, value = {
+            INDICATION_FILTER_SIGNAL_STRENGTH,
+            INDICATION_FILTER_FULL_NETWORK_STATE,
+            INDICATION_FILTER_DATA_CALL_DORMANCY_CHANGED
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface IndicationFilters{}
+
+    /**
+     * Sets radio indication update mode. This can be used to control the behavior of indication
+     * update from modem to Android frameworks. For example, by default several indication updates
+     * are turned off when screen is off, but in some special cases (e.g. carkit is connected but
+     * screen is off) we want to turn on those indications even when the screen is off.
+     *
+     * <p>Requires Permission:
+     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
+     *
+     * @param filters Indication filters. Should be a bitmask of INDICATION_FILTER_XXX.
+     * @see #INDICATION_FILTER_SIGNAL_STRENGTH
+     * @see #INDICATION_FILTER_FULL_NETWORK_STATE
+     * @see #INDICATION_FILTER_DATA_CALL_DORMANCY_CHANGED
+     * @param updateMode The voice activation state
+     * @see #INDICATION_UPDATE_MODE_NORMAL
+     * @see #INDICATION_UPDATE_MODE_IGNORE_SCREEN_OFF
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public void setRadioIndicationUpdateMode(@IndicationFilters int filters,
+                                             @IndicationUpdateMode int updateMode) {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                telephony.setRadioIndicationUpdateMode(getSubId(), filters, updateMode);
+            }
+        } catch (RemoteException ex) {
+            // This could happen if binder process crashes.
+            ex.rethrowAsRuntimeException();
+        }
+    }
 }
diff --git a/telephony/java/android/telephony/UiccAccessRule.java b/telephony/java/android/telephony/UiccAccessRule.java
index c3f8a19..d8836dc 100644
--- a/telephony/java/android/telephony/UiccAccessRule.java
+++ b/telephony/java/android/telephony/UiccAccessRule.java
@@ -157,6 +157,13 @@
     }
 
     /**
+     * Returns the hex string of the certificate hash.
+     */
+    public String getCertificateHexString() {
+        return IccUtils.bytesToHexString(mCertificateHash);
+    }
+
+    /**
      * Returns the carrier privilege status associated with the given package.
      *
      * @param packageInfo package info fetched from
@@ -221,6 +228,15 @@
     }
 
     @Override
+    public int hashCode() {
+        int result = 1;
+        result = 31 * result + Arrays.hashCode(mCertificateHash);
+        result = 31 * result + Objects.hashCode(mPackageName);
+        result = 31 * result + Objects.hashCode(mAccessType);
+        return result;
+    }
+
+    @Override
     public String toString() {
         return "cert: " + IccUtils.bytesToHexString(mCertificateHash) + " pkg: " +
                 mPackageName + " access: " + mAccessType;
diff --git a/telephony/java/android/telephony/data/DataProfile.java b/telephony/java/android/telephony/data/DataProfile.java
index 41c1430..e8597b2 100644
--- a/telephony/java/android/telephony/data/DataProfile.java
+++ b/telephony/java/android/telephony/data/DataProfile.java
@@ -17,6 +17,7 @@
 package android.telephony.data;
 
 import android.annotation.SystemApi;
+import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
@@ -230,8 +231,10 @@
 
     @Override
     public String toString() {
-        return "DataProfile=" + mProfileId + "/" + mApn + "/" + mProtocol + "/" + mAuthType
-                + "/" + mUserName + "/" + mPassword + "/" + mType + "/" + mMaxConnsTime
+        return "DataProfile=" + mProfileId + "/" + mProtocol + "/" + mAuthType
+                + "/" + (Build.IS_USER ? "***/***/***" :
+                         (mApn + "/" + mUserName + "/" + mPassword))
+                + "/" + mType + "/" + mMaxConnsTime
                 + "/" + mMaxConns + "/" + mWaitTime + "/" + mEnabled + "/"
                 + mSupportedApnTypesBitmap + "/" + mRoamingProtocol + "/" + mBearerBitmap + "/"
                 + mMtu + "/" + mMvnoType + "/" + mMvnoMatchData + "/" + mModemCognitive;
diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java
index 1fdbae9..d537699 100644
--- a/telephony/java/android/telephony/ims/feature/ImsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java
@@ -87,7 +87,9 @@
     // ImsFeatures that are defined in the Manifests. Ensure that these values match the previously
     // defined values in ImsServiceClass for compatibility purposes.
     /**
-     * This feature supports emergency calling over MMTEL.
+     * This feature supports emergency calling over MMTEL. If defined, the framework will try to
+     * place an emergency call over IMS first. If it is not defined, the framework will only use
+     * CSFB for emergency calling.
      */
     public static final int FEATURE_EMERGENCY_MMTEL = 0;
     /**
diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
index 09267fc..2fffd36 100644
--- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java
+++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
@@ -332,20 +332,14 @@
     public static final int PROCESS_CALL_IMS = 0;
     /**
      * To be returned by {@link #shouldProcessCall(String[])} when the telephony framework should
-     * not process the outgoing NON_EMERGENCY call as IMS and should instead use circuit switch.
+     * not process the outgoing call as IMS and should instead use circuit switch.
      */
     public static final int PROCESS_CALL_CSFB = 1;
-    /**
-     * To be returned by {@link #shouldProcessCall(String[])} when the telephony framework should
-     * not process the outgoing EMERGENCY call as IMS and should instead use circuit switch.
-     */
-    public static final int PROCESS_CALL_EMERGENCY_CSFB = 2;
 
     @IntDef(flag = true,
             value = {
                     PROCESS_CALL_IMS,
-                    PROCESS_CALL_CSFB,
-                    PROCESS_CALL_EMERGENCY_CSFB
+                    PROCESS_CALL_CSFB
             })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ProcessCallResult {}
@@ -536,12 +530,15 @@
 
     /**
      * Called by the framework to determine if the outgoing call, designated by the outgoing
-     * {@link Uri}s, should be processed as an IMS call or CSFB call.
+     * {@link String}s, should be processed as an IMS call or CSFB call. If this method's
+     * functionality is not overridden, the platform will process every call as IMS as long as the
+     * MmTelFeature reports that the {@link MmTelCapabilities#CAPABILITY_TYPE_VOICE} capability is
+     * available.
      * @param numbers An array of {@link String}s that will be used for placing the call. There can
      *         be multiple {@link String}s listed in the case when we want to place an outgoing
      *         call as a conference.
      * @return a {@link ProcessCallResult} to the framework, which will be used to determine if the
-     *        call wil lbe placed over IMS or via CSFB.
+     *        call will be placed over IMS or via CSFB.
      */
     public @ProcessCallResult int shouldProcessCall(String[] numbers) {
         return PROCESS_CALL_IMS;
diff --git a/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java
index 0673a38..0664a7e 100644
--- a/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java
@@ -74,7 +74,9 @@
     /** @hide */
     @IntDef({
             DELIVER_STATUS_OK,
-            DELIVER_STATUS_ERROR
+            DELIVER_STATUS_ERROR_GENERIC,
+            DELIVER_STATUS_ERROR_NO_MEMORY,
+            DELIVER_STATUS_ERROR_REQUEST_NOT_SUPPORTED
         })
     @Retention(RetentionPolicy.SOURCE)
     public @interface DeliverStatusResult {}
@@ -86,7 +88,17 @@
     /**
      * Message was not delivered.
      */
-    public static final int DELIVER_STATUS_ERROR = 2;
+    public static final int DELIVER_STATUS_ERROR_GENERIC = 2;
+
+    /**
+     * Message was not delivered due to lack of memory.
+     */
+    public static final int DELIVER_STATUS_ERROR_NO_MEMORY = 3;
+
+    /**
+     * Message was not delivered as the request is not supported.
+     */
+    public static final int DELIVER_STATUS_ERROR_REQUEST_NOT_SUPPORTED = 4;
 
     /** @hide */
     @IntDef({
@@ -106,7 +118,6 @@
      */
     public static final int STATUS_REPORT_STATUS_ERROR = 2;
 
-
     // Lock for feature synchronization
     private final Object mLock = new Object();
     private IImsSmsListener mListener;
@@ -157,7 +168,9 @@
      * @param token token provided in {@link #onSmsReceived(int, String, byte[])}
      * @param result result of delivering the message. Valid values are:
      *  {@link #DELIVER_STATUS_OK},
-     *  {@link #DELIVER_STATUS_ERROR}
+     *  {@link #DELIVER_STATUS_ERROR_GENERIC},
+     *  {@link #DELIVER_STATUS_ERROR_NO_MEMORY},
+     *  {@link #DELIVER_STATUS_ERROR_REQUEST_NOT_SUPPORTED}
      * @param messageRef the message reference
      */
     public void acknowledgeSms(int token, @DeliverStatusResult int messageRef, int result) {
@@ -200,7 +213,7 @@
                 mListener.onSmsReceived(token, format, pdu);
             } catch (RemoteException e) {
                 Log.e(LOG_TAG, "Can not deliver sms: " + e.getMessage());
-                acknowledgeSms(token, 0, DELIVER_STATUS_ERROR);
+                acknowledgeSms(token, 0, DELIVER_STATUS_ERROR_GENERIC);
             }
         }
     }
diff --git a/telephony/java/android/telephony/mbms/DownloadRequest.java b/telephony/java/android/telephony/mbms/DownloadRequest.java
index f0d60b6..602c796 100644
--- a/telephony/java/android/telephony/mbms/DownloadRequest.java
+++ b/telephony/java/android/telephony/mbms/DownloadRequest.java
@@ -27,10 +27,13 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.Externalizable;
+import java.io.File;
 import java.io.IOException;
+import java.io.ObjectInput;
 import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
 import java.io.ObjectOutputStream;
-import java.io.Serializable;
 import java.net.URISyntaxException;
 import java.nio.charset.StandardCharsets;
 import java.security.MessageDigest;
@@ -54,34 +57,116 @@
     public static final int MAX_DESTINATION_URI_SIZE = 50000;
 
     /** @hide */
-    private static class OpaqueDataContainer implements Serializable {
-        private final String appIntent;
-        private final int version;
+    private static class SerializationDataContainer implements Externalizable {
+        private String fileServiceId;
+        private Uri source;
+        private Uri destination;
+        private int subscriptionId;
+        private String appIntent;
+        private int version;
 
-        public OpaqueDataContainer(String appIntent, int version) {
-            this.appIntent = appIntent;
-            this.version = version;
+        public SerializationDataContainer() {}
+
+        SerializationDataContainer(DownloadRequest request) {
+            fileServiceId = request.fileServiceId;
+            source = request.sourceUri;
+            destination = request.destinationUri;
+            subscriptionId = request.subscriptionId;
+            appIntent = request.serializedResultIntentForApp;
+            version = request.version;
+        }
+
+        @Override
+        public void writeExternal(ObjectOutput objectOutput) throws IOException {
+            objectOutput.write(version);
+            objectOutput.writeUTF(fileServiceId);
+            objectOutput.writeUTF(source.toString());
+            objectOutput.writeUTF(destination.toString());
+            objectOutput.write(subscriptionId);
+            objectOutput.writeUTF(appIntent);
+        }
+
+        @Override
+        public void readExternal(ObjectInput objectInput) throws IOException {
+            version = objectInput.read();
+            fileServiceId = objectInput.readUTF();
+            source = Uri.parse(objectInput.readUTF());
+            destination = Uri.parse(objectInput.readUTF());
+            subscriptionId = objectInput.read();
+            appIntent = objectInput.readUTF();
+            // Do version checks here -- future versions may have other fields.
         }
     }
 
     public static class Builder {
         private String fileServiceId;
         private Uri source;
+        private Uri destination;
         private int subscriptionId;
         private String appIntent;
         private int version = CURRENT_VERSION;
 
+        /**
+         * Constructs a {@link Builder} from a {@link DownloadRequest}
+         * @param other The {@link DownloadRequest} from which the data for the {@link Builder}
+         *              should come.
+         * @return An instance of {@link Builder} pre-populated with data from the provided
+         *         {@link DownloadRequest}.
+         */
+        public static Builder fromDownloadRequest(DownloadRequest other) {
+            Builder result = new Builder(other.sourceUri, other.destinationUri)
+                    .setServiceId(other.fileServiceId)
+                    .setSubscriptionId(other.subscriptionId);
+            result.appIntent = other.serializedResultIntentForApp;
+            // Version of the result is going to be the current version -- as this class gets
+            // updated, new fields will be set to default values in here.
+            return result;
+        }
+
+        /**
+         * This method constructs a new instance of {@link Builder} based on the serialized data
+         * passed in.
+         * @param data A byte array, the contents of which should have been originally obtained
+         *             from {@link DownloadRequest#toByteArray()}.
+         */
+        public static Builder fromSerializedRequest(byte[] data) {
+            Builder builder;
+            try {
+                ObjectInputStream stream = new ObjectInputStream(new ByteArrayInputStream(data));
+                SerializationDataContainer dataContainer =
+                        (SerializationDataContainer) stream.readObject();
+                builder = new Builder(dataContainer.source, dataContainer.destination);
+                builder.version = dataContainer.version;
+                builder.appIntent = dataContainer.appIntent;
+                builder.fileServiceId = dataContainer.fileServiceId;
+                builder.subscriptionId = dataContainer.subscriptionId;
+            } catch (IOException e) {
+                // Really should never happen
+                Log.e(LOG_TAG, "Got IOException trying to parse opaque data");
+                throw new IllegalArgumentException(e);
+            } catch (ClassNotFoundException e) {
+                Log.e(LOG_TAG, "Got ClassNotFoundException trying to parse opaque data");
+                throw new IllegalArgumentException(e);
+            }
+            return builder;
+        }
 
         /**
          * Builds a new DownloadRequest.
          * @param sourceUri the source URI for the DownloadRequest to be built. This URI should
          *     never be null.
+         * @param destinationUri The final location for the file(s) that are to be downloaded. It
+         *     must be on the same filesystem as the temp file directory set via
+         *     {@link android.telephony.MbmsDownloadSession#setTempFileRootDirectory(File)}.
+         *     The provided path must be a directory that exists. An
+         *     {@link IllegalArgumentException} will be thrown otherwise.
          */
-        public Builder(@NonNull Uri sourceUri) {
-            if (sourceUri == null) {
-                throw new IllegalArgumentException("Source URI must be non-null.");
+        public Builder(@NonNull Uri sourceUri, @NonNull Uri destinationUri) {
+            if (sourceUri == null || destinationUri == null) {
+                throw new IllegalArgumentException("Source and destination URIs must be non-null.");
             }
             source = sourceUri;
+            destination = destinationUri;
         }
 
         /**
@@ -130,68 +215,34 @@
             return this;
         }
 
-        /**
-         * For use by the middleware to set the byte array of opaque data. The opaque data
-         * includes information about the download request that is used by the client app and the
-         * manager code, but is irrelevant to the middleware.
-         * @param data A byte array, the contents of which should have been originally obtained
-         *             from {@link DownloadRequest#getOpaqueData()}.
-         * @hide
-         */
-        @SystemApi
-        public Builder setOpaqueData(byte[] data) {
-            try {
-                ObjectInputStream stream = new ObjectInputStream(new ByteArrayInputStream(data));
-                OpaqueDataContainer dataContainer = (OpaqueDataContainer) stream.readObject();
-                version = dataContainer.version;
-                appIntent = dataContainer.appIntent;
-            } catch (IOException e) {
-                // Really should never happen
-                Log.e(LOG_TAG, "Got IOException trying to parse opaque data");
-                throw new IllegalArgumentException(e);
-            } catch (ClassNotFoundException e) {
-                Log.e(LOG_TAG, "Got ClassNotFoundException trying to parse opaque data");
-                throw new IllegalArgumentException(e);
-            }
-            return this;
-        }
-
         public DownloadRequest build() {
-            return new DownloadRequest(fileServiceId, source, subscriptionId, appIntent, version);
+            return new DownloadRequest(fileServiceId, source, destination,
+                    subscriptionId, appIntent, version);
         }
     }
 
     private final String fileServiceId;
     private final Uri sourceUri;
+    private final Uri destinationUri;
     private final int subscriptionId;
     private final String serializedResultIntentForApp;
     private final int version;
 
     private DownloadRequest(String fileServiceId,
-            Uri source, int sub,
+            Uri source, Uri destination, int sub,
             String appIntent, int version) {
         this.fileServiceId = fileServiceId;
         sourceUri = source;
         subscriptionId = sub;
+        destinationUri = destination;
         serializedResultIntentForApp = appIntent;
         this.version = version;
     }
 
-    public static DownloadRequest copy(DownloadRequest other) {
-        return new DownloadRequest(other);
-    }
-
-    private DownloadRequest(DownloadRequest dr) {
-        fileServiceId = dr.fileServiceId;
-        sourceUri = dr.sourceUri;
-        subscriptionId = dr.subscriptionId;
-        serializedResultIntentForApp = dr.serializedResultIntentForApp;
-        version = dr.version;
-    }
-
     private DownloadRequest(Parcel in) {
         fileServiceId = in.readString();
         sourceUri = in.readParcelable(getClass().getClassLoader());
+        destinationUri = in.readParcelable(getClass().getClassLoader());
         subscriptionId = in.readInt();
         serializedResultIntentForApp = in.readString();
         version = in.readInt();
@@ -204,6 +255,7 @@
     public void writeToParcel(Parcel out, int flags) {
         out.writeString(fileServiceId);
         out.writeParcelable(sourceUri, flags);
+        out.writeParcelable(destinationUri, flags);
         out.writeInt(subscriptionId);
         out.writeString(serializedResultIntentForApp);
         out.writeInt(version);
@@ -224,6 +276,13 @@
     }
 
     /**
+     * @return The destination {@link Uri} of the downloaded file.
+     */
+    public Uri getDestinationUri() {
+        return destinationUri;
+    }
+
+    /**
      * @return The subscription ID on which to perform MBMS operations.
      */
     public int getSubscriptionId() {
@@ -244,19 +303,16 @@
     }
 
     /**
-     * For use by the middleware only. The byte array returned from this method should be
-     * persisted and sent back to the app upon download completion or failure by passing it into
-     * {@link Builder#setOpaqueData(byte[])}.
-     * @return A byte array of opaque data to persist.
-     * @hide
+     * This method returns a byte array that may be persisted to disk and restored to a
+     * {@link DownloadRequest}. The instance of {@link DownloadRequest} persisted by this method
+     * may be recovered via {@link Builder#fromSerializedRequest(byte[])}.
+     * @return A byte array of data to persist.
      */
-    @SystemApi
-    public byte[] getOpaqueData() {
+    public byte[] toByteArray() {
         try {
             ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
             ObjectOutputStream stream = new ObjectOutputStream(byteArrayOutputStream);
-            OpaqueDataContainer container = new OpaqueDataContainer(
-                    serializedResultIntentForApp, version);
+            SerializationDataContainer container = new SerializationDataContainer(this);
             stream.writeObject(container);
             stream.flush();
             return byteArrayOutputStream.toByteArray();
@@ -299,15 +355,6 @@
     }
 
     /**
-     * @hide
-     */
-    public boolean isMultipartDownload() {
-        // TODO: figure out what qualifies a request as a multipart download request.
-        return getSourceUri().getLastPathSegment() != null &&
-                getSourceUri().getLastPathSegment().contains("*");
-    }
-
-    /**
      * Retrieves the hash string that should be used as the filename when storing a token for
      * this DownloadRequest.
      * @hide
@@ -320,8 +367,9 @@
             throw new RuntimeException("Could not get sha256 hash object");
         }
         if (version >= 1) {
-            // Hash the source URI and the app intent
+            // Hash the source, destination, and the app intent
             digest.update(sourceUri.toString().getBytes(StandardCharsets.UTF_8));
+            digest.update(destinationUri.toString().getBytes(StandardCharsets.UTF_8));
             if (serializedResultIntentForApp != null) {
                 digest.update(serializedResultIntentForApp.getBytes(StandardCharsets.UTF_8));
             }
@@ -344,12 +392,13 @@
                 version == request.version &&
                 Objects.equals(fileServiceId, request.fileServiceId) &&
                 Objects.equals(sourceUri, request.sourceUri) &&
+                Objects.equals(destinationUri, request.destinationUri) &&
                 Objects.equals(serializedResultIntentForApp, request.serializedResultIntentForApp);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(fileServiceId, sourceUri,
+        return Objects.hash(fileServiceId, sourceUri, destinationUri,
                 subscriptionId, serializedResultIntentForApp, version);
     }
 }
diff --git a/telephony/java/android/telephony/mbms/InternalDownloadSessionCallback.java b/telephony/java/android/telephony/mbms/InternalDownloadSessionCallback.java
index a7a5958..c2a79d8 100644
--- a/telephony/java/android/telephony/mbms/InternalDownloadSessionCallback.java
+++ b/telephony/java/android/telephony/mbms/InternalDownloadSessionCallback.java
@@ -16,22 +16,23 @@
 
 package android.telephony.mbms;
 
-import android.os.Handler;
+import android.os.Binder;
 import android.os.RemoteException;
 
 import java.util.List;
+import java.util.concurrent.Executor;
 
 /** @hide */
 public class InternalDownloadSessionCallback extends IMbmsDownloadSessionCallback.Stub {
 
-    private final Handler mHandler;
+    private final Executor mExecutor;
     private final MbmsDownloadSessionCallback mAppCallback;
     private volatile boolean mIsStopped = false;
 
     public InternalDownloadSessionCallback(MbmsDownloadSessionCallback appCallback,
-            Handler handler) {
+            Executor executor) {
         mAppCallback = appCallback;
-        mHandler = handler;
+        mExecutor = executor;
     }
 
     @Override
@@ -40,10 +41,15 @@
             return;
         }
 
-        mHandler.post(new Runnable() {
+        mExecutor.execute(new Runnable() {
             @Override
             public void run() {
-                mAppCallback.onError(errorCode, message);
+                long token = Binder.clearCallingIdentity();
+                try {
+                    mAppCallback.onError(errorCode, message);
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
             }
         });
     }
@@ -54,10 +60,15 @@
             return;
         }
 
-        mHandler.post(new Runnable() {
+        mExecutor.execute(new Runnable() {
             @Override
             public void run() {
-                mAppCallback.onFileServicesUpdated(services);
+                long token = Binder.clearCallingIdentity();
+                try {
+                    mAppCallback.onFileServicesUpdated(services);
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
             }
         });
     }
@@ -68,18 +79,19 @@
             return;
         }
 
-        mHandler.post(new Runnable() {
+        mExecutor.execute(new Runnable() {
             @Override
             public void run() {
-                mAppCallback.onMiddlewareReady();
+                long token = Binder.clearCallingIdentity();
+                try {
+                    mAppCallback.onMiddlewareReady();
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
             }
         });
     }
 
-    public Handler getHandler() {
-        return mHandler;
-    }
-
     public void stop() {
         mIsStopped = true;
     }
diff --git a/telephony/java/android/telephony/mbms/InternalDownloadStateCallback.java b/telephony/java/android/telephony/mbms/InternalDownloadStateCallback.java
index 8702952..f30ae27 100644
--- a/telephony/java/android/telephony/mbms/InternalDownloadStateCallback.java
+++ b/telephony/java/android/telephony/mbms/InternalDownloadStateCallback.java
@@ -16,20 +16,22 @@
 
 package android.telephony.mbms;
 
-import android.os.Handler;
+import android.os.Binder;
 import android.os.RemoteException;
 
+import java.util.concurrent.Executor;
+
 /**
  * @hide
  */
 public class InternalDownloadStateCallback extends IDownloadStateCallback.Stub {
-    private final Handler mHandler;
+    private final Executor mExecutor;
     private final DownloadStateCallback mAppCallback;
     private volatile boolean mIsStopped = false;
 
-    public InternalDownloadStateCallback(DownloadStateCallback appCallback, Handler handler) {
+    public InternalDownloadStateCallback(DownloadStateCallback appCallback, Executor executor) {
         mAppCallback = appCallback;
-        mHandler = handler;
+        mExecutor = executor;
     }
 
     @Override
@@ -40,11 +42,16 @@
             return;
         }
 
-        mHandler.post(new Runnable() {
+        mExecutor.execute(new Runnable() {
             @Override
             public void run() {
-                mAppCallback.onProgressUpdated(request, fileInfo, currentDownloadSize,
-                        fullDownloadSize, currentDecodedSize, fullDecodedSize);
+                long token = Binder.clearCallingIdentity();
+                try {
+                    mAppCallback.onProgressUpdated(request, fileInfo, currentDownloadSize,
+                            fullDownloadSize, currentDecodedSize, fullDecodedSize);
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
             }
         });
     }
@@ -56,10 +63,15 @@
             return;
         }
 
-        mHandler.post(new Runnable() {
+        mExecutor.execute(new Runnable() {
             @Override
             public void run() {
-                mAppCallback.onStateUpdated(request, fileInfo, state);
+                long token = Binder.clearCallingIdentity();
+                try {
+                    mAppCallback.onStateUpdated(request, fileInfo, state);
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
             }
         });
     }
diff --git a/telephony/java/android/telephony/mbms/InternalStreamingServiceCallback.java b/telephony/java/android/telephony/mbms/InternalStreamingServiceCallback.java
index eb6579ce..e9f39ff 100644
--- a/telephony/java/android/telephony/mbms/InternalStreamingServiceCallback.java
+++ b/telephony/java/android/telephony/mbms/InternalStreamingServiceCallback.java
@@ -16,18 +16,21 @@
 
 package android.telephony.mbms;
 
-import android.os.Handler;
+import android.os.Binder;
 import android.os.RemoteException;
 
+import java.util.concurrent.Executor;
+
 /** @hide */
 public class InternalStreamingServiceCallback extends IStreamingServiceCallback.Stub {
     private final StreamingServiceCallback mAppCallback;
-    private final Handler mHandler;
+    private final Executor mExecutor;
     private volatile boolean mIsStopped = false;
 
-    public InternalStreamingServiceCallback(StreamingServiceCallback appCallback, Handler handler) {
+    public InternalStreamingServiceCallback(StreamingServiceCallback appCallback,
+            Executor executor) {
         mAppCallback = appCallback;
-        mHandler = handler;
+        mExecutor = executor;
     }
 
     @Override
@@ -36,10 +39,15 @@
             return;
         }
 
-        mHandler.post(new Runnable() {
+        mExecutor.execute(new Runnable() {
             @Override
             public void run() {
-                mAppCallback.onError(errorCode, message);
+                long token = Binder.clearCallingIdentity();
+                try {
+                    mAppCallback.onError(errorCode, message);
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
             }
         });
     }
@@ -50,10 +58,15 @@
             return;
         }
 
-        mHandler.post(new Runnable() {
+        mExecutor.execute(new Runnable() {
             @Override
             public void run() {
-                mAppCallback.onStreamStateUpdated(state, reason);
+                long token = Binder.clearCallingIdentity();
+                try {
+                    mAppCallback.onStreamStateUpdated(state, reason);
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
             }
         });
     }
@@ -64,10 +77,15 @@
             return;
         }
 
-        mHandler.post(new Runnable() {
+        mExecutor.execute(new Runnable() {
             @Override
             public void run() {
-                mAppCallback.onMediaDescriptionUpdated();
+                long token = Binder.clearCallingIdentity();
+                try {
+                    mAppCallback.onMediaDescriptionUpdated();
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
             }
         });
     }
@@ -78,10 +96,15 @@
             return;
         }
 
-        mHandler.post(new Runnable() {
+        mExecutor.execute(new Runnable() {
             @Override
             public void run() {
-                mAppCallback.onBroadcastSignalStrengthUpdated(signalStrength);
+                long token = Binder.clearCallingIdentity();
+                try {
+                    mAppCallback.onBroadcastSignalStrengthUpdated(signalStrength);
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
             }
         });
     }
@@ -92,10 +115,15 @@
             return;
         }
 
-        mHandler.post(new Runnable() {
+        mExecutor.execute(new Runnable() {
             @Override
             public void run() {
-                mAppCallback.onStreamMethodUpdated(methodType);
+                long token = Binder.clearCallingIdentity();
+                try {
+                    mAppCallback.onStreamMethodUpdated(methodType);
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
             }
         });
     }
diff --git a/telephony/java/android/telephony/mbms/InternalStreamingSessionCallback.java b/telephony/java/android/telephony/mbms/InternalStreamingSessionCallback.java
index d782d12..d47f5ad 100644
--- a/telephony/java/android/telephony/mbms/InternalStreamingSessionCallback.java
+++ b/telephony/java/android/telephony/mbms/InternalStreamingSessionCallback.java
@@ -16,21 +16,22 @@
 
 package android.telephony.mbms;
 
-import android.os.Handler;
+import android.os.Binder;
 import android.os.RemoteException;
 
 import java.util.List;
+import java.util.concurrent.Executor;
 
 /** @hide */
 public class InternalStreamingSessionCallback extends IMbmsStreamingSessionCallback.Stub {
-    private final Handler mHandler;
+    private final Executor mExecutor;
     private final MbmsStreamingSessionCallback mAppCallback;
     private volatile boolean mIsStopped = false;
 
     public InternalStreamingSessionCallback(MbmsStreamingSessionCallback appCallback,
-            Handler handler) {
+            Executor executor) {
         mAppCallback = appCallback;
-        mHandler = handler;
+        mExecutor = executor;
     }
 
     @Override
@@ -39,10 +40,15 @@
             return;
         }
 
-        mHandler.post(new Runnable() {
+        mExecutor.execute(new Runnable() {
             @Override
             public void run() {
-                mAppCallback.onError(errorCode, message);
+                long token = Binder.clearCallingIdentity();
+                try {
+                    mAppCallback.onError(errorCode, message);
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
             }
         });
     }
@@ -54,10 +60,15 @@
             return;
         }
 
-        mHandler.post(new Runnable() {
+        mExecutor.execute(new Runnable() {
             @Override
             public void run() {
-                mAppCallback.onStreamingServicesUpdated(services);
+                long token = Binder.clearCallingIdentity();
+                try {
+                    mAppCallback.onStreamingServicesUpdated(services);
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
             }
         });
     }
@@ -68,18 +79,19 @@
             return;
         }
 
-        mHandler.post(new Runnable() {
+        mExecutor.execute(new Runnable() {
             @Override
             public void run() {
-                mAppCallback.onMiddlewareReady();
+                long token = Binder.clearCallingIdentity();
+                try {
+                    mAppCallback.onMiddlewareReady();
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
             }
         });
     }
 
-    public Handler getHandler() {
-        return mHandler;
-    }
-
     public void stop() {
         mIsStopped = true;
     }
diff --git a/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java b/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
index 9ef188c..b0c00c6 100644
--- a/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
+++ b/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
@@ -21,8 +21,10 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.net.Uri;
 import android.os.Bundle;
 import android.telephony.MbmsDownloadSession;
@@ -31,14 +33,11 @@
 
 import java.io.File;
 import java.io.FileFilter;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
 import java.nio.file.FileSystems;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
@@ -62,6 +61,8 @@
     /** @hide */
     public static final String MBMS_FILE_PROVIDER_META_DATA_KEY = "mbms-file-provider-authority";
 
+    private static final String EMBMS_INTENT_PERMISSION = "android.permission.SEND_EMBMS_INTENTS";
+
     /**
      * Indicates that the requested operation completed without error.
      * @hide
@@ -137,6 +138,8 @@
     /** @hide */
     @Override
     public void onReceive(Context context, Intent intent) {
+        verifyPermissionIntegrity(context);
+
         if (!verifyIntentContents(context, intent)) {
             setResultCode(RESULT_MALFORMED_INTENT);
             return;
@@ -260,20 +263,18 @@
 
         FileInfo completedFileInfo =
                 (FileInfo) intent.getParcelableExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO);
-        Path stagingDirectory = FileSystems.getDefault().getPath(
-                MbmsTempFileProvider.getEmbmsTempFileDir(context).getPath(),
-                TEMP_FILE_STAGING_LOCATION);
+        Path appSpecifiedDestination = FileSystems.getDefault().getPath(
+                request.getDestinationUri().getPath());
 
-        Uri stagedFileLocation;
+        Uri finalLocation;
         try {
-            stagedFileLocation = stageTempFile(finalTempFile, stagingDirectory);
+            finalLocation = moveToFinalLocation(finalTempFile, appSpecifiedDestination);
         } catch (IOException e) {
             Log.w(LOG_TAG, "Failed to move temp file to final destination");
             setResultCode(RESULT_DOWNLOAD_FINALIZATION_ERROR);
             return;
         }
-        intentForApp.putExtra(MbmsDownloadSession.EXTRA_MBMS_COMPLETED_FILE_URI,
-                stagedFileLocation);
+        intentForApp.putExtra(MbmsDownloadSession.EXTRA_MBMS_COMPLETED_FILE_URI, finalLocation);
         intentForApp.putExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO, completedFileInfo);
 
         context.sendBroadcast(intentForApp);
@@ -437,19 +438,22 @@
     }
 
     /*
-     * Moves a tempfile located at fromPath to a new location in the staging directory.
+     * Moves a tempfile located at fromPath to its final home where the app wants it
      */
-    private static Uri stageTempFile(Uri fromPath, Path stagingDirectory) throws IOException {
+    private static Uri moveToFinalLocation(Uri fromPath, Path appSpecifiedPath) throws IOException {
         if (!ContentResolver.SCHEME_FILE.equals(fromPath.getScheme())) {
-            Log.w(LOG_TAG, "Moving source uri " + fromPath+ " does not have a file scheme");
+            Log.w(LOG_TAG, "Downloaded file location uri " + fromPath +
+                    " does not have a file scheme");
             return null;
         }
 
         Path fromFile = FileSystems.getDefault().getPath(fromPath.getPath());
-        if (!Files.isDirectory(stagingDirectory)) {
-            Files.createDirectory(stagingDirectory);
+        if (!Files.isDirectory(appSpecifiedPath)) {
+            Files.createDirectory(appSpecifiedPath);
         }
-        Path result = Files.move(fromFile, stagingDirectory.resolve(fromFile.getFileName()));
+        // TODO: do we want to support directory trees within the download directory?
+        Path result = Files.move(fromFile, appSpecifiedPath.resolve(fromFile.getFileName()),
+                StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
 
         return Uri.fromFile(result.toFile());
     }
@@ -513,39 +517,29 @@
         return mMiddlewarePackageNameCache;
     }
 
-    private static boolean manualMove(File src, File dst) {
-        InputStream in = null;
-        OutputStream out = null;
-        try {
-            if (!dst.exists()) {
-                dst.createNewFile();
-            }
-            in = new FileInputStream(src);
-            out = new FileOutputStream(dst);
-            byte[] buffer = new byte[2048];
-            int len;
-            do {
-                len = in.read(buffer);
-                out.write(buffer, 0, len);
-            } while (len > 0);
-        } catch (IOException e) {
-            Log.w(LOG_TAG, "Manual file move failed due to exception "  + e);
-            if (dst.exists()) {
-                dst.delete();
-            }
-            return false;
-        } finally {
-            try {
-                if (in != null) {
-                    in.close();
-                }
-                if (out != null) {
-                    out.close();
-                }
-            } catch (IOException e) {
-                Log.w(LOG_TAG, "Error closing streams: " + e);
-            }
+    private void verifyPermissionIntegrity(Context context) {
+        PackageManager pm = context.getPackageManager();
+        Intent queryIntent = new Intent(context, MbmsDownloadReceiver.class);
+        List<ResolveInfo> infos = pm.queryBroadcastReceivers(queryIntent, 0);
+        if (infos.size() != 1) {
+            throw new IllegalStateException("Non-unique download receiver in your app");
         }
-        return true;
+        ActivityInfo selfInfo = infos.get(0).activityInfo;
+        if (selfInfo == null) {
+            throw new IllegalStateException("Queried ResolveInfo does not contain a receiver");
+        }
+        if (MbmsUtils.getOverrideServiceName(context,
+                MbmsDownloadSession.MBMS_DOWNLOAD_SERVICE_ACTION) != null) {
+            // If an override was specified, just make sure that the permission isn't null.
+            if (selfInfo.permission == null) {
+                throw new IllegalStateException(
+                        "MbmsDownloadReceiver must require some permission");
+            }
+            return;
+        }
+        if (!Objects.equals(EMBMS_INTENT_PERMISSION, selfInfo.permission)) {
+            throw new IllegalStateException("MbmsDownloadReceiver must require the " +
+                    "SEND_EMBMS_INTENTS permission.");
+        }
     }
 }
diff --git a/telephony/java/android/telephony/mbms/MbmsErrors.java b/telephony/java/android/telephony/mbms/MbmsErrors.java
index 75ca35e..b5fec44 100644
--- a/telephony/java/android/telephony/mbms/MbmsErrors.java
+++ b/telephony/java/android/telephony/mbms/MbmsErrors.java
@@ -108,8 +108,8 @@
 
         /**
          * Indicates that the app called
-         * {@link MbmsStreamingSession#startStreaming(
-         * StreamingServiceInfo, StreamingServiceCallback, android.os.Handler)}
+         * {@link MbmsStreamingSession#startStreaming(StreamingServiceInfo,
+         * java.util.concurrent.Executor, StreamingServiceCallback)}
          * more than once for the same {@link StreamingServiceInfo}.
          */
         public static final int ERROR_DUPLICATE_START_STREAM = 303;
diff --git a/telephony/java/android/telephony/mbms/MbmsStreamingSessionCallback.java b/telephony/java/android/telephony/mbms/MbmsStreamingSessionCallback.java
index 5c130a0..6e03957 100644
--- a/telephony/java/android/telephony/mbms/MbmsStreamingSessionCallback.java
+++ b/telephony/java/android/telephony/mbms/MbmsStreamingSessionCallback.java
@@ -22,11 +22,12 @@
 import android.telephony.MbmsStreamingSession;
 
 import java.util.List;
+import java.util.concurrent.Executor;
 
 /**
  * A callback class that is used to receive information from the middleware on MBMS streaming
  * services. An instance of this object should be passed into
- * {@link MbmsStreamingSession#create(Context, MbmsStreamingSessionCallback, int, Handler)}.
+ * {@link MbmsStreamingSession#create(Context, Executor, int, MbmsStreamingSessionCallback)}.
  */
 public class MbmsStreamingSessionCallback {
     /**
diff --git a/telephony/java/android/telephony/mbms/MbmsUtils.java b/telephony/java/android/telephony/mbms/MbmsUtils.java
index b4ad1d7..ef317ee 100644
--- a/telephony/java/android/telephony/mbms/MbmsUtils.java
+++ b/telephony/java/android/telephony/mbms/MbmsUtils.java
@@ -50,7 +50,7 @@
         return new ComponentName(ci.packageName, ci.name);
     }
 
-    private static ComponentName getOverrideServiceName(Context context, String serviceAction) {
+    public static ComponentName getOverrideServiceName(Context context, String serviceAction) {
         String metaDataKey = null;
         switch (serviceAction) {
             case MbmsDownloadSession.MBMS_DOWNLOAD_SERVICE_ACTION:
diff --git a/telephony/java/android/telephony/mbms/StreamingService.java b/telephony/java/android/telephony/mbms/StreamingService.java
index ec9134a..b6239fe 100644
--- a/telephony/java/android/telephony/mbms/StreamingService.java
+++ b/telephony/java/android/telephony/mbms/StreamingService.java
@@ -29,11 +29,11 @@
 
 /**
  * Class used to represent a single MBMS stream. After a stream has been started with
- * {@link MbmsStreamingSession#startStreaming(StreamingServiceInfo,
- * StreamingServiceCallback, android.os.Handler)},
+ * {@link MbmsStreamingSession#startStreaming(StreamingServiceInfo, java.util.concurrent.Executor,
+ * StreamingServiceCallback)},
  * this class is used to hold information about the stream and control it.
  */
-public class StreamingService {
+public class StreamingService implements AutoCloseable {
     private static final String LOG_TAG = "MbmsStreamingService";
 
     /**
@@ -41,7 +41,7 @@
      * @hide
      */
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef({STATE_STOPPED, STATE_STARTED, STATE_STALLED})
+    @IntDef(prefix = { "STATE_" }, value = {STATE_STOPPED, STATE_STARTED, STATE_STALLED})
     public @interface StreamingState {}
     public final static int STATE_STOPPED = 1;
     public final static int STATE_STARTED = 2;
@@ -53,7 +53,8 @@
      * @hide
      */
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef({REASON_BY_USER_REQUEST, REASON_END_OF_SESSION, REASON_FREQUENCY_CONFLICT,
+    @IntDef(prefix = { "REASON_" },
+            value = {REASON_BY_USER_REQUEST, REASON_END_OF_SESSION, REASON_FREQUENCY_CONFLICT,
             REASON_OUT_OF_MEMORY, REASON_NOT_CONNECTED_TO_HOMECARRIER_LTE,
             REASON_LEFT_MBMS_BROADCAST_AREA, REASON_NONE})
     public @interface StreamingStateChangeReason {}
@@ -64,9 +65,9 @@
     public static final int REASON_NONE = 0;
 
     /**
-     * State changed due to a call to {@link #stopStreaming()} or
+     * State changed due to a call to {@link #close()} or
      * {@link MbmsStreamingSession#startStreaming(StreamingServiceInfo,
-     * StreamingServiceCallback, android.os.Handler)}
+     * java.util.concurrent.Executor, StreamingServiceCallback)}
      */
     public static final int REASON_BY_USER_REQUEST = 1;
 
@@ -161,7 +162,8 @@
      *
      * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException}
      */
-    public void stopStreaming() {
+    @Override
+    public void close() {
         if (mService == null) {
             throw new IllegalStateException("No streaming service attached");
         }
diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
index 8e3f4c0..1cfe8c2 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -21,6 +21,7 @@
 import android.telephony.SignalStrength;
 import android.telephony.CellInfo;
 import android.telephony.DataConnectionRealTimeInfo;
+import android.telephony.PhysicalChannelConfig;
 import android.telephony.PreciseCallState;
 import android.telephony.PreciseDataConnectionState;
 import android.telephony.VoLteServiceState;
@@ -37,6 +38,7 @@
     void onDataConnectionStateChanged(int state, int networkType);
     void onDataActivity(int direction);
     void onSignalStrengthsChanged(in SignalStrength signalStrength);
+    void onPhysicalChannelConfigurationChanged(in List<PhysicalChannelConfig> configs);
     void onOtaspChanged(in int otaspMode);
     void onCellInfoChanged(in List<CellInfo> cellInfo);
     void onPreciseCallStateChanged(in PreciseCallState callState);
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index fe37531..a4eb424 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -187,6 +187,57 @@
             in PendingIntent deliveryIntent, in boolean persistMessage);
 
     /**
+     * Send an SMS with options using Subscription Id.
+     *
+     * @param subId the subId on which the SMS has to be sent.
+     * @param destAddr the address to send the message to
+     * @param scAddr the SMSC to send the message through, or NULL for the
+     *  default SMSC
+     * @param text the body of the message to send
+     * @param sentIntent if not NULL this <code>PendingIntent</code> is
+     *  broadcast when the message is sucessfully sent, or failed.
+     *  The result code will be <code>Activity.RESULT_OK<code> for success,
+     *  or one of these errors:<br>
+     *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
+     *  <code>RESULT_ERROR_RADIO_OFF</code><br>
+     *  <code>RESULT_ERROR_NULL_PDU</code><br>
+     *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
+     *  the extra "errorCode" containing a radio technology specific value,
+     *  generally only useful for troubleshooting.<br>
+     *  The per-application based SMS control checks sentIntent. If sentIntent
+     *  is NULL the caller will be checked against all unknown applications,
+     *  which cause smaller number of SMS to be sent in checking period.
+     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
+     *  broadcast when the message is delivered to the recipient.  The
+     *  raw pdu of the status report is in the extended data ("pdu").
+     * @param persistMessageForNonDefaultSmsApp whether the sent message should
+     *   be automatically persisted in the SMS db. It only affects messages sent
+     *   by a non-default SMS app. Currently only the carrier app can set this
+     *   parameter to false to skip auto message persistence.
+     * @param priority Priority level of the message
+     *  Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1
+     *  ---------------------------------
+     *  PRIORITY      | Level of Priority
+     *  ---------------------------------
+     *      '00'      |     Normal
+     *      '01'      |     Interactive
+     *      '10'      |     Urgent
+     *      '11'      |     Emergency
+     *  ----------------------------------
+     *  Any Other values included Negative considered as Invalid Priority Indicator of the message.
+     * @param expectMore is a boolean to indicate the sending message is multi segmented or not.
+     * @param validityPeriod Validity Period of the message in mins.
+     *  Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1.
+     *  Validity Period(Minimum) -> 5 mins
+     *  Validity Period(Maximum) -> 635040 mins(i.e.63 weeks).
+     *  Any Other values included Negative considered as Invalid Validity Period of the message.
+     */
+    void sendTextForSubscriberWithOptions(in int subId, String callingPkg, in String destAddr,
+            in String scAddr, in String text, in PendingIntent sentIntent,
+            in PendingIntent deliveryIntent, in boolean persistMessageForNonDefaultSmsApp,
+            in int priority, in boolean expectMore, in int validityPeriod);
+
+    /**
      * Inject an SMS PDU into the android platform.
      *
      * @param subId the subId on which the SMS has to be injected.
@@ -234,6 +285,56 @@
             in List<PendingIntent> deliveryIntents, in boolean persistMessageForNonDefaultSmsApp);
 
     /**
+     * Send a multi-part text based SMS with options using Subscription Id.
+     *
+     * @param subId the subId on which the SMS has to be sent.
+     * @param destinationAddress the address to send the message to
+     * @param scAddress is the service center address or null to use
+     *   the current default SMSC
+     * @param parts an <code>ArrayList</code> of strings that, in order,
+     *   comprise the original message
+     * @param sentIntents if not null, an <code>ArrayList</code> of
+     *   <code>PendingIntent</code>s (one for each message part) that is
+     *   broadcast when the corresponding message part has been sent.
+     *   The result code will be <code>Activity.RESULT_OK<code> for success,
+     *   or one of these errors:
+     *   <code>RESULT_ERROR_GENERIC_FAILURE</code>
+     *   <code>RESULT_ERROR_RADIO_OFF</code>
+     *   <code>RESULT_ERROR_NULL_PDU</code>.
+     * @param deliveryIntents if not null, an <code>ArrayList</code> of
+     *   <code>PendingIntent</code>s (one for each message part) that is
+     *   broadcast when the corresponding message part has been delivered
+     *   to the recipient.  The raw pdu of the status report is in the
+     *   extended data ("pdu").
+     * @param persistMessageForNonDefaultSmsApp whether the sent message should
+     *   be automatically persisted in the SMS db. It only affects messages sent
+     *   by a non-default SMS app. Currently only the carrier app can set this
+     *   parameter to false to skip auto message persistence.
+     * @param priority Priority level of the message
+     *  Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1
+     *  ---------------------------------
+     *  PRIORITY      | Level of Priority
+     *  ---------------------------------
+     *      '00'      |     Normal
+     *      '01'      |     Interactive
+     *      '10'      |     Urgent
+     *      '11'      |     Emergency
+     *  ----------------------------------
+     *  Any Other values included Negative considered as Invalid Priority Indicator of the message.
+     * @param expectMore is a boolean to indicate the sending message is multi segmented or not.
+     * @param validityPeriod Validity Period of the message in mins.
+     *  Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1.
+     *  Validity Period(Minimum) -> 5 mins
+     *  Validity Period(Maximum) -> 635040 mins(i.e.63 weeks).
+     *  Any Other values included Negative considered as Invalid Validity Period of the message.
+     */
+    void sendMultipartTextForSubscriberWithOptions(in int subId, String callingPkg,
+            in String destinationAddress, in String scAddress, in List<String> parts,
+            in List<PendingIntent> sentIntents, in List<PendingIntent> deliveryIntents,
+            in boolean persistMessageForNonDefaultSmsApp, in int priority, in boolean expectMore,
+            in int validityPeriod);
+
+    /**
      * Enable reception of cell broadcast (SMS-CB) messages with the given
      * message identifier and RAN type. The RAN type specify this message ID
      * belong to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different clients
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 02cc82c..a941a56 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -823,6 +823,12 @@
     IImsConfig getImsConfig(int slotId, int feature);
 
     /**
+    * Returns true if emergency calling is available for the MMTEL feature associated with the
+    * slot specified.
+    */
+    boolean isEmergencyMmTelAvailable(int slotId);
+
+    /**
      * Set the network selection mode to automatic.
      *
      * @param subId the id of the subscription to update.
@@ -952,6 +958,11 @@
     int getCarrierPrivilegeStatus(int subId);
 
     /**
+     * Similar to above, but check for the given uid.
+     */
+    int getCarrierPrivilegeStatusForUid(int subId, int uid);
+
+    /**
      * Similar to above, but check for the package whose name is pkgName.
      */
     int checkCarrierPrivilegesForPackage(String pkgName);
@@ -1468,4 +1479,12 @@
      * @return boolean Return true if the switch succeeds, false if the switch fails.
      */
     boolean switchSlots(in int[] physicalSlots);
+
+    /**
+     * Sets radio indication update mode. This can be used to control the behavior of indication
+     * update from modem to Android frameworks. For example, by default several indication updates
+     * are turned off when screen is off, but in some special cases (e.g. carkit is connected but
+     * screen is off) we want to turn on those indications even when the screen is off.
+     */
+    void setRadioIndicationUpdateMode(int subId, int filters, int mode);
 }
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 188167c..06dc13e 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -21,9 +21,9 @@
 import android.net.NetworkCapabilities;
 import android.os.Bundle;
 import android.telephony.CellInfo;
+import android.telephony.PhysicalChannelConfig;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
-import android.telephony.CellInfo;
 import android.telephony.VoLteServiceState;
 import com.android.internal.telephony.IPhoneStateListener;
 import com.android.internal.telephony.IOnSubscriptionsChangedListener;
@@ -58,6 +58,9 @@
     void notifyCellLocationForSubscriber(in int subId, in Bundle cellLocation);
     void notifyOtaspChanged(in int otaspMode);
     void notifyCellInfo(in List<CellInfo> cellInfo);
+    void notifyPhysicalChannelConfiguration(in List<PhysicalChannelConfig> configs);
+    void notifyPhysicalChannelConfigurationForSubscriber(in int subId,
+            in List<PhysicalChannelConfig> configs);
     void notifyPreciseCallState(int ringingCallState, int foregroundCallState,
             int backgroundCallState);
     void notifyDisconnectCause(int disconnectCause, int preciseDisconnectCause);
diff --git a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
new file mode 100644
index 0000000..da8471f
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.telephony;
+
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.telephony.Rlog;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.ITelephony;
+
+/** Utility class for Telephony permission enforcement. */
+public final class TelephonyPermissions {
+    private static final String LOG_TAG = "TelephonyPermissions";
+
+    private static final boolean DBG = false;
+
+    private TelephonyPermissions() {}
+
+    /**
+     * Check whether the caller (or self, if not processing an IPC) can read phone state.
+     *
+     * <p>This method behaves in one of the following ways:
+     * <ul>
+     *   <li>return true: if the caller has either the READ_PRIVILEGED_PHONE_STATE permission or the
+     *       READ_PHONE_STATE runtime permission.
+     *   <li>throw SecurityException: if the caller didn't declare any of these permissions, or, for
+     *       apps which support runtime permissions, if the caller does not currently have any of
+     *       these permissions.
+     *   <li>return false: if the caller lacks all of these permissions and doesn't support runtime
+     *       permissions. This implies that the user revoked the ability to read phone state
+     *       manually (via AppOps). In this case we can't throw as it would break app compatibility,
+     *       so we return false to indicate that the calling function should return dummy data.
+     * </ul>
+     */
+    public static boolean checkCallingOrSelfReadPhoneState(
+            Context context, String callingPackage, String message) {
+        return checkReadPhoneState(context, Binder.getCallingPid(), Binder.getCallingUid(),
+                callingPackage, message);
+    }
+
+    /**
+     * Check whether the app with the given pid/uid can read phone state.
+     *
+     * <p>This method behaves in one of the following ways:
+     * <ul>
+     *   <li>return true: if the caller has either the READ_PRIVILEGED_PHONE_STATE permission or the
+     *       READ_PHONE_STATE runtime permission.
+     *   <li>throw SecurityException: if the caller didn't declare any of these permissions, or, for
+     *       apps which support runtime permissions, if the caller does not currently have any of
+     *       these permissions.
+     *   <li>return false: if the caller lacks all of these permissions and doesn't support runtime
+     *       permissions. This implies that the user revoked the ability to read phone state
+     *       manually (via AppOps). In this case we can't throw as it would break app compatibility,
+     *       so we return false to indicate that the calling function should return dummy data.
+     * </ul>
+     */
+    public static boolean checkReadPhoneState(
+            Context context, int pid, int uid, String callingPackage, String message) {
+        try {
+            context.enforcePermission(
+                    android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, pid, uid, message);
+
+            // SKIP checking for run-time permission since caller has PRIVILEGED permission
+            return true;
+        } catch (SecurityException privilegedPhoneStateException) {
+            context.enforcePermission(
+                    android.Manifest.permission.READ_PHONE_STATE, pid, uid, message);
+        }
+
+        // We have READ_PHONE_STATE permission, so return true as long as the AppOps bit hasn't been
+        // revoked.
+        AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+        return appOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, uid, callingPackage) ==
+                AppOpsManager.MODE_ALLOWED;
+    }
+
+    /**
+     * Returns whether the caller can read phone numbers.
+     *
+     * <p>Besides apps with the ability to read phone state per {@link #checkReadPhoneState}, the
+     * default SMS app and apps with READ_SMS or READ_PHONE_NUMBERS can also read phone numbers.
+     */
+    public static boolean checkCallingOrSelfReadPhoneNumber(
+            Context context, String callingPackage, String message) {
+        return checkReadPhoneNumber(
+                context, Binder.getCallingPid(), Binder.getCallingUid(), callingPackage, message);
+    }
+
+    @VisibleForTesting
+    public static boolean checkReadPhoneNumber(
+            Context context, int pid, int uid, String callingPackage, String message) {
+        // Default SMS app can always read it.
+        AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+        if (appOps.noteOp(AppOpsManager.OP_WRITE_SMS, uid, callingPackage) ==
+                AppOpsManager.MODE_ALLOWED) {
+            return true;
+        }
+
+        // NOTE(b/73308711): If an app has one of the following AppOps bits explicitly revoked, they
+        // will be denied access, even if they have another permission and AppOps bit if needed.
+
+        // First, check if we can read the phone state.
+        try {
+            return checkReadPhoneState(context, pid, uid, callingPackage, message);
+        } catch (SecurityException readPhoneStateSecurityException) {
+        }
+        // Can be read with READ_SMS too.
+        try {
+            context.enforcePermission(android.Manifest.permission.READ_SMS, pid, uid, message);
+            int opCode = AppOpsManager.permissionToOpCode(android.Manifest.permission.READ_SMS);
+            if (opCode != AppOpsManager.OP_NONE) {
+                return appOps.noteOp(opCode, uid, callingPackage) == AppOpsManager.MODE_ALLOWED;
+            } else {
+                return true;
+            }
+        } catch (SecurityException readSmsSecurityException) {
+        }
+        // Can be read with READ_PHONE_NUMBERS too.
+        try {
+            context.enforcePermission(android.Manifest.permission.READ_PHONE_NUMBERS, pid, uid,
+                    message);
+            int opCode = AppOpsManager.permissionToOpCode(
+                    android.Manifest.permission.READ_PHONE_NUMBERS);
+            if (opCode != AppOpsManager.OP_NONE) {
+                return appOps.noteOp(opCode, uid, callingPackage) == AppOpsManager.MODE_ALLOWED;
+            } else {
+                return true;
+            }
+        } catch (SecurityException readPhoneNumberSecurityException) {
+        }
+
+        throw new SecurityException(message + ": Neither user " + uid +
+                " nor current process has " + android.Manifest.permission.READ_PHONE_STATE +
+                ", " + android.Manifest.permission.READ_SMS + ", or " +
+                android.Manifest.permission.READ_PHONE_NUMBERS);
+    }
+
+    /**
+     * Ensure the caller (or self, if not processing an IPC) has MODIFY_PHONE_STATE (and is thus a
+     * privileged app) or carrier privileges.
+     *
+     * @throws SecurityException if the caller does not have the required permission/privileges
+     */
+    public static void enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+            Context context, int subId, String message) {
+        if (context.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE) ==
+                PackageManager.PERMISSION_GRANTED) {
+            return;
+        }
+
+        if (DBG) Rlog.d(LOG_TAG, "No modify permission, check carrier privilege next.");
+        enforceCallingOrSelfCarrierPrivilege(subId, message);
+    }
+
+    /**
+     * Make sure the caller (or self, if not processing an IPC) has carrier privileges.
+     *
+     * @throws SecurityException if the caller does not have the required privileges
+     */
+    public static void enforceCallingOrSelfCarrierPrivilege(int subId, String message) {
+        // NOTE: It's critical that we explicitly pass the calling UID here rather than call
+        // TelephonyManager#hasCarrierPrivileges directly, as the latter only works when called from
+        // the phone process. When called from another process, it will check whether that process
+        // has carrier privileges instead.
+        enforceCarrierPrivilege(subId, Binder.getCallingUid(), message);
+    }
+
+    private static void enforceCarrierPrivilege(int subId, int uid, String message) {
+        if (getCarrierPrivilegeStatus(subId, uid) !=
+                TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+            if (DBG) Rlog.e(LOG_TAG, "No Carrier Privilege.");
+            throw new SecurityException(message);
+        }
+    }
+
+    private static int getCarrierPrivilegeStatus(int subId, int uid) {
+        ITelephony telephony =
+                ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));
+        try {
+            if (telephony != null) {
+                return telephony.getCarrierPrivilegeStatusForUid(subId, uid);
+            }
+        } catch (RemoteException e) {
+            // Fallback below.
+        }
+        Rlog.e(LOG_TAG, "Phone process is down, cannot check carrier privileges");
+        return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
+    }
+}
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index 7a53ef6..14c5f4b 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -99,6 +99,15 @@
     private static final int RETURN_NO_ACK  = 0;
     private static final int RETURN_ACK     = 1;
 
+    /**
+     * Supported priority modes for CDMA SMS messages
+     * (See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1)
+     */
+    private static final int PRIORITY_NORMAL        = 0x0;
+    private static final int PRIORITY_INTERACTIVE   = 0x1;
+    private static final int PRIORITY_URGENT        = 0x2;
+    private static final int PRIORITY_EMERGENCY     = 0x3;
+
     private SmsEnvelope mEnvelope;
     private BearerData mBearerData;
 
@@ -211,6 +220,26 @@
      */
     public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, String message,
             boolean statusReportRequested, SmsHeader smsHeader) {
+        return getSubmitPdu(scAddr, destAddr, message, statusReportRequested, smsHeader, -1);
+    }
+
+    /**
+     * Get an SMS-SUBMIT PDU for a destination address and a message
+     *
+     * @param scAddr                Service Centre address.  Null means use default.
+     * @param destAddr              Address of the recipient.
+     * @param message               String representation of the message payload.
+     * @param statusReportRequested Indicates whether a report is requested for this message.
+     * @param smsHeader             Array containing the data for the User Data Header, preceded
+     *                              by the Element Identifiers.
+     * @param priority              Priority level of the message
+     * @return a <code>SubmitPdu</code> containing the encoded SC
+     *         address, if applicable, and the encoded message.
+     *         Returns null on encode error.
+     * @hide
+     */
+    public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, String message,
+            boolean statusReportRequested, SmsHeader smsHeader, int priority) {
 
         /**
          * TODO(cleanup): Do we really want silent failure like this?
@@ -224,7 +253,7 @@
         UserData uData = new UserData();
         uData.payloadStr = message;
         uData.userDataHeader = smsHeader;
-        return privateGetSubmitPdu(destAddr, statusReportRequested, uData);
+        return privateGetSubmitPdu(destAddr, statusReportRequested, uData, priority);
     }
 
     /**
@@ -282,6 +311,22 @@
     }
 
     /**
+     * Get an SMS-SUBMIT PDU for a data message to a destination address &amp; port
+     *
+     * @param destAddr the address of the destination for the message
+     * @param userData the data for the message
+     * @param statusReportRequested Indicates whether a report is requested for this message.
+     * @param priority Priority level of the message
+     * @return a <code>SubmitPdu</code> containing the encoded SC
+     *         address, if applicable, and the encoded message.
+     *         Returns null on encode error.
+     */
+    public static SubmitPdu getSubmitPdu(String destAddr, UserData userData,
+            boolean statusReportRequested, int priority) {
+        return privateGetSubmitPdu(destAddr, statusReportRequested, userData, priority);
+    }
+
+    /**
      * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
      */
     @Override
@@ -764,6 +809,15 @@
      */
     private static SubmitPdu privateGetSubmitPdu(String destAddrStr, boolean statusReportRequested,
             UserData userData) {
+        return privateGetSubmitPdu(destAddrStr, statusReportRequested, userData, -1);
+    }
+
+    /**
+     * Creates BearerData and Envelope from parameters for a Submit SMS.
+     * @return byte stream for SubmitPdu.
+     */
+    private static SubmitPdu privateGetSubmitPdu(String destAddrStr, boolean statusReportRequested,
+            UserData userData, int priority) {
 
         /**
          * TODO(cleanup): give this function a more meaningful name.
@@ -792,6 +846,10 @@
         bearerData.userAckReq = false;
         bearerData.readAckReq = false;
         bearerData.reportReq = false;
+        if (priority >= PRIORITY_NORMAL && priority <= PRIORITY_EMERGENCY) {
+            bearerData.priorityIndicatorSet = true;
+            bearerData.priority = priority;
+        }
 
         bearerData.userData = userData;
 
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index 1ca19e0..4f5bfa9 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -89,6 +89,18 @@
 
     private int mVoiceMailCount = 0;
 
+    private static final int VALIDITY_PERIOD_FORMAT_NONE = 0x00;
+    private static final int VALIDITY_PERIOD_FORMAT_ENHANCED = 0x01;
+    private static final int VALIDITY_PERIOD_FORMAT_RELATIVE = 0x02;
+    private static final int VALIDITY_PERIOD_FORMAT_ABSOLUTE = 0x03;
+
+    //Validity Period min - 5 mins
+    private static final int VALIDITY_PERIOD_MIN = 5;
+    //Validity Period max - 63 weeks
+    private static final int VALIDITY_PERIOD_MAX = 635040;
+
+    private static final int INVALID_VALIDITY_PERIOD = -1;
+
     public static class SubmitPdu extends SubmitPduBase {
     }
 
@@ -202,6 +214,45 @@
     }
 
     /**
+     * Get Encoded Relative Validty Period Value from Validity period in mins.
+     *
+     * @param validityPeriod Validity period in mins.
+     *
+     * Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1.
+     * ||relValidityPeriod (TP-VP)  ||                 ||  validityPeriod   ||
+     *
+     *      0 to 143                            --->       (TP-VP + 1) x 5 minutes
+     *
+     *      144 to 167                         --->        12 hours + ((TP-VP -143) x 30 minutes)
+     *
+     *      168 to 196                         --->        (TP-VP - 166) x 1 day
+     *
+     *      197 to 255                         --->        (TP-VP - 192) x 1 week
+     *
+     * @return relValidityPeriod Encoded Relative Validity Period Value.
+     * @hide
+     */
+    public static int getRelativeValidityPeriod(int validityPeriod) {
+        int relValidityPeriod = INVALID_VALIDITY_PERIOD;
+
+        if (validityPeriod < VALIDITY_PERIOD_MIN  || validityPeriod > VALIDITY_PERIOD_MAX) {
+            Rlog.e(LOG_TAG,"Invalid Validity Period" + validityPeriod);
+            return relValidityPeriod;
+        }
+
+        if (validityPeriod <= 720) {
+            relValidityPeriod = (validityPeriod  / 5) - 1;
+        } else if (validityPeriod <= 1440) {
+            relValidityPeriod = ((validityPeriod - 720) / 30) + 143;
+        } else if (validityPeriod <= 43200) {
+            relValidityPeriod = (validityPeriod  / 1440) + 166;
+        } else if (validityPeriod <= 635040) {
+            relValidityPeriod = (validityPeriod  / 10080) + 192;
+        }
+        return relValidityPeriod;
+    }
+
+    /**
      * Get an SMS-SUBMIT PDU for a destination address and a message
      *
      * @param scAddress Service Centre address.  Null means use default.
@@ -236,6 +287,29 @@
             String destinationAddress, String message,
             boolean statusReportRequested, byte[] header, int encoding,
             int languageTable, int languageShiftTable) {
+        return getSubmitPdu(scAddress, destinationAddress, message, statusReportRequested,
+            header, encoding, languageTable, languageShiftTable, -1);
+    }
+
+    /**
+     * Get an SMS-SUBMIT PDU for a destination address and a message using the
+     * specified encoding.
+     *
+     * @param scAddress Service Centre address.  Null means use default.
+     * @param encoding Encoding defined by constants in
+     *        com.android.internal.telephony.SmsConstants.ENCODING_*
+     * @param languageTable
+     * @param languageShiftTable
+     * @param validityPeriod Validity Period of the message in Minutes.
+     * @return a <code>SubmitPdu</code> containing the encoded SC
+     *         address, if applicable, and the encoded message.
+     *         Returns null on encode error.
+     * @hide
+     */
+    public static SubmitPdu getSubmitPdu(String scAddress,
+            String destinationAddress, String message,
+            boolean statusReportRequested, byte[] header, int encoding,
+            int languageTable, int languageShiftTable, int validityPeriod) {
 
         // Perform null parameter checks.
         if (message == null || destinationAddress == null) {
@@ -272,8 +346,19 @@
         }
 
         SubmitPdu ret = new SubmitPdu();
-        // MTI = SMS-SUBMIT, UDHI = header != null
-        byte mtiByte = (byte)(0x01 | (header != null ? 0x40 : 0x00));
+
+        int validityPeriodFormat = VALIDITY_PERIOD_FORMAT_NONE;
+        int relativeValidityPeriod = INVALID_VALIDITY_PERIOD;
+
+        // TP-Validity-Period-Format (TP-VPF) in 3GPP TS 23.040 V6.8.1 section 9.2.3.3
+        //bit 4:3 = 10 - TP-VP field present - relative format
+        if((relativeValidityPeriod = getRelativeValidityPeriod(validityPeriod)) >= 0) {
+            validityPeriodFormat = VALIDITY_PERIOD_FORMAT_RELATIVE;
+        }
+
+        byte mtiByte = (byte)(0x01 | (validityPeriodFormat << 0x03) |
+                (header != null ? 0x40 : 0x00));
+
         ByteArrayOutputStream bo = getSubmitPduHead(
                 scAddress, destinationAddress, mtiByte,
                 statusReportRequested, ret);
@@ -338,7 +423,11 @@
             bo.write(0x08);
         }
 
-        // (no TP-Validity-Period)
+        if (validityPeriodFormat == VALIDITY_PERIOD_FORMAT_RELATIVE) {
+            // ( TP-Validity-Period - relative format)
+            bo.write(relativeValidityPeriod);
+        }
+
         bo.write(userData, 0, userData.length);
         ret.encodedMessage = bo.toByteArray();
         return ret;
@@ -388,6 +477,24 @@
     }
 
     /**
+     * Get an SMS-SUBMIT PDU for a destination address and a message
+     *
+     * @param scAddress Service Centre address.  Null means use default.
+     * @param destinationAddress the address of the destination for the message
+     * @param statusReportRequested staus report of the message Requested
+     * @param validityPeriod Validity Period of the message in Minutes.
+     * @return a <code>SubmitPdu</code> containing the encoded SC
+     *         address, if applicable, and the encoded message.
+     *         Returns null on encode error.
+     */
+    public static SubmitPdu getSubmitPdu(String scAddress,
+            String destinationAddress, String message,
+            boolean statusReportRequested, int validityPeriod) {
+        return getSubmitPdu(scAddress, destinationAddress, message, statusReportRequested,
+                null, ENCODING_UNKNOWN, 0, 0, validityPeriod);
+    }
+
+    /**
      * Get an SMS-SUBMIT PDU for a data message to a destination address &amp; port
      *
      * @param scAddress Service Centre address. null == use default
diff --git a/test-mock/Android.bp b/test-mock/Android.bp
index 54e07a16..bb07363 100644
--- a/test-mock/Android.bp
+++ b/test-mock/Android.bp
@@ -19,7 +19,6 @@
 java_library {
     name: "android.test.mock",
 
-    // Needs to be consistent with the repackaged version of this make target.
     java_version: "1.8",
     srcs: ["src/**/*.java"],
 
@@ -28,15 +27,3 @@
         "framework",
     ],
 }
-
-// Build the repackaged.android.test.mock library
-// ==============================================
-java_library_static {
-    name: "repackaged.android.test.mock",
-
-    static_libs: ["android.test.mock"],
-
-    jarjar_rules: "jarjar-rules.txt",
-    // Pin java_version until jarjar is certified to support later versions. http://b/72703434
-    java_version: "1.8",
-}
diff --git a/test-mock/src/android/test/mock/MockPackageManager.java b/test-mock/src/android/test/mock/MockPackageManager.java
index 1ddc52c..1af7c3a 100644
--- a/test-mock/src/android/test/mock/MockPackageManager.java
+++ b/test-mock/src/android/test/mock/MockPackageManager.java
@@ -1209,4 +1209,11 @@
         throw new UnsupportedOperationException();
     }
 
+    /**
+     * @hide
+     */
+    @Override
+    public String getSystemTextClassifierPackageName() {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/test-runner/Android.bp b/test-runner/Android.bp
index a2edb04..1cce2c3 100644
--- a/test-runner/Android.bp
+++ b/test-runner/Android.bp
@@ -24,12 +24,11 @@
     srcs: ["src/**/*.java"],
 
     errorprone: {
-      javacflags: ["-Xep:DepAnn:ERROR"],
+        javacflags: ["-Xep:DepAnn:ERROR"],
     },
 
-    no_framework_libs: true,
+    sdk_version: "current",
     libs: [
-        "framework",
         "android.test.base",
         "android.test.mock",
     ],
@@ -44,9 +43,8 @@
 
     srcs: ["src/android/**/*.java"],
 
-    no_framework_libs: true,
+    sdk_version: "current",
     libs: [
-        "framework",
         "android.test.base",
         "android.test.mock",
         "junit",
@@ -58,7 +56,21 @@
 java_library_static {
     name: "repackaged.android.test.runner",
 
-    static_libs: ["android.test.runner"],
+    srcs: ["src/**/*.java"],
+    exclude_srcs: [
+        "src/android/test/ActivityUnitTestCase.java",
+        "src/android/test/ApplicationTestCase.java",
+        "src/android/test/IsolatedContext.java",
+        "src/android/test/ProviderTestCase.java",
+        "src/android/test/ProviderTestCase2.java",
+        "src/android/test/RenamingDelegatingContext.java",
+        "src/android/test/ServiceTestCase.java",
+    ],
+
+    sdk_version: "current",
+    libs: [
+        "android.test.base",
+    ],
 
     jarjar_rules: "jarjar-rules.txt",
     // Pin java_version until jarjar is certified to support later versions. http://b/72703434
diff --git a/test-runner/tests/Android.mk b/test-runner/tests/Android.mk
index 1a4f6d5..f97d1c9 100644
--- a/test-runner/tests/Android.mk
+++ b/test-runner/tests/Android.mk
@@ -32,6 +32,8 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := FrameworkTestRunnerTests
+# Because of android.test.mock.
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 include $(BUILD_PACKAGE)
 
diff --git a/tests/AccessibilityEventsLogger/Android.mk b/tests/AccessibilityEventsLogger/Android.mk
index 52bc579..4224017 100644
--- a/tests/AccessibilityEventsLogger/Android.mk
+++ b/tests/AccessibilityEventsLogger/Android.mk
@@ -6,6 +6,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := AccessibilityEventsLogger
+LOCAL_SDK_VERSION := current
 LOCAL_CERTIFICATE := platform
 
 LOCAL_PROGUARD_ENABLED := disabled
diff --git a/tests/ActivityManagerPerfTests/README.txt b/tests/ActivityManagerPerfTests/README.txt
index 1040ed1..1560262 100644
--- a/tests/ActivityManagerPerfTests/README.txt
+++ b/tests/ActivityManagerPerfTests/README.txt
@@ -5,13 +5,7 @@
 * Self-contained perf tests should go in frameworks/base/apct-tests/perftests
 
 Command to run tests
-* atest .../frameworks/base/tests/ActivityManagerPerfTests/tests/
-  * Command currently not working: b/71859981
-* m ActivityManagerPerfTests ActivityManagerPerfTestsTestApp && \
-  adb install "$OUT"/data/app/ActivityManagerPerfTests/ActivityManagerPerfTests.apk && \
-  adb install "$OUT"/data/app/ActivityManagerPerfTestsTestApp/ActivityManagerPerfTestsTestApp.apk && \
-  adb shell am instrument -w \
-  com.android.frameworks.perftests.amtests/android.support.test.runner.AndroidJUnitRunner
+* atest -v ActivityManagerPerfTests
 
 Overview
 * The numbers we are trying to measure are end-to-end numbers
@@ -55,5 +49,7 @@
       can be reported in an iteration
   * If the target package should be running before your test logic starts, add startTargetPackage();
     at the beginning of the iteration
+
 * Reporting
-  * Look at go/am-perf for how to add new tests to dashboards and receive notification on regression
+  * Look at internal documentation for how to add new tests to dashboards and receive notification
+    on regressions
diff --git a/tests/ActivityManagerPerfTests/test-app/Android.mk b/tests/ActivityManagerPerfTests/test-app/Android.mk
index 767e899..33d15d2 100644
--- a/tests/ActivityManagerPerfTests/test-app/Android.mk
+++ b/tests/ActivityManagerPerfTests/test-app/Android.mk
@@ -26,5 +26,6 @@
 LOCAL_MIN_SDK_VERSION := 25
 
 LOCAL_PACKAGE_NAME := ActivityManagerPerfTestsTestApp
+LOCAL_SDK_VERSION := current
 
 include $(BUILD_PACKAGE)
diff --git a/tests/ActivityManagerPerfTests/test-app/AndroidManifest.xml b/tests/ActivityManagerPerfTests/test-app/AndroidManifest.xml
index 23a151c..32905a9 100644
--- a/tests/ActivityManagerPerfTests/test-app/AndroidManifest.xml
+++ b/tests/ActivityManagerPerfTests/test-app/AndroidManifest.xml
@@ -19,7 +19,6 @@
             android:minSdkVersion="21"
             android:targetSdkVersion="27" />
     <application android:name=".TestApplication">
-        <activity android:name=".TestActivity" android:exported="true"/>
         <provider
                 android:authorities="com.android.frameworks.perftests.amteststestapp"
                 android:name=".TestContentProvider"
@@ -33,6 +32,9 @@
             </intent-filter>
         </receiver>
         <service
+                android:name=".StartProcessService"
+                android:exported="true" />
+        <service
                 android:name=".TestService"
                 android:exported="true" />
     </application>
diff --git a/tests/ActivityManagerPerfTests/test-app/src/com/android/frameworks/perftests/amteststestapp/TestActivity.java b/tests/ActivityManagerPerfTests/test-app/src/com/android/frameworks/perftests/amteststestapp/StartProcessService.java
similarity index 60%
rename from tests/ActivityManagerPerfTests/test-app/src/com/android/frameworks/perftests/amteststestapp/TestActivity.java
rename to tests/ActivityManagerPerfTests/test-app/src/com/android/frameworks/perftests/amteststestapp/StartProcessService.java
index 4e7bb4c..054097e 100644
--- a/tests/ActivityManagerPerfTests/test-app/src/com/android/frameworks/perftests/amteststestapp/TestActivity.java
+++ b/tests/ActivityManagerPerfTests/test-app/src/com/android/frameworks/perftests/amteststestapp/StartProcessService.java
@@ -16,19 +16,26 @@
 
 package com.android.frameworks.perftests.amteststestapp;
 
-import android.app.Activity;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
 import android.os.Looper;
+import android.util.Log;
 
-import com.android.frameworks.perftests.am.util.Constants;
 import com.android.frameworks.perftests.am.util.Utils;
 
-public class TestActivity extends Activity {
+/**
+ * Service used to start up the target package and make sure it's running.
+ * Should be bound to, then wait for it to call the ILooperIdleCallback.
+ */
+public class StartProcessService extends Service {
     @Override
-    protected void onResume() {
-        super.onResume();
-        Looper.myQueue().addIdleHandler(() -> {
-            Utils.sendTime(getIntent(), Constants.TYPE_TARGET_PACKAGE_START);
+    public IBinder onBind(Intent intent) {
+        Looper.getMainLooper().getQueue().addIdleHandler(() -> {
+            Utils.sendLooperIdle(intent);
             return false;
         });
+        return new Binder();
     }
 }
diff --git a/tests/ActivityManagerPerfTests/tests/Android.mk b/tests/ActivityManagerPerfTests/tests/Android.mk
index 7597e69..f23a665 100644
--- a/tests/ActivityManagerPerfTests/tests/Android.mk
+++ b/tests/ActivityManagerPerfTests/tests/Android.mk
@@ -26,6 +26,7 @@
     ActivityManagerPerfTestsUtils
 
 LOCAL_PACKAGE_NAME := ActivityManagerPerfTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_MIN_SDK_VERSION := 25
 
diff --git a/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/BasePerfTest.java b/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/BasePerfTest.java
index cf175e0..58fb136 100644
--- a/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/BasePerfTest.java
+++ b/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/BasePerfTest.java
@@ -16,11 +16,9 @@
 
 package com.android.frameworks.perftests.am.tests;
 
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.os.IBinder;
 import android.perftests.utils.ManualBenchmarkState;
 import android.perftests.utils.PerfManualStatusReporter;
 import android.support.test.InstrumentationRegistry;
@@ -28,20 +26,16 @@
 import com.android.frameworks.perftests.am.util.TargetPackageUtils;
 import com.android.frameworks.perftests.am.util.TimeReceiver;
 
-import org.junit.After;
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
 
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
 import java.util.function.LongSupplier;
 
 public class BasePerfTest {
     private static final String TAG = BasePerfTest.class.getSimpleName();
-    private static final long AWAIT_SERVICE_CONNECT_MS = 2000;
 
     private TimeReceiver mTimeReceiver;
+    private ServiceConnection mAliveServiceConnection;
 
     @Rule
     public PerfManualStatusReporter mPerfManualStatusReporter = new PerfManualStatusReporter();
@@ -54,11 +48,6 @@
         mTimeReceiver = new TimeReceiver();
     }
 
-    @After
-    public void tearDown() {
-        TargetPackageUtils.killTargetPackage(mContext);
-    }
-
     protected void addReceivedTimeNs(String type) {
         mTimeReceiver.addTimeForTypeToQueue(type, System.nanoTime());
     }
@@ -71,46 +60,6 @@
         return intent;
     }
 
-    protected ServiceConnection bindAndWaitForConnectedService() {
-        return bindAndWaitForConnectedService(0);
-    }
-
-    protected ServiceConnection bindAndWaitForConnectedService(int flags) {
-        CountDownLatch countDownLatch = new CountDownLatch(1);
-        final ServiceConnection serviceConnection = new ServiceConnection() {
-            @Override
-            public void onServiceConnected(ComponentName name, IBinder service) {
-                countDownLatch.countDown();
-            }
-
-            @Override
-            public void onServiceDisconnected(ComponentName name) {
-            }
-        };
-
-        final Intent intent = createServiceIntent();
-        final boolean success = mContext.bindService(intent, serviceConnection,
-                Context.BIND_AUTO_CREATE | flags);
-        Assert.assertTrue("Could not bind to service", success);
-
-        try {
-            boolean connectedSuccess = countDownLatch.await(AWAIT_SERVICE_CONNECT_MS,
-                    TimeUnit.MILLISECONDS);
-            Assert.assertTrue("Timeout when waiting for ServiceConnection.onServiceConnected()",
-                    connectedSuccess);
-        } catch (InterruptedException e) {
-            throw new RuntimeException(e);
-        }
-
-        return serviceConnection;
-    }
-
-    protected void unbindFromService(ServiceConnection serviceConnection) {
-        if (serviceConnection != null) {
-            mContext.unbindService(serviceConnection);
-        }
-    }
-
     protected Intent createBroadcastIntent(String action) {
         final Intent intent = new Intent(action);
         intent.addFlags(
@@ -125,11 +74,14 @@
 
     private void setUpIteration() {
         mTimeReceiver.clear();
-        TargetPackageUtils.killTargetPackage(mContext);
+    }
+
+    private void tearDownIteration() {
+        TargetPackageUtils.killTargetPackage(mContext, mAliveServiceConnection);
     }
 
     protected void startTargetPackage() {
-        TargetPackageUtils.startTargetPackage(mContext, mTimeReceiver);
+        mAliveServiceConnection = TargetPackageUtils.startTargetPackage(mContext);
     }
 
     protected long getReceivedTimeNs(String type) {
@@ -142,6 +94,7 @@
         while (benchmarkState.keepRunning(elapsedTimeNs)) {
             setUpIteration();
             elapsedTimeNs = func.getAsLong();
+            tearDownIteration();
         }
     }
 }
diff --git a/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/ServiceBindPerfTest.java b/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/ServiceBindPerfTest.java
index 6d2935a..e1263db 100644
--- a/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/ServiceBindPerfTest.java
+++ b/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/ServiceBindPerfTest.java
@@ -25,6 +25,7 @@
 import android.support.test.runner.AndroidJUnit4;
 
 import com.android.frameworks.perftests.am.util.Constants;
+import com.android.frameworks.perftests.am.util.TargetPackageUtils;
 
 import org.junit.Assert;
 import org.junit.Test;
@@ -75,7 +76,7 @@
                 final long endTimeNs = getReceivedTimeNs(Constants.TYPE_SERVICE_CONNECTED);
                 return endTimeNs - startTimeNs;
             } finally {
-                unbindFromService(serviceConnection);
+                TargetPackageUtils.unbindFromService(mContext, serviceConnection);
             }
         });
     }
@@ -97,7 +98,7 @@
                 final long endTimeNs = getReceivedTimeNs(Constants.TYPE_SERVICE_CONNECTED);
                 return endTimeNs - startTimeNs;
             } finally {
-                unbindFromService(serviceConnection);
+                TargetPackageUtils.unbindFromService(mContext, serviceConnection);
             }
         });
     }
@@ -112,7 +113,8 @@
             startTargetPackage();
 
             final Intent intent = createServiceIntent();
-            final ServiceConnection alreadyBoundServiceConnection = bindAndWaitForConnectedService();
+            final ServiceConnection alreadyBoundServiceConnection =
+                    TargetPackageUtils.bindAndWaitForConnectedService(mContext, intent);
 
             try {
                 final ServiceConnection serviceConnection = createServiceConnectionReportTime();
@@ -123,10 +125,10 @@
                     final long endTimeNs = getReceivedTimeNs(Constants.TYPE_SERVICE_CONNECTED);
                     return endTimeNs - startTimeNs;
                 } finally {
-                    unbindFromService(serviceConnection);
+                    TargetPackageUtils.unbindFromService(mContext, serviceConnection);
                 }
             } finally {
-                unbindFromService(alreadyBoundServiceConnection);
+                TargetPackageUtils.unbindFromService(mContext, alreadyBoundServiceConnection);
             }
         });
     }
@@ -139,8 +141,9 @@
     public void bindServiceAllowOomManagement() {
         runPerfFunction(() -> {
             final Intent intentNoOom = createServiceIntent();
-            final ServiceConnection serviceConnectionOom = bindAndWaitForConnectedService(
-                    Context.BIND_ALLOW_OOM_MANAGEMENT);
+            final ServiceConnection serviceConnectionOom =
+                    TargetPackageUtils.bindAndWaitForConnectedService(mContext, intentNoOom,
+                            Context.BIND_ALLOW_OOM_MANAGEMENT);
 
             try {
                 final ServiceConnection serviceConnectionNoOom =
@@ -152,10 +155,10 @@
 
                     return endTimeNs - startTimeNs;
                 } finally {
-                    unbindFromService(serviceConnectionNoOom);
+                    TargetPackageUtils.unbindFromService(mContext, serviceConnectionNoOom);
                 }
             } finally {
-                unbindFromService(serviceConnectionOom);
+                TargetPackageUtils.unbindFromService(mContext, serviceConnectionOom);
             }
         });
     }
diff --git a/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/ServiceStartPerfTest.java b/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/ServiceStartPerfTest.java
index 626ee02..f05f323 100644
--- a/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/ServiceStartPerfTest.java
+++ b/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/ServiceStartPerfTest.java
@@ -23,6 +23,7 @@
 import android.support.test.runner.AndroidJUnit4;
 
 import com.android.frameworks.perftests.am.util.Constants;
+import com.android.frameworks.perftests.am.util.TargetPackageUtils;
 
 import org.junit.Assert;
 import org.junit.Test;
@@ -86,7 +87,8 @@
     public void startServiceAlreadyBound() {
         runPerfFunction(() -> {
             final ServiceConnection alreadyBoundServiceConnection =
-                    bindAndWaitForConnectedService();
+                    TargetPackageUtils.bindAndWaitForConnectedService(mContext,
+                            createServiceIntent());
             try {
                 final Intent intent = createServiceIntent();
 
@@ -96,20 +98,21 @@
 
                 return endTimeNs - startTimeNs;
             } finally {
-                unbindFromService(alreadyBoundServiceConnection);
+                TargetPackageUtils.unbindFromService(mContext, alreadyBoundServiceConnection);
             }
         });
     }
 
     /**
      * Benchmark time from Context.startService() with FLAG_GRANT_READ_URI_PERMISSION to
-     * Service.onStartCommand() when target process is running.
+     * Service.onStartCommand() when target service is already running.
      */
     @Test
     public void startServiceProcessRunningReadUriPermission() {
         runPerfFunction(() -> {
             final ServiceConnection alreadyBoundServiceConnection =
-                    bindAndWaitForConnectedService();
+                    TargetPackageUtils.bindAndWaitForConnectedService(mContext,
+                            createServiceIntent());
             try {
                 final Intent intent = createServiceIntent();
                 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
@@ -120,7 +123,7 @@
 
                 return endTimeNs - startTimeNs;
             } finally {
-                unbindFromService(alreadyBoundServiceConnection);
+                TargetPackageUtils.unbindFromService(mContext, alreadyBoundServiceConnection);
             }
         });
     }
diff --git a/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/util/TargetPackageUtils.java b/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/util/TargetPackageUtils.java
index 3db8abc..046dd6b 100644
--- a/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/util/TargetPackageUtils.java
+++ b/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/util/TargetPackageUtils.java
@@ -17,19 +17,33 @@
 package com.android.frameworks.perftests.am.util;
 
 import android.app.ActivityManager;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.ResultReceiver;
 import android.os.SystemClock;
 
+import org.junit.Assert;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
 public class TargetPackageUtils {
     private static final String TAG = TargetPackageUtils.class.getSimpleName();
 
     public static final String PACKAGE_NAME = "com.android.frameworks.perftests.amteststestapp";
     public static final String ACTIVITY_NAME = PACKAGE_NAME + ".TestActivity";
     public static final String SERVICE_NAME = PACKAGE_NAME + ".TestService";
+    private static final String START_SERVICE_NAME = PACKAGE_NAME + ".StartProcessService";
 
     private static final long WAIT_TIME_MS = 100L;
+    private static final long AWAIT_SERVICE_CONNECT_MS = 10000L;
 
     // Cache for test app's uid, so we only have to query it once.
     private static int sTestAppUid = -1;
@@ -37,11 +51,13 @@
     /**
      * Kills the test package synchronously.
      */
-    public static void killTargetPackage(Context context) {
-        ActivityManager activityManager = context.getSystemService(ActivityManager.class);
+    public static void killTargetPackage(Context context, ServiceConnection serviceConnection) {
+        unbindFromService(context, serviceConnection);
+
+        final ActivityManager activityManager = context.getSystemService(ActivityManager.class);
         activityManager.forceStopPackage(PACKAGE_NAME);
         while (targetPackageIsRunning(context)) {
-            sleep();
+            SystemClock.sleep(WAIT_TIME_MS);
         }
 
         Utils.drainBroadcastQueue();
@@ -50,21 +66,24 @@
     /**
      * Starts the test package synchronously. It does so by starting an Activity.
      */
-    public static void startTargetPackage(Context context, TimeReceiver timeReceiver) {
-        // "am start-activity -W PACKAGE_NAME/ACTIVITY_CLASS_NAME" still requires a sleep even
-        // though it should be synchronous, so just use Intent instead
+    public static ServiceConnection startTargetPackage(Context context) {
+        final CountDownLatch countDownLatch = new CountDownLatch(1);
         final Intent intent = new Intent();
-        intent.putExtras(timeReceiver.createReceiveTimeExtraBinder());
-        intent.setClassName(PACKAGE_NAME, ACTIVITY_NAME);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        context.startActivity(intent);
+        intent.putExtra(Intent.EXTRA_RESULT_RECEIVER, new CountDownResultReceiver(countDownLatch));
+        intent.setClassName(PACKAGE_NAME, START_SERVICE_NAME);
+        final ServiceConnection serviceConnection = bindAndWaitForConnectedService(context, intent);
 
-        while (!targetPackageIsRunning(context)) {
-            sleep();
+        try {
+            final boolean targetPackageIdleSuccess = countDownLatch.await(AWAIT_SERVICE_CONNECT_MS,
+                    TimeUnit.MILLISECONDS);
+            Assert.assertTrue("Timeout when waiting for ILooperIdleCallback.Stub.looperIdle()",
+                    targetPackageIdleSuccess);
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
         }
-        // make sure Application has run
-        timeReceiver.getReceivedTimeNs(Constants.TYPE_TARGET_PACKAGE_START);
+
         Utils.drainBroadcastQueue();
+        return serviceConnection;
     }
 
     private static boolean targetPackageIsRunning(Context context) {
@@ -74,10 +93,6 @@
         return !result.contains("(NONEXISTENT)");
     }
 
-    private static void sleep() {
-        SystemClock.sleep(WAIT_TIME_MS);
-    }
-
     private static int getTestAppUid(Context context) {
         if (sTestAppUid == -1) {
             final PackageManager pm = context.getPackageManager();
@@ -90,5 +105,45 @@
         return sTestAppUid;
     }
 
+    public static ServiceConnection bindAndWaitForConnectedService(Context context, Intent intent) {
+        return bindAndWaitForConnectedService(context, intent, 0);
+    }
+
+    public static ServiceConnection bindAndWaitForConnectedService(Context context, Intent intent,
+            int bindFlags) {
+        final CountDownLatch countDownLatch = new CountDownLatch(1);
+        final ServiceConnection serviceConnection = new ServiceConnection() {
+            @Override
+            public void onServiceConnected(ComponentName name, IBinder service) {
+                countDownLatch.countDown();
+            }
+
+            @Override
+            public void onServiceDisconnected(ComponentName name) {
+            }
+        };
+
+        final boolean success = context.bindService(intent, serviceConnection,
+                Context.BIND_AUTO_CREATE | bindFlags);
+        Assert.assertTrue("Could not bind to service", success);
+
+        try {
+            final boolean connectedSuccess = countDownLatch.await(AWAIT_SERVICE_CONNECT_MS,
+                    TimeUnit.MILLISECONDS);
+            Assert.assertTrue("Timeout when waiting for ServiceConnection.onServiceConnected()",
+                    connectedSuccess);
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+
+        return serviceConnection;
+    }
+
+    public static void unbindFromService(Context context, ServiceConnection serviceConnection) {
+        if (serviceConnection != null) {
+            context.unbindService(serviceConnection);
+        }
+    }
+
 }
 
diff --git a/tests/ActivityManagerPerfTests/utils/Android.mk b/tests/ActivityManagerPerfTests/utils/Android.mk
index 7276e37..60c9423 100644
--- a/tests/ActivityManagerPerfTests/utils/Android.mk
+++ b/tests/ActivityManagerPerfTests/utils/Android.mk
@@ -16,6 +16,7 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
 
 LOCAL_SRC_FILES := \
     $(call all-java-files-under, src) \
diff --git a/tests/ActivityManagerPerfTests/utils/src/com/android/frameworks/perftests/am/util/Constants.java b/tests/ActivityManagerPerfTests/utils/src/com/android/frameworks/perftests/am/util/Constants.java
index ffb3f84..9b076c5 100644
--- a/tests/ActivityManagerPerfTests/utils/src/com/android/frameworks/perftests/am/util/Constants.java
+++ b/tests/ActivityManagerPerfTests/utils/src/com/android/frameworks/perftests/am/util/Constants.java
@@ -29,4 +29,5 @@
             "com.android.frameworks.perftests.ACTION_BROADCAST_REGISTERED_RECEIVE";
 
     public static final String EXTRA_RECEIVER_CALLBACK = "receiver_callback_binder";
+    public static final String EXTRA_LOOPER_IDLE_CALLBACK = "looper_idle_callback_binder";
 }
diff --git a/tests/ActivityManagerPerfTests/utils/src/com/android/frameworks/perftests/am/util/CountDownResultReceiver.java b/tests/ActivityManagerPerfTests/utils/src/com/android/frameworks/perftests/am/util/CountDownResultReceiver.java
new file mode 100644
index 0000000..6c032c4
--- /dev/null
+++ b/tests/ActivityManagerPerfTests/utils/src/com/android/frameworks/perftests/am/util/CountDownResultReceiver.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * 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.frameworks.perftests.am.util;
+
+import android.os.Bundle;
+import android.os.ResultReceiver;
+
+import java.util.concurrent.CountDownLatch;
+
+public class CountDownResultReceiver extends ResultReceiver {
+    private CountDownLatch mCountDownLatch;
+
+    public CountDownResultReceiver(CountDownLatch countDownLatch) {
+        super(null);
+        mCountDownLatch = countDownLatch;
+    }
+
+    @Override
+    protected void onReceiveResult(int resultCode, Bundle resultData) {
+        mCountDownLatch.countDown();
+    }
+}
diff --git a/tests/ActivityManagerPerfTests/utils/src/com/android/frameworks/perftests/am/util/Utils.java b/tests/ActivityManagerPerfTests/utils/src/com/android/frameworks/perftests/am/util/Utils.java
index 493d8cd..67071d2 100644
--- a/tests/ActivityManagerPerfTests/utils/src/com/android/frameworks/perftests/am/util/Utils.java
+++ b/tests/ActivityManagerPerfTests/utils/src/com/android/frameworks/perftests/am/util/Utils.java
@@ -18,6 +18,7 @@
 
 import android.content.Intent;
 import android.os.RemoteException;
+import android.os.ResultReceiver;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.uiautomator.UiDevice;
 import android.util.Log;
@@ -56,4 +57,12 @@
             Log.e(TAG, e.getMessage());
         }
     }
+
+    /**
+     * Notify the listener that the main Looper queue is idle.
+     */
+    public static void sendLooperIdle(Intent intent) {
+        ResultReceiver resultReceiver = intent.getParcelableExtra(Intent.EXTRA_RESULT_RECEIVER);
+        resultReceiver.send(0, null);
+    }
 }
diff --git a/tests/ActivityTests/Android.mk b/tests/ActivityTests/Android.mk
index f3c6b5a..274fc5f 100644
--- a/tests/ActivityTests/Android.mk
+++ b/tests/ActivityTests/Android.mk
@@ -4,6 +4,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := ActivityTest
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_MODULE_TAGS := tests
 LOCAL_CERTIFICATE := platform
diff --git a/tests/AppLaunch/Android.mk b/tests/AppLaunch/Android.mk
index 917293f..1fb548b 100644
--- a/tests/AppLaunch/Android.mk
+++ b/tests/AppLaunch/Android.mk
@@ -7,6 +7,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := AppLaunch
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_CERTIFICATE := platform
 LOCAL_JAVA_LIBRARIES := android.test.base android.test.runner
diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
index 2a13093..494ee65 100644
--- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
+++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
@@ -83,6 +83,7 @@
     private static final String KEY_TRACE_BUFFERSIZE = "trace_bufferSize";
     private static final String KEY_TRACE_DUMPINTERVAL = "tracedump_interval";
     private static final String KEY_COMPILER_FILTERS = "compiler_filters";
+    private static final String KEY_FORCE_STOP_APP = "force_stop_app";
 
     private static final String SIMPLEPERF_APP_CMD =
             "simpleperf --log fatal stat --csv -e cpu-cycles,major-faults --app %s & %s";
@@ -103,6 +104,7 @@
     private static final String DROP_CACHE_SCRIPT = "/data/local/tmp/dropCache.sh";
     private static final String APP_LAUNCH_CMD = "am start -W -n";
     private static final String SUCCESS_MESSAGE = "Status: ok";
+    private static final String WARNING_MESSAGE = "Warning:";
     private static final String COMPILE_SUCCESS = "Success";
     private static final String THIS_TIME = "ThisTime:";
     private static final String LAUNCH_ITERATION = "LAUNCH_ITERATION - %d";
@@ -125,6 +127,7 @@
     private String mLaunchOrder = null;
     private boolean mDropCache = false;
     private int mLaunchIterations = 10;
+    private boolean mForceStopApp = true;
     private int mTraceLaunchCount = 0;
     private String mTraceDirectoryStr = null;
     private Bundle mResult = new Bundle();
@@ -246,7 +249,7 @@
                     // We only need to run a trial for the speed-profile filter, but we always
                     // run one for "applaunch.txt" consistency.
                     AppLaunchResult launchResult =
-                        startApp(launch.getApp(), true, launch.getLaunchReason());
+                        startApp(launch.getApp(), launch.getLaunchReason());
                     if (launchResult.mLaunchTime < 0) {
                         addLaunchResult(launch, new AppLaunchResult());
                         // simply pass the app if launch isn't successful
@@ -274,7 +277,7 @@
                     }
                     // In the "applaunch.txt" file app launches are referenced using
                     // "LAUNCH_ITERATION - ITERATION NUM"
-                    launchResults = startApp(launch.getApp(), true, launch.getLaunchReason());
+                    launchResults = startApp(launch.getApp(), launch.getLaunchReason());
                     if (launchResults.mLaunchTime < 0) {
                         addLaunchResult(launch, new AppLaunchResult());
                         // if it fails once, skip the rest of the launches
@@ -295,14 +298,18 @@
                         atraceLogger.atraceStart(traceCategoriesSet, traceBufferSize,
                                 traceDumpInterval, rootTraceSubDir,
                                 String.format("%s-%s", launch.getApp(), launch.getLaunchReason()));
-                        startApp(launch.getApp(), true, launch.getLaunchReason());
+                        startApp(launch.getApp(), launch.getLaunchReason());
                         sleep(POST_LAUNCH_IDLE_TIMEOUT);
                     } finally {
                         // Stop the trace
                         atraceLogger.atraceStop();
                     }
                 }
-                closeApp(launch.getApp());
+                if(mForceStopApp) {
+                    closeApp(launch.getApp());
+                } else {
+                    startHomeIntent();
+                }
                 sleep(BETWEEN_LAUNCH_SLEEP_TIMEOUT);
             }
         } finally {
@@ -425,6 +432,10 @@
         if (launchIterations != null) {
             mLaunchIterations = Integer.parseInt(launchIterations);
         }
+        String forceStopApp = args.getString(KEY_FORCE_STOP_APP);
+        if (forceStopApp != null) {
+            mForceStopApp = Boolean.parseBoolean(forceStopApp);
+        }
         String appList = args.getString(KEY_APPS);
         if (appList == null)
             return;
@@ -522,8 +533,8 @@
         }
     }
 
-    private AppLaunchResult startApp(String appName, boolean forceStopBeforeLaunch,
-            String launchReason) throws NameNotFoundException, RemoteException {
+    private AppLaunchResult startApp(String appName, String launchReason)
+            throws NameNotFoundException, RemoteException {
         Log.i(TAG, "Starting " + appName);
 
         Intent startIntent = mNameToIntent.get(appName);
@@ -532,8 +543,7 @@
             mResult.putString(mNameToResultKey.get(appName), "App does not exist");
             return new AppLaunchResult();
         }
-        AppLaunchRunnable runnable = new AppLaunchRunnable(startIntent, forceStopBeforeLaunch,
-                launchReason);
+        AppLaunchRunnable runnable = new AppLaunchRunnable(startIntent, launchReason);
         Thread t = new Thread(runnable);
         t.start();
         try {
@@ -682,13 +692,10 @@
     private class AppLaunchRunnable implements Runnable {
         private Intent mLaunchIntent;
         private AppLaunchResult mLaunchResult;
-        private boolean mForceStopBeforeLaunch;
         private String mLaunchReason;
 
-        public AppLaunchRunnable(Intent intent, boolean forceStopBeforeLaunch,
-                String launchReason) {
+        public AppLaunchRunnable(Intent intent, String launchReason) {
             mLaunchIntent = intent;
-            mForceStopBeforeLaunch = forceStopBeforeLaunch;
             mLaunchReason = launchReason;
             mLaunchResult = new AppLaunchResult();
         }
@@ -702,7 +709,7 @@
             try {
                 String packageName = mLaunchIntent.getComponent().getPackageName();
                 String componentName = mLaunchIntent.getComponent().flattenToShortString();
-                if (mForceStopBeforeLaunch) {
+                if (mForceStopApp) {
                     mAm.forceStopPackage(packageName, UserHandle.USER_CURRENT);
                 }
                 String launchCmd = String.format("%s %s", APP_LAUNCH_CMD, componentName);
@@ -752,10 +759,11 @@
             String launchTime = "-1";
             String cpuCycles = "-1";
             String majorFaults = "-1";
-            boolean launchSuccess = false;
+            boolean coldLaunchSuccess = false;
+            boolean hotLaunchSuccess = false;
             try {
                 InputStream inputStream = new FileInputStream(parcelDesc.getFileDescriptor());
-                /* SAMPLE OUTPUT :
+                /* SAMPLE OUTPUT : Cold launch
                 Starting: Intent { cmp=com.google.android.calculator/com.android.calculator2.Calculator }
                 Status: ok
                 Activity: com.google.android.calculator/com.android.calculator2.Calculator
@@ -763,6 +771,15 @@
                 TotalTime: 357
                 WaitTime: 377
                 Complete*/
+                /* SAMPLE OUTPUT : Hot launch
+                Starting: Intent { cmp=com.google.android.calculator/com.android.calculator2.Calculator }
+                Warning: Activity not started, its current task has been brought to the front
+                Status: ok
+                Activity: com.google.android.calculator/com.android.calculator2.CalculatorGoogle
+                ThisTime: 60
+                TotalTime: 60
+                WaitTime: 67
+                Complete*/
                 /* WITH SIMPLEPERF :
                 Performance counter statistics,
                 6595722690,cpu-cycles,4.511040,GHz,(100%),
@@ -776,24 +793,33 @@
                 mBufferedWriter.write(headerInfo);
                 mBufferedWriter.newLine();
                 while ((line = bufferedReader.readLine()) != null) {
-                    if (lineCount == 2 && line.contains(SUCCESS_MESSAGE)) {
-                        launchSuccess = true;
+                    if (lineCount == 2 && line.startsWith(SUCCESS_MESSAGE)) {
+                        coldLaunchSuccess = true;
+                    }
+                    if (lineCount == 2 && line.startsWith(WARNING_MESSAGE)) {
+                        hotLaunchSuccess = true;
                     }
                     // Parse TotalTime which is the launch time
-                    if (launchSuccess && lineCount == 5) {
+                    if (coldLaunchSuccess && lineCount == 5) {
+                        String launchSplit[] = line.split(":");
+                        launchTime = launchSplit[1].trim();
+                    }
+                    if (hotLaunchSuccess && lineCount == 6) {
                         String launchSplit[] = line.split(":");
                         launchTime = launchSplit[1].trim();
                     }
 
                     if (mSimplePerfAppOnly) {
                         // Parse simpleperf output.
-                        if (lineCount == 9) {
+                        if ((lineCount == 9 && coldLaunchSuccess)
+                                || (lineCount == 10 && hotLaunchSuccess)) {
                             if (!line.contains("cpu-cycles")) {
                                 Log.e(TAG, "Error in simpleperf output");
                             } else {
                                 cpuCycles = line.split(",")[0].trim();
                             }
-                        } else if (lineCount == 10) {
+                        } else if ((lineCount == 10 && coldLaunchSuccess)
+                                || (lineCount == 11 && hotLaunchSuccess)) {
                             if (!line.contains("major-faults")) {
                                 Log.e(TAG, "Error in simpleperf output");
                             } else {
diff --git a/tests/AppLaunchWear/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunchWear/src/com/android/tests/applaunch/AppLaunch.java
index f32464b..38c298c 100644
--- a/tests/AppLaunchWear/src/com/android/tests/applaunch/AppLaunch.java
+++ b/tests/AppLaunchWear/src/com/android/tests/applaunch/AppLaunch.java
@@ -103,6 +103,7 @@
     private static final String DROP_CACHE_SCRIPT = "/data/local/tmp/dropCache.sh";
     private static final String APP_LAUNCH_CMD = "am start -W -n";
     private static final String SUCCESS_MESSAGE = "Status: ok";
+    private static final String WARNING_MESSAGE = "Warning: Activity not started";
     private static final String COMPILE_SUCCESS = "Success";
     private static final String THIS_TIME = "ThisTime:";
     private static final String LAUNCH_ITERATION = "LAUNCH_ITERATION - %d";
@@ -231,12 +232,14 @@
                 dropCache();
                 String appPkgName = mNameToIntent.get(launch.getApp())
                         .getComponent().getPackageName();
-
+                Log.v(TAG, String.format("\nApp name: %s", launch.getApp()));
+                Log.v(TAG, String.format("Adding app package name: %s", appPkgName));
                 // App launch times for trial launch will not be used for final
                 // launch time calculations.
                 if (launch.getLaunchReason().equals(TRIAL_LAUNCH)) {
                     // In the "applaunch.txt" file, trail launches is referenced using
                     // "TRIAL_LAUNCH"
+                    Log.v(TAG, "Trial Launch");
                     if (SPEED_PROFILE_FILTER.equals(launch.getCompilerFilter())) {
                         assertTrue(String.format("Not able to compile the app : %s", appPkgName),
                               compileApp(VERIFY_FILTER, appPkgName));
@@ -246,8 +249,14 @@
                     }
                     // We only need to run a trial for the speed-profile filter, but we always
                     // run one for "applaunch.txt" consistency.
-                    AppLaunchResult launchResult =
-                        startApp(launch.getApp(), true, launch.getLaunchReason());
+                    AppLaunchResult launchResult = null;
+                    if (appPkgName.contains(WEARABLE_HOME_PACKAGE)) {
+                        Log.v(TAG, "Home package detected. Not killing app");
+                        launchResult = startApp(launch.getApp(), false, launch.getLaunchReason());
+                    } else {
+                        Log.v(TAG, "Will kill app before launch");
+                        launchResult = startApp(launch.getApp(), true, launch.getLaunchReason());
+                    }
                     if (launchResult.mLaunchTime < 0) {
                         addLaunchResult(launch, new AppLaunchResult());
                         // simply pass the app if launch isn't successful
@@ -268,6 +277,7 @@
 
                 // App launch times used for final calculation
                 else if (launch.getLaunchReason().contains(LAUNCH_ITERATION_PREFIX)) {
+                    Log.v(TAG, "Launch iteration prefix.");
                     AppLaunchResult launchResults = null;
                     if (hasFailureOnFirstLaunch(launch)) {
                         // skip if the app has failures while launched first
@@ -276,8 +286,10 @@
                     // In the "applaunch.txt" file app launches are referenced using
                     // "LAUNCH_ITERATION - ITERATION NUM"
                     if (appPkgName.contains(WEARABLE_HOME_PACKAGE)) {
+                        Log.v(TAG, "Home package detected. Not killing app");
                         launchResults = startApp(launch.getApp(), false, launch.getLaunchReason());
                     } else {
+                        Log.v(TAG, "Will kill app before launch");
                         launchResults = startApp(launch.getApp(), true, launch.getLaunchReason());
                     }
                     if (launchResults.mLaunchTime < 0) {
@@ -293,6 +305,7 @@
                 // App launch times for trace launch will not be used for final
                 // launch time calculations.
                 else if (launch.getLaunchReason().contains(TRACE_ITERATION_PREFIX)) {
+                    Log.v(TAG, "Trace iteration prefix");
                     AtraceLogger atraceLogger = AtraceLogger
                             .getAtraceLoggerInstance(getInstrumentation());
                     // Start the trace
@@ -300,7 +313,13 @@
                         atraceLogger.atraceStart(traceCategoriesSet, traceBufferSize,
                                 traceDumpInterval, rootTraceSubDir,
                                 String.format("%s-%s", launch.getApp(), launch.getLaunchReason()));
-                        startApp(launch.getApp(), true, launch.getLaunchReason());
+                        if (appPkgName.contains(WEARABLE_HOME_PACKAGE)) {
+                            Log.v(TAG, "Home package detected. Not killing app");
+                            startApp(launch.getApp(), false, launch.getLaunchReason());
+                        } else {
+                            Log.v(TAG, "Will kill app before launch");
+                            startApp(launch.getApp(), true, launch.getLaunchReason());
+                        }
                         sleep(POST_LAUNCH_IDLE_TIMEOUT);
                     } finally {
                         // Stop the trace
@@ -707,7 +726,12 @@
                 String packageName = mLaunchIntent.getComponent().getPackageName();
                 String componentName = mLaunchIntent.getComponent().flattenToShortString();
                 if (mForceStopBeforeLaunch) {
+                    Log.v(TAG, "Stopping app before launch");
                     mAm.forceStopPackage(packageName, UserHandle.USER_CURRENT);
+                } else {
+                    Log.v(TAG, "Not killing app. Going to Home Screen.");
+                    ParcelFileDescriptor goHome = getInstrumentation().getUiAutomation()
+                        .executeShellCommand("input keyevent 3");
                 }
                 String launchCmd = String.format("%s %s", APP_LAUNCH_CMD, componentName);
                 if (mSimplePerfAppOnly) {
@@ -767,6 +791,17 @@
                 TotalTime: 357
                 WaitTime: 377
                 Complete*/
+                /* WHEN NOT KILLING HOME :
+                Starting: Intent { cmp=com.google.android.wearable.app/
+                    com.google.android.clockwork.home.calendar.AgendaActivity }
+                Warning: Activity not started, its current task has been brought to the front
+                Status: ok
+                Activity: com.google.android.wearable.app/
+                    com.google.android.clockwork.home.calendar.AgendaActivity
+                ThisTime: 209
+                TotalTime: 209
+                WaitTime: 285
+                Complete*/
                 /* WITH SIMPLEPERF :
                 Performance counter statistics,
                 6595722690,cpu-cycles,4.511040,GHz,(100%),
@@ -776,28 +811,32 @@
                         inputStream));
                 String line = null;
                 int lineCount = 1;
+                int addLineForWarning = 0;
                 mBufferedWriter.newLine();
                 mBufferedWriter.write(headerInfo);
                 mBufferedWriter.newLine();
                 while ((line = bufferedReader.readLine()) != null) {
-                    if (lineCount == 2 && line.contains(SUCCESS_MESSAGE)) {
+                    if (lineCount == 2 && line.contains(WARNING_MESSAGE)) {
+                        addLineForWarning = 1;
+                    }
+                    if (lineCount == (2 + addLineForWarning) && line.contains(SUCCESS_MESSAGE)) {
                         launchSuccess = true;
                     }
                     // Parse TotalTime which is the launch time
-                    if (launchSuccess && lineCount == 5) {
+                    if (launchSuccess && lineCount == (5 + addLineForWarning)) {
                         String launchSplit[] = line.split(":");
                         launchTime = launchSplit[1].trim();
                     }
 
                     if (mSimplePerfAppOnly) {
                         // Parse simpleperf output.
-                        if (lineCount == 9) {
+                        if (lineCount == (9 + addLineForWarning)) {
                             if (!line.contains("cpu-cycles")) {
                                 Log.e(TAG, "Error in simpleperf output");
                             } else {
                                 cpuCycles = line.split(",")[0].trim();
                             }
-                        } else if (lineCount == 10) {
+                        } else if (lineCount == (10 + addLineForWarning)) {
                             if (!line.contains("major-faults")) {
                                 Log.e(TAG, "Error in simpleperf output");
                             } else {
diff --git a/tests/Assist/Android.mk b/tests/Assist/Android.mk
index f31c4dd..d0d3eca 100644
--- a/tests/Assist/Android.mk
+++ b/tests/Assist/Android.mk
@@ -6,5 +6,6 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := Assist
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 include $(BUILD_PACKAGE)
diff --git a/tests/BackgroundDexOptServiceIntegrationTests/Android.mk b/tests/BackgroundDexOptServiceIntegrationTests/Android.mk
index da1a08b..b10305d 100644
--- a/tests/BackgroundDexOptServiceIntegrationTests/Android.mk
+++ b/tests/BackgroundDexOptServiceIntegrationTests/Android.mk
@@ -27,6 +27,7 @@
     android-support-test \
 
 LOCAL_PACKAGE_NAME := BackgroundDexOptServiceIntegrationTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_COMPATIBILITY_SUITE := device-tests
 
 LOCAL_CERTIFICATE := platform
diff --git a/tests/BandwidthTests/Android.mk b/tests/BandwidthTests/Android.mk
index 7bc5f857..d00fdc6 100644
--- a/tests/BandwidthTests/Android.mk
+++ b/tests/BandwidthTests/Android.mk
@@ -19,6 +19,7 @@
 LOCAL_MODULE_TAGS := tests
 
 LOCAL_PACKAGE_NAME := BandwidthEnforcementTest
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 include $(BUILD_PACKAGE)
diff --git a/tests/BatteryWaster/Android.mk b/tests/BatteryWaster/Android.mk
index 6db34a7..fb244a8 100644
--- a/tests/BatteryWaster/Android.mk
+++ b/tests/BatteryWaster/Android.mk
@@ -6,6 +6,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := BatteryWaster
+LOCAL_SDK_VERSION := current
 LOCAL_CERTIFICATE := platform
 
 include $(BUILD_PACKAGE)
diff --git a/tests/BiDiTests/Android.mk b/tests/BiDiTests/Android.mk
index ae29fc2..78cf4be 100644
--- a/tests/BiDiTests/Android.mk
+++ b/tests/BiDiTests/Android.mk
@@ -21,6 +21,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := BiDiTests
+LOCAL_SDK_VERSION := current
 
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 
diff --git a/tests/BrowserPowerTest/Android.mk b/tests/BrowserPowerTest/Android.mk
index 5765575..0934889 100644
--- a/tests/BrowserPowerTest/Android.mk
+++ b/tests/BrowserPowerTest/Android.mk
@@ -25,6 +25,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := BrowserPowerTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 #LOCAL_INSTRUMENTATION_FOR := browserpowertest
 
diff --git a/tests/Camera2Tests/SmartCamera/SimpleCamera/tests/Android.mk b/tests/Camera2Tests/SmartCamera/SimpleCamera/tests/Android.mk
index 9e7f618..a900077 100644
--- a/tests/Camera2Tests/SmartCamera/SimpleCamera/tests/Android.mk
+++ b/tests/Camera2Tests/SmartCamera/SimpleCamera/tests/Android.mk
@@ -19,6 +19,7 @@
 LOCAL_MODULE_TAGS := tests
 
 # LOCAL_SDK_VERSION := current
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_PACKAGE_NAME := SmartCamera-tests
 
diff --git a/tests/CameraPrewarmTest/Android.mk b/tests/CameraPrewarmTest/Android.mk
index b6316f0..e128504 100644
--- a/tests/CameraPrewarmTest/Android.mk
+++ b/tests/CameraPrewarmTest/Android.mk
@@ -4,6 +4,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := CameraPrewarmTest
+LOCAL_SDK_VERSION := current
 
 LOCAL_MODULE_TAGS := tests
 LOCAL_CERTIFICATE := platform
diff --git a/tests/CanvasCompare/Android.mk b/tests/CanvasCompare/Android.mk
index b071ec4..6a0a93e 100644
--- a/tests/CanvasCompare/Android.mk
+++ b/tests/CanvasCompare/Android.mk
@@ -20,6 +20,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
 
 LOCAL_PACKAGE_NAME := CanvasCompare
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_MODULE_TAGS := tests
 
diff --git a/tests/Compatibility/Android.mk b/tests/Compatibility/Android.mk
index 82e2126..9c47a26 100644
--- a/tests/Compatibility/Android.mk
+++ b/tests/Compatibility/Android.mk
@@ -24,6 +24,7 @@
 
 
 LOCAL_PACKAGE_NAME := AppCompatibilityTest
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_CERTIFICATE := platform
 include $(BUILD_PACKAGE)
 
diff --git a/tests/CoreTests/android/Android.mk b/tests/CoreTests/android/Android.mk
index 56d7918..04f6739 100644
--- a/tests/CoreTests/android/Android.mk
+++ b/tests/CoreTests/android/Android.mk
@@ -7,14 +7,14 @@
 	$(call all-subdir-java-files)
 
 LOCAL_JAVA_LIBRARIES := \
-    android.test.runner \
-    bouncycastle \
-    conscrypt \
+    android.test.runner.stubs \
     org.apache.http.legacy \
-    android.test.base \
+    android.test.base.stubs \
+
+LOCAL_SDK_VERSION := current
 
 LOCAL_STATIC_JAVA_LIBRARIES := junit
 
-LOCAL_PACKAGE_NAME := CoreTests
+LOCAL_PACKAGE_NAME := LegacyCoreTests
 
 include $(BUILD_PACKAGE)
diff --git a/tests/CoreTests/android/core/JniLibTest.java b/tests/CoreTests/android/core/JniLibTest.java
deleted file mode 100644
index d476072..0000000
--- a/tests/CoreTests/android/core/JniLibTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package android.core;
-
-import android.test.suitebuilder.annotation.Suppress;
-import android.util.Log;
-import junit.framework.TestCase;
-
-
-@Suppress
-public class JniLibTest extends TestCase {
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        /*
-         * This causes the native shared library to be loaded when the
-         * class is first used.  The library is only loaded once, even if
-         * multiple classes include this line.
-         *
-         * The library must be in java.library.path, which is derived from
-         * LD_LIBRARY_PATH.  The actual library name searched for will be
-         * "libjni_lib_test.so" under Linux, but may be different on other
-         * platforms.
-         */
-        try {
-            System.loadLibrary("jni_lib_test");
-        } catch (UnsatisfiedLinkError ule) {
-            Log.e("JniLibTest", "WARNING: Could not load jni_lib_test natives");
-        }
-    }
-
-    private static native int nativeStaticThing(float f);
-    private native void nativeThing(int val);
-
-    public void testNativeCall() {
-        Log.i("JniLibTest", "JNI search path is "
-                + System.getProperty("java.library.path"));
-        Log.i("JniLibTest", "'jni_lib_test' becomes '"
-                + System.mapLibraryName("jni_lib_test") + "'");
-
-        int result = nativeStaticThing(1234.5f);
-        nativeThing(result);
-    }
-}
diff --git a/tests/CoreTests/android/core/MiscRegressionTest.java b/tests/CoreTests/android/core/MiscRegressionTest.java
deleted file mode 100644
index 32995b5..0000000
--- a/tests/CoreTests/android/core/MiscRegressionTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.core;
-
-import android.test.suitebuilder.annotation.MediumTest;
-import java.util.logging.Logger;
-import junit.framework.TestCase;
-
-public class MiscRegressionTest extends TestCase {
-
-    // Regression test for #951285: Suitable LogHandler should be chosen
-    // depending on the environment.
-    @MediumTest
-    public void testAndroidLogHandler() throws Exception {
-        Logger.global.severe("This has logging Level.SEVERE, should become ERROR");
-        Logger.global.warning("This has logging Level.WARNING, should become WARN");
-        Logger.global.info("This has logging Level.INFO, should become INFO");
-        Logger.global.config("This has logging Level.CONFIG, should become DEBUG");
-        Logger.global.fine("This has logging Level.FINE, should become VERBOSE");
-        Logger.global.finer("This has logging Level.FINER, should become VERBOSE");
-        Logger.global.finest("This has logging Level.FINEST, should become VERBOSE");
-    }
-}
diff --git a/tests/CoreTests/android/core/RequestAPITest.java b/tests/CoreTests/android/core/RequestAPITest.java
index 94eb23e..206f228 100644
--- a/tests/CoreTests/android/core/RequestAPITest.java
+++ b/tests/CoreTests/android/core/RequestAPITest.java
@@ -22,7 +22,6 @@
 import android.test.suitebuilder.annotation.Suppress;
 import android.util.Log;
 import android.webkit.CookieSyncManager;
-import com.google.android.collect.Maps;
 
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
@@ -87,7 +86,7 @@
          * header is attempted to be set
          */
         Log.d(LOGTAG, "testRequestAddNullHeader start ");
-        Map<String, String> headers = Maps.newHashMap();
+        Map<String, String> headers = new HashMap<>();
         headers.put(null, null);
         verifyFailure(headers);
         Log.d(LOGTAG, "testRequestAddNullHeader - returning");
@@ -99,7 +98,7 @@
          * value is attempted to be set
          */
         Log.d(LOGTAG, "testRequestAddNullValue start ");
-        Map<String, String> headers = Maps.newHashMap();
+        Map<String, String> headers = new HashMap<>();
         headers.put("TestHeader", null);
         verifyFailure(headers);
         Log.d(LOGTAG, "testRequestAddNullValue - returning");
@@ -111,7 +110,7 @@
          * header is attempted to be set
          */
         Log.d(LOGTAG, "testRequestAddEmptyValue start ");
-        Map<String, String> headers = Maps.newHashMap();
+        Map<String, String> headers = new HashMap<>();
         headers.put("TestHeader", "");
         verifyFailure(headers);
         Log.d(LOGTAG, "testRequestAddEmptyValue - returning");
@@ -131,7 +130,7 @@
          * generating and exception
          */
         Log.d(LOGTAG, "testRequestAddHeader start ");
-        Map<String, String> headers = Maps.newHashMap();
+        Map<String, String> headers = new HashMap<>();
         headers.put("TestHeader", "RequestAddHeader");
         verifySuccess(headers);
         Log.d(LOGTAG, "testRequestAddHeader - returning");
@@ -143,7 +142,7 @@
          * can be set without generating and exception
          */
         Log.d(LOGTAG, "testRequestAddMultiHeader start ");
-        Map<String, String> headers = Maps.newHashMap();
+        Map<String, String> headers = new HashMap<>();
         headers.put("TestHeader", "RequestAddMultiHeader");
         headers.put("TestHeader2", "RequestAddMultiHeader");
         headers.put("TestHeader3", "RequestAddMultiHeader");
@@ -157,7 +156,7 @@
          * and values can be set without generating and exception
          */
         Log.d(LOGTAG, "testRequestAddSameHeader start ");
-        Map<String, String> headers = Maps.newHashMap();
+        Map<String, String> headers = new HashMap<>();
         headers.put("TestHeader", "RequestAddSameHeader");
         headers.put("TestHeader", "RequestAddSameHeader");
         headers.put("TestHeader", "RequestAddSameHeader");
diff --git a/tests/CoreTests/android/core/Sha1Test.java b/tests/CoreTests/android/core/Sha1Test.java
deleted file mode 100644
index 8ed1205..0000000
--- a/tests/CoreTests/android/core/Sha1Test.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.core;
-
-import android.test.suitebuilder.annotation.SmallTest;
-import java.security.MessageDigest;
-import junit.framework.TestCase;
-
-/**
- * Tests SHA1 message digest algorithm.
- */
-public class Sha1Test extends TestCase {
-    class TestData {
-        private String input;
-        private String result;
-
-        public TestData(String i, String r) {
-            input = i;
-            result = r;
-        }
-    }
-
-    TestData[] mTestData = new TestData[]{
-            new TestData("abc", "a9993e364706816aba3e25717850c26c9cd0d89d"),
-            new TestData("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
-                    "84983e441c3bd26ebaae4aa1f95129e5e54670f1")
-    };
-
-    @SmallTest
-    public void testSha1() throws Exception {
-        MessageDigest digest = MessageDigest.getInstance("SHA-1");
-
-        int numTests = mTestData.length;
-        for (int i = 0; i < numTests; i++) {
-            digest.update(mTestData[i].input.getBytes());
-            byte[] hash = digest.digest();
-            String encodedHash = encodeHex(hash);
-            assertEquals(encodedHash, mTestData[i].result);
-        }
-    }
-
-    private static String encodeHex(byte[] bytes) {
-        StringBuffer hex = new StringBuffer(bytes.length * 2);
-
-        for (int i = 0; i < bytes.length; i++) {
-            if (((int) bytes[i] & 0xff) < 0x10) {
-                hex.append("0");
-            }
-            hex.append(Integer.toString((int) bytes[i] & 0xff, 16));
-        }
-
-        return hex.toString();
-    }
-}
-
diff --git a/tests/DataIdleTest/Android.mk b/tests/DataIdleTest/Android.mk
index 85f7edf..bcf3599 100644
--- a/tests/DataIdleTest/Android.mk
+++ b/tests/DataIdleTest/Android.mk
@@ -20,6 +20,7 @@
 LOCAL_MODULE_TAGS := tests
 
 LOCAL_PACKAGE_NAME := DataIdleTest
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
 LOCAL_STATIC_JAVA_LIBRARIES := junit
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/DexLoggerIntegrationTests/Android.mk b/tests/DexLoggerIntegrationTests/Android.mk
index 7187a37..ee2ec0a 100644
--- a/tests/DexLoggerIntegrationTests/Android.mk
+++ b/tests/DexLoggerIntegrationTests/Android.mk
@@ -35,6 +35,7 @@
 
 LOCAL_MODULE_TAGS := tests
 LOCAL_PACKAGE_NAME := DexLoggerIntegrationTests
+LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := device-tests
 LOCAL_CERTIFICATE := platform
 LOCAL_SRC_FILES := $(call all-java-files-under, src/com/android/server/pm)
diff --git a/tests/DozeTest/Android.mk b/tests/DozeTest/Android.mk
index 01f10e5..ec250ff 100644
--- a/tests/DozeTest/Android.mk
+++ b/tests/DozeTest/Android.mk
@@ -7,6 +7,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := DozeTest
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 include $(BUILD_PACKAGE)
 
diff --git a/tests/DpiTest/Android.mk b/tests/DpiTest/Android.mk
index f55ce6e..e69d082 100644
--- a/tests/DpiTest/Android.mk
+++ b/tests/DpiTest/Android.mk
@@ -4,6 +4,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := DensityTest
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_MODULE_TAGS := tests
 
diff --git a/tests/FeatureSplit/base/Android.mk b/tests/FeatureSplit/base/Android.mk
index 6da1b38..8646460 100644
--- a/tests/FeatureSplit/base/Android.mk
+++ b/tests/FeatureSplit/base/Android.mk
@@ -20,6 +20,7 @@
 LOCAL_USE_AAPT2 := true
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 LOCAL_PACKAGE_NAME := FeatureSplitBase
+LOCAL_SDK_VERSION := current
 LOCAL_EXPORT_PACKAGE_RESOURCES := true
 
 LOCAL_MODULE_TAGS := tests
diff --git a/tests/FeatureSplit/feature1/Android.mk b/tests/FeatureSplit/feature1/Android.mk
index e6ba5c2..d4d2589 100644
--- a/tests/FeatureSplit/feature1/Android.mk
+++ b/tests/FeatureSplit/feature1/Android.mk
@@ -20,6 +20,7 @@
 LOCAL_USE_AAPT2 := true
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 LOCAL_PACKAGE_NAME := FeatureSplit1
+LOCAL_SDK_VERSION := current
 LOCAL_MODULE_TAGS := tests
 
 LOCAL_APK_LIBRARIES := FeatureSplitBase
diff --git a/tests/FeatureSplit/feature2/Android.mk b/tests/FeatureSplit/feature2/Android.mk
index c8e8609..5e5e78b 100644
--- a/tests/FeatureSplit/feature2/Android.mk
+++ b/tests/FeatureSplit/feature2/Android.mk
@@ -20,6 +20,7 @@
 LOCAL_USE_AAPT2 := true
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 LOCAL_PACKAGE_NAME := FeatureSplit2
+LOCAL_SDK_VERSION := current
 LOCAL_MODULE_TAGS := tests
 
 LOCAL_APK_LIBRARIES := FeatureSplitBase
diff --git a/tests/FixVibrateSetting/Android.mk b/tests/FixVibrateSetting/Android.mk
index 2a88e5a..86db09e 100644
--- a/tests/FixVibrateSetting/Android.mk
+++ b/tests/FixVibrateSetting/Android.mk
@@ -6,6 +6,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := FixVibrateSetting
+LOCAL_SDK_VERSION := current
 LOCAL_CERTIFICATE := platform
 
 include $(BUILD_PACKAGE)
diff --git a/tests/FrameworkPerf/Android.mk b/tests/FrameworkPerf/Android.mk
index 1873cc1..0664d4d 100644
--- a/tests/FrameworkPerf/Android.mk
+++ b/tests/FrameworkPerf/Android.mk
@@ -6,6 +6,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := FrameworkPerf
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
 LOCAL_STATIC_JAVA_LIBRARIES := junit
diff --git a/tests/GridLayoutTest/Android.mk b/tests/GridLayoutTest/Android.mk
index a02918b..e7e3ccd 100644
--- a/tests/GridLayoutTest/Android.mk
+++ b/tests/GridLayoutTest/Android.mk
@@ -20,6 +20,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := GridLayoutTest
+LOCAL_SDK_VERSION := current
 
 LOCAL_MODULE_TAGS := tests
 
diff --git a/tests/HierarchyViewerTest/Android.mk b/tests/HierarchyViewerTest/Android.mk
index 8550d70..cf1a512 100644
--- a/tests/HierarchyViewerTest/Android.mk
+++ b/tests/HierarchyViewerTest/Android.mk
@@ -6,8 +6,9 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := HierarchyViewerTest
+LOCAL_SDK_VERSION := current
 
-LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
+LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs
 LOCAL_STATIC_JAVA_LIBRARIES := junit
 
 include $(BUILD_PACKAGE)
diff --git a/tests/HwAccelerationTest/Android.mk b/tests/HwAccelerationTest/Android.mk
index d4743f9..11ea954 100644
--- a/tests/HwAccelerationTest/Android.mk
+++ b/tests/HwAccelerationTest/Android.mk
@@ -20,6 +20,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := HwAccelerationTest
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_MODULE_TAGS := tests
 
diff --git a/tests/ImfTest/Android.mk b/tests/ImfTest/Android.mk
index eb5327b..a8f5b08 100644
--- a/tests/ImfTest/Android.mk
+++ b/tests/ImfTest/Android.mk
@@ -8,6 +8,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := ImfTest
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 include $(BUILD_PACKAGE)
 
diff --git a/tests/ImfTest/tests/Android.mk b/tests/ImfTest/tests/Android.mk
index a0df959..14186d7 100644
--- a/tests/ImfTest/tests/Android.mk
+++ b/tests/ImfTest/tests/Android.mk
@@ -11,6 +11,7 @@
 LOCAL_STATIC_JAVA_LIBRARIES := junit
 
 LOCAL_PACKAGE_NAME := ImfTestTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_INSTRUMENTATION_FOR := ImfTest
 
diff --git a/tests/Internal/Android.mk b/tests/Internal/Android.mk
index b69e3e4..da56696 100644
--- a/tests/Internal/Android.mk
+++ b/tests/Internal/Android.mk
@@ -18,6 +18,7 @@
 LOCAL_CERTIFICATE := platform
 
 LOCAL_PACKAGE_NAME := InternalTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_COMPATIBILITY_SUITE := device-tests
 
 include $(BUILD_PACKAGE)
diff --git a/tests/JobSchedulerTestApp/Android.mk b/tests/JobSchedulerTestApp/Android.mk
index 7336d8c..48ee1f6 100644
--- a/tests/JobSchedulerTestApp/Android.mk
+++ b/tests/JobSchedulerTestApp/Android.mk
@@ -8,6 +8,7 @@
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := JobSchedulerTestApp
+LOCAL_SDK_VERSION := current
 
 LOCAL_PROGUARD_ENABLED := disabled
 
diff --git a/tests/LargeAssetTest/Android.mk b/tests/LargeAssetTest/Android.mk
index cb7f01b..f6d98bf 100644
--- a/tests/LargeAssetTest/Android.mk
+++ b/tests/LargeAssetTest/Android.mk
@@ -6,6 +6,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := LargeAssetTest
+LOCAL_SDK_VERSION := current
 LOCAL_CERTIFICATE := platform
 
 include $(BUILD_PACKAGE)
diff --git a/tests/LegacyAssistant/Android.mk b/tests/LegacyAssistant/Android.mk
index 0ad48d1..a583369 100644
--- a/tests/LegacyAssistant/Android.mk
+++ b/tests/LegacyAssistant/Android.mk
@@ -4,6 +4,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := LegacyAssistant
+LOCAL_SDK_VERSION := current
 
 LOCAL_MODULE_TAGS := tests
 LOCAL_CERTIFICATE := platform
diff --git a/tests/LocationTracker/Android.mk b/tests/LocationTracker/Android.mk
index b142d22..0d51b3b 100644
--- a/tests/LocationTracker/Android.mk
+++ b/tests/LocationTracker/Android.mk
@@ -4,6 +4,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := LocationTracker
+LOCAL_SDK_VERSION := current
 
 LOCAL_MODULE_TAGS := tests
 
diff --git a/tests/LockTaskTests/Android.mk b/tests/LockTaskTests/Android.mk
index ed58643..a693eaa 100644
--- a/tests/LockTaskTests/Android.mk
+++ b/tests/LockTaskTests/Android.mk
@@ -5,6 +5,7 @@
 LOCAL_MODULE_PATH := $(PRODUCT_OUT)/system/priv-app
 
 LOCAL_PACKAGE_NAME := LockTaskTests
+LOCAL_SDK_VERSION := current
 LOCAL_CERTIFICATE := platform
 
 LOCAL_SRC_FILES := $(call all-Iaidl-files-under, src) $(call all-java-files-under, src)
diff --git a/tests/LotsOfApps/Android.mk b/tests/LotsOfApps/Android.mk
index 0ef9550..bee3bcc 100644
--- a/tests/LotsOfApps/Android.mk
+++ b/tests/LotsOfApps/Android.mk
@@ -6,6 +6,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := LotsOfApps
+LOCAL_SDK_VERSION := current
 LOCAL_CERTIFICATE := platform
 
 LOCAL_PROGUARD_ENABLED := disabled
diff --git a/tests/LowStorageTest/Android.mk b/tests/LowStorageTest/Android.mk
index ab5b9e9..bdde6bd 100644
--- a/tests/LowStorageTest/Android.mk
+++ b/tests/LowStorageTest/Android.mk
@@ -21,5 +21,6 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := lowstoragetest
+LOCAL_SDK_VERSION := current
 
 include $(BUILD_PACKAGE)
diff --git a/tests/MemoryUsage/Android.mk b/tests/MemoryUsage/Android.mk
index e186e9f..5040d5a 100644
--- a/tests/MemoryUsage/Android.mk
+++ b/tests/MemoryUsage/Android.mk
@@ -7,6 +7,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := MemoryUsage
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_CERTIFICATE := platform
 LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
diff --git a/tests/NetworkSecurityConfigTest/Android.mk b/tests/NetworkSecurityConfigTest/Android.mk
index 6fb6025..fe65ecc 100644
--- a/tests/NetworkSecurityConfigTest/Android.mk
+++ b/tests/NetworkSecurityConfigTest/Android.mk
@@ -17,5 +17,6 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := NetworkSecurityConfigTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 include $(BUILD_PACKAGE)
diff --git a/tests/OneMedia/Android.mk b/tests/OneMedia/Android.mk
index 9fc6403..41f3f64 100644
--- a/tests/OneMedia/Android.mk
+++ b/tests/OneMedia/Android.mk
@@ -7,6 +7,7 @@
         $(call all-Iaidl-files-under, src)
 
 LOCAL_PACKAGE_NAME := OneMedia
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_CERTIFICATE := platform
 
 LOCAL_JAVA_LIBRARIES += org.apache.http.legacy
diff --git a/tests/RemoteDisplayProvider/Android.mk b/tests/RemoteDisplayProvider/Android.mk
index 2f4b343..e827ec2 100644
--- a/tests/RemoteDisplayProvider/Android.mk
+++ b/tests/RemoteDisplayProvider/Android.mk
@@ -21,6 +21,6 @@
 LOCAL_SDK_VERSION := current
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_RESOURCE_DIR = $(LOCAL_PATH)/res
-LOCAL_JAVA_LIBRARIES := com.android.media.remotedisplay
+LOCAL_JAVA_LIBRARIES := com.android.media.remotedisplay.stubs
 LOCAL_CERTIFICATE := platform
 include $(BUILD_PACKAGE)
diff --git a/tests/RenderThreadTest/Android.mk b/tests/RenderThreadTest/Android.mk
index e07e943..4e5f35b 100644
--- a/tests/RenderThreadTest/Android.mk
+++ b/tests/RenderThreadTest/Android.mk
@@ -7,6 +7,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := RenderThreadTest
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_STATIC_JAVA_LIBRARIES += android-common
 
diff --git a/tests/SerialChat/Android.mk b/tests/SerialChat/Android.mk
index a534e1a..ed6ca999 100644
--- a/tests/SerialChat/Android.mk
+++ b/tests/SerialChat/Android.mk
@@ -22,5 +22,6 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := SerialChat
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 include $(BUILD_PACKAGE)
diff --git a/tests/ServiceCrashTest/Android.mk b/tests/ServiceCrashTest/Android.mk
index f7b3452..d1f6450 100644
--- a/tests/ServiceCrashTest/Android.mk
+++ b/tests/ServiceCrashTest/Android.mk
@@ -7,6 +7,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := ServiceCrashTest
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_CERTIFICATE := platform
 LOCAL_JAVA_LIBRARIES := android.test.base
diff --git a/tests/SharedLibrary/client/Android.mk b/tests/SharedLibrary/client/Android.mk
index a04fb05..9e76c40 100644
--- a/tests/SharedLibrary/client/Android.mk
+++ b/tests/SharedLibrary/client/Android.mk
@@ -7,6 +7,7 @@
 LOCAL_RES_LIBRARIES := SharedLibrary
 
 LOCAL_PACKAGE_NAME := SharedLibraryClient
+LOCAL_SDK_VERSION := current
 
 LOCAL_MODULE_TAGS := tests
 
diff --git a/tests/SharedLibrary/lib/Android.mk b/tests/SharedLibrary/lib/Android.mk
index 78fcb8b..3c1ca87 100644
--- a/tests/SharedLibrary/lib/Android.mk
+++ b/tests/SharedLibrary/lib/Android.mk
@@ -6,6 +6,7 @@
 
 LOCAL_AAPT_FLAGS := --shared-lib
 LOCAL_PACKAGE_NAME := SharedLibrary
+LOCAL_SDK_VERSION := current
 
 LOCAL_EXPORT_PACKAGE_RESOURCES := true
 LOCAL_PRIVILEGED_MODULE := true
diff --git a/tests/ShowWhenLockedApp/Android.mk b/tests/ShowWhenLockedApp/Android.mk
index 0064167..41e0ac4 100644
--- a/tests/ShowWhenLockedApp/Android.mk
+++ b/tests/ShowWhenLockedApp/Android.mk
@@ -4,6 +4,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := ShowWhenLocked
+LOCAL_SDK_VERSION := current
 
 LOCAL_MODULE_TAGS := tests
 
diff --git a/tests/SmokeTestApps/Android.mk b/tests/SmokeTestApps/Android.mk
index 3f5f011..1f564e0 100644
--- a/tests/SmokeTestApps/Android.mk
+++ b/tests/SmokeTestApps/Android.mk
@@ -6,6 +6,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := SmokeTestTriggerApps
+LOCAL_SDK_VERSION := current
 
 include $(BUILD_PACKAGE)
 
diff --git a/tests/SoundTriggerTestApp/Android.mk b/tests/SoundTriggerTestApp/Android.mk
index c327b09..73fb5e8 100644
--- a/tests/SoundTriggerTestApp/Android.mk
+++ b/tests/SoundTriggerTestApp/Android.mk
@@ -4,6 +4,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := SoundTriggerTestApp
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_MODULE_TAGS := optional
 
diff --git a/tests/SoundTriggerTests/Android.mk b/tests/SoundTriggerTests/Android.mk
index 030d5f4..204a74e 100644
--- a/tests/SoundTriggerTests/Android.mk
+++ b/tests/SoundTriggerTests/Android.mk
@@ -31,5 +31,6 @@
 LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
 
 LOCAL_PACKAGE_NAME := SoundTriggerTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 include $(BUILD_PACKAGE)
diff --git a/tests/Split/Android.mk b/tests/Split/Android.mk
index b068bef..4d15b2d 100644
--- a/tests/Split/Android.mk
+++ b/tests/Split/Android.mk
@@ -19,6 +19,7 @@
 
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 LOCAL_PACKAGE_NAME := Split
+LOCAL_SDK_VERSION := current
 
 LOCAL_PACKAGE_SPLITS := mdpi-v4 hdpi-v4 xhdpi-v4 xxhdpi-v4
 
diff --git a/tests/StatusBar/Android.mk b/tests/StatusBar/Android.mk
index 502657f..e845335 100644
--- a/tests/StatusBar/Android.mk
+++ b/tests/StatusBar/Android.mk
@@ -6,6 +6,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := StatusBarTest
+LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_CERTIFICATE := platform
 
 LOCAL_PROGUARD_ENABLED := disabled
diff --git a/tests/SurfaceComposition/src/android/surfacecomposition/SurfaceCompositionTest.java b/tests/SurfaceComposition/src/android/surfacecomposition/SurfaceCompositionTest.java
index 388f91a..261ea2e 100644
--- a/tests/SurfaceComposition/src/android/surfacecomposition/SurfaceCompositionTest.java
+++ b/tests/SurfaceComposition/src/android/surfacecomposition/SurfaceCompositionTest.java
@@ -66,9 +66,6 @@
         super(SurfaceCompositionMeasuringActivity.class);
     }
 
-    private void testRestoreContexts() {
-    }
-
     @SmallTest
     public void testSurfaceCompositionPerformance() {
         Bundle status = new Bundle();
diff --git a/tests/SystemUIDemoModeController/Android.mk b/tests/SystemUIDemoModeController/Android.mk
index 64ea63c..cc6fa8d 100644
--- a/tests/SystemUIDemoModeController/Android.mk
+++ b/tests/SystemUIDemoModeController/Android.mk
@@ -6,5 +6,6 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := DemoModeController
+LOCAL_SDK_VERSION := current
 
 include $(BUILD_PACKAGE)
diff --git a/tests/TouchLatency/Android.mk b/tests/TouchLatency/Android.mk
index 969283d..2334bd8 100644
--- a/tests/TouchLatency/Android.mk
+++ b/tests/TouchLatency/Android.mk
@@ -15,6 +15,7 @@
     --auto-add-overlay
 
 LOCAL_PACKAGE_NAME := TouchLatency
+LOCAL_SDK_VERSION := current
 
 LOCAL_COMPATIBILITY_SUITE := device-tests
 
diff --git a/tests/TransformTest/Android.mk b/tests/TransformTest/Android.mk
index 2d3637d..5340cdd 100644
--- a/tests/TransformTest/Android.mk
+++ b/tests/TransformTest/Android.mk
@@ -4,6 +4,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := TransformTest
+LOCAL_SDK_VERSION := current
 
 LOCAL_MODULE_TAGS := tests
 
diff --git a/tests/TransitionTests/Android.mk b/tests/TransitionTests/Android.mk
index 22fa638..a696156 100644
--- a/tests/TransitionTests/Android.mk
+++ b/tests/TransitionTests/Android.mk
@@ -7,6 +7,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := TransitionTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_STATIC_JAVA_LIBRARIES += android-common
 
diff --git a/tests/TtsTests/Android.mk b/tests/TtsTests/Android.mk
index 2fa1950..116cc0a 100644
--- a/tests/TtsTests/Android.mk
+++ b/tests/TtsTests/Android.mk
@@ -24,5 +24,6 @@
 LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
 
 LOCAL_PACKAGE_NAME := TtsTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 include $(BUILD_PACKAGE)
diff --git a/tests/UsageStatsTest/Android.mk b/tests/UsageStatsTest/Android.mk
index 6b5c999..6735c7c 100644
--- a/tests/UsageStatsTest/Android.mk
+++ b/tests/UsageStatsTest/Android.mk
@@ -11,5 +11,6 @@
 LOCAL_CERTIFICATE := platform
 
 LOCAL_PACKAGE_NAME := UsageStatsTest
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 include $(BUILD_PACKAGE)
diff --git a/tests/UsbHostExternalManagmentTest/AoapTestDevice/Android.mk b/tests/UsbHostExternalManagmentTest/AoapTestDevice/Android.mk
index 3137a73..cd7aaed 100644
--- a/tests/UsbHostExternalManagmentTest/AoapTestDevice/Android.mk
+++ b/tests/UsbHostExternalManagmentTest/AoapTestDevice/Android.mk
@@ -25,6 +25,7 @@
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := AoapTestDeviceApp
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_MODULE_TAGS := tests
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
diff --git a/tests/UsbHostExternalManagmentTest/AoapTestHost/Android.mk b/tests/UsbHostExternalManagmentTest/AoapTestHost/Android.mk
index 354e8c9..bd8a51b 100644
--- a/tests/UsbHostExternalManagmentTest/AoapTestHost/Android.mk
+++ b/tests/UsbHostExternalManagmentTest/AoapTestHost/Android.mk
@@ -25,6 +25,7 @@
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := AoapTestHostApp
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_MODULE_TAGS := tests
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
diff --git a/tests/UsbHostExternalManagmentTest/UsbHostExternalManagmentTestApp/Android.mk b/tests/UsbHostExternalManagmentTest/UsbHostExternalManagmentTestApp/Android.mk
index 2d6d6ea8..fed454e 100644
--- a/tests/UsbHostExternalManagmentTest/UsbHostExternalManagmentTestApp/Android.mk
+++ b/tests/UsbHostExternalManagmentTest/UsbHostExternalManagmentTestApp/Android.mk
@@ -25,6 +25,7 @@
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := UsbHostExternalManagementTestApp
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_PRIVILEGED_MODULE := true
 # TODO remove tests tag
diff --git a/tests/UsbTests/Android.mk b/tests/UsbTests/Android.mk
index a04f32a..4e215cc 100644
--- a/tests/UsbTests/Android.mk
+++ b/tests/UsbTests/Android.mk
@@ -38,6 +38,7 @@
 LOCAL_CERTIFICATE := platform
 
 LOCAL_PACKAGE_NAME := UsbTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_COMPATIBILITY_SUITE := device-tests
 
diff --git a/tests/UsbTests/res/raw/readme.txt b/tests/UsbTests/res/raw/readme.txt
new file mode 100644
index 0000000..62b673c
--- /dev/null
+++ b/tests/UsbTests/res/raw/readme.txt
@@ -0,0 +1,35 @@
+The usbdescriptors_ files contain raw USB descriptors from the Google
+USB-C to 3.5mm adapter, with different loads connected to the 3.5mm
+jack.
+
+usbdescriptors_nothing.bin:
+ - The descriptors when the jack is disconnected.
+
+usbdescriptors_headphones.bin:
+ - The descriptors when the jack is connected to 32-ohm headphones,
+   no microphone.
+   The relevant output terminal is:
+        bDescriptorSubtype      3 (OUTPUT_TERMINAL)
+        bTerminalID            15
+        wTerminalType      0x0302 Headphones
+   
+usbdescriptors_lineout.bin:
+ - The descriptors when the jack is connected to a PC line-in jack.
+   The relevant output terminal is:
+        bDescriptorSubtype      3 (OUTPUT_TERMINAL)
+        bTerminalID            15
+        wTerminalType      0x0603 Line Connector
+
+usbdescriptors_headset.bin:
+ - The descriptors when a headset with microphone and low-impedance
+   headphones are connected.
+   The relevant input terminal is:
+        bDescriptorSubtype      2 (INPUT_TERMINAL)
+        bTerminalID             1
+        wTerminalType      0x0201 Microphone
+   The relevant output terminal is:
+        bDescriptorSubtype      3 (OUTPUT_TERMINAL)
+        bTerminalID            15
+        wTerminalType      0x0302 Headphones
+
+
diff --git a/tests/UsbTests/res/raw/usbdescriptors_headphones.bin b/tests/UsbTests/res/raw/usbdescriptors_headphones.bin
new file mode 100644
index 0000000..e8f2932
--- /dev/null
+++ b/tests/UsbTests/res/raw/usbdescriptors_headphones.bin
Binary files differ
diff --git a/tests/UsbTests/res/raw/usbdescriptors_headset.bin b/tests/UsbTests/res/raw/usbdescriptors_headset.bin
new file mode 100644
index 0000000..30eef2a
--- /dev/null
+++ b/tests/UsbTests/res/raw/usbdescriptors_headset.bin
Binary files differ
diff --git a/tests/UsbTests/res/raw/usbdescriptors_lineout.bin b/tests/UsbTests/res/raw/usbdescriptors_lineout.bin
new file mode 100644
index 0000000..d540d33
--- /dev/null
+++ b/tests/UsbTests/res/raw/usbdescriptors_lineout.bin
Binary files differ
diff --git a/tests/UsbTests/res/raw/usbdescriptors_nothing.bin b/tests/UsbTests/res/raw/usbdescriptors_nothing.bin
new file mode 100644
index 0000000..c318abf
--- /dev/null
+++ b/tests/UsbTests/res/raw/usbdescriptors_nothing.bin
Binary files differ
diff --git a/tests/UsbTests/src/com/android/server/usb/UsbDescriptorParserTests.java b/tests/UsbTests/src/com/android/server/usb/UsbDescriptorParserTests.java
new file mode 100644
index 0000000..f323952
--- /dev/null
+++ b/tests/UsbTests/src/com/android/server/usb/UsbDescriptorParserTests.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.usb;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.server.usb.descriptors.UsbDescriptorParser;
+import com.google.common.io.ByteStreams;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.lang.Exception;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for {@link com.android.server.usb.descriptors.UsbDescriptorParser}
+ */
+@RunWith(AndroidJUnit4.class)
+public class UsbDescriptorParserTests {
+
+    public UsbDescriptorParser loadParser(int resource) {
+        Context c = InstrumentationRegistry.getContext();
+        Resources res = c.getResources();
+        InputStream is = null;
+        try {
+            is = res.openRawResource(resource);
+        } catch (NotFoundException e) {
+            fail("Failed to load resource.");
+        }
+
+        byte[] descriptors = null;
+        try {
+            descriptors = ByteStreams.toByteArray(is);
+        } catch (IOException e) {
+            fail("Failed to convert descriptor strema to bytearray.");
+        }
+
+        // Testing same codepath as UsbHostManager.java:usbDeviceAdded
+        UsbDescriptorParser parser = new UsbDescriptorParser("test-usb-addr");
+        if (!parser.parseDescriptors(descriptors)) {
+            fail("failed to parse descriptors.");
+        }
+        return parser;
+    }
+
+    // A Headset has a microphone and a speaker and is a headset.
+    @Test
+    @SmallTest
+    public void testHeadsetDescriptorParser() {
+        UsbDescriptorParser parser = loadParser(R.raw.usbdescriptors_headset);
+        assertTrue(parser.hasInput());
+        assertTrue(parser.hasOutput());
+        assertTrue(parser.isInputHeadset());
+        assertTrue(parser.isOutputHeadset());
+    }
+
+    // Headphones have no microphones but are considered a headset.
+    @Test
+    @SmallTest
+    public void testHeadphoneDescriptorParser() {
+        UsbDescriptorParser parser = loadParser(R.raw.usbdescriptors_headphones);
+        assertFalse(parser.hasInput());
+        assertTrue(parser.hasOutput());
+        assertFalse(parser.isInputHeadset());
+        assertTrue(parser.isOutputHeadset());
+    }
+
+    // Line out has no microphones and aren't considered a headset.
+    @Test
+    @SmallTest
+    public void testLineoutDescriptorParser() {
+        UsbDescriptorParser parser = loadParser(R.raw.usbdescriptors_lineout);
+        assertFalse(parser.hasInput());
+        assertTrue(parser.hasOutput());
+        assertFalse(parser.isInputHeadset());
+        assertFalse(parser.isOutputHeadset());
+    }
+
+    // An HID-only device shouldn't be considered anything at all.
+    @Test
+    @SmallTest
+    public void testNothingDescriptorParser() {
+        UsbDescriptorParser parser = loadParser(R.raw.usbdescriptors_nothing);
+        assertFalse(parser.hasInput());
+        assertFalse(parser.hasOutput());
+        assertFalse(parser.isInputHeadset());
+        assertFalse(parser.isOutputHeadset());
+    }
+
+}
diff --git a/tests/UsesFeature2Test/Android.mk b/tests/UsesFeature2Test/Android.mk
index cc784d7..4cba4ff 100644
--- a/tests/UsesFeature2Test/Android.mk
+++ b/tests/UsesFeature2Test/Android.mk
@@ -19,6 +19,7 @@
 
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 LOCAL_PACKAGE_NAME := UsesFeature2Test
+LOCAL_SDK_VERSION := current
 
 LOCAL_MODULE_TAGS := tests
 
diff --git a/tests/VectorDrawableTest/Android.mk b/tests/VectorDrawableTest/Android.mk
index dd8a4d4..155b2bc 100644
--- a/tests/VectorDrawableTest/Android.mk
+++ b/tests/VectorDrawableTest/Android.mk
@@ -20,6 +20,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := VectorDrawableTest
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_MODULE_TAGS := tests
 
diff --git a/tests/VoiceEnrollment/Android.mk b/tests/VoiceEnrollment/Android.mk
index 2ab3d02..725e2bd 100644
--- a/tests/VoiceEnrollment/Android.mk
+++ b/tests/VoiceEnrollment/Android.mk
@@ -4,6 +4,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := VoiceEnrollment
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_MODULE_TAGS := optional
 
diff --git a/tests/VoiceInteraction/Android.mk b/tests/VoiceInteraction/Android.mk
index 8decca7..aa48b42 100644
--- a/tests/VoiceInteraction/Android.mk
+++ b/tests/VoiceInteraction/Android.mk
@@ -6,5 +6,6 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := VoiceInteraction
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 include $(BUILD_PACKAGE)
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
index 0401737..db48984 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
@@ -57,7 +57,9 @@
     Button mCompleteButton;
     Button mAbortButton;
 
+    Bundle mAssistData;
     AssistStructure mAssistStructure;
+    AssistContent mAssistContent;
 
     static final int STATE_IDLE = 0;
     static final int STATE_LAUNCHING = 1;
@@ -169,19 +171,15 @@
     public void onHandleAssist(Bundle assistBundle) {
     }
 
-    @Override
-    public void onHandleAssist(Bundle data, AssistStructure structure, AssistContent content) {
-        mAssistStructure = structure;
-        if (mAssistVisualizer != null) {
-            if (mAssistStructure != null) {
-                mAssistVisualizer.setAssistStructure(mAssistStructure);
-            } else {
-                mAssistVisualizer.clearAssistData();
-            }
-        }
+    private void logAssistContentAndData(AssistContent content, Bundle data) {
         if (content != null) {
             Log.i(TAG, "Assist intent: " + content.getIntent());
+            Log.i(TAG, "Assist intent from app: " + content.isAppProvidedIntent());
             Log.i(TAG, "Assist clipdata: " + content.getClipData());
+            Log.i(TAG, "Assist structured data: " + content.getStructuredData());
+            Log.i(TAG, "Assist web uri: " + content.getWebUri());
+            Log.i(TAG, "Assist web uri from app: " + content.isAppProvidedWebUri());
+            Log.i(TAG, "Assist extras: " + content.getExtras());
         }
         if (data != null) {
             Uri referrer = data.getParcelable(Intent.EXTRA_REFERRER);
@@ -192,6 +190,21 @@
     }
 
     @Override
+    public void onHandleAssist(Bundle data, AssistStructure structure, AssistContent content) {
+        mAssistData = data;
+        mAssistStructure = structure;
+        mAssistContent = content;
+        if (mAssistVisualizer != null) {
+            if (mAssistStructure != null) {
+                mAssistVisualizer.setAssistStructure(mAssistStructure);
+            } else {
+                mAssistVisualizer.clearAssistData();
+            }
+        }
+        logAssistContentAndData(content, data);
+    }
+
+    @Override
     public void onHandleAssistSecondary(final Bundle data, final AssistStructure structure,
             final AssistContent content, int index, int count) {
         Log.i(TAG, "Got secondary activity assist data " + index + " of " + count);
@@ -246,6 +259,7 @@
     public void onClick(View v) {
         if (v == mTreeButton) {
             if (mAssistVisualizer != null) {
+                logAssistContentAndData(mAssistContent, mAssistData);
                 mAssistVisualizer.logTree();
             }
         } else if (v == mTextButton) {
diff --git a/tests/WallpaperTest/Android.mk b/tests/WallpaperTest/Android.mk
index b4259cd..4815500 100644
--- a/tests/WallpaperTest/Android.mk
+++ b/tests/WallpaperTest/Android.mk
@@ -8,6 +8,7 @@
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := WallpaperTest
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_PROGUARD_ENABLED := disabled
 
diff --git a/tests/WindowManagerStressTest/Android.mk b/tests/WindowManagerStressTest/Android.mk
index e4cbe93..6f4403f 100644
--- a/tests/WindowManagerStressTest/Android.mk
+++ b/tests/WindowManagerStressTest/Android.mk
@@ -20,6 +20,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := WindowManagerStressTest
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_MODULE_TAGS := tests
 
diff --git a/tests/appwidgets/AppWidgetHostTest/Android.mk b/tests/appwidgets/AppWidgetHostTest/Android.mk
index 4d0c704..c9e6c6b 100644
--- a/tests/appwidgets/AppWidgetHostTest/Android.mk
+++ b/tests/appwidgets/AppWidgetHostTest/Android.mk
@@ -6,6 +6,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := AppWidgetHostTest
+LOCAL_SDK_VERSION := current
 LOCAL_CERTIFICATE := platform
 
 include $(BUILD_PACKAGE)
diff --git a/tests/appwidgets/AppWidgetProviderTest/Android.mk b/tests/appwidgets/AppWidgetProviderTest/Android.mk
index 6084fb9..b26c60b 100644
--- a/tests/appwidgets/AppWidgetProviderTest/Android.mk
+++ b/tests/appwidgets/AppWidgetProviderTest/Android.mk
@@ -6,6 +6,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := AppWidgetProvider
+LOCAL_SDK_VERSION := current
 LOCAL_CERTIFICATE := platform
 
 include $(BUILD_PACKAGE)
diff --git a/tests/backup/Android.mk b/tests/backup/Android.mk
index 202a699..e9618300 100644
--- a/tests/backup/Android.mk
+++ b/tests/backup/Android.mk
@@ -40,6 +40,7 @@
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
 LOCAL_PACKAGE_NAME := BackupTest
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_PROGUARD_ENABLED := disabled
 
diff --git a/tests/net/java/android/net/NetworkCapabilitiesTest.java b/tests/net/java/android/net/NetworkCapabilitiesTest.java
index 2e1519b..4227da6 100644
--- a/tests/net/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/java/android/net/NetworkCapabilitiesTest.java
@@ -22,6 +22,7 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
 import static android.net.NetworkCapabilities.RESTRICTED_CAPABILITIES;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
@@ -252,6 +253,19 @@
         assertEqualsThroughMarshalling(netCap);
     }
 
+    @Test
+    public void testOemPaid() {
+        NetworkCapabilities nc = new NetworkCapabilities();
+        nc.maybeMarkCapabilitiesRestricted();
+        assertFalse(nc.hasCapability(NET_CAPABILITY_OEM_PAID));
+        assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
+
+        nc.addCapability(NET_CAPABILITY_OEM_PAID);
+        nc.maybeMarkCapabilitiesRestricted();
+        assertTrue(nc.hasCapability(NET_CAPABILITY_OEM_PAID));
+        assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
+    }
+
     private void assertEqualsThroughMarshalling(NetworkCapabilities netCap) {
         Parcel p = Parcel.obtain();
         netCap.writeToParcel(p, /* flags */ 0);
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 28f8122..2aea1d7 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -914,8 +914,10 @@
                 mock(INetworkPolicyManager.class),
                 mock(IpConnectivityLog.class));
 
-        mService.systemReady();
+        // Create local CM before sending system ready so that we can answer
+        // getSystemService() correctly.
         mCm = new WrappedConnectivityManager(InstrumentationRegistry.getContext(), mService);
+        mService.systemReady();
         mCm.bindProcessToNetwork(null);
 
         // Ensure that the default setting for Captive Portals is used for most tests
@@ -3412,8 +3414,10 @@
 
     @Test
     public void testNetworkCallbackMaximum() {
-        final int MAX_REQUESTS = 100;
-        final int CALLBACKS = 90;
+        // We can only have 99 callbacks, because MultipathPolicyTracker is
+        // already one of them.
+        final int MAX_REQUESTS = 99;
+        final int CALLBACKS = 89;
         final int INTENTS = 10;
         assertEquals(MAX_REQUESTS, CALLBACKS + INTENTS);
 
diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
index 66e0955..3e1ff6d 100644
--- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
@@ -281,6 +281,7 @@
                         anyInt());
     }
 
+    @Test
     public void testCreateTwoTransformsWithSameSpis() throws Exception {
         IpSecConfig ipSecConfig = new IpSecConfig();
         addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index b1b05e8..49b2643 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -95,6 +95,7 @@
 
 import com.android.internal.net.VpnInfo;
 import com.android.internal.util.test.BroadcastInterceptingContext;
+import com.android.server.LocalServices;
 import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
 import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;
 
@@ -221,6 +222,9 @@
 
     @After
     public void tearDown() throws Exception {
+        // Registered by NetworkStatsService's constructor.
+        LocalServices.removeServiceForTest(NetworkStatsManagerInternal.class);
+
         IoUtils.deleteContents(mStatsDir);
 
         mServiceContext = null;
diff --git a/tests/permission/Android.mk b/tests/permission/Android.mk
index 7f81d9a3..dd2f3ec 100644
--- a/tests/permission/Android.mk
+++ b/tests/permission/Android.mk
@@ -10,6 +10,7 @@
 LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common android.test.base
 LOCAL_STATIC_JAVA_LIBRARIES := junit
 LOCAL_PACKAGE_NAME := FrameworkPermissionTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 include $(BUILD_PACKAGE)
 
diff --git a/tests/privapp-permissions/Android.mk b/tests/privapp-permissions/Android.mk
index 3c80ad8..9795188 100644
--- a/tests/privapp-permissions/Android.mk
+++ b/tests/privapp-permissions/Android.mk
@@ -2,6 +2,7 @@
 
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := PrivAppPermissionTest
+LOCAL_SDK_VERSION := current
 LOCAL_PRIVILEGED_MODULE := true
 LOCAL_MANIFEST_FILE := system/AndroidManifest.xml
 LOCAL_REQUIRED_MODULES := privapp-permissions-test.xml
@@ -16,6 +17,7 @@
 
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := VendorPrivAppPermissionTest
+LOCAL_SDK_VERSION := current
 LOCAL_PRIVILEGED_MODULE := true
 LOCAL_MANIFEST_FILE := vendor/AndroidManifest.xml
 LOCAL_VENDOR_MODULE := true
@@ -31,6 +33,7 @@
 
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := ProductPrivAppPermissionTest
+LOCAL_SDK_VERSION := current
 LOCAL_PRIVILEGED_MODULE := true
 LOCAL_MANIFEST_FILE := product/AndroidManifest.xml
 LOCAL_PRODUCT_MODULE := true
diff --git a/tests/testables/tests/Android.mk b/tests/testables/tests/Android.mk
index f9b3ce4..3b0221c 100644
--- a/tests/testables/tests/Android.mk
+++ b/tests/testables/tests/Android.mk
@@ -19,6 +19,7 @@
 LOCAL_MODULE_TAGS := tests
 
 LOCAL_PACKAGE_NAME := TestablesTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src) \
     $(call all-Iaidl-files-under, src)
diff --git a/tests/utils/DummyIME/Android.mk b/tests/utils/DummyIME/Android.mk
index c8d9f87..0f6c988 100644
--- a/tests/utils/DummyIME/Android.mk
+++ b/tests/utils/DummyIME/Android.mk
@@ -22,5 +22,6 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := DummyIME
+LOCAL_SDK_VERSION := current
 
 include $(BUILD_PACKAGE)
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 7cffeea..1b6f882 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -26,11 +26,14 @@
 #include "ResourceUtils.h"
 #include "ResourceValues.h"
 #include "ValueVisitor.h"
+#include "text/Utf8Iterator.h"
 #include "util/ImmutableMap.h"
 #include "util/Maybe.h"
 #include "util/Util.h"
 #include "xml/XmlPullParser.h"
 
+using ::aapt::ResourceUtils::StringBuilder;
+using ::aapt::text::Utf8Iterator;
 using ::android::StringPiece;
 
 namespace aapt {
@@ -169,114 +172,212 @@
       config_(config),
       options_(options) {}
 
-/**
- * Build a string from XML that converts nested elements into Span objects.
- */
+// Base class Node for representing the various Spans and UntranslatableSections of an XML string.
+// This will be used to traverse and flatten the XML string into a single std::string, with all
+// Span and Untranslatable data maintained in parallel, as indices into the string.
+class Node {
+ public:
+  virtual ~Node() = default;
+
+  // Adds the given child node to this parent node's set of child nodes, moving ownership to the
+  // parent node as well.
+  // Returns a pointer to the child node that was added as a convenience.
+  template <typename T>
+  T* AddChild(std::unique_ptr<T> node) {
+    T* raw_ptr = node.get();
+    children.push_back(std::move(node));
+    return raw_ptr;
+  }
+
+  virtual void Build(StringBuilder* builder) const {
+    for (const auto& child : children) {
+      child->Build(builder);
+    }
+  }
+
+  std::vector<std::unique_ptr<Node>> children;
+};
+
+// A chunk of text in the XML string. This lives between other tags, such as XLIFF tags and Spans.
+class SegmentNode : public Node {
+ public:
+  std::string data;
+
+  void Build(StringBuilder* builder) const override {
+    builder->AppendText(data);
+  }
+};
+
+// A tag that will be encoded into the final flattened string. Tags like <b> or <i>.
+class SpanNode : public Node {
+ public:
+  std::string name;
+
+  void Build(StringBuilder* builder) const override {
+    StringBuilder::SpanHandle span_handle = builder->StartSpan(name);
+    Node::Build(builder);
+    builder->EndSpan(span_handle);
+  }
+};
+
+// An XLIFF 'g' tag, which marks a section of the string as untranslatable.
+class UntranslatableNode : public Node {
+ public:
+  void Build(StringBuilder* builder) const override {
+    StringBuilder::UntranslatableHandle handle = builder->StartUntranslatable();
+    Node::Build(builder);
+    builder->EndUntranslatable(handle);
+  }
+};
+
+// Build a string from XML that converts nested elements into Span objects.
 bool ResourceParser::FlattenXmlSubtree(
     xml::XmlPullParser* parser, std::string* out_raw_string, StyleString* out_style_string,
     std::vector<UntranslatableSection>* out_untranslatable_sections) {
-  // Keeps track of formatting tags (<b>, <i>) and the range of characters for which they apply.
-  // The stack elements refer to the indices in out_style_string->spans.
-  // By first adding to the out_style_string->spans vector, and then using the stack to refer
-  // to this vector, the original order of tags is preserved in cases such as <b><i>hello</b></i>.
-  std::vector<size_t> span_stack;
-
-  // Clear the output variables.
-  out_raw_string->clear();
-  out_style_string->spans.clear();
-  out_untranslatable_sections->clear();
-
-  // The StringBuilder will concatenate the various segments of text which are initially
-  // separated by tags. It also handles unicode escape codes and quotations.
-  util::StringBuilder builder;
+  std::string raw_string;
+  std::string current_text;
 
   // The first occurrence of a <xliff:g> tag. Nested <xliff:g> tags are illegal.
   Maybe<size_t> untranslatable_start_depth;
 
+  Node root;
+  std::vector<Node*> node_stack;
+  node_stack.push_back(&root);
+
+  bool saw_span_node = false;
+  SegmentNode* first_segment = nullptr;
+  SegmentNode* last_segment = nullptr;
+
   size_t depth = 1;
-  while (xml::XmlPullParser::IsGoodEvent(parser->Next())) {
+  while (depth > 0 && xml::XmlPullParser::IsGoodEvent(parser->Next())) {
     const xml::XmlPullParser::Event event = parser->event();
 
-    if (event == xml::XmlPullParser::Event::kStartElement) {
-      if (parser->element_namespace().empty()) {
-        // This is an HTML tag which we encode as a span. Add it to the span stack.
-        std::string span_name = parser->element_name();
-        const auto end_attr_iter = parser->end_attributes();
-        for (auto attr_iter = parser->begin_attributes(); attr_iter != end_attr_iter; ++attr_iter) {
-          span_name += ";";
-          span_name += attr_iter->name;
-          span_name += "=";
-          span_name += attr_iter->value;
+    // First take care of any SegmentNodes that should be created.
+    if (event == xml::XmlPullParser::Event::kStartElement ||
+        event == xml::XmlPullParser::Event::kEndElement) {
+      if (!current_text.empty()) {
+        std::unique_ptr<SegmentNode> segment_node = util::make_unique<SegmentNode>();
+        segment_node->data = std::move(current_text);
+        last_segment = node_stack.back()->AddChild(std::move(segment_node));
+        if (first_segment == nullptr) {
+          first_segment = last_segment;
         }
+        current_text = {};
+      }
+    }
 
-        // Make sure the string is representable in our binary format.
-        if (builder.Utf16Len() > std::numeric_limits<uint32_t>::max()) {
-          diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
-                       << "style string '" << builder.ToString() << "' is too long");
-          return false;
-        }
+    switch (event) {
+      case xml::XmlPullParser::Event::kText: {
+        current_text += parser->text();
+        raw_string += parser->text();
+      } break;
 
-        out_style_string->spans.push_back(
-            Span{std::move(span_name), static_cast<uint32_t>(builder.Utf16Len())});
-        span_stack.push_back(out_style_string->spans.size() - 1);
-      } else if (parser->element_namespace() == sXliffNamespaceUri) {
-        if (parser->element_name() == "g") {
-          if (untranslatable_start_depth) {
-            // We've already encountered an <xliff:g> tag, and nested <xliff:g> tags are illegal.
-            diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
-                         << "illegal nested XLIFF 'g' tag");
-            return false;
-          } else {
-            // Mark the start of an untranslatable section. Use UTF8 indices/lengths.
-            untranslatable_start_depth = depth;
-            const size_t current_idx = builder.ToString().size();
-            out_untranslatable_sections->push_back(UntranslatableSection{current_idx, current_idx});
+      case xml::XmlPullParser::Event::kStartElement: {
+        if (parser->element_namespace().empty()) {
+          // This is an HTML tag which we encode as a span. Add it to the span stack.
+          std::unique_ptr<SpanNode> span_node = util::make_unique<SpanNode>();
+          span_node->name = parser->element_name();
+          const auto end_attr_iter = parser->end_attributes();
+          for (auto attr_iter = parser->begin_attributes(); attr_iter != end_attr_iter;
+               ++attr_iter) {
+            span_node->name += ";";
+            span_node->name += attr_iter->name;
+            span_node->name += "=";
+            span_node->name += attr_iter->value;
           }
+
+          node_stack.push_back(node_stack.back()->AddChild(std::move(span_node)));
+          saw_span_node = true;
+        } else if (parser->element_namespace() == sXliffNamespaceUri) {
+          // This is an XLIFF tag, which is not encoded as a span.
+          if (parser->element_name() == "g") {
+            // Check that an 'untranslatable' tag is not already being processed. Nested
+            // <xliff:g> tags are illegal.
+            if (untranslatable_start_depth) {
+              diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
+                           << "illegal nested XLIFF 'g' tag");
+              return false;
+            } else {
+              // Mark the beginning of an 'untranslatable' section.
+              untranslatable_start_depth = depth;
+              node_stack.push_back(
+                  node_stack.back()->AddChild(util::make_unique<UntranslatableNode>()));
+            }
+          } else {
+            // Ignore unknown XLIFF tags, but don't warn.
+            node_stack.push_back(node_stack.back()->AddChild(util::make_unique<Node>()));
+          }
+        } else {
+          // Besides XLIFF, any other namespaced tag is unsupported and ignored.
+          diag_->Warn(DiagMessage(source_.WithLine(parser->line_number()))
+                      << "ignoring element '" << parser->element_name()
+                      << "' with unknown namespace '" << parser->element_namespace() << "'");
+          node_stack.push_back(node_stack.back()->AddChild(util::make_unique<Node>()));
         }
-        // Ignore other xliff tags, they get handled by other tools.
 
-      } else {
-        // Besides XLIFF, any other namespaced tag is unsupported and ignored.
-        diag_->Warn(DiagMessage(source_.WithLine(parser->line_number()))
-                    << "ignoring element '" << parser->element_name()
-                    << "' with unknown namespace '" << parser->element_namespace() << "'");
-      }
+        // Enter one level inside the element.
+        depth++;
+      } break;
 
-      // Enter one level inside the element.
-      depth++;
-    } else if (event == xml::XmlPullParser::Event::kText) {
-      // Record both the raw text and append to the builder to deal with escape sequences
-      // and quotations.
-      out_raw_string->append(parser->text());
-      builder.Append(parser->text());
-    } else if (event == xml::XmlPullParser::Event::kEndElement) {
-      // Return one level from within the element.
-      depth--;
-      if (depth == 0) {
+      case xml::XmlPullParser::Event::kEndElement: {
+        // Return one level from within the element.
+        depth--;
+        if (depth == 0) {
+          break;
+        }
+
+        node_stack.pop_back();
+        if (untranslatable_start_depth == make_value(depth)) {
+          // This is the end of an untranslatable section.
+          untranslatable_start_depth = {};
+        }
+      } break;
+
+      default:
+        // ignore.
         break;
-      }
-
-      if (parser->element_namespace().empty()) {
-        // This is an HTML tag which we encode as a span. Update the span
-        // stack and pop the top entry.
-        Span& top_span = out_style_string->spans[span_stack.back()];
-        top_span.last_char = builder.Utf16Len() - 1;
-        span_stack.pop_back();
-      } else if (untranslatable_start_depth == make_value(depth)) {
-        // This is the end of an untranslatable section. Use UTF8 indices/lengths.
-        UntranslatableSection& untranslatable_section = out_untranslatable_sections->back();
-        untranslatable_section.end = builder.ToString().size();
-        untranslatable_start_depth = {};
-      }
-    } else if (event == xml::XmlPullParser::Event::kComment) {
-      // Ignore.
-    } else {
-      LOG(FATAL) << "unhandled XML event";
     }
   }
 
-  CHECK(span_stack.empty()) << "spans haven't been fully processed";
-  out_style_string->str = builder.ToString();
+  // Sanity check to make sure we processed all the nodes.
+  CHECK(node_stack.size() == 1u);
+  CHECK(node_stack.back() == &root);
+
+  if (!saw_span_node) {
+    // If there were no spans, we must treat this string a little differently (according to AAPT).
+    // Find and strip the leading whitespace from the first segment, and the trailing whitespace
+    // from the last segment.
+    if (first_segment != nullptr) {
+      // Trim leading whitespace.
+      StringPiece trimmed = util::TrimLeadingWhitespace(first_segment->data);
+      if (trimmed.size() != first_segment->data.size()) {
+        first_segment->data = trimmed.to_string();
+      }
+    }
+
+    if (last_segment != nullptr) {
+      // Trim trailing whitespace.
+      StringPiece trimmed = util::TrimTrailingWhitespace(last_segment->data);
+      if (trimmed.size() != last_segment->data.size()) {
+        last_segment->data = trimmed.to_string();
+      }
+    }
+  }
+
+  // Have the XML structure flatten itself into the StringBuilder. The StringBuilder will take
+  // care of recording the correctly adjusted Spans and UntranslatableSections.
+  StringBuilder builder;
+  root.Build(&builder);
+  if (!builder) {
+    diag_->Error(DiagMessage(source_.WithLine(parser->line_number())) << builder.GetError());
+    return false;
+  }
+
+  ResourceUtils::FlattenedXmlString flattened_string = builder.GetFlattenedString();
+  *out_raw_string = std::move(raw_string);
+  *out_untranslatable_sections = std::move(flattened_string.untranslatable_sections);
+  out_style_string->str = std::move(flattened_string.text);
+  out_style_string->spans = std::move(flattened_string.spans);
   return true;
 }
 
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index 618c8ed..c98c0b9 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -95,6 +95,16 @@
   ASSERT_THAT(str, NotNull());
   EXPECT_THAT(*str, StrValueEq("  hey there "));
   EXPECT_THAT(str->untranslatable_sections, IsEmpty());
+
+  ASSERT_TRUE(TestParse(R"(<string name="bar">Isn\'t it cool?</string>)"));
+  str = test::GetValue<String>(&table_, "string/bar");
+  ASSERT_THAT(str, NotNull());
+  EXPECT_THAT(*str, StrValueEq("Isn't it cool?"));
+
+  ASSERT_TRUE(TestParse(R"(<string name="baz">"Isn't it cool?"</string>)"));
+  str = test::GetValue<String>(&table_, "string/baz");
+  ASSERT_THAT(str, NotNull());
+  EXPECT_THAT(*str, StrValueEq("Isn't it cool?"));
 }
 
 TEST_F(ResourceParserTest, ParseEscapedString) {
@@ -126,16 +136,16 @@
   StyledString* str = test::GetValue<StyledString>(&table_, "string/foo");
   ASSERT_THAT(str, NotNull());
 
-  EXPECT_THAT(str->value->value, Eq("This is my aunt\u2019s fickle string"));
+  EXPECT_THAT(str->value->value, StrEq("This is my aunt\u2019s fickle string"));
   EXPECT_THAT(str->value->spans, SizeIs(2));
   EXPECT_THAT(str->untranslatable_sections, IsEmpty());
 
-  EXPECT_THAT(*str->value->spans[0].name, Eq("b"));
-  EXPECT_THAT(str->value->spans[0].first_char, Eq(17u));
+  EXPECT_THAT(*str->value->spans[0].name, StrEq("b"));
+  EXPECT_THAT(str->value->spans[0].first_char, Eq(18u));
   EXPECT_THAT(str->value->spans[0].last_char, Eq(30u));
 
-  EXPECT_THAT(*str->value->spans[1].name, Eq("small"));
-  EXPECT_THAT(str->value->spans[1].first_char, Eq(24u));
+  EXPECT_THAT(*str->value->spans[1].name, StrEq("small"));
+  EXPECT_THAT(str->value->spans[1].first_char, Eq(25u));
   EXPECT_THAT(str->value->spans[1].last_char, Eq(30u));
 }
 
@@ -144,7 +154,7 @@
 
   String* str = test::GetValue<String>(&table_, "string/foo");
   ASSERT_THAT(str, NotNull());
-  EXPECT_THAT(*str->value, Eq("This is what I think"));
+  EXPECT_THAT(*str->value, StrEq("This is what I think"));
   EXPECT_THAT(str->untranslatable_sections, IsEmpty());
 
   ASSERT_TRUE(TestParse(R"(<string name="foo2">"  This is what  I think  "</string>)"));
@@ -154,6 +164,25 @@
   EXPECT_THAT(*str, StrValueEq("  This is what  I think  "));
 }
 
+TEST_F(ResourceParserTest, ParseStyledStringWithWhitespace) {
+  std::string input = R"(<string name="foo">  <b> My <i> favorite</i> string </b>  </string>)";
+  ASSERT_TRUE(TestParse(input));
+
+  StyledString* str = test::GetValue<StyledString>(&table_, "string/foo");
+  ASSERT_THAT(str, NotNull());
+  EXPECT_THAT(str->value->value, StrEq("  My  favorite string  "));
+  EXPECT_THAT(str->untranslatable_sections, IsEmpty());
+
+  ASSERT_THAT(str->value->spans, SizeIs(2u));
+  EXPECT_THAT(*str->value->spans[0].name, StrEq("b"));
+  EXPECT_THAT(str->value->spans[0].first_char, Eq(1u));
+  EXPECT_THAT(str->value->spans[0].last_char, Eq(21u));
+
+  EXPECT_THAT(*str->value->spans[1].name, StrEq("i"));
+  EXPECT_THAT(str->value->spans[1].first_char, Eq(5u));
+  EXPECT_THAT(str->value->spans[1].last_char, Eq(13u));
+}
+
 TEST_F(ResourceParserTest, IgnoreXliffTagsOtherThanG) {
   std::string input = R"(
       <string name="foo" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
@@ -182,12 +211,9 @@
   String* str = test::GetValue<String>(&table_, "string/foo");
   ASSERT_THAT(str, NotNull());
   EXPECT_THAT(*str, StrValueEq("There are %1$d apples"));
-  ASSERT_THAT(str->untranslatable_sections, SizeIs(1));
 
-  // We expect indices and lengths that span to include the whitespace
-  // before %1$d. This is due to how the StringBuilder withholds whitespace unless
-  // needed (to deal with line breaks, etc.).
-  EXPECT_THAT(str->untranslatable_sections[0].start, Eq(9u));
+  ASSERT_THAT(str->untranslatable_sections, SizeIs(1));
+  EXPECT_THAT(str->untranslatable_sections[0].start, Eq(10u));
   EXPECT_THAT(str->untranslatable_sections[0].end, Eq(14u));
 }
 
@@ -199,14 +225,16 @@
 
   StyledString* str = test::GetValue<StyledString>(&table_, "string/foo");
   ASSERT_THAT(str, NotNull());
-  EXPECT_THAT(str->value->value, Eq("There are %1$d apples"));
-  ASSERT_THAT(str->untranslatable_sections, SizeIs(1));
+  EXPECT_THAT(str->value->value, Eq(" There are %1$d apples"));
 
-  // We expect indices and lengths that span to include the whitespace
-  // before %1$d. This is due to how the StringBuilder withholds whitespace unless
-  // needed (to deal with line breaks, etc.).
-  EXPECT_THAT(str->untranslatable_sections[0].start, Eq(9u));
-  EXPECT_THAT(str->untranslatable_sections[0].end, Eq(14u));
+  ASSERT_THAT(str->untranslatable_sections, SizeIs(1));
+  EXPECT_THAT(str->untranslatable_sections[0].start, Eq(11u));
+  EXPECT_THAT(str->untranslatable_sections[0].end, Eq(15u));
+
+  ASSERT_THAT(str->value->spans, SizeIs(1u));
+  EXPECT_THAT(*str->value->spans[0].name, StrEq("b"));
+  EXPECT_THAT(str->value->spans[0].first_char, Eq(11u));
+  EXPECT_THAT(str->value->spans[0].last_char, Eq(14u));
 }
 
 TEST_F(ResourceParserTest, ParseNull) {
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index 628466d..8fc3d65 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -18,17 +18,23 @@
 
 #include <sstream>
 
+#include "android-base/stringprintf.h"
 #include "androidfw/ResourceTypes.h"
 #include "androidfw/ResourceUtils.h"
 
 #include "NameMangler.h"
 #include "SdkConstants.h"
 #include "format/binary/ResourceTypeExtensions.h"
+#include "text/Unicode.h"
+#include "text/Utf8Iterator.h"
 #include "util/Files.h"
 #include "util/Util.h"
 
+using ::aapt::text::IsWhitespace;
+using ::aapt::text::Utf8Iterator;
 using ::android::StringPiece;
 using ::android::StringPiece16;
+using ::android::base::StringPrintf;
 
 namespace aapt {
 namespace ResourceUtils {
@@ -750,5 +756,195 @@
   return util::make_unique<BinaryPrimitive>(res_value);
 }
 
+// Converts the codepoint to UTF-8 and appends it to the string.
+static bool AppendCodepointToUtf8String(char32_t codepoint, std::string* output) {
+  ssize_t len = utf32_to_utf8_length(&codepoint, 1);
+  if (len < 0) {
+    return false;
+  }
+
+  const size_t start_append_pos = output->size();
+
+  // Make room for the next character.
+  output->resize(output->size() + len);
+
+  char* dst = &*(output->begin() + start_append_pos);
+  utf32_to_utf8(&codepoint, 1, dst, len + 1);
+  return true;
+}
+
+// Reads up to 4 UTF-8 characters that represent a Unicode escape sequence, and appends the
+// Unicode codepoint represented by the escape sequence to the string.
+static bool AppendUnicodeEscapeSequence(Utf8Iterator* iter, std::string* output) {
+  char32_t code = 0;
+  for (size_t i = 0; i < 4 && iter->HasNext(); i++) {
+    char32_t codepoint = iter->Next();
+    char32_t a;
+    if (codepoint >= U'0' && codepoint <= U'9') {
+      a = codepoint - U'0';
+    } else if (codepoint >= U'a' && codepoint <= U'f') {
+      a = codepoint - U'a' + 10;
+    } else if (codepoint >= U'A' && codepoint <= U'F') {
+      a = codepoint - U'A' + 10;
+    } else {
+      return {};
+    }
+    code = (code << 4) | a;
+  }
+  return AppendCodepointToUtf8String(code, output);
+}
+
+StringBuilder::StringBuilder(bool preserve_spaces)
+    : preserve_spaces_(preserve_spaces), quote_(preserve_spaces) {
+}
+
+StringBuilder& StringBuilder::AppendText(const std::string& text) {
+  if (!error_.empty()) {
+    return *this;
+  }
+
+  const size_t previous_len = xml_string_.text.size();
+  Utf8Iterator iter(text);
+  while (iter.HasNext()) {
+    char32_t codepoint = iter.Next();
+    if (!quote_ && text::IsWhitespace(codepoint)) {
+      if (!last_codepoint_was_space_) {
+        // Emit a space if it's the first.
+        xml_string_.text += ' ';
+        last_codepoint_was_space_ = true;
+      }
+
+      // Keep eating spaces.
+      continue;
+    }
+
+    // This is not a space.
+    last_codepoint_was_space_ = false;
+
+    if (codepoint == U'\\') {
+      if (iter.HasNext()) {
+        codepoint = iter.Next();
+        switch (codepoint) {
+          case U't':
+            xml_string_.text += '\t';
+            break;
+
+          case U'n':
+            xml_string_.text += '\n';
+            break;
+
+          case U'#':
+          case U'@':
+          case U'?':
+          case U'"':
+          case U'\'':
+          case U'\\':
+            xml_string_.text += static_cast<char>(codepoint);
+            break;
+
+          case U'u':
+            if (!AppendUnicodeEscapeSequence(&iter, &xml_string_.text)) {
+              error_ =
+                  StringPrintf("invalid unicode escape sequence in string\n\"%s\"", text.c_str());
+              return *this;
+            }
+            break;
+
+          default:
+            // Ignore the escape character and just include the codepoint.
+            AppendCodepointToUtf8String(codepoint, &xml_string_.text);
+            break;
+        }
+      }
+    } else if (!preserve_spaces_ && codepoint == U'"') {
+      // Only toggle the quote state when we are not preserving spaces.
+      quote_ = !quote_;
+
+    } else if (!quote_ && codepoint == U'\'') {
+      // This should be escaped.
+      error_ = StringPrintf("unescaped apostrophe in string\n\"%s\"", text.c_str());
+      return *this;
+
+    } else {
+      AppendCodepointToUtf8String(codepoint, &xml_string_.text);
+    }
+  }
+
+  // Accumulate the added string's UTF-16 length.
+  const uint8_t* utf8_data = reinterpret_cast<const uint8_t*>(xml_string_.text.c_str());
+  const size_t utf8_length = xml_string_.text.size();
+  ssize_t len = utf8_to_utf16_length(utf8_data + previous_len, utf8_length - previous_len);
+  if (len < 0) {
+    error_ = StringPrintf("invalid unicode code point in string\n\"%s\"", utf8_data + previous_len);
+    return *this;
+  }
+
+  utf16_len_ += static_cast<uint32_t>(len);
+  return *this;
+}
+
+StringBuilder::SpanHandle StringBuilder::StartSpan(const std::string& name) {
+  if (!error_.empty()) {
+    return 0u;
+  }
+
+  // When we start a span, all state associated with whitespace truncation and quotation is ended.
+  ResetTextState();
+  Span span;
+  span.name = name;
+  span.first_char = span.last_char = utf16_len_;
+  xml_string_.spans.push_back(std::move(span));
+  return xml_string_.spans.size() - 1;
+}
+
+void StringBuilder::EndSpan(SpanHandle handle) {
+  if (!error_.empty()) {
+    return;
+  }
+
+  // When we end a span, all state associated with whitespace truncation and quotation is ended.
+  ResetTextState();
+  xml_string_.spans[handle].last_char = utf16_len_ - 1u;
+}
+
+StringBuilder::UntranslatableHandle StringBuilder::StartUntranslatable() {
+  if (!error_.empty()) {
+    return 0u;
+  }
+
+  UntranslatableSection section;
+  section.start = section.end = xml_string_.text.size();
+  xml_string_.untranslatable_sections.push_back(section);
+  return xml_string_.untranslatable_sections.size() - 1;
+}
+
+void StringBuilder::EndUntranslatable(UntranslatableHandle handle) {
+  if (!error_.empty()) {
+    return;
+  }
+  xml_string_.untranslatable_sections[handle].end = xml_string_.text.size();
+}
+
+FlattenedXmlString StringBuilder::GetFlattenedString() const {
+  return xml_string_;
+}
+
+std::string StringBuilder::to_string() const {
+  return xml_string_.text;
+}
+
+StringBuilder::operator bool() const {
+  return error_.empty();
+}
+
+std::string StringBuilder::GetError() const {
+  return error_;
+}
+
+void StringBuilder::ResetTextState() {
+  quote_ = preserve_spaces_;
+  last_codepoint_was_space_ = false;
+}
+
 }  // namespace ResourceUtils
 }  // namespace aapt
diff --git a/tools/aapt2/ResourceUtils.h b/tools/aapt2/ResourceUtils.h
index f83d49e..7af2fe0 100644
--- a/tools/aapt2/ResourceUtils.h
+++ b/tools/aapt2/ResourceUtils.h
@@ -224,6 +224,95 @@
                                           const android::Res_value& res_value,
                                           StringPool* dst_pool);
 
+// A string flattened from an XML hierarchy, which maintains tags and untranslatable sections
+// in parallel data structures.
+struct FlattenedXmlString {
+  std::string text;
+  std::vector<UntranslatableSection> untranslatable_sections;
+  std::vector<Span> spans;
+};
+
+// Flattens an XML hierarchy into a FlattenedXmlString, formatting the text, escaping characters,
+// and removing whitespace, all while keeping the untranslatable sections and spans in sync with the
+// transformations.
+//
+// Specifically, the StringBuilder will handle escaped characters like \t, \n, \\, \', etc.
+// Single quotes *must* be escaped, unless within a pair of double-quotes.
+// Pairs of double-quotes disable whitespace stripping of the enclosed text.
+// Unicode escape codes (\u0049) are interpreted and the represented Unicode character is inserted.
+//
+// A NOTE ON WHITESPACE:
+//
+// When preserve_spaces is false, and when text is not enclosed within double-quotes,
+// StringBuilder replaces a series of whitespace with a single space character. This happens at the
+// start and end of the string as well, so leading and trailing whitespace is possible.
+//
+// When a Span is started or stopped, the whitespace counter is reset, meaning if whitespace
+// is encountered directly after the span, it will be emitted. This leads to situations like the
+// following: "This <b> is </b> spaced" -> "This  is  spaced". Without spans, this would be properly
+// compressed: "This  is  spaced" -> "This is spaced".
+//
+// Untranslatable sections do not have the same problem:
+// "This <xliff:g> is </xliff:g> not spaced" -> "This is not spaced".
+//
+// NOTE: This is all the way it is because AAPT1 did it this way. Maintaining backwards
+// compatibility is important.
+//
+class StringBuilder {
+ public:
+  using SpanHandle = size_t;
+  using UntranslatableHandle = size_t;
+
+  // Creates a StringBuilder. If preserve_spaces is true, whitespace removal is not performed, and
+  // single quotations can be used without escaping them.
+  explicit StringBuilder(bool preserve_spaces = false);
+
+  // Appends a chunk of text.
+  StringBuilder& AppendText(const std::string& text);
+
+  // Starts a Span (tag) with the given name. The name is expected to be of the form:
+  //  "tag_name;attr1=value;attr2=value;"
+  // Which is how Spans are encoded in the ResStringPool.
+  // To end the span, pass back the SpanHandle received from this method to the EndSpan() method.
+  SpanHandle StartSpan(const std::string& name);
+
+  // Ends a Span (tag). Pass in the matching SpanHandle previously obtained from StartSpan().
+  void EndSpan(SpanHandle handle);
+
+  // Starts an Untranslatable section.
+  // To end the section, pass back the UntranslatableHandle received from this method to
+  // the EndUntranslatable() method.
+  UntranslatableHandle StartUntranslatable();
+
+  // Ends an Untranslatable section. Pass in the matching UntranslatableHandle previously obtained
+  // from StartUntranslatable().
+  void EndUntranslatable(UntranslatableHandle handle);
+
+  // Returns the flattened XML string, with all spans and untranslatable sections encoded as
+  // parallel data structures.
+  FlattenedXmlString GetFlattenedString() const;
+
+  // Returns just the flattened XML text, with no spans or untranslatable sections.
+  std::string to_string() const;
+
+  // Returns true if there was no error.
+  explicit operator bool() const;
+
+  std::string GetError() const;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(StringBuilder);
+
+  void ResetTextState();
+
+  std::string error_;
+  FlattenedXmlString xml_string_;
+  uint32_t utf16_len_ = 0u;
+  bool preserve_spaces_;
+  bool quote_;
+  bool last_codepoint_was_space_ = false;
+};
+
 }  // namespace ResourceUtils
 }  // namespace aapt
 
diff --git a/tools/aapt2/ResourceUtils_test.cpp b/tools/aapt2/ResourceUtils_test.cpp
index cb786d3..11f3fa3 100644
--- a/tools/aapt2/ResourceUtils_test.cpp
+++ b/tools/aapt2/ResourceUtils_test.cpp
@@ -212,4 +212,48 @@
               Pointee(ValueEq(BinaryPrimitive(Res_value::TYPE_FLOAT, expected_float_flattened))));
 }
 
+TEST(ResourceUtilsTest, StringBuilderWhitespaceRemoval) {
+  EXPECT_THAT(ResourceUtils::StringBuilder()
+                  .AppendText("    hey guys ")
+                  .AppendText(" this is so cool ")
+                  .to_string(),
+              Eq(" hey guys this is so cool "));
+  EXPECT_THAT(ResourceUtils::StringBuilder()
+                  .AppendText(" \" wow,  so many \t ")
+                  .AppendText("spaces. \"what? ")
+                  .to_string(),
+              Eq("  wow,  so many \t spaces. what? "));
+  EXPECT_THAT(ResourceUtils::StringBuilder()
+                  .AppendText("  where \t ")
+                  .AppendText(" \nis the pie?")
+                  .to_string(),
+              Eq(" where is the pie?"));
+}
+
+TEST(ResourceUtilsTest, StringBuilderEscaping) {
+  EXPECT_THAT(ResourceUtils::StringBuilder()
+                  .AppendText("hey guys\\n ")
+                  .AppendText(" this \\t is so\\\\ cool")
+                  .to_string(),
+              Eq("hey guys\n this \t is so\\ cool"));
+  EXPECT_THAT(ResourceUtils::StringBuilder().AppendText("\\@\\?\\#\\\\\\'").to_string(),
+              Eq("@?#\\\'"));
+}
+
+TEST(ResourceUtilsTest, StringBuilderMisplacedQuote) {
+  ResourceUtils::StringBuilder builder;
+  EXPECT_FALSE(builder.AppendText("they're coming!"));
+}
+
+TEST(ResourceUtilsTest, StringBuilderUnicodeCodes) {
+  EXPECT_THAT(ResourceUtils::StringBuilder().AppendText("\\u00AF\\u0AF0 woah").to_string(),
+              Eq("\u00AF\u0AF0 woah"));
+  EXPECT_FALSE(ResourceUtils::StringBuilder().AppendText("\\u00 yo"));
+}
+
+TEST(ResourceUtilsTest, StringBuilderPreserveSpaces) {
+  EXPECT_THAT(ResourceUtils::StringBuilder(true /*preserve_spaces*/).AppendText("\"").to_string(),
+              Eq("\""));
+}
+
 }  // namespace aapt
diff --git a/tools/aapt2/format/binary/XmlFlattener.cpp b/tools/aapt2/format/binary/XmlFlattener.cpp
index 345cc95..781b9fe 100644
--- a/tools/aapt2/format/binary/XmlFlattener.cpp
+++ b/tools/aapt2/format/binary/XmlFlattener.cpp
@@ -25,13 +25,17 @@
 #include "androidfw/ResourceTypes.h"
 #include "utils/misc.h"
 
+#include "ResourceUtils.h"
 #include "SdkConstants.h"
+#include "ValueVisitor.h"
 #include "format/binary/ChunkWriter.h"
 #include "format/binary/ResourceTypeExtensions.h"
 #include "xml/XmlDom.h"
 
 using namespace android;
 
+using ::aapt::ResourceUtils::StringBuilder;
+
 namespace aapt {
 
 namespace {
@@ -88,9 +92,9 @@
     ResXMLTree_cdataExt* flat_text = writer.NextBlock<ResXMLTree_cdataExt>();
 
     // Process plain strings to make sure they get properly escaped.
-    util::StringBuilder builder;
-    builder.Append(node->text);
-    AddString(builder.ToString(), kLowPriority, &flat_text->data);
+    StringBuilder builder;
+    builder.AppendText(node->text);
+    AddString(builder.to_string(), kLowPriority, &flat_text->data);
 
     writer.Finish();
   }
@@ -153,6 +157,9 @@
  private:
   DISALLOW_COPY_AND_ASSIGN(XmlFlattenerVisitor);
 
+  // We are adding strings to a StringPool whose strings will be sorted and merged with other
+  // string pools. That means we can't encode the ID of a string directly. Instead, we defer the
+  // writing of the ID here, until after the StringPool is merged and sorted.
   void AddString(const StringPiece& str, uint32_t priority, android::ResStringPool_ref* dest,
                  bool treat_empty_string_as_null = false) {
     if (str.empty() && treat_empty_string_as_null) {
@@ -164,6 +171,9 @@
     }
   }
 
+  // We are adding strings to a StringPool whose strings will be sorted and merged with other
+  // string pools. That means we can't encode the ID of a string directly. Instead, we defer the
+  // writing of the ID here, until after the StringPool is merged and sorted.
   void AddString(const StringPool::Ref& ref, android::ResStringPool_ref* dest) {
     string_refs.push_back(StringFlattenDest{ref, dest});
   }
@@ -248,30 +258,39 @@
         AddString(name_ref, &flat_attr->name);
       }
 
-      // Process plain strings to make sure they get properly escaped.
-      StringPiece raw_value = xml_attr->value;
-
-      util::StringBuilder str_builder(true /*preserve_spaces*/);
-      str_builder.Append(xml_attr->value);
-
-      if (!options_.keep_raw_values) {
-        raw_value = str_builder.ToString();
-      }
-
-      if (options_.keep_raw_values || !xml_attr->compiled_value) {
-        // Keep raw values if the value is not compiled or
-        // if we're building a static library (need symbols).
-        AddString(raw_value, kLowPriority, &flat_attr->rawValue);
-      }
-
-      if (xml_attr->compiled_value) {
-        CHECK(xml_attr->compiled_value->Flatten(&flat_attr->typedValue));
+      std::string processed_str;
+      Maybe<StringPiece> compiled_text;
+      if (xml_attr->compiled_value != nullptr) {
+        // Make sure we're not flattening a String. A String can be referencing a string from
+        // a different StringPool than we're using here to build the binary XML.
+        String* string_value = ValueCast<String>(xml_attr->compiled_value.get());
+        if (string_value != nullptr) {
+          // Mark the String's text as needing to be serialized.
+          compiled_text = StringPiece(*string_value->value);
+        } else {
+          // Serialize this compiled value safely.
+          CHECK(xml_attr->compiled_value->Flatten(&flat_attr->typedValue));
+        }
       } else {
-        // Flatten as a regular string type.
-        flat_attr->typedValue.dataType = android::Res_value::TYPE_STRING;
+        // There is no compiled value, so treat the raw string as compiled, once it is processed to
+        // make sure escape sequences are properly interpreted.
+        processed_str =
+            StringBuilder(true /*preserve_spaces*/).AppendText(xml_attr->value).to_string();
+        compiled_text = StringPiece(processed_str);
+      }
 
-        AddString(str_builder.ToString(), kLowPriority,
-                  (ResStringPool_ref*)&flat_attr->typedValue.data);
+      if (compiled_text) {
+        // Write out the compiled text and raw_text.
+        flat_attr->typedValue.dataType = android::Res_value::TYPE_STRING;
+        AddString(compiled_text.value(), kLowPriority,
+                  reinterpret_cast<ResStringPool_ref*>(&flat_attr->typedValue.data));
+        if (options_.keep_raw_values) {
+          AddString(xml_attr->value, kLowPriority, &flat_attr->rawValue);
+        } else {
+          AddString(compiled_text.value(), kLowPriority, &flat_attr->rawValue);
+        }
+      } else if (options_.keep_raw_values && !xml_attr->value.empty()) {
+        AddString(xml_attr->value, kLowPriority, &flat_attr->rawValue);
       }
 
       flat_attr->typedValue.size = util::HostToDevice16(sizeof(flat_attr->typedValue));
diff --git a/tools/aapt2/format/binary/XmlFlattener_test.cpp b/tools/aapt2/format/binary/XmlFlattener_test.cpp
index 0450f6c..08243fe 100644
--- a/tools/aapt2/format/binary/XmlFlattener_test.cpp
+++ b/tools/aapt2/format/binary/XmlFlattener_test.cpp
@@ -286,4 +286,92 @@
   EXPECT_THAT(tree.getText(&len), StrEq(u"\\d{5}"));
 }
 
+TEST_F(XmlFlattenerTest, FlattenRawValueOnlyMakesCompiledValueToo) {
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(<element foo="bar" />)");
+
+  // Raw values are kept when encoding an attribute with no compiled value, regardless of option.
+  XmlFlattenerOptions options;
+  options.keep_raw_values = false;
+
+  android::ResXMLTree tree;
+  ASSERT_TRUE(Flatten(doc.get(), &tree, options));
+
+  while (tree.next() != android::ResXMLTree::START_TAG) {
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT));
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT));
+  }
+
+  ASSERT_THAT(tree.getAttributeCount(), Eq(1u));
+  EXPECT_THAT(tree.getAttributeValueStringID(0), Ge(0));
+  EXPECT_THAT(tree.getAttributeDataType(0), Eq(android::Res_value::TYPE_STRING));
+  EXPECT_THAT(tree.getAttributeValueStringID(0), Eq(tree.getAttributeData(0)));
+}
+
+TEST_F(XmlFlattenerTest, FlattenCompiledStringValuePreservesRawValue) {
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(<element foo="bar" />)");
+  doc->root->attributes[0].compiled_value =
+      util::make_unique<String>(doc->string_pool.MakeRef("bar"));
+
+  // Raw values are kept when encoding a string anyways.
+  XmlFlattenerOptions options;
+  options.keep_raw_values = false;
+
+  android::ResXMLTree tree;
+  ASSERT_TRUE(Flatten(doc.get(), &tree, options));
+
+  while (tree.next() != android::ResXMLTree::START_TAG) {
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT));
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT));
+  }
+
+  ASSERT_THAT(tree.getAttributeCount(), Eq(1u));
+  EXPECT_THAT(tree.getAttributeValueStringID(0), Ge(0));
+  EXPECT_THAT(tree.getAttributeDataType(0), Eq(android::Res_value::TYPE_STRING));
+  EXPECT_THAT(tree.getAttributeValueStringID(0), Eq(tree.getAttributeData(0)));
+}
+
+TEST_F(XmlFlattenerTest, FlattenCompiledValueExcludesRawValueWithKeepRawOptionFalse) {
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(<element foo="true" />)");
+  doc->root->attributes[0].compiled_value = ResourceUtils::MakeBool(true);
+
+  XmlFlattenerOptions options;
+  options.keep_raw_values = false;
+
+  android::ResXMLTree tree;
+  ASSERT_TRUE(Flatten(doc.get(), &tree, options));
+
+  while (tree.next() != android::ResXMLTree::START_TAG) {
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT));
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT));
+  }
+
+  ASSERT_THAT(tree.getAttributeCount(), Eq(1u));
+  EXPECT_THAT(tree.getAttributeValueStringID(0), Eq(-1));
+  EXPECT_THAT(tree.getAttributeDataType(0), Eq(android::Res_value::TYPE_INT_BOOLEAN));
+}
+
+TEST_F(XmlFlattenerTest, FlattenCompiledValueExcludesRawValueWithKeepRawOptionTrue) {
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(<element foo="true" />)");
+  doc->root->attributes[0].compiled_value = ResourceUtils::MakeBool(true);
+
+  XmlFlattenerOptions options;
+  options.keep_raw_values = true;
+
+  android::ResXMLTree tree;
+  ASSERT_TRUE(Flatten(doc.get(), &tree, options));
+
+  while (tree.next() != android::ResXMLTree::START_TAG) {
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::BAD_DOCUMENT));
+    ASSERT_THAT(tree.getEventType(), Ne(android::ResXMLTree::END_DOCUMENT));
+  }
+
+  ASSERT_THAT(tree.getAttributeCount(), Eq(1u));
+  EXPECT_THAT(tree.getAttributeValueStringID(0), Ge(0));
+
+  size_t len;
+  EXPECT_THAT(tree.getAttributeStringValue(0, &len), StrEq(u"true"));
+
+  EXPECT_THAT(tree.getAttributeDataType(0), Eq(android::Res_value::TYPE_INT_BOOLEAN));
+}
+
 }  // namespace aapt
diff --git a/tools/aapt2/link/ReferenceLinker.cpp b/tools/aapt2/link/ReferenceLinker.cpp
index b8f8804..9aaaa69 100644
--- a/tools/aapt2/link/ReferenceLinker.cpp
+++ b/tools/aapt2/link/ReferenceLinker.cpp
@@ -30,6 +30,7 @@
 #include "util/Util.h"
 #include "xml/XmlUtil.h"
 
+using ::aapt::ResourceUtils::StringBuilder;
 using ::android::StringPiece;
 
 namespace aapt {
@@ -133,10 +134,11 @@
 
       // If we could not parse as any specific type, try a basic STRING.
       if (!transformed && (attr->type_mask & android::ResTable_map::TYPE_STRING)) {
-        util::StringBuilder string_builder;
-        string_builder.Append(*raw_string->value);
+        StringBuilder string_builder;
+        string_builder.AppendText(*raw_string->value);
         if (string_builder) {
-          transformed = util::make_unique<String>(string_pool_->MakeRef(string_builder.ToString()));
+          transformed =
+              util::make_unique<String>(string_pool_->MakeRef(string_builder.to_string()));
         }
       }
 
diff --git a/tools/aapt2/util/Util.cpp b/tools/aapt2/util/Util.cpp
index e42145d..d1c9ca1 100644
--- a/tools/aapt2/util/Util.cpp
+++ b/tools/aapt2/util/Util.cpp
@@ -76,6 +76,34 @@
   return str.substr(str.size() - suffix.size(), suffix.size()) == suffix;
 }
 
+StringPiece TrimLeadingWhitespace(const StringPiece& str) {
+  if (str.size() == 0 || str.data() == nullptr) {
+    return str;
+  }
+
+  const char* start = str.data();
+  const char* end = start + str.length();
+
+  while (start != end && isspace(*start)) {
+    start++;
+  }
+  return StringPiece(start, end - start);
+}
+
+StringPiece TrimTrailingWhitespace(const StringPiece& str) {
+  if (str.size() == 0 || str.data() == nullptr) {
+    return str;
+  }
+
+  const char* start = str.data();
+  const char* end = start + str.length();
+
+  while (end != start && isspace(*(end - 1))) {
+    end--;
+  }
+  return StringPiece(start, end - start);
+}
+
 StringPiece TrimWhitespace(const StringPiece& str) {
   if (str.size() == 0 || str.data() == nullptr) {
     return str;
@@ -269,162 +297,6 @@
   return true;
 }
 
-static bool AppendCodepointToUtf8String(char32_t codepoint, std::string* output) {
-  ssize_t len = utf32_to_utf8_length(&codepoint, 1);
-  if (len < 0) {
-    return false;
-  }
-
-  const size_t start_append_pos = output->size();
-
-  // Make room for the next character.
-  output->resize(output->size() + len);
-
-  char* dst = &*(output->begin() + start_append_pos);
-  utf32_to_utf8(&codepoint, 1, dst, len + 1);
-  return true;
-}
-
-static bool AppendUnicodeCodepoint(Utf8Iterator* iter, std::string* output) {
-  char32_t code = 0;
-  for (size_t i = 0; i < 4 && iter->HasNext(); i++) {
-    char32_t codepoint = iter->Next();
-    char32_t a;
-    if (codepoint >= U'0' && codepoint <= U'9') {
-      a = codepoint - U'0';
-    } else if (codepoint >= U'a' && codepoint <= U'f') {
-      a = codepoint - U'a' + 10;
-    } else if (codepoint >= U'A' && codepoint <= U'F') {
-      a = codepoint - U'A' + 10;
-    } else {
-      return {};
-    }
-    code = (code << 4) | a;
-  }
-  return AppendCodepointToUtf8String(code, output);
-}
-
-static bool IsCodepointSpace(char32_t codepoint) {
-  if (static_cast<uint32_t>(codepoint) & 0xffffff00u) {
-    return false;
-  }
-  return isspace(static_cast<char>(codepoint));
-}
-
-StringBuilder::StringBuilder(bool preserve_spaces) : preserve_spaces_(preserve_spaces) {
-}
-
-StringBuilder& StringBuilder::Append(const StringPiece& str) {
-  if (!error_.empty()) {
-    return *this;
-  }
-
-  // Where the new data will be appended to.
-  const size_t new_data_index = str_.size();
-
-  Utf8Iterator iter(str);
-  while (iter.HasNext()) {
-    const char32_t codepoint = iter.Next();
-
-    if (last_char_was_escape_) {
-      switch (codepoint) {
-        case U't':
-          str_ += '\t';
-          break;
-
-        case U'n':
-          str_ += '\n';
-          break;
-
-        case U'#':
-        case U'@':
-        case U'?':
-        case U'"':
-        case U'\'':
-        case U'\\':
-          str_ += static_cast<char>(codepoint);
-          break;
-
-        case U'u':
-          if (!AppendUnicodeCodepoint(&iter, &str_)) {
-            error_ = "invalid unicode escape sequence";
-            return *this;
-          }
-          break;
-
-        default:
-          // Ignore the escape character and just include the codepoint.
-          AppendCodepointToUtf8String(codepoint, &str_);
-          break;
-      }
-      last_char_was_escape_ = false;
-
-    } else if (!preserve_spaces_ && codepoint == U'"') {
-      if (!quote_ && trailing_space_) {
-        // We found an opening quote, and we have trailing space, so we should append that
-        // space now.
-        if (trailing_space_) {
-          // We had trailing whitespace, so replace with a single space.
-          if (!str_.empty()) {
-            str_ += ' ';
-          }
-          trailing_space_ = false;
-        }
-      }
-      quote_ = !quote_;
-
-    } else if (!preserve_spaces_ && codepoint == U'\'' && !quote_) {
-      // This should be escaped.
-      error_ = "unescaped apostrophe";
-      return *this;
-
-    } else if (codepoint == U'\\') {
-      // This is an escape sequence, convert to the real value.
-      if (!quote_ && trailing_space_) {
-        // We had trailing whitespace, so
-        // replace with a single space.
-        if (!str_.empty()) {
-          str_ += ' ';
-        }
-        trailing_space_ = false;
-      }
-      last_char_was_escape_ = true;
-    } else {
-      if (preserve_spaces_ || quote_) {
-        // Quotes mean everything is taken, including whitespace.
-        AppendCodepointToUtf8String(codepoint, &str_);
-      } else {
-        // This is not quoted text, so we will accumulate whitespace and only emit a single
-        // character of whitespace if it is followed by a non-whitespace character.
-        if (IsCodepointSpace(codepoint)) {
-          // We found whitespace.
-          trailing_space_ = true;
-        } else {
-          if (trailing_space_) {
-            // We saw trailing space before, so replace all
-            // that trailing space with one space.
-            if (!str_.empty()) {
-              str_ += ' ';
-            }
-            trailing_space_ = false;
-          }
-          AppendCodepointToUtf8String(codepoint, &str_);
-        }
-      }
-    }
-  }
-
-  // Accumulate the added string's UTF-16 length.
-  ssize_t len = utf8_to_utf16_length(reinterpret_cast<const uint8_t*>(str_.data()) + new_data_index,
-                                     str_.size() - new_data_index);
-  if (len < 0) {
-    error_ = "invalid unicode code point";
-    return *this;
-  }
-  utf16_len_ += len;
-  return *this;
-}
-
 std::u16string Utf8ToUtf16(const StringPiece& utf8) {
   ssize_t utf16_length = utf8_to_utf16_length(
       reinterpret_cast<const uint8_t*>(utf8.data()), utf8.length());
diff --git a/tools/aapt2/util/Util.h b/tools/aapt2/util/Util.h
index 7c949b90..0eb35d1 100644
--- a/tools/aapt2/util/Util.h
+++ b/tools/aapt2/util/Util.h
@@ -59,7 +59,15 @@
 // Returns true if the string ends with suffix.
 bool EndsWith(const android::StringPiece& str, const android::StringPiece& suffix);
 
-// Creates a new StringPiece16 that points to a substring of the original string without leading or
+// Creates a new StringPiece that points to a substring of the original string without leading
+// whitespace.
+android::StringPiece TrimLeadingWhitespace(const android::StringPiece& str);
+
+// Creates a new StringPiece that points to a substring of the original string without trailing
+// whitespace.
+android::StringPiece TrimTrailingWhitespace(const android::StringPiece& str);
+
+// Creates a new StringPiece that points to a substring of the original string without leading or
 // trailing whitespace.
 android::StringPiece TrimWhitespace(const android::StringPiece& str);
 
@@ -141,9 +149,12 @@
 // break the string interpolation.
 bool VerifyJavaStringFormat(const android::StringPiece& str);
 
+bool AppendStyledString(const android::StringPiece& input, bool preserve_spaces,
+                        std::string* out_str, std::string* out_error);
+
 class StringBuilder {
  public:
-  explicit StringBuilder(bool preserve_spaces = false);
+  StringBuilder() = default;
 
   StringBuilder& Append(const android::StringPiece& str);
   const std::string& ToString() const;
@@ -158,7 +169,6 @@
   explicit operator bool() const;
 
  private:
-  bool preserve_spaces_;
   std::string str_;
   size_t utf16_len_ = 0;
   bool quote_ = false;
diff --git a/tools/aapt2/util/Util_test.cpp b/tools/aapt2/util/Util_test.cpp
index 2d1242a..d4e3bec 100644
--- a/tools/aapt2/util/Util_test.cpp
+++ b/tools/aapt2/util/Util_test.cpp
@@ -41,45 +41,6 @@
   EXPECT_TRUE(util::StartsWith("hello.xml", "he"));
 }
 
-TEST(UtilTest, StringBuilderSplitEscapeSequence) {
-  EXPECT_THAT(util::StringBuilder().Append("this is a new\\").Append("nline.").ToString(),
-              Eq("this is a new\nline."));
-}
-
-TEST(UtilTest, StringBuilderWhitespaceRemoval) {
-  EXPECT_THAT(util::StringBuilder().Append("    hey guys ").Append(" this is so cool ").ToString(),
-              Eq("hey guys this is so cool"));
-  EXPECT_THAT(
-      util::StringBuilder().Append(" \" wow,  so many \t ").Append("spaces. \"what? ").ToString(),
-      Eq(" wow,  so many \t spaces. what?"));
-  EXPECT_THAT(util::StringBuilder().Append("  where \t ").Append(" \nis the pie?").ToString(),
-              Eq("where is the pie?"));
-}
-
-TEST(UtilTest, StringBuilderEscaping) {
-  EXPECT_THAT(util::StringBuilder()
-                  .Append("    hey guys\\n ")
-                  .Append(" this \\t is so\\\\ cool ")
-                  .ToString(),
-              Eq("hey guys\n this \t is so\\ cool"));
-  EXPECT_THAT(util::StringBuilder().Append("\\@\\?\\#\\\\\\'").ToString(), Eq("@?#\\\'"));
-}
-
-TEST(UtilTest, StringBuilderMisplacedQuote) {
-  util::StringBuilder builder;
-  EXPECT_FALSE(builder.Append("they're coming!"));
-}
-
-TEST(UtilTest, StringBuilderUnicodeCodes) {
-  EXPECT_THAT(util::StringBuilder().Append("\\u00AF\\u0AF0 woah").ToString(),
-              Eq("\u00AF\u0AF0 woah"));
-  EXPECT_FALSE(util::StringBuilder().Append("\\u00 yo"));
-}
-
-TEST(UtilTest, StringBuilderPreserveSpaces) {
-  EXPECT_THAT(util::StringBuilder(true /*preserve_spaces*/).Append("\"").ToString(), Eq("\""));
-}
-
 TEST(UtilTest, TokenizeInput) {
   auto tokenizer = util::Tokenize(StringPiece("this| is|the|end"), '|');
   auto iter = tokenizer.begin();
diff --git a/tools/aapt2/xml/XmlDom.cpp b/tools/aapt2/xml/XmlDom.cpp
index 7b748ce..b6cd086 100644
--- a/tools/aapt2/xml/XmlDom.cpp
+++ b/tools/aapt2/xml/XmlDom.cpp
@@ -248,8 +248,14 @@
 
       android::Res_value res_value;
       if (parser->getAttributeValue(i, &res_value) > 0) {
-        attr.compiled_value = ResourceUtils::ParseBinaryResValue(
-            ResourceType::kAnim, {}, parser->getStrings(), res_value, out_pool);
+        // Only compile the value if it is not a string, or it is a string that differs from
+        // the raw attribute value.
+        int32_t raw_value_idx = parser->getAttributeValueStringID(i);
+        if (res_value.dataType != android::Res_value::TYPE_STRING || raw_value_idx < 0 ||
+            static_cast<uint32_t>(raw_value_idx) != res_value.data) {
+          attr.compiled_value = ResourceUtils::ParseBinaryResValue(
+              ResourceType::kAnim, {}, parser->getStrings(), res_value, out_pool);
+        }
       }
 
       el->attributes.push_back(std::move(attr));
@@ -262,8 +268,8 @@
   // an enum, which causes errors when qualifying it with android::
   using namespace android;
 
-  StringPool string_pool;
-  std::unique_ptr<Element> root;
+  std::unique_ptr<XmlResource> xml_resource = util::make_unique<XmlResource>();
+
   std::stack<Element*> node_stack;
   std::unique_ptr<Element> pending_element;
 
@@ -322,12 +328,12 @@
         }
 
         Element* this_el = el.get();
-        CopyAttributes(el.get(), &tree, &string_pool);
+        CopyAttributes(el.get(), &tree, &xml_resource->string_pool);
 
         if (!node_stack.empty()) {
           node_stack.top()->AppendChild(std::move(el));
         } else {
-          root = std::move(el);
+          xml_resource->root = std::move(el);
         }
         node_stack.push(this_el);
         break;
@@ -359,7 +365,7 @@
         break;
     }
   }
-  return util::make_unique<XmlResource>(ResourceFile{}, std::move(string_pool), std::move(root));
+  return xml_resource;
 }
 
 std::unique_ptr<XmlResource> XmlResource::Clone() const {
diff --git a/tools/incident_section_gen/main.cpp b/tools/incident_section_gen/main.cpp
index e7b269a..9183918 100644
--- a/tools/incident_section_gen/main.cpp
+++ b/tools/incident_section_gen/main.cpp
@@ -411,6 +411,11 @@
             case SECTION_LOG:
                 printf("    new LogSection(%d, %s),\n", field->number(), s.args().c_str());
                 break;
+            case SECTION_GZIP:
+                printf("    new GZipSection(%d,", field->number());
+                splitAndPrint(s.args());
+                printf(" NULL),\n");
+                break;
         }
     }
     printf("    NULL };\n");
diff --git a/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp
index dc2ed43..948422c 100644
--- a/tools/stats_log_api_gen/Android.bp
+++ b/tools/stats_log_api_gen/Android.bp
@@ -62,10 +62,14 @@
 
     shared_libs: [
         "libstats_proto_host",
+        "libprotobuf-cpp-full",
     ],
 
     proto: {
         type: "full",
+        include_dirs: [
+            "external/protobuf/src",
+        ],
     },
 }
 
diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp
index 0e57f7f..ab106d7 100644
--- a/tools/stats_log_api_gen/Collation.cpp
+++ b/tools/stats_log_api_gen/Collation.cpp
@@ -41,12 +41,12 @@
 }
 
 AtomDecl::AtomDecl(const AtomDecl& that)
-    :code(that.code),
-     name(that.name),
-     message(that.message),
-     fields(that.fields)
-{
-}
+    : code(that.code),
+      name(that.name),
+      message(that.message),
+      fields(that.fields),
+      primaryFields(that.primaryFields),
+      exclusiveField(that.exclusiveField) {}
 
 AtomDecl::AtomDecl(int c, const string& n, const string& m)
     :code(c),
@@ -237,6 +237,31 @@
       signature->push_back(javaType);
     }
     atomDecl->fields.push_back(atField);
+
+    if (field->options().GetExtension(os::statsd::stateFieldOption).option() ==
+        os::statsd::StateField::PRIMARY) {
+        if (javaType == JAVA_TYPE_UNKNOWN ||
+            javaType == JAVA_TYPE_ATTRIBUTION_CHAIN ||
+            javaType == JAVA_TYPE_OBJECT || javaType == JAVA_TYPE_BYTE_ARRAY) {
+            errorCount++;
+        }
+        atomDecl->primaryFields.push_back(it->first);
+    }
+
+    if (field->options().GetExtension(os::statsd::stateFieldOption).option() ==
+        os::statsd::StateField::EXCLUSIVE) {
+        if (javaType == JAVA_TYPE_UNKNOWN ||
+            javaType == JAVA_TYPE_ATTRIBUTION_CHAIN ||
+            javaType == JAVA_TYPE_OBJECT || javaType == JAVA_TYPE_BYTE_ARRAY) {
+            errorCount++;
+        }
+
+        if (atomDecl->exclusiveField == 0) {
+            atomDecl->exclusiveField = it->first;
+        } else {
+            errorCount++;
+        }
+    }
   }
 
   return errorCount;
@@ -318,6 +343,9 @@
     AtomDecl atomDecl(atomField->number(), atomField->name(), atom->name());
     vector<java_type_t> signature;
     errorCount += collate_atom(atom, &atomDecl, &signature);
+    if (atomDecl.primaryFields.size() != 0 && atomDecl.exclusiveField == 0) {
+        errorCount++;
+    }
     atoms->signatures.insert(signature);
     atoms->decls.insert(atomDecl);
 
diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h
index 0455eca..edba3e2 100644
--- a/tools/stats_log_api_gen/Collation.h
+++ b/tools/stats_log_api_gen/Collation.h
@@ -81,6 +81,9 @@
     string message;
     vector<AtomField> fields;
 
+    vector<int> primaryFields;
+    int exclusiveField = 0;
+
     AtomDecl();
     AtomDecl(const AtomDecl& that);
     AtomDecl(int code, const string& name, const string& message);
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index da67e92..d58c223 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -320,6 +320,7 @@
     fprintf(out, "\n");
     fprintf(out, "#include <stdint.h>\n");
     fprintf(out, "#include <vector>\n");
+    fprintf(out, "#include <map>\n");
     fprintf(out, "#include <set>\n");
     fprintf(out, "\n");
 
@@ -412,6 +413,43 @@
 
     fprintf(out, "const static int kMaxPushedAtomId = %d;\n\n", maxPushedAtomId);
 
+    fprintf(out, "struct StateAtomFieldOptions {\n");
+    fprintf(out, "  std::vector<int> primaryFields;\n");
+    fprintf(out, "  int exclusiveField;\n");
+    fprintf(out, "\n");
+    fprintf(out,
+            "  static std::map<int, StateAtomFieldOptions> "
+            "getStateAtomFieldOptions() {\n");
+    fprintf(out, "    std::map<int, StateAtomFieldOptions> options;\n");
+    fprintf(out, "    StateAtomFieldOptions opt;\n");
+    for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
+         atom != atoms.decls.end(); atom++) {
+        if (atom->primaryFields.size() == 0 && atom->exclusiveField == 0) {
+            continue;
+        }
+        fprintf(out,
+                "\n    // Adding primary and exclusive fields for atom "
+                "(%d)%s\n",
+                atom->code, atom->name.c_str());
+        fprintf(out, "    opt.primaryFields.clear();\n");
+        for (const auto& field : atom->primaryFields) {
+            fprintf(out, "    opt.primaryFields.push_back(%d);\n", field);
+        }
+
+        fprintf(out, "    opt.exclusiveField = %d;\n", atom->exclusiveField);
+        fprintf(out, "    options[static_cast<int>(%s)] = opt;\n",
+                make_constant_name(atom->name).c_str());
+    }
+
+    fprintf(out, "    return options;\n");
+    fprintf(out, "  }\n");
+    fprintf(out, "};\n");
+
+    fprintf(out,
+            "const static std::map<int, StateAtomFieldOptions> "
+            "kStateAtomsFieldOptions = "
+            "StateAtomFieldOptions::getStateAtomFieldOptions();\n");
+
     // Print write methods
     fprintf(out, "//\n");
     fprintf(out, "// Write methods\n");
diff --git a/tools/stats_log_api_gen/test.proto b/tools/stats_log_api_gen/test.proto
index 66cbee8..264a865 100644
--- a/tools/stats_log_api_gen/test.proto
+++ b/tools/stats_log_api_gen/test.proto
@@ -17,6 +17,7 @@
 syntax = "proto2";
 
 import "frameworks/base/cmds/statsd/src/atoms.proto";
+import "frameworks/base/cmds/statsd/src/atom_field_options.proto";
 
 package android.stats_log_api_gen;
 
@@ -108,3 +109,68 @@
   oneof event { BadAttributionNodePositionAtom bad = 1; }
 }
 
+message BadStateAtoms {
+    oneof event {
+        BadStateAtom1 bad1 = 1;
+        BadStateAtom2 bad2 = 2;
+        BadStateAtom3 bad3 = 3;
+    }
+}
+
+message GoodStateAtoms {
+    oneof event {
+        GoodStateAtom1 good1 = 1;
+        GoodStateAtom2 good2 = 2;
+    }
+}
+
+// The atom has only primary field but no exclusive state field.
+message BadStateAtom1 {
+    optional int32 uid = 1
+            [(android.os.statsd.stateFieldOption).option = PRIMARY];
+}
+
+// Only primative types can be annotated.
+message BadStateAtom2 {
+    repeated android.os.statsd.AttributionNode attribution = 1
+            [(android.os.statsd.stateFieldOption).option = PRIMARY];
+    optional int32 state = 2
+            [(android.os.statsd.stateFieldOption).option = EXCLUSIVE];
+}
+
+// Having 2 exclusive state field in the atom means the atom is badly designed.
+// E.g., putting bluetooth state and wifi state in the same atom.
+message BadStateAtom3 {
+    optional int32 uid = 1
+            [(android.os.statsd.stateFieldOption).option = PRIMARY];
+    optional int32 state = 2
+            [(android.os.statsd.stateFieldOption).option = EXCLUSIVE];
+    optional int32 state2 = 3
+            [(android.os.statsd.stateFieldOption).option = EXCLUSIVE];
+}
+
+message GoodStateAtom1 {
+    optional int32 uid = 1
+            [(android.os.statsd.stateFieldOption).option = PRIMARY];
+    optional int32 state = 2
+            [(android.os.statsd.stateFieldOption).option = EXCLUSIVE];
+}
+
+// Atoms can have exclusive state field, but no primary field. That means
+// the state is globally exclusive (e.g., DisplayState).
+message GoodStateAtom2 {
+    optional int32 uid = 1;
+    optional int32 state = 2
+            [(android.os.statsd.stateFieldOption).option = EXCLUSIVE];
+}
+
+// We can have more than one primary fields. That means their combination is a
+// primary key.
+message GoodStateAtom3 {
+    optional int32 uid = 1
+            [(android.os.statsd.stateFieldOption).option = PRIMARY];
+    optional int32 tid = 2
+            [(android.os.statsd.stateFieldOption).option = PRIMARY];
+    optional int32 state = 3
+            [(android.os.statsd.stateFieldOption).option = EXCLUSIVE];
+}
\ No newline at end of file
diff --git a/tools/stats_log_api_gen/test_collation.cpp b/tools/stats_log_api_gen/test_collation.cpp
index 9e22cd9..1936d96 100644
--- a/tools/stats_log_api_gen/test_collation.cpp
+++ b/tools/stats_log_api_gen/test_collation.cpp
@@ -199,5 +199,18 @@
   EXPECT_EQ(1, errorCount);
 }
 
+TEST(CollationTest, FailOnBadStateAtomOptions) {
+    Atoms atoms;
+    int errorCount = collate_atoms(BadStateAtoms::descriptor(), &atoms);
+
+    EXPECT_EQ(3, errorCount);
+}
+
+TEST(CollationTest, PassOnGoodStateAtomOptions) {
+    Atoms atoms;
+    int errorCount = collate_atoms(GoodStateAtoms::descriptor(), &atoms);
+    EXPECT_EQ(0, errorCount);
+}
+
 }  // namespace stats_log_api_gen
 }  // namespace android
\ No newline at end of file
diff --git a/wifi/java/android/net/wifi/RttManager.java b/wifi/java/android/net/wifi/RttManager.java
index b5273dd..50c4b5e 100644
--- a/wifi/java/android/net/wifi/RttManager.java
+++ b/wifi/java/android/net/wifi/RttManager.java
@@ -999,6 +999,7 @@
                             // just in case legacy API needed some relatively real timestamp
                             legacyResults[i].ts = SystemClock.elapsedRealtime() * 1000;
                         }
+                        i++;
                     }
                     listener.onSuccess(legacyResults);
                 }
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
index 06a5c2e..8529a89 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
@@ -27,6 +27,7 @@
 import android.net.NetworkRequest;
 import android.net.NetworkSpecifier;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -420,9 +421,12 @@
                     "createNetworkSpecifier: Invalid 'role' argument when creating a network "
                             + "specifier");
         }
-        if (peerHandle == null) {
-            throw new IllegalArgumentException(
-                    "createNetworkSpecifier: Invalid peer handle - cannot be null");
+        if (role == WIFI_AWARE_DATA_PATH_ROLE_INITIATOR || !WifiAwareUtils.isLegacyVersion(mContext,
+                Build.VERSION_CODES.P)) {
+            if (peerHandle == null) {
+                throw new IllegalArgumentException(
+                        "createNetworkSpecifier: Invalid peer handle - cannot be null");
+            }
         }
 
         return new WifiAwareNetworkSpecifier(
@@ -453,9 +457,12 @@
                     "createNetworkSpecifier: Invalid 'role' argument when creating a network "
                             + "specifier");
         }
-        if (peer == null) {
-            throw new IllegalArgumentException(
-                    "createNetworkSpecifier: Invalid peer MAC - cannot be null");
+        if (role == WIFI_AWARE_DATA_PATH_ROLE_INITIATOR || !WifiAwareUtils.isLegacyVersion(mContext,
+                Build.VERSION_CODES.P)) {
+            if (peer == null) {
+                throw new IllegalArgumentException(
+                        "createNetworkSpecifier: Invalid peer MAC - cannot be null");
+            }
         }
         if (peer != null && peer.length != 6) {
             throw new IllegalArgumentException("createNetworkSpecifier: Invalid peer MAC address");
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareUtils.java b/wifi/java/android/net/wifi/aware/WifiAwareUtils.java
index fda7a9a..3ece93d 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareUtils.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareUtils.java
@@ -16,6 +16,8 @@
 
 package android.net.wifi.aware;
 
+import android.content.Context;
+import android.content.pm.PackageManager;
 import android.hardware.wifi.V1_0.Constants;
 
 /**
@@ -84,4 +86,21 @@
 
         return true;
     }
+
+    /**
+     * Returns true if the App version is older than minVersion.
+     */
+    public static boolean isLegacyVersion(Context context, int minVersion) {
+        try {
+            if (context.getPackageManager().getApplicationInfo(context.getOpPackageName(), 0)
+                    .targetSdkVersion < minVersion) {
+                return true;
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            // In case of exception, assume known app (more strict checking)
+            // Note: This case will never happen since checkPackage is
+            // called to verify valididity before checking App's version.
+        }
+        return false;
+    }
 }
diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
index 84e3ed9..272f727 100644
--- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
@@ -19,14 +19,20 @@
 import static org.hamcrest.core.IsEqual.equalTo;
 import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.net.wifi.RttManager;
+import android.os.Build;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Parcel;
@@ -79,12 +85,32 @@
     @Mock
     public RttManager.RttListener mockRttListener;
 
+    @Mock
+    public PackageManager mockPackageManager;
+
+    @Mock
+    public ApplicationInfo mockApplicationInfo;
+
     private static final int AWARE_STATUS_ERROR = -1;
 
+    private static final byte[] PMK_VALID = "01234567890123456789012345678901".getBytes();
+    private static final byte[] PMK_INVALID = "012".getBytes();
+
+    private static final String PASSPHRASE_VALID = "SomeLongEnoughPassphrase";
+    private static final String PASSPHRASE_TOO_SHORT = "012";
+    private static final String PASSPHRASE_TOO_LONG =
+            "0123456789012345678901234567890123456789012345678901234567890123456789";
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
 
+        mockApplicationInfo.targetSdkVersion = Build.VERSION_CODES.P;
+        when(mockPackageManager.getApplicationInfo(anyString(), anyInt())).thenReturn(
+                mockApplicationInfo);
+        when(mockContext.getOpPackageName()).thenReturn("XXX");
+        when(mockContext.getPackageManager()).thenReturn(mockPackageManager);
+
         mDut = new WifiAwareManager(mockContext, mockAwareService);
         mMockLooper = new TestLooper();
         mMockLooperHandler = new Handler(mMockLooper.getLooper());
@@ -884,8 +910,8 @@
         final int sessionId = 123;
         final PeerHandle peerHandle = new PeerHandle(123412);
         final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
-        final byte[] pmk = "01234567890123456789012345678901".getBytes();
-        final String passphrase = "A really bad password";
+        final byte[] pmk = PMK_VALID;
+        final String passphrase = PASSPHRASE_VALID;
         final ConfigRequest configRequest = new ConfigRequest.Builder().build();
         final PublishConfig publishConfig = new PublishConfig.Builder().build();
 
@@ -965,8 +991,8 @@
         final ConfigRequest configRequest = new ConfigRequest.Builder().build();
         final byte[] someMac = HexEncoding.decode("000102030405".toCharArray(), false);
         final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR;
-        final byte[] pmk = "01234567890123456789012345678901".getBytes();
-        final String passphrase = "A really bad password";
+        final byte[] pmk = PMK_VALID;
+        final String passphrase = PASSPHRASE_VALID;
 
         ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
                 WifiAwareSession.class);
@@ -1030,7 +1056,7 @@
      */
     @Test(expected = IllegalArgumentException.class)
     public void testNetworkSpecifierWithClientIncorrectLengthPmk() throws Exception {
-        executeNetworkSpecifierWithClient(new PeerHandle(123412), true, "012".getBytes(), null);
+        executeNetworkSpecifierWithClient(new PeerHandle(123412), true, PMK_INVALID, null);
     }
 
     /**
@@ -1045,17 +1071,17 @@
      * Validate that a too short Passphrase triggers an exception.
      */
     @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierWithClientShortPassphrase() throws Exception {
-        executeNetworkSpecifierWithClient(new PeerHandle(123412), false, null, "012");
+    public void testNetworkSpecifierWithClientTooShortPassphrase() throws Exception {
+        executeNetworkSpecifierWithClient(new PeerHandle(123412), false, null,
+                PASSPHRASE_TOO_SHORT);
     }
 
     /**
      * Validate that a too long Passphrase triggers an exception.
      */
     @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierWithClientLongPassphrase() throws Exception {
-        executeNetworkSpecifierWithClient(new PeerHandle(123412), false, null,
-                "0123456789012345678901234567890123456789012345678901234567890123456789");
+    public void testNetworkSpecifierWithClientTooLongPassphrase() throws Exception {
+        executeNetworkSpecifierWithClient(new PeerHandle(123412), false, null, PASSPHRASE_TOO_LONG);
     }
 
     /**
@@ -1063,8 +1089,16 @@
      */
     @Test(expected = IllegalArgumentException.class)
     public void testNetworkSpecifierWithClientNullPeer() throws Exception {
-        executeNetworkSpecifierWithClient(null, false, null,
-                "0123456789012345678901234567890123456789012345678901234567890123456789");
+        executeNetworkSpecifierWithClient(null, false, null, PASSPHRASE_VALID);
+    }
+
+    /**
+     * Validate that a null PeerHandle does not trigger an exception for legacy API.
+     */
+    @Test
+    public void testNetworkSpecifierWithClientNullPeerLegacyApi() throws Exception {
+        mockApplicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
+        executeNetworkSpecifierWithClient(null, false, null, PASSPHRASE_VALID);
     }
 
     private void executeNetworkSpecifierWithClient(PeerHandle peerHandle, boolean doPmk, byte[] pmk,
@@ -1117,7 +1151,7 @@
     @Test(expected = IllegalArgumentException.class)
     public void testNetworkSpecifierDirectNullPmk() throws Exception {
         executeNetworkSpecifierDirect(HexEncoding.decode("000102030405".toCharArray(), false), true,
-                null, null);
+                null, null, true);
     }
 
     /**
@@ -1126,7 +1160,7 @@
     @Test(expected = IllegalArgumentException.class)
     public void testNetworkSpecifierDirectIncorrectLengthPmk() throws Exception {
         executeNetworkSpecifierDirect(HexEncoding.decode("000102030405".toCharArray(), false), true,
-                "012".getBytes(), null);
+                PMK_INVALID, null, true);
     }
 
     /**
@@ -1135,40 +1169,57 @@
     @Test(expected = IllegalArgumentException.class)
     public void testNetworkSpecifierDirectNullPassphrase() throws Exception {
         executeNetworkSpecifierDirect(HexEncoding.decode("000102030405".toCharArray(), false),
-                false, null, null);
+                false, null, null, true);
     }
 
     /**
      * Validate that a too short Passphrase triggers an exception.
      */
     @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierDirectShortPassphrase() throws Exception {
+    public void testNetworkSpecifierDirectTooShortPassphrase() throws Exception {
         executeNetworkSpecifierDirect(HexEncoding.decode("000102030405".toCharArray(), false),
-                false, null, "012");
+                false, null, PASSPHRASE_TOO_SHORT, true);
     }
 
     /**
      * Validate that a too long Passphrase triggers an exception.
      */
     @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierDirectLongPassphrase() throws Exception {
+    public void testNetworkSpecifierDirectTooLongPassphrase() throws Exception {
         executeNetworkSpecifierDirect(HexEncoding.decode("000102030405".toCharArray(), false),
-                false, null,
-                "0123456789012345678901234567890123456789012345678901234567890123456789");
+                false, null, PASSPHRASE_TOO_LONG, true);
     }
 
     /**
-     * Validate that a null peer MAC triggers an exception.
+     * Validate that a null peer MAC triggers an exception for an Initiator.
      */
     @Test(expected = IllegalArgumentException.class)
-    public void testNetworkSpecifierDirectNullPeer() throws Exception {
-        executeNetworkSpecifierDirect(null, false, null, null);
+    public void testNetworkSpecifierDirectNullPeerInitiator() throws Exception {
+        executeNetworkSpecifierDirect(null, false, null, PASSPHRASE_VALID, true);
+    }
+
+    /**
+     * Validate that a null peer MAC triggers an exception for a Resonder.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testNetworkSpecifierDirectNullPeerResponder() throws Exception {
+        executeNetworkSpecifierDirect(null, false, null, PASSPHRASE_VALID, false);
+    }
+
+    /**
+     * Validate that a null peer MAC does not trigger an exception for a Resonder on legacy API.
+     */
+    @Test
+    public void testNetworkSpecifierDirectNullPeerResponderLegacyApi() throws Exception {
+        mockApplicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
+        executeNetworkSpecifierDirect(null, false, null, PASSPHRASE_VALID, false);
     }
 
     private void executeNetworkSpecifierDirect(byte[] someMac, boolean doPmk, byte[] pmk,
-            String passphrase) throws Exception {
+            String passphrase, boolean doInitiator) throws Exception {
         final int clientId = 134;
-        final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR;
+        final int role = doInitiator ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
+                : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
         final ConfigRequest configRequest = new ConfigRequest.Builder().build();
 
         ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
index b573adf..c5ad7de 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
@@ -263,6 +263,7 @@
      *
      * @throws Exception
      */
+    @Test
     public void validateCertCredentialWithoutCaCert() throws Exception {
         Credential cred = createCredentialWithCertificateCredential();
         cred.setCaCertificate(null);