Merge "Modified getActiveAdminsForAffectedUser"
diff --git a/Android.bp b/Android.bp
index 412099d..3fff2d4 100644
--- a/Android.bp
+++ b/Android.bp
@@ -471,7 +471,6 @@
         "framework-platform-compat-config",
         "libcore-platform-compat-config",
         "services-platform-compat-config",
-        "media-provider-platform-compat-config",
     ],
     static_libs: [
         // If MimeMap ever becomes its own APEX, then this dependency would need to be removed
@@ -761,17 +760,6 @@
     ],
 }
 
-filegroup {
-    name: "framework-tethering-annotations",
-    srcs: [
-        "core/java/android/annotation/NonNull.java",
-        "core/java/android/annotation/Nullable.java",
-        "core/java/android/annotation/RequiresPermission.java",
-        "core/java/android/annotation/SystemApi.java",
-        "core/java/android/annotation/TestApi.java",
-        "core/java/com/android/internal/annotations/GuardedBy.java",
-    ],
-}
 // Build ext.jar
 // ============================================================
 java_library {
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 50d23ad2..4616ced 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -197,20 +197,17 @@
             api_file: "api/module-lib-current.txt",
             removed_api_file: "api/module-lib-removed.txt",
         },
-        // TODO(b/147559833) enable the compatibility check against the last release API
-        // and the API lint
-        //last_released: {
-        //    api_file: ":last-released-module-lib-api",
-        //    removed_api_file: "api/module-lib-removed.txt",
-        //    baseline_file: ":module-lib-api-incompatibilities-with-last-released"
-        //},
-        //api_lint: {
-        //    enabled: true,
-        //    new_since: ":last-released-module-lib-api",
-        //    baseline_file: "api/module-lib-lint-baseline.txt",
-        //},
+        last_released: {
+            api_file: ":last-released-module-lib-api",
+            removed_api_file: "api/module-lib-removed.txt",
+            baseline_file: ":module-lib-api-incompatibilities-with-last-released"
+        },
+        api_lint: {
+            enabled: true,
+            new_since: ":last-released-module-lib-api",
+            baseline_file: "api/module-lib-lint-baseline.txt",
+        },
     },
-    //jdiff_enabled: true,
 }
 
 
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
index 8a9c774..b905273 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
@@ -606,10 +606,6 @@
         return hasLateConstraint;
     }
 
-    private static boolean kindofEqualsBundle(BaseBundle a, BaseBundle b) {
-        return (a == b) || (a != null && a.kindofEquals(b));
-    }
-
     @Override
     public boolean equals(Object o) {
         if (!(o instanceof JobInfo)) {
@@ -620,11 +616,11 @@
             return false;
         }
         // XXX won't be correct if one is parcelled and the other not.
-        if (!kindofEqualsBundle(extras, j.extras)) {
+        if (!BaseBundle.kindofEquals(extras, j.extras)) {
             return false;
         }
         // XXX won't be correct if one is parcelled and the other not.
-        if (!kindofEqualsBundle(transientExtras, j.transientExtras)) {
+        if (!BaseBundle.kindofEquals(transientExtras, j.transientExtras)) {
             return false;
         }
         // XXX for now we consider two different clip data objects to be different,
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
index cf7f380..789f20b 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
@@ -1648,11 +1648,11 @@
                     pw.println();
                 }
             }
-            if (job.getExtras() != null && !job.getExtras().maybeIsEmpty()) {
+            if (job.getExtras() != null && !job.getExtras().isDefinitelyEmpty()) {
                 pw.print(prefix); pw.print("  Extras: ");
                 pw.println(job.getExtras().toShortString());
             }
-            if (job.getTransientExtras() != null && !job.getTransientExtras().maybeIsEmpty()) {
+            if (job.getTransientExtras() != null && !job.getTransientExtras().isDefinitelyEmpty()) {
                 pw.print(prefix); pw.print("  Transient extras: ");
                 pw.println(job.getTransientExtras().toShortString());
             }
@@ -1869,10 +1869,10 @@
                             job.getTriggerContentMaxDelay());
                 }
             }
-            if (job.getExtras() != null && !job.getExtras().maybeIsEmpty()) {
+            if (job.getExtras() != null && !job.getExtras().isDefinitelyEmpty()) {
                 job.getExtras().dumpDebug(proto, JobStatusDumpProto.JobInfo.EXTRAS);
             }
-            if (job.getTransientExtras() != null && !job.getTransientExtras().maybeIsEmpty()) {
+            if (job.getTransientExtras() != null && !job.getTransientExtras().isDefinitelyEmpty()) {
                 job.getTransientExtras().dumpDebug(proto, JobStatusDumpProto.JobInfo.TRANSIENT_EXTRAS);
             }
             if (job.getClipData() != null) {
diff --git a/apex/statsd/Android.bp b/apex/statsd/Android.bp
index baa1c25..c8aa526 100644
--- a/apex/statsd/Android.bp
+++ b/apex/statsd/Android.bp
@@ -20,8 +20,6 @@
 
 apex_defaults {
     native_shared_libs: [
-        "libstatssocket",
-        "libstatspull",
         "libstats_jni",
     ],
     // binaries: ["vold"],
@@ -30,7 +28,6 @@
         "service-statsd",
     ],
     // prebuilts: ["my_prebuilt"],
-    compile_multilib: "both",
     name: "com.android.os.statsd-defaults",
     key: "com.android.os.statsd.key",
     certificate: ":com.android.os.statsd.certificate",
@@ -74,7 +71,5 @@
     apex_available: [
         "com.android.os.statsd",
         "test_com.android.os.statsd",
-        //TODO (b/148620413): remove platform.
-         "//apex_available:platform",
     ],
-}
+}
\ No newline at end of file
diff --git a/apex/statsd/aidl/Android.bp b/apex/statsd/aidl/Android.bp
index 4ccdd7e..7c93bc7 100644
--- a/apex/statsd/aidl/Android.bp
+++ b/apex/statsd/aidl/Android.bp
@@ -38,10 +38,6 @@
         },
         ndk: {
             enabled: true,
-            apex_available: [
-                "com.android.os.statsd",
-            ],
         }
-
-    },
+    }
 }
diff --git a/apex/statsd/framework/java/android/util/StatsLog.java b/apex/statsd/framework/java/android/util/StatsLog.java
index 511bc01..536b71a 100644
--- a/apex/statsd/framework/java/android/util/StatsLog.java
+++ b/apex/statsd/framework/java/android/util/StatsLog.java
@@ -36,6 +36,11 @@
  * define custom metrics inside statsd.
  */
 public final class StatsLog {
+
+    // Load JNI library
+    static {
+        System.loadLibrary("stats_jni");
+    }
     private static final String TAG = "StatsLog";
     private static final boolean DEBUG = false;
     private static final int EXPERIMENT_IDS_FIELD_ID = 1;
diff --git a/api/current.txt b/api/current.txt
index 3b34995..23eeb7d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -289,7 +289,7 @@
     field public static final int allowBackup = 16843392; // 0x1010280
     field public static final int allowClearUserData = 16842757; // 0x1010005
     field public static final int allowEmbedded = 16843765; // 0x10103f5
-    field public static final int allowNativeHeapPointerTagging = 16844311; // 0x1010617
+    field public static final int allowNativeHeapPointerTagging = 16844307; // 0x1010613
     field public static final int allowParallelSyncs = 16843570; // 0x1010332
     field public static final int allowSingleTap = 16843353; // 0x1010259
     field public static final int allowTaskReparenting = 16843268; // 0x1010204
@@ -335,9 +335,6 @@
     field public static final int autoUrlDetect = 16843404; // 0x101028c
     field public static final int autoVerify = 16844014; // 0x10104ee
     field public static final int autofillHints = 16844118; // 0x1010556
-    field public static final int autofillInlineSuggestionChip = 16844307; // 0x1010613
-    field public static final int autofillInlineSuggestionSubtitle = 16844309; // 0x1010615
-    field public static final int autofillInlineSuggestionTitle = 16844308; // 0x1010614
     field public static final int autofilledHighlight = 16844136; // 0x1010568
     field public static final int background = 16842964; // 0x10100d4
     field public static final int backgroundDimAmount = 16842802; // 0x1010032
@@ -1082,6 +1079,7 @@
     field public static final int preferenceScreenStyle = 16842891; // 0x101008b
     field public static final int preferenceStyle = 16842894; // 0x101008e
     field public static final int presentationTheme = 16843712; // 0x10103c0
+    field public static final int preserveLegacyExternalStorage = 16844308; // 0x1010614
     field public static final int previewImage = 16843482; // 0x10102da
     field public static final int primaryContentAlpha = 16844114; // 0x1010552
     field public static final int priority = 16842780; // 0x101001c
@@ -2259,7 +2257,6 @@
     field public static final int ThemeOverlay_Material_Dialog = 16974550; // 0x10302d6
     field public static final int ThemeOverlay_Material_Dialog_Alert = 16974551; // 0x10302d7
     field public static final int ThemeOverlay_Material_Light = 16974410; // 0x103024a
-    field public static final int Theme_AutofillInlineSuggestion = 16974565; // 0x10302e5
     field public static final int Theme_Black = 16973832; // 0x1030008
     field public static final int Theme_Black_NoTitleBar = 16973833; // 0x1030009
     field public static final int Theme_Black_NoTitleBar_Fullscreen = 16973834; // 0x103000a
@@ -6426,9 +6423,13 @@
   public class StatusBarManager {
   }
 
-  public final class SyncNotedAppOp {
+  public final class SyncNotedAppOp implements android.os.Parcelable {
+    ctor public SyncNotedAppOp(@IntRange(from=0L) int, @Nullable String);
+    method public int describeContents();
     method @Nullable public String getFeatureId();
     method @NonNull public String getOp();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.SyncNotedAppOp> CREATOR;
   }
 
   @Deprecated public class TabActivity extends android.app.ActivityGroup {
@@ -7242,7 +7243,7 @@
   public final class FactoryResetProtectionPolicy implements android.os.Parcelable {
     method public int describeContents();
     method @NonNull public java.util.List<java.lang.String> getFactoryResetProtectionAccounts();
-    method public boolean isFactoryResetProtectionDisabled();
+    method public boolean isFactoryResetProtectionEnabled();
     method public void writeToParcel(@NonNull android.os.Parcel, @Nullable int);
     field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.FactoryResetProtectionPolicy> CREATOR;
   }
@@ -7251,7 +7252,7 @@
     ctor public FactoryResetProtectionPolicy.Builder();
     method @NonNull public android.app.admin.FactoryResetProtectionPolicy build();
     method @NonNull public android.app.admin.FactoryResetProtectionPolicy.Builder setFactoryResetProtectionAccounts(@NonNull java.util.List<java.lang.String>);
-    method @NonNull public android.app.admin.FactoryResetProtectionPolicy.Builder setFactoryResetProtectionDisabled(boolean);
+    method @NonNull public android.app.admin.FactoryResetProtectionPolicy.Builder setFactoryResetProtectionEnabled(boolean);
   }
 
   public class FreezePeriod {
@@ -26129,6 +26130,7 @@
     field public static final String KEY_AUDIO_SESSION_ID = "audio-session-id";
     field public static final String KEY_BITRATE_MODE = "bitrate-mode";
     field public static final String KEY_BIT_RATE = "bitrate";
+    field public static final String KEY_CAPTION_SERVICE_NUMBER = "caption-service-number";
     field public static final String KEY_CAPTURE_RATE = "capture-rate";
     field public static final String KEY_CHANNEL_COUNT = "channel-count";
     field public static final String KEY_CHANNEL_MASK = "channel-mask";
@@ -27424,7 +27426,7 @@
   public final class RouteDiscoveryPreference implements android.os.Parcelable {
     method public int describeContents();
     method @NonNull public java.util.List<java.lang.String> getPreferredFeatures();
-    method public boolean isActiveScan();
+    method public boolean shouldPerformActiveScan();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.media.RouteDiscoveryPreference> CREATOR;
   }
@@ -27433,8 +27435,8 @@
     ctor public RouteDiscoveryPreference.Builder(@NonNull java.util.List<java.lang.String>, boolean);
     ctor public RouteDiscoveryPreference.Builder(@NonNull android.media.RouteDiscoveryPreference);
     method @NonNull public android.media.RouteDiscoveryPreference build();
-    method @NonNull public android.media.RouteDiscoveryPreference.Builder setActiveScan(boolean);
     method @NonNull public android.media.RouteDiscoveryPreference.Builder setPreferredFeatures(@NonNull java.util.List<java.lang.String>);
+    method @NonNull public android.media.RouteDiscoveryPreference.Builder setShouldPerformActiveScan(boolean);
   }
 
   public final class RoutingSessionInfo implements android.os.Parcelable {
@@ -30816,7 +30818,7 @@
 
   public class AudioGroup {
     ctor @Deprecated public AudioGroup();
-    ctor public AudioGroup(@Nullable android.content.Context);
+    ctor public AudioGroup(@NonNull android.content.Context);
     method public void clear();
     method public int getMode();
     method public android.net.rtp.AudioStream[] getStreams();
@@ -31728,7 +31730,7 @@
     method public int describeContents();
     method public android.net.wifi.hotspot2.pps.Credential getCredential();
     method public android.net.wifi.hotspot2.pps.HomeSp getHomeSp();
-    method public long getSubscriptionExpirationTimeInMillis();
+    method public long getSubscriptionExpirationTimeMillis();
     method @NonNull public String getUniqueId() throws java.lang.IllegalStateException;
     method public boolean isOsuProvisioned();
     method public void setCredential(android.net.wifi.hotspot2.pps.Credential);
@@ -37314,6 +37316,7 @@
     method public void setCacheBehaviorTombstone(java.io.File, boolean) throws java.io.IOException;
     method public boolean unmountObb(String, boolean, android.os.storage.OnObbStateChangeListener);
     method public void unregisterStorageVolumeCallback(@NonNull android.os.storage.StorageManager.StorageVolumeCallback);
+    field @RequiresPermission(android.Manifest.permission.MANAGE_EXTERNAL_STORAGE) public static final String ACTION_CLEAR_APP_CACHE = "android.os.storage.action.CLEAR_APP_CACHE";
     field public static final String ACTION_MANAGE_STORAGE = "android.os.storage.action.MANAGE_STORAGE";
     field public static final String EXTRA_REQUESTED_BYTES = "android.os.storage.extra.REQUESTED_BYTES";
     field public static final String EXTRA_UUID = "android.os.storage.extra.UUID";
@@ -43047,6 +43050,7 @@
     method @NonNull public android.service.autofill.FillResponse build();
     method @NonNull public android.service.autofill.FillResponse.Builder disableAutofill(long);
     method @NonNull public android.service.autofill.FillResponse.Builder setAuthentication(@NonNull android.view.autofill.AutofillId[], @Nullable android.content.IntentSender, @Nullable android.widget.RemoteViews);
+    method @NonNull public android.service.autofill.FillResponse.Builder setAuthentication(@NonNull android.view.autofill.AutofillId[], @Nullable android.content.IntentSender, @Nullable android.widget.RemoteViews, @Nullable android.service.autofill.InlinePresentation);
     method @NonNull public android.service.autofill.FillResponse.Builder setClientState(@Nullable android.os.Bundle);
     method @NonNull public android.service.autofill.FillResponse.Builder setFieldClassificationIds(@NonNull android.view.autofill.AutofillId...);
     method @NonNull public android.service.autofill.FillResponse.Builder setFlags(int);
@@ -43964,7 +43968,7 @@
 
 package android.service.quickaccesswallet {
 
-  public final class GetWalletCardsCallback {
+  public interface GetWalletCardsCallback {
     method public void onFailure(@NonNull android.service.quickaccesswallet.GetWalletCardsError);
     method public void onSuccess(@NonNull android.service.quickaccesswallet.GetWalletCardsResponse);
   }
@@ -44005,7 +44009,6 @@
     method public abstract void onWalletCardsRequested(@NonNull android.service.quickaccesswallet.GetWalletCardsRequest, @NonNull android.service.quickaccesswallet.GetWalletCardsCallback);
     method public abstract void onWalletDismissed();
     method public final void sendWalletServiceEvent(@NonNull android.service.quickaccesswallet.WalletServiceEvent);
-    field public static final String ACTION_DISMISS_WALLET = "android.service.quickaccesswallet.action.DISMISS_WALLET";
     field public static final String ACTION_VIEW_WALLET = "android.service.quickaccesswallet.action.VIEW_WALLET";
     field public static final String ACTION_VIEW_WALLET_SETTINGS = "android.service.quickaccesswallet.action.VIEW_WALLET_SETTINGS";
     field public static final String SERVICE_INTERFACE = "android.service.quickaccesswallet.QuickAccessWalletService";
@@ -46893,7 +46896,7 @@
   }
 
   public final class CellIdentityGsm extends android.telephony.CellIdentity {
-    method @NonNull public java.util.List<java.lang.String> getAdditionalPlmns();
+    method @NonNull public java.util.Set<java.lang.String> getAdditionalPlmns();
     method public int getArfcn();
     method public int getBsic();
     method public int getCid();
@@ -46909,7 +46912,7 @@
   }
 
   public final class CellIdentityLte extends android.telephony.CellIdentity {
-    method @NonNull public java.util.List<java.lang.String> getAdditionalPlmns();
+    method @NonNull public java.util.Set<java.lang.String> getAdditionalPlmns();
     method @NonNull public java.util.List<java.lang.Integer> getBands();
     method public int getBandwidth();
     method public int getCi();
@@ -46927,7 +46930,7 @@
   }
 
   public final class CellIdentityNr extends android.telephony.CellIdentity {
-    method @NonNull public java.util.List<java.lang.String> getAdditionalPlmns();
+    method @NonNull public java.util.Set<java.lang.String> getAdditionalPlmns();
     method @NonNull public java.util.List<java.lang.Integer> getBands();
     method @Nullable public String getMccString();
     method @Nullable public String getMncString();
@@ -46940,7 +46943,7 @@
   }
 
   public final class CellIdentityTdscdma extends android.telephony.CellIdentity {
-    method @NonNull public java.util.List<java.lang.String> getAdditionalPlmns();
+    method @NonNull public java.util.Set<java.lang.String> getAdditionalPlmns();
     method public int getCid();
     method @Nullable public android.telephony.ClosedSubscriberGroupInfo getClosedSubscriberGroupInfo();
     method public int getCpid();
@@ -46954,7 +46957,7 @@
   }
 
   public final class CellIdentityWcdma extends android.telephony.CellIdentity {
-    method @NonNull public java.util.List<java.lang.String> getAdditionalPlmns();
+    method @NonNull public java.util.Set<java.lang.String> getAdditionalPlmns();
     method public int getCid();
     method @Nullable public android.telephony.ClosedSubscriberGroupInfo getClosedSubscriberGroupInfo();
     method public int getLac();
@@ -47244,7 +47247,7 @@
     method @Nullable public android.telephony.CellIdentity getCellIdentity();
     method public int getDomain();
     method public int getNrState();
-    method @NonNull public String getRegisteredPlmn();
+    method @Nullable public String getRegisteredPlmn();
     method public int getTransportType();
     method public boolean isRegistered();
     method public boolean isRoaming();
@@ -52155,6 +52158,8 @@
     field public static final int CONTEXT_CLICK = 6; // 0x6
     field public static final int FLAG_IGNORE_GLOBAL_SETTING = 2; // 0x2
     field public static final int FLAG_IGNORE_VIEW_SETTING = 1; // 0x1
+    field public static final int GESTURE_END = 13; // 0xd
+    field public static final int GESTURE_START = 12; // 0xc
     field public static final int KEYBOARD_PRESS = 3; // 0x3
     field public static final int KEYBOARD_RELEASE = 7; // 0x7
     field public static final int KEYBOARD_TAP = 3; // 0x3
@@ -53536,10 +53541,10 @@
     method public boolean dispatchUnhandledMove(android.view.View, int);
     method protected void dispatchVisibilityChanged(@NonNull android.view.View, int);
     method public void dispatchWindowFocusChanged(boolean);
-    method public void dispatchWindowInsetsAnimationFinish(@NonNull android.view.WindowInsetsAnimationCallback.InsetsAnimation);
-    method public void dispatchWindowInsetsAnimationPrepare(@NonNull android.view.WindowInsetsAnimationCallback.InsetsAnimation);
-    method @NonNull public android.view.WindowInsets dispatchWindowInsetsAnimationProgress(@NonNull android.view.WindowInsets);
-    method @NonNull public android.view.WindowInsetsAnimationCallback.AnimationBounds dispatchWindowInsetsAnimationStart(@NonNull android.view.WindowInsetsAnimationCallback.InsetsAnimation, @NonNull android.view.WindowInsetsAnimationCallback.AnimationBounds);
+    method public void dispatchWindowInsetsAnimationEnd(@NonNull android.view.WindowInsetsAnimation);
+    method public void dispatchWindowInsetsAnimationPrepare(@NonNull android.view.WindowInsetsAnimation);
+    method @NonNull public android.view.WindowInsets dispatchWindowInsetsAnimationProgress(@NonNull android.view.WindowInsets, @NonNull java.util.List<android.view.WindowInsetsAnimation>);
+    method @NonNull public android.view.WindowInsetsAnimation.Bounds dispatchWindowInsetsAnimationStart(@NonNull android.view.WindowInsetsAnimation, @NonNull android.view.WindowInsetsAnimation.Bounds);
     method @Deprecated public void dispatchWindowSystemUiVisiblityChanged(int);
     method public void dispatchWindowVisibilityChanged(int);
     method @CallSuper public void draw(android.graphics.Canvas);
@@ -54060,7 +54065,7 @@
     method public void setVisibility(int);
     method @Deprecated public void setWillNotCacheDrawing(boolean);
     method public void setWillNotDraw(boolean);
-    method public void setWindowInsetsAnimationCallback(@Nullable android.view.WindowInsetsAnimationCallback);
+    method public void setWindowInsetsAnimationCallback(@Nullable android.view.WindowInsetsAnimation.Callback);
     method public void setX(float);
     method public void setY(float);
     method public void setZ(float);
@@ -55227,25 +55232,8 @@
     method public static int tappableElement();
   }
 
-  public interface WindowInsetsAnimationCallback {
-    method public int getDispatchMode();
-    method public default void onFinish(@NonNull android.view.WindowInsetsAnimationCallback.InsetsAnimation);
-    method public default void onPrepare(@NonNull android.view.WindowInsetsAnimationCallback.InsetsAnimation);
-    method @NonNull public android.view.WindowInsets onProgress(@NonNull android.view.WindowInsets);
-    method @NonNull public default android.view.WindowInsetsAnimationCallback.AnimationBounds onStart(@NonNull android.view.WindowInsetsAnimationCallback.InsetsAnimation, @NonNull android.view.WindowInsetsAnimationCallback.AnimationBounds);
-    field public static final int DISPATCH_MODE_CONTINUE_ON_SUBTREE = 1; // 0x1
-    field public static final int DISPATCH_MODE_STOP = 0; // 0x0
-  }
-
-  public static final class WindowInsetsAnimationCallback.AnimationBounds {
-    ctor public WindowInsetsAnimationCallback.AnimationBounds(@NonNull android.graphics.Insets, @NonNull android.graphics.Insets);
-    method @NonNull public android.graphics.Insets getLowerBound();
-    method @NonNull public android.graphics.Insets getUpperBound();
-    method @NonNull public android.view.WindowInsetsAnimationCallback.AnimationBounds inset(@NonNull android.graphics.Insets);
-  }
-
-  public static final class WindowInsetsAnimationCallback.InsetsAnimation {
-    ctor public WindowInsetsAnimationCallback.InsetsAnimation(int, @Nullable android.view.animation.Interpolator, long);
+  public final class WindowInsetsAnimation {
+    ctor public WindowInsetsAnimation(int, @Nullable android.view.animation.Interpolator, long);
     method @FloatRange(from=0.0f, to=1.0f) public float getAlpha();
     method public long getDurationMillis();
     method @FloatRange(from=0.0f, to=1.0f) public float getFraction();
@@ -55256,6 +55244,24 @@
     method public void setFraction(@FloatRange(from=0.0f, to=1.0f) float);
   }
 
+  public static final class WindowInsetsAnimation.Bounds {
+    ctor public WindowInsetsAnimation.Bounds(@NonNull android.graphics.Insets, @NonNull android.graphics.Insets);
+    method @NonNull public android.graphics.Insets getLowerBound();
+    method @NonNull public android.graphics.Insets getUpperBound();
+    method @NonNull public android.view.WindowInsetsAnimation.Bounds inset(@NonNull android.graphics.Insets);
+  }
+
+  public abstract static class WindowInsetsAnimation.Callback {
+    ctor public WindowInsetsAnimation.Callback(int);
+    method public final int getDispatchMode();
+    method public void onEnd(@NonNull android.view.WindowInsetsAnimation);
+    method public void onPrepare(@NonNull android.view.WindowInsetsAnimation);
+    method @NonNull public abstract android.view.WindowInsets onProgress(@NonNull android.view.WindowInsets, @NonNull java.util.List<android.view.WindowInsetsAnimation>);
+    method @NonNull public android.view.WindowInsetsAnimation.Bounds onStart(@NonNull android.view.WindowInsetsAnimation, @NonNull android.view.WindowInsetsAnimation.Bounds);
+    field public static final int DISPATCH_MODE_CONTINUE_ON_SUBTREE = 1; // 0x1
+    field public static final int DISPATCH_MODE_STOP = 0; // 0x0
+  }
+
   public interface WindowInsetsAnimationControlListener {
     method public void onCancelled();
     method public void onReady(@NonNull android.view.WindowInsetsAnimationController, int);
diff --git a/api/module-lib-lint-baseline.txt b/api/module-lib-lint-baseline.txt
new file mode 100644
index 0000000..6e59596
--- /dev/null
+++ b/api/module-lib-lint-baseline.txt
@@ -0,0 +1,33 @@
+// Baseline format: 1.0
+ActionValue: android.net.TetheringConstants#EXTRA_ADD_TETHER_TYPE:
+    Inconsistent extra value; expected `android.net.extra.ADD_TETHER_TYPE`, was `extraAddTetherType`
+ActionValue: android.net.TetheringConstants#EXTRA_PROVISION_CALLBACK:
+    Inconsistent extra value; expected `android.net.extra.PROVISION_CALLBACK`, was `extraProvisionCallback`
+ActionValue: android.net.TetheringConstants#EXTRA_REM_TETHER_TYPE:
+    Inconsistent extra value; expected `android.net.extra.REM_TETHER_TYPE`, was `extraRemTetherType`
+ActionValue: android.net.TetheringConstants#EXTRA_RUN_PROVISION:
+    Inconsistent extra value; expected `android.net.extra.RUN_PROVISION`, was `extraRunProvision`
+ActionValue: android.net.TetheringConstants#EXTRA_SET_ALARM:
+    Inconsistent extra value; expected `android.net.extra.SET_ALARM`, was `extraSetAlarm`
+ActionValue: android.net.TetheringManager#ACTION_TETHER_STATE_CHANGED:
+    Inconsistent action value; expected `android.net.action.TETHER_STATE_CHANGED`, was `android.net.conn.TETHER_STATE_CHANGED`
+ActionValue: android.net.TetheringManager#EXTRA_ACTIVE_TETHER:
+    Inconsistent extra value; expected `android.net.extra.ACTIVE_TETHER`, was `tetherArray`
+ActionValue: android.net.TetheringManager#EXTRA_AVAILABLE_TETHER:
+    Inconsistent extra value; expected `android.net.extra.AVAILABLE_TETHER`, was `availableArray`
+ActionValue: android.net.TetheringManager#EXTRA_ERRORED_TETHER:
+    Inconsistent extra value; expected `android.net.extra.ERRORED_TETHER`, was `erroredArray`
+
+
+ManagerConstructor: android.net.TetheringManager#TetheringManager(android.content.Context, java.util.function.Supplier<android.os.IBinder>):
+    Managers must always be obtained from Context; no direct constructors
+
+
+PrivateSuperclass: android.location.GnssAntennaInfo.PhaseCenterVariationCorrections:
+    Public class android.location.GnssAntennaInfo.PhaseCenterVariationCorrections extends private class android.location.GnssAntennaInfo.SphericalCorrections
+PrivateSuperclass: android.location.GnssAntennaInfo.SignalGainCorrections:
+    Public class android.location.GnssAntennaInfo.SignalGainCorrections extends private class android.location.GnssAntennaInfo.SphericalCorrections
+
+
+StaticUtils: android.net.TetheringConstants:
+    Fully-static utility classes must not have constructor
diff --git a/api/system-current.txt b/api/system-current.txt
index 8725538..773cd4d 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -18,6 +18,7 @@
     field public static final String ACCESS_SHARED_LIBRARIES = "android.permission.ACCESS_SHARED_LIBRARIES";
     field public static final String ACCESS_SHORTCUTS = "android.permission.ACCESS_SHORTCUTS";
     field public static final String ACCESS_SURFACE_FLINGER = "android.permission.ACCESS_SURFACE_FLINGER";
+    field public static final String ACCESS_TV_DESCRAMBLER = "android.permission.ACCESS_TV_DESCRAMBLER";
     field public static final String ACCESS_TV_TUNER = "android.permission.ACCESS_TV_TUNER";
     field public static final String ACCESS_VIBRATOR_STATE = "android.permission.ACCESS_VIBRATOR_STATE";
     field public static final String ACTIVITY_EMBEDDING = "android.permission.ACTIVITY_EMBEDDING";
@@ -256,7 +257,6 @@
 
   public static final class R.attr {
     field public static final int allowClearUserDataOnFailedRestore = 16844288; // 0x1010600
-    field public static final int isAutofillInlineSuggestionTheme = 16844310; // 0x1010616
     field public static final int isVrOnly = 16844152; // 0x1010578
     field public static final int minExtensionVersion = 16844306; // 0x1010612
     field public static final int requiredSystemPropertyName = 16844133; // 0x1010565
@@ -364,6 +364,7 @@
   }
 
   public class AppOpsManager {
+    method @Nullable @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public android.app.RuntimeAppOpAccessMessage collectRuntimeAppOpAccessMessage();
     method @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public void getHistoricalOps(@NonNull android.app.AppOpsManager.HistoricalOpsRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>);
     method public static String[] getOpStrs();
     method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, @NonNull String, @Nullable java.lang.String...);
@@ -680,6 +681,19 @@
     method public void setNotificationAssistantAccessGranted(@Nullable android.content.ComponentName, boolean);
   }
 
+  public final class RuntimeAppOpAccessMessage implements android.os.Parcelable {
+    ctor public RuntimeAppOpAccessMessage(@IntRange(from=0L) int, @IntRange(from=0L) int, @NonNull String, @Nullable String, @NonNull String, int);
+    method public int describeContents();
+    method @Nullable public String getFeatureId();
+    method @NonNull public String getMessage();
+    method @NonNull public String getOp();
+    method @NonNull public String getPackageName();
+    method public int getSamplingStrategy();
+    method @IntRange(from=0L) public int getUid();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.RuntimeAppOpAccessMessage> CREATOR;
+  }
+
   public class SearchManager implements android.content.DialogInterface.OnCancelListener android.content.DialogInterface.OnDismissListener {
     method public void launchAssist(@Nullable android.os.Bundle);
   }
@@ -4877,7 +4891,7 @@
     method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public static android.media.tv.tuner.DemuxCapabilities getDemuxCapabilities(@NonNull android.content.Context);
     method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public android.media.tv.tuner.frontend.FrontendInfo getFrontendInfo();
     method @Nullable public android.media.tv.tuner.frontend.FrontendStatus getFrontendStatus(@NonNull int[]);
-    method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public android.media.tv.tuner.Descrambler openDescrambler();
+    method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_TV_DESCRAMBLER) public android.media.tv.tuner.Descrambler openDescrambler();
     method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public android.media.tv.tuner.dvr.DvrPlayback openDvrPlayback(long, @Nullable java.util.concurrent.Executor, @Nullable android.media.tv.tuner.dvr.OnPlaybackStatusChangedListener);
     method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public android.media.tv.tuner.dvr.DvrRecorder openDvrRecorder(long, @Nullable java.util.concurrent.Executor, @Nullable android.media.tv.tuner.dvr.OnRecordStatusChangedListener);
     method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public android.media.tv.tuner.filter.Filter openFilter(int, int, long, @Nullable java.util.concurrent.Executor, @Nullable android.media.tv.tuner.filter.FilterCallback);
@@ -4897,8 +4911,10 @@
   }
 
   public final class TunerConstants {
-    field public static final int INVALID_STREAM_ID = -1; // 0xffffffff
-    field public static final int INVALID_TS_PID = -1; // 0xffffffff
+    field public static final int INVALID_AV_SYNC_ID = -1; // 0xffffffff
+    field public static final int INVALID_FILTER_ID = -1; // 0xffffffff
+    field public static final int INVALID_STREAM_ID = 65535; // 0xffff
+    field public static final int INVALID_TS_PID = 65535; // 0xffff
     field public static final int RESULT_INVALID_ARGUMENT = 4; // 0x4
     field public static final int RESULT_INVALID_STATE = 3; // 0x3
     field public static final int RESULT_NOT_INITIALIZED = 2; // 0x2
@@ -7598,7 +7614,7 @@
     field @Deprecated public int numAssociation;
     field @Deprecated public int numScorerOverride;
     field @Deprecated public int numScorerOverrideAndSwitchedNetwork;
-    field @Deprecated public boolean requirePMF;
+    field @Deprecated public boolean requirePmf;
     field @Deprecated @Nullable public String saePasswordId;
     field @Deprecated public boolean shared;
     field @Deprecated public boolean useExternalScores;
@@ -9680,6 +9696,7 @@
     field public static final String ACTION_REQUEST_ENABLE_CONTENT_CAPTURE = "android.settings.REQUEST_ENABLE_CONTENT_CAPTURE";
     field public static final String ACTION_SHOW_ADMIN_SUPPORT_DETAILS = "android.settings.SHOW_ADMIN_SUPPORT_DETAILS";
     field public static final String ACTION_TETHER_PROVISIONING_UI = "android.settings.TETHER_PROVISIONING_UI";
+    field public static final String ACTION_TETHER_SETTINGS = "android.settings.TETHER_SETTINGS";
   }
 
   public static final class Settings.Global extends android.provider.Settings.NameValueTable {
@@ -10186,6 +10203,7 @@
     method public void onConnected();
     method public void onDisconnected();
     method public void onFillRequest(@NonNull android.service.autofill.augmented.FillRequest, @NonNull android.os.CancellationSignal, @NonNull android.service.autofill.augmented.FillController, @NonNull android.service.autofill.augmented.FillCallback);
+    method public final boolean requestAutofill(@NonNull android.content.ComponentName, @NonNull android.view.autofill.AutofillId);
     field public static final String SERVICE_INTERFACE = "android.service.autofill.augmented.AugmentedAutofillService";
   }
 
@@ -14063,6 +14081,14 @@
 
 }
 
+package android.view.inline {
+
+  public final class InlinePresentationSpec implements android.os.Parcelable {
+    method @Nullable public String getStyle();
+  }
+
+}
+
 package android.webkit {
 
   public abstract class CookieManager {
diff --git a/api/system-lint-baseline.txt b/api/system-lint-baseline.txt
index dfb0d74..f440381 100644
--- a/api/system-lint-baseline.txt
+++ b/api/system-lint-baseline.txt
@@ -206,7 +206,7 @@
     
 MutableBareField: android.net.wifi.WifiConfiguration#meteredOverride:
     
-MutableBareField: android.net.wifi.WifiConfiguration#requirePMF:
+MutableBareField: android.net.wifi.WifiConfiguration#requirePmf:
     
 MutableBareField: android.net.wifi.WifiConfiguration#saePasswordId:
     
diff --git a/api/test-current.txt b/api/test-current.txt
index 4c8bb02..79d29f6 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -15,6 +15,7 @@
     field public static final String MANAGE_ACTIVITY_STACKS = "android.permission.MANAGE_ACTIVITY_STACKS";
     field public static final String MANAGE_CRATES = "android.permission.MANAGE_CRATES";
     field public static final String MANAGE_ROLLBACKS = "android.permission.MANAGE_ROLLBACKS";
+    field public static final String NETWORK_SETTINGS = "android.permission.NETWORK_SETTINGS";
     field public static final String NETWORK_STACK = "android.permission.NETWORK_STACK";
     field public static final String READ_CELL_BROADCASTS = "android.permission.READ_CELL_BROADCASTS";
     field public static final String REMOVE_TASKS = "android.permission.REMOVE_TASKS";
@@ -164,6 +165,7 @@
   public class AppOpsManager {
     method @RequiresPermission("android.permission.MANAGE_APPOPS") public void addHistoricalOps(@NonNull android.app.AppOpsManager.HistoricalOps);
     method @RequiresPermission("android.permission.MANAGE_APPOPS") public void clearHistory();
+    method @Nullable @RequiresPermission("android.permission.GET_APP_OPS_STATS") public android.app.RuntimeAppOpAccessMessage collectRuntimeAppOpAccessMessage();
     method @RequiresPermission("android.permission.GET_APP_OPS_STATS") public void getHistoricalOps(@NonNull android.app.AppOpsManager.HistoricalOpsRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>);
     method @RequiresPermission("android.permission.MANAGE_APPOPS") public void getHistoricalOpsFromDiskRaw(@NonNull android.app.AppOpsManager.HistoricalOpsRequest, @Nullable java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>);
     method public static int getNumOps();
@@ -447,6 +449,19 @@
     method public android.graphics.Rect getSourceRectHint();
   }
 
+  public final class RuntimeAppOpAccessMessage implements android.os.Parcelable {
+    ctor public RuntimeAppOpAccessMessage(@IntRange(from=0L) int, @IntRange(from=0L) int, @NonNull String, @Nullable String, @NonNull String, int);
+    method public int describeContents();
+    method @Nullable public String getFeatureId();
+    method @NonNull public String getMessage();
+    method @NonNull public String getOp();
+    method @NonNull public String getPackageName();
+    method public int getSamplingStrategy();
+    method @IntRange(from=0L) public int getUid();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.RuntimeAppOpAccessMessage> CREATOR;
+  }
+
   public class StatusBarManager {
     method public void collapsePanels();
     method public void expandNotificationsPanel();
@@ -2962,6 +2977,9 @@
     field public static final String ENABLED_VR_LISTENERS = "enabled_vr_listeners";
     field public static final String LOCATION_ACCESS_CHECK_DELAY_MILLIS = "location_access_check_delay_millis";
     field public static final String LOCATION_ACCESS_CHECK_INTERVAL_MILLIS = "location_access_check_interval_millis";
+    field public static final String LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS = "lock_screen_allow_private_notifications";
+    field public static final String LOCK_SCREEN_SHOW_NOTIFICATIONS = "lock_screen_show_notifications";
+    field public static final String NFC_PAYMENT_DEFAULT_COMPONENT = "nfc_payment_default_component";
     field public static final String NOTIFICATION_BADGING = "notification_badging";
     field @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public static final String SYNC_PARENT_SOUNDS = "sync_parent_sounds";
     field public static final String USER_SETUP_COMPLETE = "user_setup_complete";
@@ -3188,6 +3206,7 @@
     method public void onConnected();
     method public void onDisconnected();
     method public void onFillRequest(@NonNull android.service.autofill.augmented.FillRequest, @NonNull android.os.CancellationSignal, @NonNull android.service.autofill.augmented.FillController, @NonNull android.service.autofill.augmented.FillCallback);
+    method public final boolean requestAutofill(@NonNull android.content.ComponentName, @NonNull android.view.autofill.AutofillId);
     field public static final String SERVICE_INTERFACE = "android.service.autofill.augmented.AugmentedAutofillService";
   }
 
@@ -3385,6 +3404,34 @@
 
 }
 
+package android.service.quickaccesswallet {
+
+  public interface QuickAccessWalletClient {
+    method public void addWalletServiceEventListener(@NonNull android.service.quickaccesswallet.QuickAccessWalletClient.WalletServiceEventListener);
+    method @NonNull public static android.service.quickaccesswallet.QuickAccessWalletClient create(@NonNull android.content.Context);
+    method @Nullable public android.content.Intent createWalletIntent();
+    method @Nullable public android.content.Intent createWalletSettingsIntent();
+    method public void disconnect();
+    method public void getWalletCards(@NonNull android.service.quickaccesswallet.GetWalletCardsRequest, @NonNull android.service.quickaccesswallet.QuickAccessWalletClient.OnWalletCardsRetrievedCallback);
+    method public boolean isWalletFeatureAvailable();
+    method public boolean isWalletFeatureAvailableWhenDeviceLocked();
+    method public boolean isWalletServiceAvailable();
+    method public void notifyWalletDismissed();
+    method public void removeWalletServiceEventListener(@NonNull android.service.quickaccesswallet.QuickAccessWalletClient.WalletServiceEventListener);
+    method public void selectWalletCard(@NonNull android.service.quickaccesswallet.SelectWalletCardRequest);
+  }
+
+  public static interface QuickAccessWalletClient.OnWalletCardsRetrievedCallback {
+    method public void onWalletCardRetrievalError(@NonNull android.service.quickaccesswallet.GetWalletCardsError);
+    method public void onWalletCardsRetrieved(@NonNull android.service.quickaccesswallet.GetWalletCardsResponse);
+  }
+
+  public static interface QuickAccessWalletClient.WalletServiceEventListener {
+    method public void onWalletServiceEvent(@NonNull android.service.quickaccesswallet.WalletServiceEvent);
+  }
+
+}
+
 package android.service.quicksettings {
 
   public class TileService extends android.app.Service {
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index 1bcf44e..2ee055d 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -120,15 +120,14 @@
         "libstatslog",
         "libstatsmetadata",
         "libsysutils",
-	// TODO(b/145923087): move to shared when statsd is moved to the apex
-        "libstatssocket",
         "libutils",
     ],
     shared_libs: [
-        "libbinder",
+        "libbinder_ndk",
         "libincident",
         "liblog",
-        "statsd-aidl-cpp",
+        "libstatssocket",
+        "statsd-aidl-ndk_platform",
     ],
 }
 
diff --git a/cmds/statsd/src/HashableDimensionKey.cpp b/cmds/statsd/src/HashableDimensionKey.cpp
index 6b9d0e4..d95d594 100644
--- a/cmds/statsd/src/HashableDimensionKey.cpp
+++ b/cmds/statsd/src/HashableDimensionKey.cpp
@@ -25,6 +25,7 @@
 
 using std::string;
 using std::vector;
+using android::base::StringPrintf;
 
 // These constants must be kept in sync with those in StatsDimensionsValue.java
 const static int STATS_DIMENSIONS_VALUE_STRING_TYPE = 2;
@@ -73,7 +74,7 @@
                     break;
                 case STRING:
                     childParcel.valueType = STATS_DIMENSIONS_VALUE_STRING_TYPE;
-                    childParcel.stringValue = String16(dim.mValue.str_value.c_str());
+                    childParcel.stringValue = dim.mValue.str_value;
                     break;
                 default:
                     ALOGE("Encountered FieldValue with unsupported value type.");
diff --git a/cmds/statsd/src/HashableDimensionKey.h b/cmds/statsd/src/HashableDimensionKey.h
index 4adcf96..a766bba 100644
--- a/cmds/statsd/src/HashableDimensionKey.h
+++ b/cmds/statsd/src/HashableDimensionKey.h
@@ -16,7 +16,7 @@
 
 #pragma once
 
-#include <android/os/StatsDimensionsValueParcel.h>
+#include <aidl/android/os/StatsDimensionsValueParcel.h>
 #include <utils/JenkinsHash.h>
 #include <vector>
 #include "android-base/stringprintf.h"
@@ -27,7 +27,7 @@
 namespace os {
 namespace statsd {
 
-using android::base::StringPrintf;
+using ::aidl::android::os::StatsDimensionsValueParcel;
 
 struct Metric2Condition {
     int64_t conditionId;
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 168833f..7087c68 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -28,8 +28,6 @@
 
 #include <android-base/file.h>
 #include <android-base/strings.h>
-#include <binder/IPCThreadState.h>
-#include <binder/PermissionController.h>
 #include <cutils/multiuser.h>
 #include <frameworks/base/cmds/statsd/src/statsd_config.pb.h>
 #include <frameworks/base/cmds/statsd/src/uid_data.pb.h>
@@ -47,85 +45,42 @@
 using android::util::FIELD_COUNT_REPEATED;
 using android::util::FIELD_TYPE_MESSAGE;
 
+using Status = ::ndk::ScopedAStatus;
+
 namespace android {
 namespace os {
 namespace statsd {
 
 constexpr const char* kPermissionDump = "android.permission.DUMP";
-constexpr const char* kPermissionUsage = "android.permission.PACKAGE_USAGE_STATS";
-
-constexpr const char* kOpUsage = "android:get_usage_stats";
 
 #define STATS_SERVICE_DIR "/data/misc/stats-service"
 
 // for StatsDataDumpProto
 const int FIELD_ID_REPORTS_LIST = 1;
 
-static binder::Status ok() {
-    return binder::Status::ok();
-}
-
-static binder::Status exception(uint32_t code, const std::string& msg) {
+static Status exception(int32_t code, const std::string& msg) {
     ALOGE("%s (%d)", msg.c_str(), code);
-    return binder::Status::fromExceptionCode(code, String8(msg.c_str()));
+    return ::ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(code, msg.c_str()));
 }
 
 static bool checkPermission(const char* permission) {
-    pid_t pid = IPCThreadState::self()->getCallingPid();
-    uid_t uid = IPCThreadState::self()->getCallingUid();
+    pid_t pid = AIBinder_getCallingPid();
+    uid_t uid = AIBinder_getCallingUid();
     return checkPermissionForIds(permission, pid, uid);
 }
 
-binder::Status checkUid(uid_t expectedUid) {
-    uid_t uid = IPCThreadState::self()->getCallingUid();
+Status checkUid(uid_t expectedUid) {
+    uid_t uid = AIBinder_getCallingUid();
     if (uid == expectedUid || uid == AID_ROOT) {
-        return ok();
+        return Status::ok();
     } else {
-        return exception(binder::Status::EX_SECURITY,
-                StringPrintf("UID %d is not expected UID %d", uid, expectedUid));
-    }
-}
-
-binder::Status checkDumpAndUsageStats(const String16& packageName) {
-    pid_t pid = IPCThreadState::self()->getCallingPid();
-    uid_t uid = IPCThreadState::self()->getCallingUid();
-
-    // Root, system, and shell always have access
-    if (uid == AID_ROOT || uid == AID_SYSTEM || uid == AID_SHELL) {
-        return ok();
-    }
-
-    // Caller must be granted these permissions
-    if (!checkPermission(kPermissionDump)) {
-        return exception(binder::Status::EX_SECURITY,
-                StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, kPermissionDump));
-    }
-    if (!checkPermission(kPermissionUsage)) {
-        return exception(binder::Status::EX_SECURITY,
-                StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, kPermissionUsage));
-    }
-
-    // Caller must also have usage stats op granted
-    PermissionController pc;
-    switch (pc.noteOp(String16(kOpUsage), uid, packageName)) {
-        case PermissionController::MODE_ALLOWED:
-        case PermissionController::MODE_DEFAULT:
-            return ok();
-        default:
-            return exception(binder::Status::EX_SECURITY,
-                    StringPrintf("UID %d / PID %d lacks app-op %s", uid, pid, kOpUsage));
+        return exception(EX_SECURITY,
+                         StringPrintf("UID %d is not expected UID %d", uid, expectedUid));
     }
 }
 
 #define ENFORCE_UID(uid) {                                        \
-    binder::Status status = checkUid((uid));                      \
-    if (!status.isOk()) {                                         \
-        return status;                                            \
-    }                                                             \
-}
-
-#define ENFORCE_DUMP_AND_USAGE_STATS(packageName) {               \
-    binder::Status status = checkDumpAndUsageStats(packageName);  \
+    Status status = checkUid((uid));                              \
     if (!status.isOk()) {                                         \
         return status;                                            \
     }                                                             \
@@ -134,13 +89,13 @@
 StatsService::StatsService(const sp<Looper>& handlerLooper, shared_ptr<LogEventQueue> queue)
     : mAnomalyAlarmMonitor(new AlarmMonitor(
               MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
-              [](const sp<IStatsCompanionService>& sc, int64_t timeMillis) {
+              [](const shared_ptr<IStatsCompanionService>& sc, int64_t timeMillis) {
                   if (sc != nullptr) {
                       sc->setAnomalyAlarm(timeMillis);
                       StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
                   }
               },
-              [](const sp<IStatsCompanionService>& sc) {
+              [](const shared_ptr<IStatsCompanionService>& sc) {
                   if (sc != nullptr) {
                       sc->cancelAnomalyAlarm();
                       StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
@@ -148,19 +103,21 @@
               })),
       mPeriodicAlarmMonitor(new AlarmMonitor(
               MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
-              [](const sp<IStatsCompanionService>& sc, int64_t timeMillis) {
+              [](const shared_ptr<IStatsCompanionService>& sc, int64_t timeMillis) {
                   if (sc != nullptr) {
                       sc->setAlarmForSubscriberTriggering(timeMillis);
                       StatsdStats::getInstance().noteRegisteredPeriodicAlarmChanged();
                   }
               },
-              [](const sp<IStatsCompanionService>& sc) {
+              [](const shared_ptr<IStatsCompanionService>& sc) {
                   if (sc != nullptr) {
                       sc->cancelAlarmForSubscriberTriggering();
                       StatsdStats::getInstance().noteRegisteredPeriodicAlarmChanged();
                   }
               })),
-      mEventQueue(queue) {
+      mEventQueue(queue),
+      mStatsCompanionServiceDeathRecipient(AIBinder_DeathRecipient_new(
+              StatsService::statsCompanionServiceDied)) {
     mUidMap = UidMap::getInstance();
     mPullerManager = new StatsPullerManager();
     StatsPuller::SetUidMap(mUidMap);
@@ -169,22 +126,20 @@
             mUidMap, mPullerManager, mAnomalyAlarmMonitor, mPeriodicAlarmMonitor,
             getElapsedRealtimeNs(),
             [this](const ConfigKey& key) {
-                sp<IPendingIntentRef> receiver = mConfigManager->GetConfigReceiver(key);
+                shared_ptr<IPendingIntentRef> receiver = mConfigManager->GetConfigReceiver(key);
                 if (receiver == nullptr) {
-                    VLOG("Could not find a broadcast receiver for %s",
-                        key.ToString().c_str());
+                    VLOG("Could not find a broadcast receiver for %s", key.ToString().c_str());
                     return false;
                 } else if (receiver->sendDataBroadcast(
                            mProcessor->getLastReportTimeNs(key)).isOk()) {
                     return true;
                 } else {
-                    VLOG("Failed to send a broadcast for receiver %s",
-                        key.ToString().c_str());
+                    VLOG("Failed to send a broadcast for receiver %s", key.ToString().c_str());
                     return false;
                 }
             },
             [this](const int& uid, const vector<int64_t>& activeConfigs) {
-                sp<IPendingIntentRef> receiver =
+                shared_ptr<IPendingIntentRef> receiver =
                     mConfigManager->GetActiveConfigsChangedReceiver(uid);
                 if (receiver == nullptr) {
                     VLOG("Could not find receiver for uid %d", uid);
@@ -245,36 +200,6 @@
 }
 
 /**
- * Implement our own because the default binder implementation isn't
- * properly handling SHELL_COMMAND_TRANSACTION.
- */
-status_t StatsService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
-                                  uint32_t flags) {
-    switch (code) {
-        case SHELL_COMMAND_TRANSACTION: {
-            int in = data.readFileDescriptor();
-            int out = data.readFileDescriptor();
-            int err = data.readFileDescriptor();
-            int argc = data.readInt32();
-            Vector<String8> args;
-            for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
-                args.add(String8(data.readString16()));
-            }
-            sp<IShellCallback> shellCallback = IShellCallback::asInterface(data.readStrongBinder());
-            sp<IResultReceiver> resultReceiver =
-                    IResultReceiver::asInterface(data.readStrongBinder());
-
-            err = command(in, out, err, args, resultReceiver);
-            if (resultReceiver != nullptr) {
-                resultReceiver->send(err);
-            }
-            return NO_ERROR;
-        }
-        default: { return BnStatsd::onTransact(code, data, reply, flags); }
-    }
-}
-
-/**
  * Write data from statsd.
  * Format for statsdStats:  adb shell dumpsys stats --metadata [-v] [--proto]
  * Format for data report:  adb shell dumpsys stats [anything other than --metadata] [--proto]
@@ -283,20 +208,21 @@
  *     (bugreports call "adb shell dumpsys stats --dump-priority NORMAL -a --proto")
  * TODO: Come up with a more robust method of enacting <serviceutils/PriorityDumper.h>.
  */
-status_t StatsService::dump(int fd, const Vector<String16>& args) {
+status_t StatsService::dump(int fd, const char** args, uint32_t numArgs) {
     if (!checkPermission(kPermissionDump)) {
         return PERMISSION_DENIED;
     }
-    int lastArg = args.size() - 1;
+
+    int lastArg = numArgs - 1;
     bool asProto = false;
-    if (lastArg >= 0 && !args[lastArg].compare(String16("--proto"))) { // last argument
+    if (lastArg >= 0 && string(args[lastArg]) == "--proto") { // last argument
         asProto = true;
         lastArg--;
     }
-    if (args.size() > 0 && !args[0].compare(String16("--metadata"))) { // first argument
+    if (numArgs > 0 && string(args[0]) == "--metadata") { // first argument
         // Request is to dump statsd stats.
         bool verbose = false;
-        if (lastArg >= 0 && !args[lastArg].compare(String16("-v"))) {
+        if (lastArg >= 0 && string(args[lastArg]) == "-v") {
             verbose = true;
             lastArg--;
         }
@@ -351,67 +277,72 @@
 /**
  * Implementation of the adb shell cmd stats command.
  */
-status_t StatsService::command(int in, int out, int err, Vector<String8>& args,
-                               sp<IResultReceiver> resultReceiver) {
-    uid_t uid = IPCThreadState::self()->getCallingUid();
-    if (uid != AID_ROOT && uid != AID_SHELL) {
+status_t StatsService::handleShellCommand(int in, int out, int err, const char** argv,
+                                          uint32_t argc) {
+    uid_t uid = AIBinder_getCallingUid();
+    if (uid != AID_ROOT || uid != AID_SHELL) {
         return PERMISSION_DENIED;
     }
 
-    const int argCount = args.size();
-    if (argCount >= 1) {
+    Vector<String8> utf8Args;
+    utf8Args.setCapacity(argc);
+    for (uint32_t i = 0; i < argc; i++) {
+        utf8Args.push(String8(argv[i]));
+    }
+
+    if (argc >= 1) {
         // adb shell cmd stats config ...
-        if (!args[0].compare(String8("config"))) {
-            return cmd_config(in, out, err, args);
+        if (!utf8Args[0].compare(String8("config"))) {
+            return cmd_config(in, out, err, utf8Args);
         }
 
-        if (!args[0].compare(String8("print-uid-map"))) {
-            return cmd_print_uid_map(out, args);
+        if (!utf8Args[0].compare(String8("print-uid-map"))) {
+            return cmd_print_uid_map(out, utf8Args);
         }
 
-        if (!args[0].compare(String8("dump-report"))) {
-            return cmd_dump_report(out, args);
+        if (!utf8Args[0].compare(String8("dump-report"))) {
+            return cmd_dump_report(out, utf8Args);
         }
 
-        if (!args[0].compare(String8("pull-source")) && args.size() > 1) {
-            return cmd_print_pulled_metrics(out, args);
+        if (!utf8Args[0].compare(String8("pull-source")) && argc > 1) {
+            return cmd_print_pulled_metrics(out, utf8Args);
         }
 
-        if (!args[0].compare(String8("send-broadcast"))) {
-            return cmd_trigger_broadcast(out, args);
+        if (!utf8Args[0].compare(String8("send-broadcast"))) {
+            return cmd_trigger_broadcast(out, utf8Args);
         }
 
-        if (!args[0].compare(String8("print-stats"))) {
-            return cmd_print_stats(out, args);
+        if (!utf8Args[0].compare(String8("print-stats"))) {
+            return cmd_print_stats(out, utf8Args);
         }
 
-        if (!args[0].compare(String8("meminfo"))) {
+        if (!utf8Args[0].compare(String8("meminfo"))) {
             return cmd_dump_memory_info(out);
         }
 
-        if (!args[0].compare(String8("write-to-disk"))) {
+        if (!utf8Args[0].compare(String8("write-to-disk"))) {
             return cmd_write_data_to_disk(out);
         }
 
-        if (!args[0].compare(String8("log-app-breadcrumb"))) {
-            return cmd_log_app_breadcrumb(out, args);
+        if (!utf8Args[0].compare(String8("log-app-breadcrumb"))) {
+            return cmd_log_app_breadcrumb(out, utf8Args);
         }
 
-        if (!args[0].compare(String8("log-binary-push"))) {
-            return cmd_log_binary_push(out, args);
+        if (!utf8Args[0].compare(String8("log-binary-push"))) {
+            return cmd_log_binary_push(out, utf8Args);
         }
 
-        if (!args[0].compare(String8("clear-puller-cache"))) {
+        if (!utf8Args[0].compare(String8("clear-puller-cache"))) {
             return cmd_clear_puller_cache(out);
         }
 
-        if (!args[0].compare(String8("print-logs"))) {
-            return cmd_print_logs(out, args);
+        if (!utf8Args[0].compare(String8("print-logs"))) {
+            return cmd_print_logs(out, utf8Args);
         }
-        if (!args[0].compare(String8("send-active-configs"))) {
-            return cmd_trigger_active_config_broadcast(out, args);
+        if (!utf8Args[0].compare(String8("send-active-configs"))) {
+            return cmd_trigger_active_config_broadcast(out, utf8Args);
         }
-        if (!args[0].compare(String8("data-subscribe"))) {
+        if (!utf8Args[0].compare(String8("data-subscribe"))) {
             {
                 std::lock_guard<std::mutex> lock(mShellSubscriberMutex);
                 if (mShellSubscriber == nullptr) {
@@ -419,14 +350,10 @@
                 }
             }
             int timeoutSec = -1;
-            if (argCount >= 2) {
-                timeoutSec = atoi(args[1].c_str());
+            if (argc >= 2) {
+                timeoutSec = atoi(utf8Args[1].c_str());
             }
-            if (resultReceiver == nullptr) {
-                ALOGI("Null resultReceiver given, no subscription will be started");
-                return UNEXPECTED_NULL;
-            }
-            mShellSubscriber->startNewSubscription(in, out, resultReceiver, timeoutSec);
+            mShellSubscriber->startNewSubscription(in, out, timeoutSec);
             return NO_ERROR;
         }
     }
@@ -556,7 +483,7 @@
     const int argCount = args.size();
     if (argCount == 2) {
         // Automatically pick the UID
-        uid = IPCThreadState::self()->getCallingUid();
+        uid = AIBinder_getCallingUid();
         name.assign(args[1].c_str(), args[1].size());
         good = true;
     } else if (argCount == 3) {
@@ -572,17 +499,15 @@
         return UNKNOWN_ERROR;
     }
     ConfigKey key(uid, StrToInt64(name));
-    sp<IPendingIntentRef> receiver = mConfigManager->GetConfigReceiver(key);
+    shared_ptr<IPendingIntentRef> receiver = mConfigManager->GetConfigReceiver(key);
     if (receiver == nullptr) {
         VLOG("Could not find receiver for %s, %s", args[1].c_str(), args[2].c_str());
         return UNKNOWN_ERROR;
-    } else if (receiver->sendDataBroadcast(
-               mProcessor->getLastReportTimeNs(key)).isOk()) {
+    } else if (receiver->sendDataBroadcast(mProcessor->getLastReportTimeNs(key)).isOk()) {
         VLOG("StatsService::trigger broadcast succeeded to %s, %s", args[1].c_str(),
              args[2].c_str());
     } else {
-        VLOG("StatsService::trigger broadcast failed to %s, %s", args[1].c_str(),
-             args[2].c_str());
+        VLOG("StatsService::trigger broadcast failed to %s, %s", args[1].c_str(), args[2].c_str());
         return UNKNOWN_ERROR;
     }
     return NO_ERROR;
@@ -594,7 +519,7 @@
     vector<int64_t> configIds;
     if (argCount == 1) {
         // Automatically pick the uid and send a broadcast that has no active configs.
-        uid = IPCThreadState::self()->getCallingUid();
+        uid = AIBinder_getCallingUid();
         mProcessor->GetActiveConfigs(uid, configIds);
     } else {
         int curArg = 1;
@@ -608,7 +533,7 @@
             }
             curArg++;
         } else {
-            uid = IPCThreadState::self()->getCallingUid();
+            uid = AIBinder_getCallingUid();
         }
         if (curArg == argCount || args[curArg] != "--configs") {
             VLOG("Reached end of args, or specify configs not set. Sending actual active configs,");
@@ -628,7 +553,7 @@
             }
         }
     }
-    sp<IPendingIntentRef> receiver = mConfigManager->GetActiveConfigsChangedReceiver(uid);
+    shared_ptr<IPendingIntentRef> receiver = mConfigManager->GetActiveConfigsChangedReceiver(uid);
     if (receiver == nullptr) {
         VLOG("Could not find receiver for uid %d", uid);
         return UNKNOWN_ERROR;
@@ -651,7 +576,7 @@
 
             if (argCount == 3) {
                 // Automatically pick the UID
-                uid = IPCThreadState::self()->getCallingUid();
+                uid = AIBinder_getCallingUid();
                 name.assign(args[2].c_str(), args[2].size());
                 good = true;
             } else if (argCount == 4) {
@@ -734,7 +659,7 @@
         }
         if (argCount == 2) {
             // Automatically pick the UID
-            uid = IPCThreadState::self()->getCallingUid();
+            uid = AIBinder_getCallingUid();
             name.assign(args[1].c_str(), args[1].size());
             good = true;
         } else if (argCount == 3) {
@@ -826,7 +751,7 @@
     const int argCount = args.size();
     if (argCount == 3) {
         // Automatically pick the UID
-        uid = IPCThreadState::self()->getCallingUid();
+        uid = AIBinder_getCallingUid();
         label = atoi(args[1].c_str());
         state = atoi(args[2].c_str());
         good = true;
@@ -903,9 +828,8 @@
 }
 
 status_t StatsService::cmd_clear_puller_cache(int out) {
-    IPCThreadState* ipc = IPCThreadState::self();
     VLOG("StatsService::cmd_clear_puller_cache with Pid %i, Uid %i",
-            ipc->getCallingPid(), ipc->getCallingUid());
+            AIBinder_getCallingPid(), AIBinder_getCallingUid());
     if (checkPermission(kPermissionDump)) {
         int cleared = mPullerManager->ForceClearPullerCache();
         dprintf(out, "Puller removed %d cached data!\n", cleared);
@@ -916,9 +840,8 @@
 }
 
 status_t StatsService::cmd_print_logs(int out, const Vector<String8>& args) {
-    IPCThreadState* ipc = IPCThreadState::self();
-    VLOG("StatsService::cmd_print_logs with Pid %i, Uid %i", ipc->getCallingPid(),
-         ipc->getCallingUid());
+    VLOG("StatsService::cmd_print_logs with Pid %i, Uid %i", AIBinder_getCallingPid(),
+         AIBinder_getCallingUid());
     if (checkPermission(kPermissionDump)) {
         bool enabled = true;
         if (args.size() >= 2) {
@@ -950,24 +873,24 @@
     }
     uid = goodUid;
 
-    int32_t callingUid = IPCThreadState::self()->getCallingUid();
+    int32_t callingUid = AIBinder_getCallingUid();
     return mEngBuild // UserDebug/EngBuild are allowed to impersonate uids.
             || (callingUid == goodUid) // Anyone can 'impersonate' themselves.
             || (callingUid == AID_ROOT && goodUid == AID_SHELL); // ROOT can impersonate SHELL.
 }
 
-Status StatsService::informAllUidData(const ParcelFileDescriptor& fd) {
+Status StatsService::informAllUidData(const ScopedFileDescriptor& fd) {
     ENFORCE_UID(AID_SYSTEM);
     // Read stream into buffer.
     string buffer;
     if (!android::base::ReadFdToString(fd.get(), &buffer)) {
-        return exception(Status::EX_ILLEGAL_ARGUMENT, "Failed to read all data from the pipe.");
+        return exception(EX_ILLEGAL_ARGUMENT, "Failed to read all data from the pipe.");
     }
 
     // Parse buffer.
     UidData uidData;
     if (!uidData.ParseFromString(buffer)) {
-        return exception(Status::EX_ILLEGAL_ARGUMENT, "Error parsing proto stream for UidData.");
+        return exception(EX_ILLEGAL_ARGUMENT, "Error parsing proto stream for UidData.");
     }
 
     vector<String16> versionStrings;
@@ -1002,20 +925,28 @@
     return Status::ok();
 }
 
-Status StatsService::informOnePackage(const String16& app, int32_t uid, int64_t version,
-                                      const String16& version_string, const String16& installer) {
+Status StatsService::informOnePackage(const string& app, int32_t uid, int64_t version,
+                                      const string& versionString, const string& installer) {
     ENFORCE_UID(AID_SYSTEM);
 
     VLOG("StatsService::informOnePackage was called");
-    mUidMap->updateApp(getElapsedRealtimeNs(), app, uid, version, version_string, installer);
+    // TODO(b/149254662): This is gross. We should consider changing statsd
+    // internals to use std::string.
+    String16 utf16App = String16(app.c_str());
+    String16 utf16VersionString = String16(versionString.c_str());
+    String16 utf16Installer = String16(installer.c_str());
+
+    mUidMap->updateApp(getElapsedRealtimeNs(), utf16App, uid, version, utf16VersionString,
+                       utf16Installer);
     return Status::ok();
 }
 
-Status StatsService::informOnePackageRemoved(const String16& app, int32_t uid) {
+Status StatsService::informOnePackageRemoved(const string& app, int32_t uid) {
     ENFORCE_UID(AID_SYSTEM);
 
     VLOG("StatsService::informOnePackageRemoved was called");
-    mUidMap->removeApp(getElapsedRealtimeNs(), app, uid);
+    String16 utf16App = String16(app.c_str());
+    mUidMap->removeApp(getElapsedRealtimeNs(), utf16App, uid);
     mConfigManager->RemoveConfigs(uid);
     return Status::ok();
 }
@@ -1079,7 +1010,7 @@
 }
 
 void StatsService::sayHiToStatsCompanion() {
-    sp<IStatsCompanionService> statsCompanion = getStatsCompanionService();
+    shared_ptr<IStatsCompanionService> statsCompanion = getStatsCompanionService();
     if (statsCompanion != nullptr) {
         VLOG("Telling statsCompanion that statsd is ready");
         statsCompanion->statsdReady();
@@ -1092,14 +1023,14 @@
     ENFORCE_UID(AID_SYSTEM);
 
     VLOG("StatsService::statsCompanionReady was called");
-    sp<IStatsCompanionService> statsCompanion = getStatsCompanionService();
+    shared_ptr<IStatsCompanionService> statsCompanion = getStatsCompanionService();
     if (statsCompanion == nullptr) {
-        return Status::fromExceptionCode(
-                Status::EX_NULL_POINTER,
-                "statscompanion unavailable despite it contacting statsd!");
+        return exception(EX_NULL_POINTER,
+                         "StatsCompanion unavailable despite it contacting statsd.");
     }
     VLOG("StatsService::statsCompanionReady linking to statsCompanion.");
-    IInterface::asBinder(statsCompanion)->linkToDeath(this);
+    AIBinder_linkToDeath(statsCompanion->asBinder().get(),
+                         mStatsCompanionServiceDeathRecipient.get(), this);
     mPullerManager->SetStatsCompanionService(statsCompanion);
     mAnomalyAlarmMonitor->setStatsCompanionService(statsCompanion);
     mPeriodicAlarmMonitor->setStatsCompanionService(statsCompanion);
@@ -1127,39 +1058,47 @@
     }
 }
 
-Status StatsService::getData(int64_t key, const int32_t callingUid, vector<uint8_t>* output) {
+Status StatsService::getData(int64_t key, const int32_t callingUid, vector<int8_t>* output) {
     ENFORCE_UID(AID_SYSTEM);
 
     VLOG("StatsService::getData with Uid %i", callingUid);
     ConfigKey configKey(callingUid, key);
+    // TODO(b/149254662): Since libbinder_ndk uses int8_t instead of uint8_t,
+    // there are inconsistencies with internal statsd logic. Instead of
+    // modifying lots of files, we create a temporary output array of int8_t and
+    // copy its data into output. This is a bad hack, but hopefully
+    // libbinder_ndk will transition to using uint8_t soon: progress is tracked
+    // in b/144957764. Same applies to StatsService::getMetadata.
+    vector<uint8_t> unsignedOutput;
     // The dump latency does not matter here since we do not include the current bucket, we do not
     // need to pull any new data anyhow.
     mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(), false /* include_current_bucket*/,
-                             true /* erase_data */, GET_DATA_CALLED, FAST, output);
+                             true /* erase_data */, GET_DATA_CALLED, FAST, &unsignedOutput);
+    *output = vector<int8_t>(unsignedOutput.begin(), unsignedOutput.end());
     return Status::ok();
 }
 
-Status StatsService::getMetadata(vector<uint8_t>* output) {
+Status StatsService::getMetadata(vector<int8_t>* output) {
     ENFORCE_UID(AID_SYSTEM);
 
-    StatsdStats::getInstance().dumpStats(output, false); // Don't reset the counters.
+    vector<uint8_t> unsignedOutput;
+    StatsdStats::getInstance().dumpStats(&unsignedOutput, false); // Don't reset the counters.
+    *output = vector<int8_t>(unsignedOutput.begin(), unsignedOutput.end());
     return Status::ok();
 }
 
-Status StatsService::addConfiguration(int64_t key, const vector <uint8_t>& config,
+Status StatsService::addConfiguration(int64_t key, const vector <int8_t>& config,
                                       const int32_t callingUid) {
     ENFORCE_UID(AID_SYSTEM);
 
     if (addConfigurationChecked(callingUid, key, config)) {
         return Status::ok();
     } else {
-        ALOGE("Could not parse malformatted StatsdConfig");
-        return Status::fromExceptionCode(binder::Status::EX_ILLEGAL_ARGUMENT,
-                                         "config does not correspond to a StatsdConfig proto");
+        return exception(EX_ILLEGAL_ARGUMENT, "Could not parse malformatted StatsdConfig.");
     }
 }
 
-bool StatsService::addConfigurationChecked(int uid, int64_t key, const vector<uint8_t>& config) {
+bool StatsService::addConfigurationChecked(int uid, int64_t key, const vector<int8_t>& config) {
     ConfigKey configKey(uid, key);
     StatsdConfig cfg;
     if (config.size() > 0) {  // If the config is empty, skip parsing.
@@ -1180,7 +1119,7 @@
 }
 
 Status StatsService::setDataFetchOperation(int64_t key,
-                                           const sp<IPendingIntentRef>& pir,
+                                           const shared_ptr<IPendingIntentRef>& pir,
                                            const int32_t callingUid) {
     ENFORCE_UID(AID_SYSTEM);
 
@@ -1194,7 +1133,7 @@
     return Status::ok();
 }
 
-Status StatsService::setActiveConfigsChangedOperation(const sp<IPendingIntentRef>& pir,
+Status StatsService::setActiveConfigsChangedOperation(const shared_ptr<IPendingIntentRef>& pir,
                                                       const int32_t callingUid,
                                                       vector<int64_t>* output) {
     ENFORCE_UID(AID_SYSTEM);
@@ -1225,7 +1164,7 @@
 
 Status StatsService::setBroadcastSubscriber(int64_t configId,
                                             int64_t subscriberId,
-                                            const sp<IPendingIntentRef>& pir,
+                                            const shared_ptr<IPendingIntentRef>& pir,
                                             const int32_t callingUid) {
     ENFORCE_UID(AID_SYSTEM);
 
@@ -1252,14 +1191,14 @@
     // Permission check not necessary as it's meant for applications to write to
     // statsd.
     android::util::stats_write(util::APP_BREADCRUMB_REPORTED,
-                               (int32_t) IPCThreadState::self()->getCallingUid(), label,
+                               (int32_t) AIBinder_getCallingUid(), label,
                                state);
     return Status::ok();
 }
 
 Status StatsService::registerPullAtomCallback(int32_t uid, int32_t atomTag, int64_t coolDownNs,
                                     int64_t timeoutNs, const std::vector<int32_t>& additiveFields,
-                                    const sp<android::os::IPullAtomCallback>& pullerCallback) {
+                                    const shared_ptr<IPullAtomCallback>& pullerCallback) {
     ENFORCE_UID(AID_SYSTEM);
 
     VLOG("StatsService::registerPullAtomCallback called.");
@@ -1270,10 +1209,10 @@
 
 Status StatsService::registerNativePullAtomCallback(int32_t atomTag, int64_t coolDownNs,
                                     int64_t timeoutNs, const std::vector<int32_t>& additiveFields,
-                                    const sp<android::os::IPullAtomCallback>& pullerCallback) {
+                                    const shared_ptr<IPullAtomCallback>& pullerCallback) {
 
     VLOG("StatsService::registerNativePullAtomCallback called.");
-    int32_t uid = IPCThreadState::self()->getCallingUid();
+    int32_t uid = AIBinder_getCallingUid();
     mPullerManager->RegisterPullAtomCallback(uid, atomTag, coolDownNs, timeoutNs, additiveFields,
                                              pullerCallback);
     return Status::ok();
@@ -1288,7 +1227,7 @@
 
 Status StatsService::unregisterNativePullAtomCallback(int32_t atomTag) {
     VLOG("StatsService::unregisterNativePullAtomCallback called.");
-    int32_t uid = IPCThreadState::self()->getCallingUid();
+    int32_t uid = AIBinder_getCallingUid();
     mPullerManager->UnregisterPullAtomCallback(uid, atomTag);
     return Status::ok();
 }
@@ -1314,7 +1253,13 @@
     return Status::ok();
 }
 
-void StatsService::binderDied(const wp <IBinder>& who) {
+
+void StatsService::statsCompanionServiceDied(void* cookie) {
+    auto thiz = static_cast<StatsService*>(cookie);
+    thiz->statsCompanionServiceDiedImpl();
+}
+
+void StatsService::statsCompanionServiceDiedImpl() {
     ALOGW("statscompanion service died");
     StatsdStats::getInstance().noteSystemServerRestart(getWallClockSec());
     if (mProcessor != nullptr) {
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index 0527d43..e6723c8 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -27,27 +27,30 @@
 #include "shell/ShellSubscriber.h"
 #include "statscompanion_util.h"
 
-#include <android/os/BnStatsd.h>
-#include <android/os/IPendingIntentRef.h>
-#include <android/os/IStatsCompanionService.h>
-#include <android/os/IStatsd.h>
-#include <binder/IResultReceiver.h>
-#include <binder/ParcelFileDescriptor.h>
+#include <aidl/android/os/BnStatsd.h>
+#include <aidl/android/os/IPendingIntentRef.h>
+#include <aidl/android/os/IPullAtomCallback.h>
 #include <utils/Looper.h>
 
 #include <mutex>
 
 using namespace android;
-using namespace android::binder;
 using namespace android::os;
 using namespace std;
 
+using Status = ::ndk::ScopedAStatus;
+using aidl::android::os::BnStatsd;
+using aidl::android::os::IPendingIntentRef;
+using aidl::android::os::IPullAtomCallback;
+using ::ndk::ScopedAIBinder_DeathRecipient;
+using ::ndk::ScopedFileDescriptor;
+using std::shared_ptr;
+
 namespace android {
 namespace os {
 namespace statsd {
 
-class StatsService : public BnStatsd,
-                     public IBinder::DeathRecipient {
+class StatsService : public BnStatsd {
 public:
     StatsService(const sp<Looper>& handlerLooper, std::shared_ptr<LogEventQueue> queue);
     virtual ~StatsService();
@@ -55,10 +58,9 @@
     /** The anomaly alarm registered with AlarmManager won't be updated by less than this. */
     const uint32_t MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS = 5;
 
-    virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
-    virtual status_t dump(int fd, const Vector<String16>& args);
-    virtual status_t command(int inFd, int outFd, int err, Vector<String8>& args,
-                             sp<IResultReceiver> resultReceiver);
+    virtual status_t dump(int fd, const char** args, uint32_t numArgs) override;
+    virtual status_t handleShellCommand(int in, int out, int err, const char** argv,
+                                        uint32_t argc) override;
 
     virtual Status systemRunning();
     virtual Status statsCompanionReady();
@@ -66,10 +68,10 @@
     virtual Status informPollAlarmFired();
     virtual Status informAlarmForSubscriberTriggeringFired();
 
-    virtual Status informAllUidData(const ParcelFileDescriptor& fd);
-    virtual Status informOnePackage(const String16& app, int32_t uid, int64_t version,
-                                    const String16& version_string, const String16& installer);
-    virtual Status informOnePackageRemoved(const String16& app, int32_t uid);
+    virtual Status informAllUidData(const ScopedFileDescriptor& fd);
+    virtual Status informOnePackage(const string& app, int32_t uid, int64_t version,
+                                    const string& versionString, const string& installer);
+    virtual Status informOnePackageRemoved(const string& app, int32_t uid);
     virtual Status informDeviceShutdown();
 
     /**
@@ -92,13 +94,13 @@
      */
     virtual Status getData(int64_t key,
                            const int32_t callingUid,
-                           vector<uint8_t>* output) override;
+                           vector<int8_t>* output) override;
 
 
     /**
      * Binder call for clients to get metadata across all configs in statsd.
      */
-    virtual Status getMetadata(vector<uint8_t>* output) override;
+    virtual Status getMetadata(vector<int8_t>* output) override;
 
 
     /**
@@ -106,14 +108,14 @@
      * should requestData for this configuration.
      */
     virtual Status addConfiguration(int64_t key,
-                                    const vector<uint8_t>& config,
+                                    const vector<int8_t>& config,
                                     const int32_t callingUid) override;
 
     /**
      * Binder call to let clients register the data fetch operation for a configuration.
      */
     virtual Status setDataFetchOperation(int64_t key,
-                                         const sp<IPendingIntentRef>& pir,
+                                         const shared_ptr<IPendingIntentRef>& pir,
                                          const int32_t callingUid) override;
 
     /**
@@ -125,7 +127,7 @@
     /**
      * Binder call to let clients register the active configs changed operation.
      */
-    virtual Status setActiveConfigsChangedOperation(const sp<IPendingIntentRef>& pir,
+    virtual Status setActiveConfigsChangedOperation(const shared_ptr<IPendingIntentRef>& pir,
                                                     const int32_t callingUid,
                                                     vector<int64_t>* output) override;
 
@@ -144,7 +146,7 @@
      */
     virtual Status setBroadcastSubscriber(int64_t configId,
                                           int64_t subscriberId,
-                                          const sp<IPendingIntentRef>& pir,
+                                          const shared_ptr<IPendingIntentRef>& pir,
                                           const int32_t callingUid) override;
 
     /**
@@ -167,14 +169,14 @@
      */
     virtual Status registerPullAtomCallback(int32_t uid, int32_t atomTag, int64_t coolDownNs,
             int64_t timeoutNs, const std::vector<int32_t>& additiveFields,
-            const sp<android::os::IPullAtomCallback>& pullerCallback) override;
+            const shared_ptr<IPullAtomCallback>& pullerCallback) override;
 
     /**
      * Binder call to register a callback function for a pulled atom.
      */
     virtual Status registerNativePullAtomCallback(int32_t atomTag, int64_t coolDownNs,
             int64_t timeoutNs, const std::vector<int32_t>& additiveFields,
-            const sp<android::os::IPullAtomCallback>& pullerCallback) override;
+            const shared_ptr<IPullAtomCallback>& pullerCallback) override;
 
     /**
      * Binder call to unregister any existing callback for the given uid and atom.
@@ -191,9 +193,6 @@
      */
     virtual Status getRegisteredExperimentIds(std::vector<int64_t>* expIdsOut);
 
-    /** IBinder::DeathRecipient */
-    virtual void binderDied(const wp<IBinder>& who) override;
-
 private:
     /**
      * Load system properties at init.
@@ -317,7 +316,7 @@
     /**
      * Adds a configuration after checking permissions and obtaining UID from binder call.
      */
-    bool addConfigurationChecked(int uid, int64_t key, const vector<uint8_t>& config);
+    bool addConfigurationChecked(int uid, int64_t key, const vector<int8_t>& config);
 
     /**
      * Update a configuration.
@@ -325,6 +324,17 @@
     void set_config(int uid, const string& name, const StatsdConfig& config);
 
     /**
+     * Death recipient callback that is called when StatsCompanionService dies.
+     * The cookie is a pointer to a StatsService object.
+     */
+    static void statsCompanionServiceDied(void* cookie);
+
+    /**
+     * Implementation of statsCompanionServiceDied.
+     */
+    void statsCompanionServiceDiedImpl();
+
+    /**
      * Tracks the uid <--> package name mapping.
      */
     sp<UidMap> mUidMap;
@@ -367,6 +377,8 @@
     mutable mutex mShellSubscriberMutex;
     std::shared_ptr<LogEventQueue> mEventQueue;
 
+    ScopedAIBinder_DeathRecipient mStatsCompanionServiceDeathRecipient;
+
     FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart);
     FRIEND_TEST(StatsServiceTest, TestAddConfig_simple);
     FRIEND_TEST(StatsServiceTest, TestAddConfig_empty);
diff --git a/cmds/statsd/src/anomaly/AlarmMonitor.cpp b/cmds/statsd/src/anomaly/AlarmMonitor.cpp
index bc36dad..02291181 100644
--- a/cmds/statsd/src/anomaly/AlarmMonitor.cpp
+++ b/cmds/statsd/src/anomaly/AlarmMonitor.cpp
@@ -26,17 +26,21 @@
 
 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),
+        const std::function<void(const shared_ptr<IStatsCompanionService>&, int64_t)>& updateAlarm,
+        const std::function<void(const shared_ptr<IStatsCompanionService>&)>& cancelAlarm)
+    : mRegisteredAlarmTimeSec(0),
+      mMinUpdateTimeSec(minDiffToUpdateRegisteredAlarmTimeSec),
       mUpdateAlarm(updateAlarm),
       mCancelAlarm(cancelAlarm) {}
 
 AlarmMonitor::~AlarmMonitor() {}
 
-void AlarmMonitor::setStatsCompanionService(sp<IStatsCompanionService> statsCompanionService) {
+void AlarmMonitor::setStatsCompanionService(
+        shared_ptr<IStatsCompanionService> statsCompanionService) {
     std::lock_guard<std::mutex> lock(mLock);
-    sp<IStatsCompanionService> tmpForLock = mStatsCompanionService;
+    // TODO(b/149254662): determine if tmpForLock is needed now that we have moved
+    // from sp to shared_ptr
+    shared_ptr<IStatsCompanionService> tmpForLock = mStatsCompanionService;
     mStatsCompanionService = statsCompanionService;
     if (statsCompanionService == nullptr) {
         VLOG("Erasing link to statsCompanionService");
diff --git a/cmds/statsd/src/anomaly/AlarmMonitor.h b/cmds/statsd/src/anomaly/AlarmMonitor.h
index 219695e..5c34e38 100644
--- a/cmds/statsd/src/anomaly/AlarmMonitor.h
+++ b/cmds/statsd/src/anomaly/AlarmMonitor.h
@@ -18,7 +18,7 @@
 
 #include "anomaly/indexed_priority_queue.h"
 
-#include <android/os/IStatsCompanionService.h>
+#include <aidl/android/os/IStatsCompanionService.h>
 #include <utils/RefBase.h>
 
 #include <unordered_set>
@@ -26,7 +26,9 @@
 
 using namespace android;
 
-using android::os::IStatsCompanionService;
+using aidl::android::os::IStatsCompanionService;
+using std::function;
+using std::shared_ptr;
 using std::unordered_set;
 
 namespace android {
@@ -64,8 +66,9 @@
      * alarm.
      */
     AlarmMonitor(uint32_t minDiffToUpdateRegisteredAlarmTimeSec,
-                 const std::function<void(const sp<IStatsCompanionService>&, int64_t)>& updateAlarm,
-                 const std::function<void(const sp<IStatsCompanionService>&)>& cancelAlarm);
+                 const function<void(const shared_ptr<IStatsCompanionService>&, int64_t)>&
+                         updateAlarm,
+                 const function<void(const shared_ptr<IStatsCompanionService>&)>& cancelAlarm);
     ~AlarmMonitor();
 
     /**
@@ -74,7 +77,7 @@
      * If nullptr, AnomalyMonitor will continue to add/remove alarms, but won't
      * update IStatsCompanionService (until such time as it is set non-null).
      */
-    void setStatsCompanionService(sp<IStatsCompanionService> statsCompanionService);
+    void setStatsCompanionService(shared_ptr<IStatsCompanionService> statsCompanionService);
 
     /**
      * Adds the given alarm (reference) to the queue.
@@ -123,7 +126,7 @@
     /**
      * Binder interface for communicating with StatsCompanionService.
      */
-    sp<IStatsCompanionService> mStatsCompanionService = nullptr;
+    shared_ptr<IStatsCompanionService> mStatsCompanionService = nullptr;
 
     /**
      * Amount by which the soonest projected alarm must differ from
@@ -147,10 +150,10 @@
     int64_t secToMs(uint32_t timeSec);
 
     // Callback function to update the alarm via StatsCompanionService.
-    std::function<void(const sp<IStatsCompanionService>, int64_t)> mUpdateAlarm;
+    std::function<void(const shared_ptr<IStatsCompanionService>, int64_t)> mUpdateAlarm;
 
     // Callback function to cancel the alarm via StatsCompanionService.
-    std::function<void(const sp<IStatsCompanionService>)> mCancelAlarm;
+    std::function<void(const shared_ptr<IStatsCompanionService>)> mCancelAlarm;
 
 };
 
diff --git a/cmds/statsd/src/anomaly/AlarmTracker.h b/cmds/statsd/src/anomaly/AlarmTracker.h
index 2fb3e3b..2da4a18 100644
--- a/cmds/statsd/src/anomaly/AlarmTracker.h
+++ b/cmds/statsd/src/anomaly/AlarmTracker.h
@@ -22,12 +22,9 @@
 #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 {
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 23a4437..27c4f4e 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -8000,6 +8000,18 @@
     // of this pull. If this number grows prohibitively large, then this can
     // cause jank due to resource contention.
     optional int32 event_connection_count = 6;
+    // Set of timings measured from when SurfaceFlinger began compositing a
+    // frame, until the frame was requested to be presented to the display. This
+    // measures SurfaceFlinger's total CPU walltime on the critical path per
+    // frame.
+    optional FrameTimingHistogram frame_duration = 7
+        [(android.os.statsd.log_mode) = MODE_BYTES];
+    // Set of timings measured from when SurfaceFlinger first began using the
+    // GPU to composite a frame, until the GPU has finished compositing that
+    // frame. This measures the total additional time SurfaceFlinger needed to
+    // perform due to falling back into GPU composition.
+    optional FrameTimingHistogram render_engine_timing = 8
+        [(android.os.statsd.log_mode) = MODE_BYTES];
 }
 
 /**
diff --git a/cmds/statsd/src/config/ConfigManager.cpp b/cmds/statsd/src/config/ConfigManager.cpp
index 986955b..9bdb588 100644
--- a/cmds/statsd/src/config/ConfigManager.cpp
+++ b/cmds/statsd/src/config/ConfigManager.cpp
@@ -42,42 +42,67 @@
 using android::base::StringPrintf;
 using std::unique_ptr;
 
-class ConfigReceiverDeathRecipient : public android::IBinder::DeathRecipient {
-    public:
-        ConfigReceiverDeathRecipient(sp<ConfigManager> configManager, const ConfigKey& configKey):
-            mConfigManager(configManager),
-            mConfigKey(configKey) {}
-        ~ConfigReceiverDeathRecipient() override = default;
-    private:
-        sp<ConfigManager> mConfigManager;
-        ConfigKey mConfigKey;
+struct ConfigReceiverDeathCookie {
+    ConfigReceiverDeathCookie(sp<ConfigManager> configManager, const ConfigKey& configKey,
+                              const shared_ptr<IPendingIntentRef>& pir):
+        mConfigManager(configManager),
+        mConfigKey(configKey),
+        mPir(pir) {}
 
-    void binderDied(const android::wp<android::IBinder>& who) override {
-        if (IInterface::asBinder(mConfigManager->GetConfigReceiver(mConfigKey)) == who.promote()) {
-             mConfigManager->RemoveConfigReceiver(mConfigKey);
-        }
-    }
+    sp<ConfigManager> mConfigManager;
+    ConfigKey mConfigKey;
+    shared_ptr<IPendingIntentRef> mPir;
 };
 
-class ActiveConfigChangedReceiverDeathRecipient : public android::IBinder::DeathRecipient {
-    public:
-        ActiveConfigChangedReceiverDeathRecipient(sp<ConfigManager> configManager, const int uid):
-            mConfigManager(configManager),
-            mUid(uid) {}
-        ~ActiveConfigChangedReceiverDeathRecipient() override = default;
-    private:
-        sp<ConfigManager> mConfigManager;
-        int mUid;
+static void configReceiverDied(void* cookie) {
+    auto cookie_ = static_cast<ConfigReceiverDeathCookie*>(cookie);
+    sp<ConfigManager> configManager = cookie_->mConfigManager;
+    ConfigKey configKey = cookie_->mConfigKey;
+    shared_ptr<IPendingIntentRef> pir = cookie_->mPir;
 
-    void binderDied(const android::wp<android::IBinder>& who) override {
-        if (IInterface::asBinder(mConfigManager->GetActiveConfigsChangedReceiver(mUid))
-              == who.promote()) {
-            mConfigManager->RemoveActiveConfigsChangedReceiver(mUid);
-        }
+    // TODO(b/149254662): Fix threading. This currently fails if a new
+    // pir gets set between the get and the remove.
+    if (configManager->GetConfigReceiver(configKey) == pir) {
+        configManager->RemoveConfigReceiver(configKey);
     }
+    // The death recipient corresponding to this specific pir can never
+    // be triggered again, so free up resources.
+    // TODO(b/149254662): Investigate other options to manage the memory.
+    delete cookie_;
+}
+
+struct ActiveConfigChangedReceiverDeathCookie {
+    ActiveConfigChangedReceiverDeathCookie(sp<ConfigManager> configManager, const int uid,
+                                           const shared_ptr<IPendingIntentRef>& pir):
+        mConfigManager(configManager),
+        mUid(uid),
+        mPir(pir) {}
+
+    sp<ConfigManager> mConfigManager;
+    int mUid;
+    shared_ptr<IPendingIntentRef> mPir;
 };
 
-ConfigManager::ConfigManager() {
+static void activeConfigChangedReceiverDied(void* cookie) {
+    auto cookie_ = static_cast<ActiveConfigChangedReceiverDeathCookie*>(cookie);
+    sp<ConfigManager> configManager = cookie_->mConfigManager;
+    int uid = cookie_->mUid;
+    shared_ptr<IPendingIntentRef> pir = cookie_->mPir;
+
+    // TODO(b/149254662): Fix threading. This currently fails if a new
+    // pir gets set between the get and the remove.
+    if (configManager->GetActiveConfigsChangedReceiver(uid) == pir) {
+        configManager->RemoveActiveConfigsChangedReceiver(uid);
+    }
+    // The death recipient corresponding to this specific pir can never
+    // be triggered again, so free up resources.
+    delete cookie_;
+}
+
+ConfigManager::ConfigManager():
+    mConfigReceiverDeathRecipient(AIBinder_DeathRecipient_new(configReceiverDied)),
+    mActiveConfigChangedReceiverDeathRecipient(
+        AIBinder_DeathRecipient_new(activeConfigChangedReceiverDied)) {
 }
 
 ConfigManager::~ConfigManager() {
@@ -150,10 +175,11 @@
 }
 
 void ConfigManager::SetConfigReceiver(const ConfigKey& key,
-                                      const sp<IPendingIntentRef>& pir) {
+                                      const shared_ptr<IPendingIntentRef>& pir) {
     lock_guard<mutex> lock(mMutex);
     mConfigReceivers[key] = pir;
-    IInterface::asBinder(pir)->linkToDeath(new ConfigReceiverDeathRecipient(this, key));
+    AIBinder_linkToDeath(pir->asBinder().get(), mConfigReceiverDeathRecipient.get(),
+                         new ConfigReceiverDeathCookie(this, key, pir));
 }
 
 void ConfigManager::RemoveConfigReceiver(const ConfigKey& key) {
@@ -162,11 +188,11 @@
 }
 
 void ConfigManager::SetActiveConfigsChangedReceiver(const int uid,
-                                                    const sp<IPendingIntentRef>& pir) {
+                                                    const shared_ptr<IPendingIntentRef>& pir) {
     lock_guard<mutex> lock(mMutex);
     mActiveConfigsChangedReceivers[uid] = pir;
-    IInterface::asBinder(pir)->linkToDeath(
-        new ActiveConfigChangedReceiverDeathRecipient(this, uid));
+    AIBinder_linkToDeath(pir->asBinder().get(), mActiveConfigChangedReceiverDeathRecipient.get(),
+                         new ActiveConfigChangedReceiverDeathCookie(this, uid, pir));
 }
 
 void ConfigManager::RemoveActiveConfigsChangedReceiver(const int uid) {
@@ -279,7 +305,7 @@
     return ret;
 }
 
-const sp<IPendingIntentRef> ConfigManager::GetConfigReceiver(const ConfigKey& key) const {
+const shared_ptr<IPendingIntentRef> ConfigManager::GetConfigReceiver(const ConfigKey& key) const {
     lock_guard<mutex> lock(mMutex);
 
     auto it = mConfigReceivers.find(key);
@@ -290,7 +316,8 @@
     }
 }
 
-const sp<IPendingIntentRef> ConfigManager::GetActiveConfigsChangedReceiver(const int uid) const {
+const shared_ptr<IPendingIntentRef> ConfigManager::GetActiveConfigsChangedReceiver(const int uid)
+        const {
     lock_guard<mutex> lock(mMutex);
 
     auto it = mActiveConfigsChangedReceivers.find(uid);
diff --git a/cmds/statsd/src/config/ConfigManager.h b/cmds/statsd/src/config/ConfigManager.h
index 2095173..824e588 100644
--- a/cmds/statsd/src/config/ConfigManager.h
+++ b/cmds/statsd/src/config/ConfigManager.h
@@ -19,12 +19,15 @@
 #include "config/ConfigKey.h"
 #include "config/ConfigListener.h"
 
-#include <android/os/IPendingIntentRef.h>
+#include <aidl/android/os/IPendingIntentRef.h>
 #include <mutex>
 #include <string>
 
 #include <stdio.h>
 
+using aidl::android::os::IPendingIntentRef;
+using std::shared_ptr;
+
 namespace android {
 namespace os {
 namespace statsd {
@@ -62,12 +65,12 @@
     /**
      * Sets the broadcast receiver for a configuration key.
      */
-    void SetConfigReceiver(const ConfigKey& key, const sp<IPendingIntentRef>& pir);
+    void SetConfigReceiver(const ConfigKey& key, const shared_ptr<IPendingIntentRef>& pir);
 
     /**
      * Returns the package name and class name representing the broadcast receiver for this config.
      */
-    const sp<IPendingIntentRef> GetConfigReceiver(const ConfigKey& key) const;
+    const shared_ptr<IPendingIntentRef> GetConfigReceiver(const ConfigKey& key) const;
 
     /**
      * Returns all config keys registered.
@@ -83,13 +86,13 @@
      * Sets the broadcast receiver that is notified whenever the list of active configs
      * changes for this uid.
      */
-    void SetActiveConfigsChangedReceiver(const int uid, const sp<IPendingIntentRef>& pir);
+    void SetActiveConfigsChangedReceiver(const int uid, const shared_ptr<IPendingIntentRef>& pir);
 
     /**
      * Returns the broadcast receiver for active configs changed for this uid.
      */
 
-    const sp<IPendingIntentRef> GetActiveConfigsChangedReceiver(const int uid) const;
+    const shared_ptr<IPendingIntentRef> GetActiveConfigsChangedReceiver(const int uid) const;
 
     /**
      * Erase any active configs changed broadcast receiver associated with this uid.
@@ -141,18 +144,23 @@
     /**
      * Each config key can be subscribed by up to one receiver, specified as IPendingIntentRef.
      */
-    std::map<ConfigKey, sp<IPendingIntentRef>> mConfigReceivers;
+    std::map<ConfigKey, shared_ptr<IPendingIntentRef>> mConfigReceivers;
 
     /**
      * Each uid can be subscribed by up to one receiver to notify that the list of active configs
      * for this uid has changed. The receiver is specified as IPendingIntentRef.
      */
-     std::map<int, sp<IPendingIntentRef>> mActiveConfigsChangedReceivers;
+     std::map<int, shared_ptr<IPendingIntentRef>> mActiveConfigsChangedReceivers;
 
     /**
      * The ConfigListeners that will be told about changes.
      */
     std::vector<sp<ConfigListener>> mListeners;
+
+    // Death recipients that are triggered when the host process holding an
+    // IPendingIntentRef dies.
+    ::ndk::ScopedAIBinder_DeathRecipient mConfigReceiverDeathRecipient;
+    ::ndk::ScopedAIBinder_DeathRecipient mActiveConfigChangedReceiverDeathRecipient;
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/external/PullResultReceiver.cpp b/cmds/statsd/src/external/PullResultReceiver.cpp
index 6b6fe7d..8aa4792 100644
--- a/cmds/statsd/src/external/PullResultReceiver.cpp
+++ b/cmds/statsd/src/external/PullResultReceiver.cpp
@@ -16,17 +16,12 @@
 
 #include "PullResultReceiver.h"
 
-using namespace android::binder;
-using namespace android::util;
-using namespace std;
-
 namespace android {
 namespace os {
 namespace statsd {
 
 PullResultReceiver::PullResultReceiver(
-        std::function<void(int32_t, bool, const vector<android::util::StatsEventParcel>&)>
-             pullFinishCb)
+        std::function<void(int32_t, bool, const vector<StatsEventParcel>&)> pullFinishCb)
     : pullFinishCallback(std::move(pullFinishCb)) {
 }
 
diff --git a/cmds/statsd/src/external/PullResultReceiver.h b/cmds/statsd/src/external/PullResultReceiver.h
index 17d06e4..ceaae80 100644
--- a/cmds/statsd/src/external/PullResultReceiver.h
+++ b/cmds/statsd/src/external/PullResultReceiver.h
@@ -14,29 +14,33 @@
  * limitations under the License.
  */
 
-#include <android/os/BnPullAtomResultReceiver.h>
+#include <aidl/android/os/BnPullAtomResultReceiver.h>
+#include <aidl/android/util/StatsEventParcel.h>
 
 using namespace std;
 
+using Status = ::ndk::ScopedAStatus;
+using aidl::android::os::BnPullAtomResultReceiver;
+using aidl::android::util::StatsEventParcel;
+
 namespace android {
 namespace os {
 namespace statsd {
 
 class PullResultReceiver : public BnPullAtomResultReceiver {
 public:
-    PullResultReceiver(function<void(int32_t, bool, const vector<android::util::StatsEventParcel>&)>
+    PullResultReceiver(function<void(int32_t, bool, const vector<StatsEventParcel>&)>
                                pullFinishCallback);
     ~PullResultReceiver();
 
     /**
      * Binder call for finishing a pull.
      */
-    binder::Status pullFinished(int32_t atomTag, bool success,
-                                const vector<android::util::StatsEventParcel>& output) override;
+    Status pullFinished(int32_t atomTag, bool success,
+                        const vector<StatsEventParcel>& output) override;
 
 private:
-    function<void(int32_t, bool, const vector<android::util::StatsEventParcel>&)>
-            pullFinishCallback;
+    function<void(int32_t, bool, const vector<StatsEventParcel>&)> pullFinishCallback;
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/external/StatsCallbackPuller.cpp b/cmds/statsd/src/external/StatsCallbackPuller.cpp
index 1a11f0e..b6c8e34 100644
--- a/cmds/statsd/src/external/StatsCallbackPuller.cpp
+++ b/cmds/statsd/src/external/StatsCallbackPuller.cpp
@@ -18,24 +18,24 @@
 #include "Log.h"
 
 #include "StatsCallbackPuller.h"
-
-#include <android/os/IPullAtomCallback.h>
-#include <android/util/StatsEventParcel.h>
-
 #include "PullResultReceiver.h"
 #include "StatsPullerManager.h"
 #include "logd/LogEvent.h"
 #include "stats_log_util.h"
 
-using namespace android::binder;
-using namespace android::util;
+#include <aidl/android/util/StatsEventParcel.h>
+
 using namespace std;
 
+using Status = ::ndk::ScopedAStatus;
+using aidl::android::util::StatsEventParcel;
+using ::ndk::SharedRefBase;
+
 namespace android {
 namespace os {
 namespace statsd {
 
-StatsCallbackPuller::StatsCallbackPuller(int tagId, const sp<IPullAtomCallback>& callback,
+StatsCallbackPuller::StatsCallbackPuller(int tagId, const shared_ptr<IPullAtomCallback>& callback,
                                          const int64_t coolDownNs, int64_t timeoutNs,
                                          const vector<int> additiveFields)
     : StatsPuller(tagId, coolDownNs, timeoutNs, additiveFields), mCallback(callback) {
@@ -57,7 +57,7 @@
     shared_ptr<vector<shared_ptr<LogEvent>>> sharedData =
             make_shared<vector<shared_ptr<LogEvent>>>();
 
-    sp<PullResultReceiver> resultReceiver = new PullResultReceiver(
+    shared_ptr<PullResultReceiver> resultReceiver = SharedRefBase::make<PullResultReceiver>(
             [cv_mutex, cv, pullFinish, pullSuccess, sharedData](
                     int32_t atomTag, bool success, const vector<StatsEventParcel>& output) {
                 // This is the result of the pull, executing in a statsd binder thread.
@@ -66,9 +66,11 @@
                 {
                     lock_guard<mutex> lk(*cv_mutex);
                     for (const StatsEventParcel& parcel: output) {
+                        uint8_t* buf = reinterpret_cast<uint8_t*>(
+                                const_cast<int8_t*>(parcel.buffer.data()));
                         shared_ptr<LogEvent> event = make_shared<LogEvent>(
-                                const_cast<uint8_t*>(parcel.buffer.data()), parcel.buffer.size(),
-                                /*uid=*/-1, /*pid=*/-1, /*useNewSchema=*/true);
+                                buf, parcel.buffer.size(), /*uid=*/-1, /*pid=*/-1,
+                                /*useNewSchema=*/true);
                         sharedData->push_back(event);
                     }
                     *pullSuccess = success;
diff --git a/cmds/statsd/src/external/StatsCallbackPuller.h b/cmds/statsd/src/external/StatsCallbackPuller.h
index fe6af19..e82e8bb 100644
--- a/cmds/statsd/src/external/StatsCallbackPuller.h
+++ b/cmds/statsd/src/external/StatsCallbackPuller.h
@@ -16,23 +16,25 @@
 
 #pragma once
 
-#include <android/os/IPullAtomCallback.h>
-
+#include <aidl/android/os/IPullAtomCallback.h>
 #include "StatsPuller.h"
 
+using aidl::android::os::IPullAtomCallback;
+using std::shared_ptr;
+
 namespace android {
 namespace os {
 namespace statsd {
 
 class StatsCallbackPuller : public StatsPuller {
 public:
-    explicit StatsCallbackPuller(int tagId, const sp<IPullAtomCallback>& callback,
+    explicit StatsCallbackPuller(int tagId, const shared_ptr<IPullAtomCallback>& callback,
                                  const int64_t coolDownNs, const int64_t timeoutNs,
                                  const std::vector<int> additiveFields);
 
 private:
-    bool PullInternal(vector<std::shared_ptr<LogEvent> >* data) override;
-    const sp<IPullAtomCallback> mCallback;
+    bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override;
+    const shared_ptr<IPullAtomCallback> mCallback;
 
     FRIEND_TEST(StatsCallbackPullerTest, PullFail);
     FRIEND_TEST(StatsCallbackPullerTest, PullSuccess);
diff --git a/cmds/statsd/src/external/StatsPuller.h b/cmds/statsd/src/external/StatsPuller.h
index 9c21695..fee571c 100644
--- a/cmds/statsd/src/external/StatsPuller.h
+++ b/cmds/statsd/src/external/StatsPuller.h
@@ -16,7 +16,7 @@
 
 #pragma once
 
-#include <android/os/IStatsCompanionService.h>
+#include <aidl/android/os/IStatsCompanionService.h>
 #include <utils/RefBase.h>
 #include <mutex>
 #include <vector>
@@ -26,6 +26,9 @@
 #include "logd/LogEvent.h"
 #include "puller_util.h"
 
+using aidl::android::os::IStatsCompanionService;
+using std::shared_ptr;
+
 namespace android {
 namespace os {
 namespace statsd {
@@ -58,7 +61,8 @@
 
     static void SetUidMap(const sp<UidMap>& uidMap);
 
-    virtual void SetStatsCompanionService(sp<IStatsCompanionService> statsCompanionService){};
+    virtual void SetStatsCompanionService(
+            shared_ptr<IStatsCompanionService> statsCompanionService) {};
 
 protected:
     const int mTagId;
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index 3ceff75..1c38542 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -19,8 +19,6 @@
 
 #include "StatsPullerManager.h"
 
-#include <android/os/IPullAtomCallback.h>
-#include <android/os/IStatsCompanionService.h>
 #include <cutils/log.h>
 #include <math.h>
 #include <stdint.h>
@@ -87,7 +85,10 @@
         return;
     }
 
-    sp<IStatsCompanionService> statsCompanionServiceCopy = mStatsCompanionService;
+    // TODO(b/149254662): Why are we creating a copy here? This is different
+    // from the other places where we create a copy because we don't reassign
+    // mStatsCompanionService so a destructor can't implicitly be called...
+    shared_ptr<IStatsCompanionService> statsCompanionServiceCopy = mStatsCompanionService;
     if (statsCompanionServiceCopy != nullptr) {
         statsCompanionServiceCopy->setPullingAlarm(mNextPullTimeNs / 1000000);
     } else {
@@ -97,9 +98,11 @@
 }
 
 void StatsPullerManager::SetStatsCompanionService(
-        sp<IStatsCompanionService> statsCompanionService) {
+        shared_ptr<IStatsCompanionService> statsCompanionService) {
+    // TODO(b/149254662): Why are we using AutoMutex instead of lock_guard?
+    // Additionally, do we need the temporary shared_ptr to prevent deadlocks?
     AutoMutex _l(mLock);
-    sp<IStatsCompanionService> tmpForLock = mStatsCompanionService;
+    shared_ptr<IStatsCompanionService> tmpForLock = mStatsCompanionService;
     mStatsCompanionService = statsCompanionService;
     for (const auto& pulledAtom : kAllPullAtomInfo) {
         pulledAtom.second->SetStatsCompanionService(statsCompanionService);
@@ -250,10 +253,11 @@
 void StatsPullerManager::RegisterPullAtomCallback(const int uid, const int32_t atomTag,
                                                   const int64_t coolDownNs, const int64_t timeoutNs,
                                                   const vector<int32_t>& additiveFields,
-                                                  const sp<IPullAtomCallback>& callback) {
+                                                  const shared_ptr<IPullAtomCallback>& callback) {
     AutoMutex _l(mLock);
     VLOG("RegisterPullerCallback: adding puller for tag %d", atomTag);
-    // TODO: linkToDeath with the callback so that we can remove it and delete the puller.
+    // TODO(b/146439412): linkToDeath with the callback so that we can remove it
+    // and delete the puller.
     StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, /*registered=*/true);
     kAllPullAtomInfo[{.atomTag = atomTag}] =
             new StatsCallbackPuller(atomTag, callback, coolDownNs, timeoutNs, additiveFields);
diff --git a/cmds/statsd/src/external/StatsPullerManager.h b/cmds/statsd/src/external/StatsPullerManager.h
index aef16dc..e067766 100644
--- a/cmds/statsd/src/external/StatsPullerManager.h
+++ b/cmds/statsd/src/external/StatsPullerManager.h
@@ -16,9 +16,8 @@
 
 #pragma once
 
-#include <android/os/IPullAtomCallback.h>
-#include <android/os/IStatsCompanionService.h>
-#include <binder/IServiceManager.h>
+#include <aidl/android/os/IPullAtomCallback.h>
+#include <aidl/android/os/IStatsCompanionService.h>
 #include <utils/RefBase.h>
 #include <utils/threads.h>
 
@@ -30,11 +29,14 @@
 #include "guardrail/StatsdStats.h"
 #include "logd/LogEvent.h"
 
+using aidl::android::os::IPullAtomCallback;
+using aidl::android::os::IStatsCompanionService;
+using std::shared_ptr;
+
 namespace android {
 namespace os {
 namespace statsd {
 
-
 typedef struct PullerKey {
     // The uid of the process that registers this puller.
     const int uid = -1;
@@ -93,18 +95,18 @@
     // Clear pull data cache if it is beyond respective cool down time.
     int ClearPullerCacheIfNecessary(int64_t timestampNs);
 
-    void SetStatsCompanionService(sp<IStatsCompanionService> statsCompanionService);
+    void SetStatsCompanionService(shared_ptr<IStatsCompanionService> statsCompanionService);
 
     void RegisterPullAtomCallback(const int uid, const int32_t atomTag, const int64_t coolDownNs,
                                   const int64_t timeoutNs, const vector<int32_t>& additiveFields,
-                                  const sp<IPullAtomCallback>& callback);
+                                  const shared_ptr<IPullAtomCallback>& callback);
 
     void UnregisterPullAtomCallback(const int uid, const int32_t atomTag);
 
     std::map<const PullerKey, sp<StatsPuller>> kAllPullAtomInfo;
 
 private:
-    sp<IStatsCompanionService> mStatsCompanionService = nullptr;
+    shared_ptr<IStatsCompanionService> mStatsCompanionService = nullptr;
 
     typedef struct {
         int64_t nextPullTimeNs;
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
index 103eb0c..9c50846 100644
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -20,7 +20,8 @@
 #include "stats_log_util.h"
 #include "statslog.h"
 
-#include <binder/IPCThreadState.h>
+#include <android/binder_ibinder.h>
+#include <android-base/stringprintf.h>
 #include <private/android_filesystem_config.h>
 
 namespace android {
@@ -31,6 +32,7 @@
 const int FIELD_ID_EXPERIMENT_ID = 1;
 
 using namespace android::util;
+using android::base::StringPrintf;
 using android::util::ProtoOutputStream;
 using std::string;
 using std::vector;
@@ -180,8 +182,8 @@
     mLogdTimestampNs = getWallClockNs();
     mElapsedTimestampNs = getElapsedRealtimeNs();
     mTagId = android::util::BINARY_PUSH_STATE_CHANGED;
-    mLogUid = android::IPCThreadState::self()->getCallingUid();
-    mLogPid = android::IPCThreadState::self()->getCallingPid();
+    mLogUid = AIBinder_getCallingUid();
+    mLogPid = AIBinder_getCallingPid();
 
     mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)), Value(trainName)));
     mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)), Value(trainVersionCode)));
@@ -290,9 +292,9 @@
 }
 
 bool LogEvent::writeBytes(const string& value) {
-    if (mContext) {
+    /* if (mContext) {
         return android_log_write_char_array(mContext, value.c_str(), value.length()) >= 0;
-    }
+    }*/
     return false;
 }
 
diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h
index a67bef4..ea449b0 100644
--- a/cmds/statsd/src/logd/LogEvent.h
+++ b/cmds/statsd/src/logd/LogEvent.h
@@ -20,7 +20,6 @@
 
 #include <android/util/ProtoOutputStream.h>
 #include <private/android_logger.h>
-#include <stats_event_list.h>
 #include <stats_event.h>
 
 #include <string>
diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp
index 140ef4e..d79b6a2 100644
--- a/cmds/statsd/src/main.cpp
+++ b/cmds/statsd/src/main.cpp
@@ -20,9 +20,9 @@
 #include "StatsService.h"
 #include "socket/StatsSocketListener.h"
 
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <binder/ProcessState.h>
+#include <android/binder_interface_utils.h>
+#include <android/binder_process.h>
+#include <android/binder_manager.h>
 #include <utils/Looper.h>
 
 #include <stdio.h>
@@ -32,16 +32,11 @@
 
 using namespace android;
 using namespace android::os::statsd;
+using ::ndk::SharedRefBase;
+using std::shared_ptr;
+using std::make_shared;
 
-/**
- * Thread function data.
- */
-struct log_reader_thread_data {
-    sp<StatsService> service;
-};
-
-
-sp<StatsService> gStatsService = nullptr;
+shared_ptr<StatsService> gStatsService = nullptr;
 
 void sigHandler(int sig) {
     if (gStatsService != nullptr) {
@@ -68,20 +63,18 @@
     sp<Looper> looper(Looper::prepare(0 /* opts */));
 
     // Set up the binder
-    sp<ProcessState> ps(ProcessState::self());
-    ps->setThreadPoolMaxThreadCount(9);
-    ps->startThreadPool();
-    ps->giveThreadPoolName();
-    IPCThreadState::self()->disableBackgroundScheduling(true);
+    ABinderProcess_setThreadPoolMaxThreadCount(9);
+    ABinderProcess_startThreadPool();
 
     std::shared_ptr<LogEventQueue> eventQueue =
             std::make_shared<LogEventQueue>(2000 /*buffer limit. Buffer is NOT pre-allocated*/);
 
     // Create the service
-    gStatsService = new StatsService(looper, eventQueue);
-    if (defaultServiceManager()->addService(String16("stats"), gStatsService, false,
-                IServiceManager::DUMP_FLAG_PRIORITY_NORMAL | IServiceManager::DUMP_FLAG_PROTO)
-            != 0) {
+    gStatsService = SharedRefBase::make<StatsService>(looper, eventQueue);
+    // TODO(b/149582373): Set DUMP_FLAG_PROTO once libbinder_ndk supports
+    // setting dumpsys priorities.
+    binder_status_t status = AServiceManager_addService(gStatsService->asBinder().get(), "stats");
+    if (status != STATUS_OK) {
         ALOGE("Failed to add service as AIDL service");
         return -1;
     }
diff --git a/cmds/statsd/src/packages/UidMap.h b/cmds/statsd/src/packages/UidMap.h
index bfac6e3..4e3c506 100644
--- a/cmds/statsd/src/packages/UidMap.h
+++ b/cmds/statsd/src/packages/UidMap.h
@@ -21,10 +21,11 @@
 #include "packages/PackageInfoListener.h"
 #include "stats_util.h"
 
-#include <binder/IShellCallback.h>
 #include <gtest/gtest_prod.h>
 #include <stdio.h>
 #include <utils/RefBase.h>
+#include <utils/String16.h>
+
 #include <list>
 #include <mutex>
 #include <set>
diff --git a/cmds/statsd/src/shell/ShellSubscriber.cpp b/cmds/statsd/src/shell/ShellSubscriber.cpp
index d6a0433..a861a3b 100644
--- a/cmds/statsd/src/shell/ShellSubscriber.cpp
+++ b/cmds/statsd/src/shell/ShellSubscriber.cpp
@@ -29,49 +29,88 @@
 
 const static int FIELD_ID_ATOM = 1;
 
-void ShellSubscriber::startNewSubscription(int in, int out, sp<IResultReceiver> resultReceiver,
-                                           int timeoutSec) {
+void ShellSubscriber::startNewSubscription(int in, int out, int timeoutSec) {
     VLOG("start new shell subscription");
+    int64_t subscriberId = getElapsedRealtimeNs();
+
     {
         std::lock_guard<std::mutex> lock(mMutex);
-        if (mResultReceiver != nullptr) {
+        if (mSubscriberId> 0) {
             VLOG("Only one shell subscriber is allowed.");
             return;
         }
+        mSubscriberId = subscriberId;
         mInput = in;
         mOutput = out;
-        mResultReceiver = resultReceiver;
-        IInterface::asBinder(mResultReceiver)->linkToDeath(this);
     }
 
-    // Note that the following is blocking, and it's intended as we cannot return until the shell
-    // cmd exits, otherwise all resources & FDs will be automatically closed.
+    bool success = readConfig();
+    if (!success) {
+        std::lock_guard<std::mutex> lock(mMutex);
+        cleanUpLocked();
+    }
 
-    // Read config forever until EOF is reached. Clients may send multiple configs -- each new
-    // config replace the previous one.
-    readConfig(in);
-    VLOG("timeout : %d", timeoutSec);
-
-    // Now we have read an EOF we now wait for the semaphore until the client exits.
-    VLOG("Now wait for client to exit");
+    VLOG("Wait for client to exit or timeout (%d sec)", timeoutSec);
     std::unique_lock<std::mutex> lk(mMutex);
 
+    // Note that the following is blocking, and it's intended as we cannot return until the shell
+    // cmd exits or we time out.
     if (timeoutSec > 0) {
         mShellDied.wait_for(lk, timeoutSec * 1s,
-                            [this, resultReceiver] { return mResultReceiver != resultReceiver; });
+                            [this, subscriberId] { return mSubscriberId != subscriberId; });
     } else {
-        mShellDied.wait(lk, [this, resultReceiver] { return mResultReceiver != resultReceiver; });
+        mShellDied.wait(lk, [this, subscriberId] { return mSubscriberId != subscriberId; });
+    }
+}
+
+
+// Read configs until EOF is reached. There may be multiple configs in the input
+// -- each new config should replace the previous one.
+//
+// Returns a boolean indicating whether the input was read successfully.
+bool ShellSubscriber::readConfig() {
+    if (mInput < 0) {
+        return false;
+    }
+
+    while (true) {
+        // Read the size of the config.
+        size_t bufferSize = 0;
+        ssize_t bytesRead = read(mInput, &bufferSize, sizeof(bufferSize));
+        if (bytesRead == 0) {
+            VLOG("We have reached the end of the input.");
+            return true;
+        } else if (bytesRead < 0 || (size_t)bytesRead != sizeof(bufferSize)) {
+            ALOGE("Error reading config size");
+            return false;
+        }
+
+        // Read and parse the config.
+        vector<uint8_t> buffer(bufferSize);
+        bytesRead = read(mInput, buffer.data(), bufferSize);
+        if (bytesRead > 0 && (size_t)bytesRead == bufferSize) {
+            ShellSubscription config;
+            if (config.ParseFromArray(buffer.data(), bufferSize)) {
+                updateConfig(config);
+            } else {
+                ALOGE("Error parsing the config");
+                return false;
+            }
+        } else {
+            VLOG("Error reading the config, expected bytes: %zu, actual bytes: %zu", bufferSize, 
+                 bytesRead);
+            return false;
+        }
     }
 }
 
 void ShellSubscriber::updateConfig(const ShellSubscription& config) {
-    std::lock_guard<std::mutex> lock(mMutex);
     mPushedMatchers.clear();
     mPulledInfo.clear();
 
     for (const auto& pushed : config.pushed()) {
         mPushedMatchers.push_back(pushed);
-        VLOG("adding matcher for atom %d", pushed.atom_id());
+        VLOG("adding matcher for pushed atom %d", pushed.atom_id());
     }
 
     int64_t token = getElapsedRealtimeNs();
@@ -89,46 +128,20 @@
     }
 
     if (mPulledInfo.size() > 0 && minInterval > 0) {
-        // This thread is guaranteed to terminate after it detects the token is different or
-        // cleaned up.
+        // This thread is guaranteed to terminate after it detects the token is
+        // different.
         std::thread puller([token, minInterval, this] { startPull(token, minInterval); });
         puller.detach();
     }
 }
 
-void ShellSubscriber::writeToOutputLocked(const vector<std::shared_ptr<LogEvent>>& data,
-                                          const SimpleAtomMatcher& matcher) {
-    if (mOutput == 0) return;
-    int count = 0;
-    mProto.clear();
-    for (const auto& event : data) {
-        VLOG("%s", event->ToString().c_str());
-        if (matchesSimple(*mUidMap, matcher, *event)) {
-            VLOG("matched");
-            count++;
-            uint64_t atomToken = mProto.start(util::FIELD_TYPE_MESSAGE |
-                                              util::FIELD_COUNT_REPEATED | FIELD_ID_ATOM);
-            event->ToProto(mProto);
-            mProto.end(atomToken);
-        }
-    }
-
-    if (count > 0) {
-        // First write the payload size.
-        size_t bufferSize = mProto.size();
-        write(mOutput, &bufferSize, sizeof(bufferSize));
-        VLOG("%d atoms, proto size: %zu", count, bufferSize);
-        // Then write the payload.
-        mProto.flush(mOutput);
-    }
-    mProto.clear();
-}
-
 void ShellSubscriber::startPull(int64_t token, int64_t intervalMillis) {
-    while (1) {
+    while (true) {
         int64_t nowMillis = getElapsedRealtimeMillis();
         {
             std::lock_guard<std::mutex> lock(mMutex);
+            // If the token has changed, the config has changed, so this
+            // puller can now stop.
             if (mPulledInfo.size() == 0 || mPullToken != token) {
                 VLOG("Pulling thread %lld done!", (long long)token);
                 return;
@@ -152,55 +165,47 @@
     }
 }
 
-void ShellSubscriber::readConfig(int in) {
-    if (in <= 0) {
+// Must be called with the lock acquired, so that mProto isn't being written to
+// at the same time by multiple threads.
+void ShellSubscriber::writeToOutputLocked(const vector<std::shared_ptr<LogEvent>>& data,
+                                          const SimpleAtomMatcher& matcher) {
+    if (mOutput < 0) {
         return;
     }
-
-    while (1) {
-        size_t bufferSize = 0;
-        int result = 0;
-        if ((result = read(in, &bufferSize, sizeof(bufferSize))) == 0) {
-            VLOG("Done reading");
-            break;
-        } else if (result < 0 || result != sizeof(bufferSize)) {
-            ALOGE("Error reading config size");
-            break;
-        }
-
-        vector<uint8_t> buffer(bufferSize);
-        if ((result = read(in, buffer.data(), bufferSize)) > 0 && ((size_t)result) == bufferSize) {
-            ShellSubscription config;
-            if (config.ParseFromArray(buffer.data(), bufferSize)) {
-                updateConfig(config);
-            } else {
-                ALOGE("error parsing the config");
-                break;
-            }
-        } else {
-            VLOG("Error reading the config, returned: %d, expecting %zu", result, bufferSize);
-            break;
+    int count = 0;
+    mProto.clear();
+    for (const auto& event : data) {
+        VLOG("%s", event->ToString().c_str());
+        if (matchesSimple(*mUidMap, matcher, *event)) {
+            VLOG("matched");
+            count++;
+            uint64_t atomToken = mProto.start(util::FIELD_TYPE_MESSAGE |
+                                              util::FIELD_COUNT_REPEATED | FIELD_ID_ATOM);
+            event->ToProto(mProto);
+            mProto.end(atomToken);
         }
     }
-}
 
-void ShellSubscriber::cleanUpLocked() {
-    // The file descriptors will be closed by binder.
-    mInput = 0;
-    mOutput = 0;
-    mResultReceiver = nullptr;
-    mPushedMatchers.clear();
-    mPulledInfo.clear();
-    mPullToken = 0;
-    VLOG("done clean up");
+    if (count > 0) {
+        // First write the payload size.
+        size_t bufferSize = mProto.size();
+        write(mOutput, &bufferSize, sizeof(bufferSize));
+
+        VLOG("%d atoms, proto size: %zu", count, bufferSize);
+        // Then write the payload.
+        mProto.flush(mOutput);
+    }
 }
 
 void ShellSubscriber::onLogEvent(const LogEvent& event) {
+    // Acquire a lock to prevent corruption from multiple threads writing to
+    // mProto.
     std::lock_guard<std::mutex> lock(mMutex);
-
-    if (mOutput <= 0) {
+    if (mOutput < 0) {
         return;
     }
+
+    mProto.clear();
     for (const auto& matcher : mPushedMatchers) {
         if (matchesSimple(*mUidMap, matcher, event)) {
             VLOG("%s", event.ToString().c_str());
@@ -208,25 +213,27 @@
                                               util::FIELD_COUNT_REPEATED | FIELD_ID_ATOM);
             event.ToProto(mProto);
             mProto.end(atomToken);
+
             // First write the payload size.
             size_t bufferSize = mProto.size();
             write(mOutput, &bufferSize, sizeof(bufferSize));
 
             // Then write the payload.
             mProto.flush(mOutput);
-            mProto.clear();
-            break;
         }
     }
 }
 
-void ShellSubscriber::binderDied(const wp<IBinder>& who) {
-    {
-        VLOG("Shell exits");
-        std::lock_guard<std::mutex> lock(mMutex);
-        cleanUpLocked();
-    }
-    mShellDied.notify_all();
+void ShellSubscriber::cleanUpLocked() {
+    // The file descriptors will be closed by binder.
+    mInput = -1;
+    mOutput = -1;
+    mSubscriberId = 0;
+    mPushedMatchers.clear();
+    mPulledInfo.clear();
+    // Setting mPullToken == 0 tells pull thread that its work is done.
+    mPullToken = 0;
+    VLOG("done clean up");
 }
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/shell/ShellSubscriber.h b/cmds/statsd/src/shell/ShellSubscriber.h
index 86d8590..eaf2ad1 100644
--- a/cmds/statsd/src/shell/ShellSubscriber.h
+++ b/cmds/statsd/src/shell/ShellSubscriber.h
@@ -19,7 +19,6 @@
 #include "logd/LogEvent.h"
 
 #include <android/util/ProtoOutputStream.h>
-#include <binder/IResultReceiver.h>
 #include <condition_variable>
 #include <mutex>
 #include <thread>
@@ -56,7 +55,7 @@
  * Only one shell subscriber allowed at a time, because each shell subscriber blocks one thread
  * until it exits.
  */
-class ShellSubscriber : public virtual IBinder::DeathRecipient {
+class ShellSubscriber : public virtual RefBase {
 public:
     ShellSubscriber(sp<UidMap> uidMap, sp<StatsPullerManager> pullerMgr)
         : mUidMap(uidMap), mPullerMgr(pullerMgr){};
@@ -64,10 +63,7 @@
     /**
      * Start a new subscription.
      */
-    void startNewSubscription(int inFd, int outFd, sp<IResultReceiver> resultReceiver,
-                              int timeoutSec);
-
-    void binderDied(const wp<IBinder>& who);
+    void startNewSubscription(int inFd, int outFd, int timeoutSec);
 
     void onLogEvent(const LogEvent& event);
 
@@ -80,7 +76,7 @@
         int64_t mInterval;
         int64_t mPrevPullElapsedRealtimeMs;
     };
-    void readConfig(int in);
+    bool readConfig();
 
     void updateConfig(const ShellSubscription& config);
 
@@ -101,16 +97,16 @@
 
     std::condition_variable mShellDied;  // semaphore for waiting until shell exits.
 
-    int mInput;  // The input file descriptor
+    int mInput = -1;  // The input file descriptor
 
-    int mOutput;  // The output file descriptor
-
-    sp<IResultReceiver> mResultReceiver;
+    int mOutput = -1;  // The output file descriptor
 
     std::vector<SimpleAtomMatcher> mPushedMatchers;
 
     std::vector<PullInfo> mPulledInfo;
 
+    int64_t mSubscriberId = 0; // A unique id to identify a subscriber.
+
     int64_t mPullToken = 0;  // A unique token to identify a puller thread.
 };
 
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index 73f640e..3d02ffb 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -17,6 +17,7 @@
 #include "hash.h"
 #include "stats_log_util.h"
 
+#include <aidl/android/os/IStatsCompanionService.h>
 #include <private/android_filesystem_config.h>
 #include <set>
 #include <utils/SystemClock.h>
@@ -35,6 +36,10 @@
 using android::util::FIELD_TYPE_UINT64;
 using android::util::ProtoOutputStream;
 
+using aidl::android::os::IStatsCompanionService;
+using std::shared_ptr;
+using std::string;
+
 namespace android {
 namespace os {
 namespace statsd {
@@ -587,13 +592,13 @@
 }
 
 bool checkPermissionForIds(const char* permission, pid_t pid, uid_t uid) {
-    sp<IStatsCompanionService> scs = getStatsCompanionService();
+    shared_ptr<IStatsCompanionService> scs = getStatsCompanionService();
     if (scs == nullptr) {
         return false;
     }
 
     bool success;
-    binder::Status status = scs->checkPermission(String16(permission), pid, uid, &success);
+    ::ndk::ScopedAStatus status = scs->checkPermission(string(permission), pid, uid, &success);
     if (!status.isOk()) {
         return false;
     }
diff --git a/cmds/statsd/src/statscompanion_util.cpp b/cmds/statsd/src/statscompanion_util.cpp
index d338827..ce07ec0 100644
--- a/cmds/statsd/src/statscompanion_util.cpp
+++ b/cmds/statsd/src/statscompanion_util.cpp
@@ -18,26 +18,16 @@
 #include "Log.h"
 
 #include "statscompanion_util.h"
+#include <android/binder_auto_utils.h>
+#include <android/binder_manager.h>
 
 namespace android {
 namespace os {
 namespace statsd {
 
-sp <IStatsCompanionService> getStatsCompanionService() {
-    sp<IStatsCompanionService> statsCompanion = nullptr;
-    // Get statscompanion service from service manager
-    static const sp <IServiceManager> sm(defaultServiceManager());
-    if (statsCompanion == nullptr) {
-        if (sm != nullptr) {
-            const String16 name("statscompanion");
-            statsCompanion = interface_cast<IStatsCompanionService>(sm->checkService(name));
-            if (statsCompanion == nullptr) {
-                ALOGW("statscompanion service unavailable!");
-                return nullptr;
-            }
-        }
-    }
-    return statsCompanion;
+shared_ptr<IStatsCompanionService> getStatsCompanionService() {
+    ::ndk::SpAIBinder binder(AServiceManager_getService("statscompanion"));
+    return IStatsCompanionService::fromBinder(binder);
 }
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/statscompanion_util.h b/cmds/statsd/src/statscompanion_util.h
index dc4f283..e20c40b 100644
--- a/cmds/statsd/src/statscompanion_util.h
+++ b/cmds/statsd/src/statscompanion_util.h
@@ -16,14 +16,17 @@
 
 #pragma once
 
-#include "StatsLogProcessor.h"
+#include <aidl/android/os/IStatsCompanionService.h>
+
+using aidl::android::os::IStatsCompanionService;
+using std::shared_ptr;
 
 namespace android {
 namespace os {
 namespace statsd {
 
 /** Fetches and returns the StatsCompanionService. */
-sp<IStatsCompanionService> getStatsCompanionService();
+shared_ptr<IStatsCompanionService> getStatsCompanionService();
 
 }  // namespace statsd
 }  // namespace os
diff --git a/cmds/statsd/src/subscriber/SubscriberReporter.cpp b/cmds/statsd/src/subscriber/SubscriberReporter.cpp
index 8fd6b46..93af5e9 100644
--- a/cmds/statsd/src/subscriber/SubscriberReporter.cpp
+++ b/cmds/statsd/src/subscriber/SubscriberReporter.cpp
@@ -27,38 +27,52 @@
 
 using std::vector;
 
-class BroadcastSubscriberDeathRecipient : public android::IBinder::DeathRecipient {
-    public:
-        BroadcastSubscriberDeathRecipient(const ConfigKey& configKey, int64_t subscriberId):
-            mConfigKey(configKey),
-            mSubscriberId(subscriberId) {}
-        ~BroadcastSubscriberDeathRecipient() override = default;
-    private:
-        ConfigKey mConfigKey;
-        int64_t mSubscriberId;
+struct BroadcastSubscriberDeathCookie {
+    BroadcastSubscriberDeathCookie(const ConfigKey& configKey, int64_t subscriberId,
+                                   const shared_ptr<IPendingIntentRef>& pir):
+        mConfigKey(configKey),
+        mSubscriberId(subscriberId),
+        mPir(pir) {}
 
-    void binderDied(const android::wp<android::IBinder>& who) override {
-        if (IInterface::asBinder(SubscriberReporter::getInstance().getBroadcastSubscriber(
-              mConfigKey, mSubscriberId)) == who.promote()) {
-            SubscriberReporter::getInstance().unsetBroadcastSubscriber(mConfigKey, mSubscriberId);
-        }
-    }
+    ConfigKey mConfigKey;
+    int64_t mSubscriberId;
+    shared_ptr<IPendingIntentRef> mPir;
 };
 
+static void broadcastSubscriberDied(void* cookie) {
+    BroadcastSubscriberDeathCookie* cookie_ = (BroadcastSubscriberDeathCookie*)cookie;
+    ConfigKey configKey = cookie_->mConfigKey;
+    int64_t subscriberId = cookie_->mSubscriberId;
+    shared_ptr<IPendingIntentRef> pir = cookie_->mPir;
+
+    // TODO(b/149254662): Fix threading. This currently fails if a new pir gets
+    // set between the get and the unset.
+    if (SubscriberReporter::getInstance().getBroadcastSubscriber(configKey, subscriberId) == pir) {
+        SubscriberReporter::getInstance().unsetBroadcastSubscriber(configKey, subscriberId);
+    }
+    // The death recipient corresponding to this specific pir can never be
+    // triggered again, so free up resources.
+    delete cookie_;
+}
+
+static ::ndk::ScopedAIBinder_DeathRecipient sBroadcastSubscriberDeathRecipient(
+        AIBinder_DeathRecipient_new(broadcastSubscriberDied));
+
 void SubscriberReporter::setBroadcastSubscriber(const ConfigKey& configKey,
                                                 int64_t subscriberId,
-                                                const sp<IPendingIntentRef>& pir) {
+                                                const shared_ptr<IPendingIntentRef>& pir) {
     VLOG("SubscriberReporter::setBroadcastSubscriber called.");
-    lock_guard<std::mutex> lock(mLock);
+    lock_guard<mutex> lock(mLock);
     mIntentMap[configKey][subscriberId] = pir;
-    IInterface::asBinder(pir)->linkToDeath(
-        new BroadcastSubscriberDeathRecipient(configKey, subscriberId));
+    // TODO(b/149254662): Is it ok to call linkToDeath while holding a lock?
+    AIBinder_linkToDeath(pir->asBinder().get(), sBroadcastSubscriberDeathRecipient.get(),
+                         new BroadcastSubscriberDeathCookie(configKey, subscriberId, pir));
 }
 
 void SubscriberReporter::unsetBroadcastSubscriber(const ConfigKey& configKey,
                                                   int64_t subscriberId) {
     VLOG("SubscriberReporter::unsetBroadcastSubscriber called.");
-    lock_guard<std::mutex> lock(mLock);
+    lock_guard<mutex> lock(mLock);
     auto subscriberMapIt = mIntentMap.find(configKey);
     if (subscriberMapIt != mIntentMap.end()) {
         subscriberMapIt->second.erase(subscriberId);
@@ -80,7 +94,7 @@
     //  config id - the name of this config (for this particular uid)
 
     VLOG("SubscriberReporter::alertBroadcastSubscriber called.");
-    lock_guard<std::mutex> lock(mLock);
+    lock_guard<mutex> lock(mLock);
 
     if (!subscription.has_broadcast_subscriber_details()
             || !subscription.broadcast_subscriber_details().has_subscriber_id()) {
@@ -89,10 +103,12 @@
     }
     int64_t subscriberId = subscription.broadcast_subscriber_details().subscriber_id();
 
-    vector<String16> cookies;
+    // TODO(b/149254662): Is there a way to convert a RepeatedPtrField into a
+    // vector without copying?
+    vector<string> cookies;
     cookies.reserve(subscription.broadcast_subscriber_details().cookie_size());
     for (auto& cookie : subscription.broadcast_subscriber_details().cookie()) {
-        cookies.push_back(String16(cookie.c_str()));
+        cookies.push_back(cookie);
     }
 
     auto it1 = mIntentMap.find(configKey);
@@ -109,10 +125,10 @@
     sendBroadcastLocked(it2->second, configKey, subscription, cookies, dimKey);
 }
 
-void SubscriberReporter::sendBroadcastLocked(const sp<IPendingIntentRef>& pir,
+void SubscriberReporter::sendBroadcastLocked(const shared_ptr<IPendingIntentRef>& pir,
                                              const ConfigKey& configKey,
                                              const Subscription& subscription,
-                                             const vector<String16>& cookies,
+                                             const vector<string>& cookies,
                                              const MetricDimensionKey& dimKey) const {
     VLOG("SubscriberReporter::sendBroadcastLocked called.");
     pir->sendSubscriberBroadcast(
@@ -124,9 +140,9 @@
             dimKey.getDimensionKeyInWhat().toStatsDimensionsValueParcel());
 }
 
-sp<IPendingIntentRef> SubscriberReporter::getBroadcastSubscriber(const ConfigKey& configKey,
-                                                                 int64_t subscriberId) {
-    lock_guard<std::mutex> lock(mLock);
+shared_ptr<IPendingIntentRef> SubscriberReporter::getBroadcastSubscriber(const ConfigKey& configKey,
+                                                                         int64_t subscriberId) {
+    lock_guard<mutex> lock(mLock);
     auto subscriberMapIt = mIntentMap.find(configKey);
     if (subscriberMapIt == mIntentMap.end()) {
         return nullptr;
diff --git a/cmds/statsd/src/subscriber/SubscriberReporter.h b/cmds/statsd/src/subscriber/SubscriberReporter.h
index 42599f5..0f97d39 100644
--- a/cmds/statsd/src/subscriber/SubscriberReporter.h
+++ b/cmds/statsd/src/subscriber/SubscriberReporter.h
@@ -16,9 +16,9 @@
 
 #pragma once
 
-#include <android/os/IPendingIntentRef.h>
-#include <android/os/IStatsCompanionService.h>
+#include <aidl/android/os/IPendingIntentRef.h>
 #include <utils/RefBase.h>
+#include <utils/String16.h>
 
 #include "config/ConfigKey.h"
 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"  // subscription
@@ -28,6 +28,13 @@
 #include <unordered_map>
 #include <vector>
 
+using aidl::android::os::IPendingIntentRef;
+using std::mutex;
+using std::shared_ptr;
+using std::string;
+using std::unordered_map;
+using std::vector;
+
 namespace android {
 namespace os {
 namespace statsd {
@@ -51,7 +58,7 @@
      */
     void setBroadcastSubscriber(const ConfigKey& configKey,
                                 int64_t subscriberId,
-                                const sp<IPendingIntentRef>& pir);
+                                const shared_ptr<IPendingIntentRef>& pir);
 
     /**
      * Erases any intentSender information from the given (configKey, subscriberId) pair.
@@ -67,28 +74,25 @@
                                   const Subscription& subscription,
                                   const MetricDimensionKey& dimKey) const;
 
-    sp<IPendingIntentRef> getBroadcastSubscriber(const ConfigKey& configKey, int64_t subscriberId);
+    shared_ptr<IPendingIntentRef> getBroadcastSubscriber(const ConfigKey& configKey,
+                                                         int64_t subscriberId);
 
 private:
     SubscriberReporter() {};
 
-    mutable std::mutex mLock;
-
-    /** Binder interface for communicating with StatsCompanionService. */
-    sp<IStatsCompanionService> mStatsCompanionService = nullptr;
+    mutable mutex mLock;
 
     /** Maps <ConfigKey, SubscriberId> -> IPendingIntentRef (which represents a PendingIntent). */
-    std::unordered_map<ConfigKey,
-            std::unordered_map<int64_t, sp<IPendingIntentRef>>> mIntentMap;
+    unordered_map<ConfigKey, unordered_map<int64_t, shared_ptr<IPendingIntentRef>>> mIntentMap;
 
     /**
      * Sends a broadcast via the given intentSender (using mStatsCompanionService), along
      * with the information in the other parameters.
      */
-    void sendBroadcastLocked(const sp<IPendingIntentRef>& pir,
+    void sendBroadcastLocked(const shared_ptr<IPendingIntentRef>& pir,
                              const ConfigKey& configKey,
                              const Subscription& subscription,
-                             const std::vector<String16>& cookies,
+                             const vector<string>& cookies,
                              const MetricDimensionKey& dimKey) const;
 };
 
diff --git a/cmds/statsd/tests/AlarmMonitor_test.cpp b/cmds/statsd/tests/AlarmMonitor_test.cpp
index 1fccb35..edbf8b5 100644
--- a/cmds/statsd/tests/AlarmMonitor_test.cpp
+++ b/cmds/statsd/tests/AlarmMonitor_test.cpp
@@ -17,14 +17,16 @@
 #include <gtest/gtest.h>
 
 using namespace android::os::statsd;
+using std::shared_ptr;
 
 #ifdef __ANDROID__
 TEST(AlarmMonitor, popSoonerThan) {
     std::string emptyMetricId;
     std::string emptyDimensionId;
     unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> set;
-    AlarmMonitor am(2, [](const sp<IStatsCompanionService>&, int64_t){},
-                    [](const sp<IStatsCompanionService>&){});
+    AlarmMonitor am(2,
+                    [](const shared_ptr<IStatsCompanionService>&, int64_t){},
+                    [](const shared_ptr<IStatsCompanionService>&){});
 
     set = am.popSoonerThan(5);
     EXPECT_TRUE(set.empty());
diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp
index 69e11ed..3d7e5c9 100644
--- a/cmds/statsd/tests/StatsLogProcessor_test.cpp
+++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp
@@ -32,6 +32,8 @@
 
 using namespace android;
 using namespace testing;
+using ::ndk::SharedRefBase;
+using std::shared_ptr;
 
 namespace android {
 namespace os {
@@ -49,10 +51,12 @@
     MockMetricsManager()
         : MetricsManager(ConfigKey(1, 12345), StatsdConfig(), 1000, 1000, new UidMap(),
                          new StatsPullerManager(),
-                         new AlarmMonitor(10, [](const sp<IStatsCompanionService>&, int64_t) {},
-                                          [](const sp<IStatsCompanionService>&) {}),
-                         new AlarmMonitor(10, [](const sp<IStatsCompanionService>&, int64_t) {},
-                                          [](const sp<IStatsCompanionService>&) {})) {
+                         new AlarmMonitor(10,
+                                          [](const shared_ptr<IStatsCompanionService>&, int64_t) {},
+                                          [](const shared_ptr<IStatsCompanionService>&) {}),
+                         new AlarmMonitor(10,
+                                          [](const shared_ptr<IStatsCompanionService>&, int64_t) {},
+                                          [](const shared_ptr<IStatsCompanionService>&) {})) {
     }
 
     MOCK_METHOD0(byteSize, size_t());
@@ -1488,9 +1492,9 @@
     metric2ActivationTrigger2->set_activation_type(ACTIVATE_IMMEDIATELY);
 
     // Send the config.
-    StatsService service(nullptr, nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     string serialized = config1.SerializeAsString();
-    service.addConfigurationChecked(uid, configId, {serialized.begin(), serialized.end()});
+    service->addConfigurationChecked(uid, configId, {serialized.begin(), serialized.end()});
 
     // Make sure the config is stored on disk. Otherwise, we will not reset on system server death.
     StatsdConfig tmpConfig;
@@ -1501,7 +1505,7 @@
     // Metric 2 is not active.
     // Metric 3 is active.
     // {{{---------------------------------------------------------------------------
-    sp<StatsLogProcessor> processor = service.mProcessor;
+    sp<StatsLogProcessor> processor = service->mProcessor;
     EXPECT_EQ(1, processor->mMetricsManagers.size());
     auto it = processor->mMetricsManagers.find(cfgKey1);
     EXPECT_TRUE(it != processor->mMetricsManagers.end());
@@ -1592,7 +1596,7 @@
     EXPECT_TRUE(approximateSystemServerDeath < NS_PER_SEC + configAddedTimeNs);
 
     // System server dies.
-    service.binderDied(nullptr);
+    service->statsCompanionServiceDiedImpl();
 
     // We should have a new metrics manager. Lets get it and ensure activation status is restored.
     // {{{---------------------------------------------------------------------------
diff --git a/cmds/statsd/tests/StatsService_test.cpp b/cmds/statsd/tests/StatsService_test.cpp
index 7c00531..86f786e 100644
--- a/cmds/statsd/tests/StatsService_test.cpp
+++ b/cmds/statsd/tests/StatsService_test.cpp
@@ -16,6 +16,7 @@
 #include "config/ConfigKey.h"
 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
 
+#include <android/binder_interface_utils.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
@@ -29,33 +30,34 @@
 namespace statsd {
 
 using android::util::ProtoOutputStream;
+using ::ndk::SharedRefBase;
 
 #ifdef __ANDROID__
 
 TEST(StatsServiceTest, TestAddConfig_simple) {
-    StatsService service(nullptr, nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     StatsdConfig config;
     config.set_id(12345);
     string serialized = config.SerializeAsString();
 
     EXPECT_TRUE(
-            service.addConfigurationChecked(123, 12345, {serialized.begin(), serialized.end()}));
+            service->addConfigurationChecked(123, 12345, {serialized.begin(), serialized.end()}));
 }
 
 TEST(StatsServiceTest, TestAddConfig_empty) {
-    StatsService service(nullptr, nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     string serialized = "";
 
     EXPECT_TRUE(
-            service.addConfigurationChecked(123, 12345, {serialized.begin(), serialized.end()}));
+            service->addConfigurationChecked(123, 12345, {serialized.begin(), serialized.end()}));
 }
 
 TEST(StatsServiceTest, TestAddConfig_invalid) {
-    StatsService service(nullptr, nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     string serialized = "Invalid config!";
 
     EXPECT_FALSE(
-            service.addConfigurationChecked(123, 12345, {serialized.begin(), serialized.end()}));
+            service->addConfigurationChecked(123, 12345, {serialized.begin(), serialized.end()}));
 }
 
 TEST(StatsServiceTest, TestGetUidFromArgs) {
@@ -69,32 +71,32 @@
 
     int32_t uid;
 
-    StatsService service(nullptr, nullptr);
-    service.mEngBuild = true;
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
+    service->mEngBuild = true;
 
     // "-1"
-    EXPECT_FALSE(service.getUidFromArgs(args, 0, uid));
+    EXPECT_FALSE(service->getUidFromArgs(args, 0, uid));
 
     // "0"
-    EXPECT_TRUE(service.getUidFromArgs(args, 1, uid));
+    EXPECT_TRUE(service->getUidFromArgs(args, 1, uid));
     EXPECT_EQ(0, uid);
 
     // "1"
-    EXPECT_TRUE(service.getUidFromArgs(args, 2, uid));
+    EXPECT_TRUE(service->getUidFromArgs(args, 2, uid));
     EXPECT_EQ(1, uid);
 
     // "999999999999999999"
-    EXPECT_FALSE(service.getUidFromArgs(args, 3, uid));
+    EXPECT_FALSE(service->getUidFromArgs(args, 3, uid));
 
     // "a1"
-    EXPECT_FALSE(service.getUidFromArgs(args, 4, uid));
+    EXPECT_FALSE(service->getUidFromArgs(args, 4, uid));
 
     // ""
-    EXPECT_FALSE(service.getUidFromArgs(args, 5, uid));
+    EXPECT_FALSE(service->getUidFromArgs(args, 5, uid));
 
     // For a non-userdebug, uid "1" cannot be impersonated.
-    service.mEngBuild = false;
-    EXPECT_FALSE(service.getUidFromArgs(args, 2, uid));
+    service->mEngBuild = false;
+    EXPECT_FALSE(service->getUidFromArgs(args, 2, uid));
 }
 
 #else
diff --git a/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp b/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp
index 5e6de1c..90ffcd0 100644
--- a/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp
+++ b/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp
@@ -15,12 +15,14 @@
 #include "src/anomaly/AlarmTracker.h"
 
 #include <gtest/gtest.h>
+#include <log/log_time.h>
 #include <stdio.h>
 #include <vector>
 
 using namespace testing;
 using android::sp;
 using std::set;
+using std::shared_ptr;
 using std::unordered_map;
 using std::vector;
 
@@ -34,8 +36,9 @@
 
 TEST(AlarmTrackerTest, TestTriggerTimestamp) {
     sp<AlarmMonitor> subscriberAlarmMonitor =
-        new AlarmMonitor(100, [](const sp<IStatsCompanionService>&, int64_t){},
-                         [](const sp<IStatsCompanionService>&){});
+        new AlarmMonitor(100,
+                         [](const shared_ptr<IStatsCompanionService>&, int64_t){},
+                         [](const shared_ptr<IStatsCompanionService>&){});
     Alarm alarm;
     alarm.set_offset_millis(15 * MS_PER_SEC);
     alarm.set_period_millis(60 * 60 * MS_PER_SEC);  // 1hr
diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
index 5e60aba..9127be8 100644
--- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
+++ b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
@@ -12,6 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include <android/binder_interface_utils.h>
 #include <gtest/gtest.h>
 
 #include <vector>
@@ -20,6 +21,8 @@
 #include "src/stats_log_util.h"
 #include "tests/statsd_test_util.h"
 
+using ::ndk::SharedRefBase;
+
 namespace android {
 namespace os {
 namespace statsd {
@@ -71,7 +74,8 @@
 
     ConfigKey cfgKey;
     auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
-                                             new FakeSubsystemSleepCallback(), ATOM_TAG);
+                                             SharedRefBase::make<FakeSubsystemSleepCallback>(),
+                                             ATOM_TAG);
     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
     processor->mPullerManager->ForceClearPullerCache();
@@ -216,7 +220,8 @@
 
     ConfigKey cfgKey;
     auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
-                                             new FakeSubsystemSleepCallback(), ATOM_TAG);
+                                             SharedRefBase::make<FakeSubsystemSleepCallback>(),
+                                             ATOM_TAG);
     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
     processor->mPullerManager->ForceClearPullerCache();
@@ -317,7 +322,8 @@
 
     ConfigKey cfgKey;
     auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
-                                             new FakeSubsystemSleepCallback, ATOM_TAG);
+                                             SharedRefBase::make<FakeSubsystemSleepCallback>(),
+                                             ATOM_TAG);
     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
     processor->mPullerManager->ForceClearPullerCache();
@@ -426,7 +432,8 @@
 
     ConfigKey cfgKey;
     auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
-                                             new FakeSubsystemSleepCallback(), ATOM_TAG);
+                                             SharedRefBase::make<FakeSubsystemSleepCallback>(),
+                                             ATOM_TAG);
     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
     processor->mPullerManager->ForceClearPullerCache();
@@ -544,7 +551,8 @@
 
     ConfigKey cfgKey;
     auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
-                                             new FakeSubsystemSleepCallback(), ATOM_TAG);
+                                             SharedRefBase::make<FakeSubsystemSleepCallback>(),
+                                             ATOM_TAG);
     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
     processor->mPullerManager->ForceClearPullerCache();
diff --git a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
index 9d58867..1eecbe5 100644
--- a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
@@ -12,9 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include <android/os/BnPullAtomCallback.h>
-#include <android/os/IPullAtomResultReceiver.h>
-#include <binder/IPCThreadState.h>
+#include <android/binder_ibinder.h>
+#include <android/binder_interface_utils.h>
 #include <gtest/gtest.h>
 
 #include <vector>
@@ -24,6 +23,9 @@
 #include "src/stats_log_util.h"
 #include "tests/statsd_test_util.h"
 
+using::ndk::SharedRefBase;
+using std::shared_ptr;
+
 namespace android {
 namespace os {
 namespace statsd {
@@ -34,19 +36,17 @@
 const int kConfigKey = 789130123;  // Randomly chosen to avoid collisions with existing configs.
 const int kCallingUid = 0; // Randomly chosen
 
-void SendConfig(StatsService& service, const StatsdConfig& config) {
+void SendConfig(shared_ptr<StatsService>& service, const StatsdConfig& config) {
     string str;
     config.SerializeToString(&str);
-    std::vector<uint8_t> configAsVec(str.begin(), str.end());
-    bool success;
-    service.addConfiguration(kConfigKey, configAsVec, kCallingUid);
+    std::vector<int8_t> configAsVec(str.begin(), str.end());
+    service->addConfiguration(kConfigKey, configAsVec, kCallingUid);
 }
 
 ConfigMetricsReport GetReports(sp<StatsLogProcessor> processor, int64_t timestamp,
                                bool include_current = false) {
     vector<uint8_t> output;
-    IPCThreadState* ipc = IPCThreadState::self();
-    ConfigKey configKey(ipc->getCallingUid(), kConfigKey);
+    ConfigKey configKey(AIBinder_getCallingUid(), kConfigKey);
     processor->onDumpReport(configKey, timestamp, include_current /* include_current_bucket*/,
                             true /* erase_data */, ADB_DUMP, NO_TIME_CONSTRAINTS, &output);
     ConfigMetricsReportList reports;
@@ -114,56 +114,56 @@
 }  // anonymous namespace
 
 TEST(PartialBucketE2eTest, TestCountMetricWithoutSplit) {
-    StatsService service(nullptr, nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     SendConfig(service, MakeConfig());
     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
                                              // initialized with.
 
-    service.mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 1).get());
-    service.mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 2).get());
+    service->mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 1).get());
+    service->mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 2).get());
 
-    ConfigMetricsReport report = GetReports(service.mProcessor, start + 3);
+    ConfigMetricsReport report = GetReports(service->mProcessor, start + 3);
     // Expect no metrics since the bucket has not finished yet.
     EXPECT_EQ(1, report.metrics_size());
     EXPECT_EQ(0, report.metrics(0).count_metrics().data_size());
 }
 
 TEST(PartialBucketE2eTest, TestCountMetricNoSplitOnNewApp) {
-    StatsService service(nullptr, nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     SendConfig(service, MakeConfig());
     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
                                              // initialized with.
 
     // Force the uidmap to update at timestamp 2.
-    service.mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 1).get());
+    service->mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 1).get());
     // This is a new installation, so there shouldn't be a split (should be same as the without
     // split case).
-    service.mUidMap->updateApp(start + 2, String16(kApp1.c_str()), 1, 2, String16("v2"),
+    service->mUidMap->updateApp(start + 2, String16(kApp1.c_str()), 1, 2, String16("v2"),
                                String16(""));
     // Goes into the second bucket.
-    service.mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 3).get());
+    service->mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 3).get());
 
-    ConfigMetricsReport report = GetReports(service.mProcessor, start + 4);
+    ConfigMetricsReport report = GetReports(service->mProcessor, start + 4);
     EXPECT_EQ(1, report.metrics_size());
     EXPECT_EQ(0, report.metrics(0).count_metrics().data_size());
 }
 
 TEST(PartialBucketE2eTest, TestCountMetricSplitOnUpgrade) {
-    StatsService service(nullptr, nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     SendConfig(service, MakeConfig());
     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
                                              // initialized with.
-    service.mUidMap->updateMap(start, {1}, {1}, {String16("v1")}, {String16(kApp1.c_str())},
-                               {String16("")});
+    service->mUidMap->updateMap(start, {1}, {1}, {String16("v1")}, {String16(kApp1.c_str())},
+                                {String16("")});
 
     // Force the uidmap to update at timestamp 2.
-    service.mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 1).get());
-    service.mUidMap->updateApp(start + 2, String16(kApp1.c_str()), 1, 2, String16("v2"),
+    service->mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 1).get());
+    service->mUidMap->updateApp(start + 2, String16(kApp1.c_str()), 1, 2, String16("v2"),
                                String16(""));
     // Goes into the second bucket.
-    service.mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 3).get());
+    service->mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 3).get());
 
-    ConfigMetricsReport report = GetReports(service.mProcessor, start + 4);
+    ConfigMetricsReport report = GetReports(service->mProcessor, start + 4);
     backfillStartEndTimestamp(&report);
 
     ASSERT_EQ(1, report.metrics_size());
@@ -177,20 +177,20 @@
 }
 
 TEST(PartialBucketE2eTest, TestCountMetricSplitOnRemoval) {
-    StatsService service(nullptr, nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     SendConfig(service, MakeConfig());
     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
                                              // initialized with.
-    service.mUidMap->updateMap(start, {1}, {1}, {String16("v1")}, {String16(kApp1.c_str())},
-                               {String16("")});
+    service->mUidMap->updateMap(start, {1}, {1}, {String16("v1")}, {String16(kApp1.c_str())},
+                                {String16("")});
 
     // Force the uidmap to update at timestamp 2.
-    service.mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 1).get());
-    service.mUidMap->removeApp(start + 2, String16(kApp1.c_str()), 1);
+    service->mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 1).get());
+    service->mUidMap->removeApp(start + 2, String16(kApp1.c_str()), 1);
     // Goes into the second bucket.
-    service.mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 3).get());
+    service->mProcessor->OnLogEvent(CreateAppCrashEvent(100, start + 3).get());
 
-    ConfigMetricsReport report = GetReports(service.mProcessor, start + 4);
+    ConfigMetricsReport report = GetReports(service->mProcessor, start + 4);
     backfillStartEndTimestamp(&report);
 
     ASSERT_EQ(1, report.metrics_size());
@@ -204,44 +204,44 @@
 }
 
 TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket) {
-    StatsService service(nullptr, nullptr);
-    service.mPullerManager->RegisterPullAtomCallback(
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
+    service->mPullerManager->RegisterPullAtomCallback(
             /*uid=*/0, android::util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
-            new FakeSubsystemSleepCallback());
+            SharedRefBase::make<FakeSubsystemSleepCallback>());
     // Partial buckets don't occur when app is first installed.
-    service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
+    service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
     SendConfig(service, MakeValueMetricConfig(0));
     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
                                              // initialized with.
 
-    service.mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
-    service.mUidMap->updateApp(5 * 60 * NS_PER_SEC + start + 2, String16(kApp1.c_str()), 1, 2,
-                               String16("v2"), String16(""));
+    service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
+    service->mUidMap->updateApp(5 * 60 * NS_PER_SEC + start + 2, String16(kApp1.c_str()), 1, 2,
+                                String16("v2"), String16(""));
 
     ConfigMetricsReport report =
-            GetReports(service.mProcessor, 5 * 60 * NS_PER_SEC + start + 100, true);
+            GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100, true);
     EXPECT_EQ(1, report.metrics_size());
     EXPECT_EQ(0, report.metrics(0).value_metrics().skipped_size());
 }
 
 TEST(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket) {
-    StatsService service(nullptr, nullptr);
-    service.mPullerManager->RegisterPullAtomCallback(
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
+    service->mPullerManager->RegisterPullAtomCallback(
             /*uid=*/0, android::util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
-            new FakeSubsystemSleepCallback());
+            SharedRefBase::make<FakeSubsystemSleepCallback>());
     // Partial buckets don't occur when app is first installed.
-    service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
+    service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
     SendConfig(service, MakeValueMetricConfig(60 * NS_PER_SEC /* One minute */));
     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
                                              // initialized with.
 
     const int64_t endSkipped = 5 * 60 * NS_PER_SEC + start + 2;
-    service.mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
-    service.mUidMap->updateApp(endSkipped, String16(kApp1.c_str()), 1, 2, String16("v2"),
+    service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
+    service->mUidMap->updateApp(endSkipped, String16(kApp1.c_str()), 1, 2, String16("v2"),
                                String16(""));
 
     ConfigMetricsReport report =
-            GetReports(service.mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC, true);
+            GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC, true);
     backfillStartEndTimestamp(&report);
 
     ASSERT_EQ(1, report.metrics_size());
@@ -253,38 +253,38 @@
 }
 
 TEST(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket) {
-    StatsService service(nullptr, nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     // Partial buckets don't occur when app is first installed.
-    service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
+    service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
     SendConfig(service, MakeGaugeMetricConfig(0));
     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
                                              // initialized with.
 
-    service.mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
-    service.mUidMap->updateApp(5 * 60 * NS_PER_SEC + start + 2, String16(kApp1.c_str()), 1, 2,
+    service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
+    service->mUidMap->updateApp(5 * 60 * NS_PER_SEC + start + 2, String16(kApp1.c_str()), 1, 2,
                                String16("v2"), String16(""));
 
     ConfigMetricsReport report =
-            GetReports(service.mProcessor, 5 * 60 * NS_PER_SEC + start + 100, true);
+            GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100, true);
     EXPECT_EQ(1, report.metrics_size());
     EXPECT_EQ(0, report.metrics(0).gauge_metrics().skipped_size());
 }
 
 TEST(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket) {
-    StatsService service(nullptr, nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     // Partial buckets don't occur when app is first installed.
-    service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
+    service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
     SendConfig(service, MakeGaugeMetricConfig(60 * NS_PER_SEC /* One minute */));
     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
                                              // initialized with.
 
     const int64_t endSkipped = 5 * 60 * NS_PER_SEC + start + 2;
-    service.mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
-    service.mUidMap->updateApp(endSkipped, String16(kApp1.c_str()), 1, 2, String16("v2"),
-                               String16(""));
+    service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
+    service->mUidMap->updateApp(endSkipped, String16(kApp1.c_str()), 1, 2, String16("v2"),
+                                String16(""));
 
     ConfigMetricsReport report =
-            GetReports(service.mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC, true);
+            GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC, true);
     backfillStartEndTimestamp(&report);
     ASSERT_EQ(1, report.metrics_size());
     ASSERT_EQ(1, report.metrics(0).gauge_metrics().skipped_size());
diff --git a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
index a140af8..9d39f9c 100644
--- a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
@@ -12,6 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include <android/binder_interface_utils.h>
 #include <gtest/gtest.h>
 
 #include "src/StatsLogProcessor.h"
@@ -20,6 +21,8 @@
 
 #include <vector>
 
+using ::ndk::SharedRefBase;
+
 namespace android {
 namespace os {
 namespace statsd {
@@ -70,7 +73,7 @@
 
     ConfigKey cfgKey;
     auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
-                                             new FakeSubsystemSleepCallback(),
+                                             SharedRefBase::make<FakeSubsystemSleepCallback>(),
                                              android::util::SUBSYSTEM_SLEEP_STATE);
     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
@@ -175,7 +178,7 @@
 
     ConfigKey cfgKey;
     auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
-                                             new FakeSubsystemSleepCallback(),
+                                             SharedRefBase::make<FakeSubsystemSleepCallback>(),
                                              android::util::SUBSYSTEM_SLEEP_STATE);
     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
@@ -288,7 +291,7 @@
 
     ConfigKey cfgKey;
     auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
-                                             new FakeSubsystemSleepCallback(),
+                                             SharedRefBase::make<FakeSubsystemSleepCallback>(),
                                              android::util::SUBSYSTEM_SLEEP_STATE);
     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
diff --git a/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp b/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp
index a011692e..e416b4c 100644
--- a/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp
+++ b/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp
@@ -14,8 +14,10 @@
 
 #include "src/external/StatsCallbackPuller.h"
 
-#include <android/os/BnPullAtomCallback.h>
-#include <android/os/IPullAtomResultReceiver.h>
+#include <aidl/android/os/BnPullAtomCallback.h>
+#include <aidl/android/os/IPullAtomResultReceiver.h>
+#include <aidl/android/util/StatsEventParcel.h>
+#include <android/binder_interface_utils.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 #include <stdio.h>
@@ -35,6 +37,11 @@
 namespace statsd {
 
 using namespace testing;
+using Status = ::ndk::ScopedAStatus;
+using aidl::android::os::BnPullAtomCallback;
+using aidl::android::os::IPullAtomResultReceiver;
+using aidl::android::util::StatsEventParcel;
+using ::ndk::SharedRefBase;
 using std::make_shared;
 using std::shared_ptr;
 using std::vector;
@@ -58,15 +65,15 @@
     return event;
 }
 
-void executePull(const sp<IPullAtomResultReceiver>& resultReceiver) {
+void executePull(const shared_ptr<IPullAtomResultReceiver>& resultReceiver) {
     // Convert stats_events into StatsEventParcels.
-    std::vector<android::util::StatsEventParcel> parcels;
+    vector<StatsEventParcel> parcels;
     for (int i = 0; i < values.size(); i++) {
         AStatsEvent* event = createSimpleEvent(values[i]);
         size_t size;
         uint8_t* buffer = AStatsEvent_getBuffer(event, &size);
 
-        android::util::StatsEventParcel p;
+        StatsEventParcel p;
         // vector.assign() creates a copy, but this is inevitable unless
         // stats_event.h/c uses a vector as opposed to a buffer.
         p.buffer.assign(buffer, buffer + size);
@@ -80,11 +87,11 @@
 
 class FakePullAtomCallback : public BnPullAtomCallback {
 public:
-    binder::Status onPullAtom(int atomTag,
-                              const sp<IPullAtomResultReceiver>& resultReceiver) override {
+    Status onPullAtom(int atomTag,
+                      const shared_ptr<IPullAtomResultReceiver>& resultReceiver) override {
         // Force pull to happen in separate thread to simulate binder.
         pullThread = std::thread(executePull, resultReceiver);
-        return binder::Status::ok();
+        return Status::ok();
     }
 };
 
@@ -111,7 +118,7 @@
 }  // Anonymous namespace.
 
 TEST_F(StatsCallbackPullerTest, PullSuccess) {
-    sp<FakePullAtomCallback> cb = new FakePullAtomCallback();
+    shared_ptr<FakePullAtomCallback> cb = SharedRefBase::make<FakePullAtomCallback>();
     int64_t value = 43;
     pullSuccess = true;
     values.push_back(value);
@@ -132,20 +139,20 @@
 }
 
 TEST_F(StatsCallbackPullerTest, PullFail) {
-    sp<FakePullAtomCallback> cb = new FakePullAtomCallback();
+    shared_ptr<FakePullAtomCallback> cb = SharedRefBase::make<FakePullAtomCallback>();
     pullSuccess = false;
     int64_t value = 1234;
     values.push_back(value);
 
     StatsCallbackPuller puller(pullTagId, cb, pullCoolDownNs, pullTimeoutNs, {});
 
-    vector<std::shared_ptr<LogEvent>> dataHolder;
+    vector<shared_ptr<LogEvent>> dataHolder;
     EXPECT_FALSE(puller.PullInternal(&dataHolder));
     EXPECT_EQ(0, dataHolder.size());
 }
 
 TEST_F(StatsCallbackPullerTest, PullTimeout) {
-    sp<FakePullAtomCallback> cb = new FakePullAtomCallback();
+    shared_ptr<FakePullAtomCallback> cb = SharedRefBase::make<FakePullAtomCallback>();
     pullSuccess = true;
     pullDelayNs = 500000000;  // 500ms.
     pullTimeoutNs = 10000;    // 10 microseconds.
@@ -154,7 +161,7 @@
 
     StatsCallbackPuller puller(pullTagId, cb, pullCoolDownNs, pullTimeoutNs, {});
 
-    vector<std::shared_ptr<LogEvent>> dataHolder;
+    vector<shared_ptr<LogEvent>> dataHolder;
     int64_t startTimeNs = getElapsedRealtimeNs();
     // Returns true to let StatsPuller code evaluate the timeout.
     EXPECT_TRUE(puller.PullInternal(&dataHolder));
@@ -174,7 +181,7 @@
 
 // Register a puller and ensure that the timeout logic works.
 TEST_F(StatsCallbackPullerTest, RegisterAndTimeout) {
-    sp<FakePullAtomCallback> cb = new FakePullAtomCallback();
+    shared_ptr<FakePullAtomCallback> cb = SharedRefBase::make<FakePullAtomCallback>();
     pullSuccess = true;
     pullDelayNs = 500000000;  // 500 ms.
     pullTimeoutNs = 10000;    // 10 microsseconds.
@@ -184,7 +191,7 @@
     StatsPullerManager pullerManager;
     pullerManager.RegisterPullAtomCallback(/*uid=*/-1, pullTagId, pullCoolDownNs, pullTimeoutNs,
                                            vector<int32_t>(), cb);
-    vector<std::shared_ptr<LogEvent>> dataHolder;
+    vector<shared_ptr<LogEvent>> dataHolder;
     int64_t startTimeNs = getElapsedRealtimeNs();
     // Returns false, since StatsPuller code will evaluate the timeout.
     EXPECT_FALSE(pullerManager.Pull(pullTagId, &dataHolder));
diff --git a/cmds/statsd/tests/shell/ShellSubscriber_test.cpp b/cmds/statsd/tests/shell/ShellSubscriber_test.cpp
index 73d1fd7..dac5f33 100644
--- a/cmds/statsd/tests/shell/ShellSubscriber_test.cpp
+++ b/cmds/statsd/tests/shell/ShellSubscriber_test.cpp
@@ -34,27 +34,6 @@
 
 #ifdef __ANDROID__
 
-class MyResultReceiver : public BnResultReceiver {
-public:
-    Mutex mMutex;
-    Condition mCondition;
-    bool mHaveResult = false;
-    int32_t mResult = 0;
-
-    virtual void send(int32_t resultCode) {
-        AutoMutex _l(mMutex);
-        mResult = resultCode;
-        mHaveResult = true;
-        mCondition.signal();
-    }
-
-    int32_t waitForResult() {
-        AutoMutex _l(mMutex);
-        mCondition.waitRelative(mMutex, 1000000000);
-        return mResult;
-    }
-};
-
 void runShellTest(ShellSubscription config, sp<MockUidMap> uidMap,
                   sp<MockStatsPullerManager> pullerManager,
                   const vector<std::shared_ptr<LogEvent>>& pushedEvents,
@@ -67,10 +46,7 @@
     ASSERT_EQ(0, pipe(fds_data));
 
     size_t bufferSize = config.ByteSize();
-
     // write the config to pipe, first write size of the config
-    vector<uint8_t> size_buffer(sizeof(bufferSize));
-    std::memcpy(size_buffer.data(), &bufferSize, sizeof(bufferSize));
     write(fds_config[1], &bufferSize, sizeof(bufferSize));
     // then write config itself
     vector<uint8_t> buffer(bufferSize);
@@ -79,11 +55,10 @@
     close(fds_config[1]);
 
     sp<ShellSubscriber> shellClient = new ShellSubscriber(uidMap, pullerManager);
-    sp<MyResultReceiver> resultReceiver = new MyResultReceiver();
 
     // mimic a binder thread that a shell subscriber runs on. it would block.
-    std::thread reader([&resultReceiver, &fds_config, &fds_data, &shellClient] {
-        shellClient->startNewSubscription(fds_config[0], fds_data[1], resultReceiver, -1);
+    std::thread reader([&shellClient, &fds_config, &fds_data] {
+        shellClient->startNewSubscription(fds_config[0], fds_data[1], /*timeoutSec=*/-1);
     });
     reader.detach();
 
diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp
index db09ee9..6958218 100644
--- a/cmds/statsd/tests/statsd_test_util.cpp
+++ b/cmds/statsd/tests/statsd_test_util.cpp
@@ -14,6 +14,11 @@
 
 #include "statsd_test_util.h"
 
+#include <aidl/android/util/StatsEventParcel.h>
+
+using aidl::android::util::StatsEventParcel;
+using std::shared_ptr;
+
 namespace android {
 namespace os {
 namespace statsd {
@@ -581,7 +586,7 @@
 
 sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs,
                                               const StatsdConfig& config, const ConfigKey& key,
-                                              const sp<IPullAtomCallback>& puller,
+                                              const shared_ptr<IPullAtomCallback>& puller,
                                               const int32_t atomTag) {
     sp<UidMap> uidMap = new UidMap();
     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
@@ -590,11 +595,13 @@
                                                 puller);
     }
     sp<AlarmMonitor> anomalyAlarmMonitor =
-        new AlarmMonitor(1,  [](const sp<IStatsCompanionService>&, int64_t){},
-                [](const sp<IStatsCompanionService>&){});
+        new AlarmMonitor(1,
+                         [](const shared_ptr<IStatsCompanionService>&, int64_t){},
+                         [](const shared_ptr<IStatsCompanionService>&){});
     sp<AlarmMonitor> periodicAlarmMonitor =
-        new AlarmMonitor(1,  [](const sp<IStatsCompanionService>&, int64_t){},
-                [](const sp<IStatsCompanionService>&){});
+        new AlarmMonitor(1,
+                         [](const shared_ptr<IStatsCompanionService>&, int64_t){},
+                         [](const shared_ptr<IStatsCompanionService>&){});
     sp<StatsLogProcessor> processor =
             new StatsLogProcessor(uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
                                   timeBaseNs, [](const ConfigKey&) { return true; },
@@ -948,10 +955,10 @@
     }
 }
 
-binder::Status FakeSubsystemSleepCallback::onPullAtom(
-        int atomTag, const sp<IPullAtomResultReceiver>& resultReceiver) {
+Status FakeSubsystemSleepCallback::onPullAtom(int atomTag,
+        const shared_ptr<IPullAtomResultReceiver>& resultReceiver) {
     // Convert stats_events into StatsEventParcels.
-    std::vector<android::util::StatsEventParcel> parcels;
+    std::vector<StatsEventParcel> parcels;
     for (int i = 1; i < 3; i++) {
         AStatsEvent* event = AStatsEvent_obtain();
         AStatsEvent_setAtomId(event, atomTag);
@@ -965,7 +972,7 @@
         size_t size;
         uint8_t* buffer = AStatsEvent_getBuffer(event, &size);
 
-        android::util::StatsEventParcel p;
+        StatsEventParcel p;
         // vector.assign() creates a copy, but this is inevitable unless
         // stats_event.h/c uses a vector as opposed to a buffer.
         p.buffer.assign(buffer, buffer + size);
@@ -973,7 +980,7 @@
         AStatsEvent_write(event);
     }
     resultReceiver->pullFinished(atomTag, /*success=*/true, parcels);
-    return binder::Status::ok();
+    return Status::ok();
 }
 
 }  // namespace statsd
diff --git a/cmds/statsd/tests/statsd_test_util.h b/cmds/statsd/tests/statsd_test_util.h
index 576a491..c8326ee 100644
--- a/cmds/statsd/tests/statsd_test_util.h
+++ b/cmds/statsd/tests/statsd_test_util.h
@@ -14,9 +14,9 @@
 
 #pragma once
 
-#include <android/os/BnPullAtomCallback.h>
-#include <android/os/IPullAtomCallback.h>
-#include <android/os/IPullAtomResultReceiver.h>
+#include <aidl/android/os/BnPullAtomCallback.h>
+#include <aidl/android/os/IPullAtomCallback.h>
+#include <aidl/android/os/IPullAtomResultReceiver.h>
 #include <gtest/gtest.h>
 
 #include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
@@ -31,8 +31,12 @@
 namespace os {
 namespace statsd {
 
+using ::aidl::android::os::BnPullAtomCallback;
+using ::aidl::android::os::IPullAtomCallback;
+using ::aidl::android::os::IPullAtomResultReceiver;
 using android::util::ProtoReader;
 using google::protobuf::RepeatedPtrField;
+using Status = ::ndk::ScopedAStatus;
 
 const int SCREEN_STATE_ATOM_ID = android::util::SCREEN_STATE_CHANGED;
 const int UID_PROCESS_STATE_ATOM_ID = android::util::UID_PROCESS_STATE_CHANGED;
@@ -230,7 +234,7 @@
 // Create a statsd log event processor upon the start time in seconds, config and key.
 sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs,
                                               const StatsdConfig& config, const ConfigKey& key,
-                                              const sp<IPullAtomCallback>& puller = nullptr,
+                                              const shared_ptr<IPullAtomCallback>& puller = nullptr,
                                               const int32_t atomTag = 0 /*for puller only*/);
 
 // Util function to sort the log events by timestamp.
@@ -285,8 +289,8 @@
 
 class FakeSubsystemSleepCallback : public BnPullAtomCallback {
 public:
-    binder::Status onPullAtom(int atomTag,
-                              const sp<IPullAtomResultReceiver>& resultReceiver) override;
+    Status onPullAtom(int atomTag,
+                      const shared_ptr<IPullAtomResultReceiver>& resultReceiver) override;
 };
 
 template <typename T>
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 2319dd2..5df67bc 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -126,6 +126,7 @@
 import android.view.autofill.AutofillManager.AutofillClient;
 import android.view.autofill.AutofillPopupWindow;
 import android.view.autofill.IAutofillWindowPresenter;
+import android.view.contentcapture.ContentCaptureContext;
 import android.view.contentcapture.ContentCaptureManager;
 import android.view.contentcapture.ContentCaptureManager.ContentCaptureClient;
 import android.widget.AdapterView;
@@ -1056,7 +1057,10 @@
         } catch (RemoteException re) {
             re.rethrowFromSystemServer();
         }
-        // TODO(b/147750355): Pass locusId and bundle to the Content Capture.
+        // If locusId is not null pass it to the Content Capture.
+        if (locusId != null) {
+            setLocusContextToContentCapture(locusId, bundle);
+        }
     }
 
     /** Return the application that owns this activity. */
@@ -1209,6 +1213,19 @@
         }
     }
 
+    private void setLocusContextToContentCapture(LocusId locusId, @Nullable Bundle bundle) {
+        final ContentCaptureManager cm = getContentCaptureManager();
+        if (cm == null) return;
+
+        ContentCaptureContext.Builder contentCaptureContextBuilder =
+                new ContentCaptureContext.Builder(locusId);
+        if (bundle != null) {
+            contentCaptureContextBuilder.setExtras(bundle);
+        }
+        cm.getMainContentCaptureSession().setContentCaptureContext(
+                contentCaptureContextBuilder.build());
+    }
+
     @Override
     protected void attachBaseContext(Context newBase) {
         super.attachBaseContext(newBase);
@@ -1890,6 +1907,7 @@
             if (!mAutoFillIgnoreFirstResumePause) {
                 View focus = getCurrentFocus();
                 if (focus != null && focus.canNotifyAutofillEnterExitEvent()) {
+                    // TODO(b/148815880): Bring up keyboard if resumed from inline authentication.
                     // TODO: in Activity killed/recreated case, i.e. SessionLifecycleTest#
                     // testDatasetVisibleWhileAutofilledAppIsLifecycled: the View's initial
                     // window visibility after recreation is INVISIBLE in onResume() and next frame
@@ -8450,7 +8468,7 @@
     /** @hide */
     @Override
     public final void autofillClientAuthenticate(int authenticationId, IntentSender intent,
-            Intent fillInIntent) {
+            Intent fillInIntent, boolean authenticateInline) {
         try {
             startIntentSenderForResultInner(intent, AUTO_FILL_AUTH_WHO_PREFIX,
                     authenticationId, fillInIntent, 0, 0, null);
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 1de68ba..f6bbc68 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -16,6 +16,10 @@
 
 package android.app;
 
+import static android.util.StatsLogInternal.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__DEFAULT;
+import static android.util.StatsLogInternal.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__RARELY_USED;
+import static android.util.StatsLogInternal.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__UNIFORM;
+
 import android.Manifest;
 import android.annotation.CallbackExecutor;
 import android.annotation.IntDef;
@@ -48,6 +52,8 @@
 import android.os.Process;
 import android.os.RemoteCallback;
 import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
 import android.os.UserManager;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -63,6 +69,7 @@
 import com.android.internal.app.IAppOpsCallback;
 import com.android.internal.app.IAppOpsNotedCallback;
 import com.android.internal.app.IAppOpsService;
+import com.android.internal.app.MessageSamplingConfig;
 import com.android.internal.os.RuntimeInit;
 import com.android.internal.os.ZygoteInit;
 import com.android.internal.util.ArrayUtils;
@@ -141,6 +148,13 @@
     @UnsupportedAppUsage
     final IAppOpsService mService;
 
+    /**
+     * Service for the application context, to be used by static methods via
+     * {@link #getService()}
+     */
+    @GuardedBy("sLock")
+    static IAppOpsService sService;
+
     @GuardedBy("mModeWatchers")
     private final ArrayMap<OnOpChangedListener, IAppOpsCallback> mModeWatchers =
             new ArrayMap<>();
@@ -159,6 +173,50 @@
     @GuardedBy("sLock")
     private static @Nullable AppOpsCollector sNotedAppOpsCollector;
 
+    /**
+     * Additional collector that collect accesses and forwards a few of them them via
+     * {@link IAppOpsService#reportRuntimeAppOpAccessMessageAndGetConfig}.
+     */
+    private static AppOpsCollector sMessageCollector =
+            new AppOpsCollector() {
+                @Override
+                public void onNoted(@NonNull SyncNotedAppOp op) {
+                    reportStackTraceIfNeeded(op);
+                }
+
+                @Override
+                public void onAsyncNoted(@NonNull AsyncNotedAppOp asyncOp) {
+                    // collected directly in AppOpsService
+                }
+
+                @Override
+                public void onSelfNoted(@NonNull SyncNotedAppOp op) {
+                    reportStackTraceIfNeeded(op);
+                }
+
+                private void reportStackTraceIfNeeded(@NonNull SyncNotedAppOp op) {
+                    if (sConfig.getSampledOpCode() == OP_NONE
+                            && sConfig.getExpirationTimeSinceBootMillis()
+                            >= SystemClock.elapsedRealtime()) {
+                        return;
+                    }
+
+                    MessageSamplingConfig config = sConfig;
+                    if (leftCircularDistance(strOpToOp(op.getOp()), config.getSampledOpCode(),
+                            _NUM_OP) <= config.getAcceptableLeftDistance()
+                            || config.getExpirationTimeSinceBootMillis()
+                            < SystemClock.elapsedRealtime()) {
+                        String stackTrace = getFormattedStackTrace();
+                        try {
+                            sConfig = getService().reportRuntimeAppOpAccessMessageAndGetConfig(
+                                    ActivityThread.currentOpPackageName(), op, stackTrace);
+                        } catch (RemoteException e) {
+                            e.rethrowFromSystemServer();
+                        }
+                    }
+                }
+            };
+
     static IBinder sClientId;
 
     /**
@@ -550,7 +608,6 @@
     })
     public @interface OpFlags {}
 
-
     /** @hide */
     public static final String getFlagName(@OpFlags int flag) {
         switch (flag) {
@@ -569,6 +626,18 @@
         }
     }
 
+    /**
+     * Strategies used for message sampling
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"RUNTIME_APP_OPS_ACCESS__SAMPLING_STRATEGY__"}, value = {
+            RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__DEFAULT,
+            RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__UNIFORM,
+            RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__RARELY_USED
+    })
+    public @interface SamplingStrategy {}
+
     private static final int UID_STATE_OFFSET = 31;
     private static final int FLAGS_MASK = 0xFFFFFFFF;
 
@@ -2225,6 +2294,10 @@
         }
     }
 
+    /** Config used to control app ops access messages sampling */
+    private static MessageSamplingConfig sConfig =
+            new MessageSamplingConfig(OP_NONE, 0, 0);
+
     /** @hide */
     public static final String KEY_HISTORICAL_OPS = "historical_ops";
 
@@ -7268,6 +7341,17 @@
         }
     }
 
+    /** @hide */
+    private static IAppOpsService getService() {
+        synchronized (sLock) {
+            if (sService == null) {
+                sService = IAppOpsService.Stub.asInterface(
+                        ServiceManager.getService(Context.APP_OPS_SERVICE));
+            }
+            return sService;
+        }
+    }
+
     /**
      * @deprecated use {@link #startOp(String, int, String, String, String)} instead
      */
@@ -7614,6 +7698,7 @@
                 sNotedAppOpsCollector.onSelfNoted(new SyncNotedAppOp(op, featureId));
             }
         }
+        sMessageCollector.onSelfNoted(new SyncNotedAppOp(op, featureId));
     }
 
     /**
@@ -7764,6 +7849,10 @@
                         }
                     }
                 }
+                for (int code = notedAppOps.nextSetBit(0); code != -1;
+                        code = notedAppOps.nextSetBit(code + 1)) {
+                    sMessageCollector.onNoted(new SyncNotedAppOp(code, featureId));
+                }
             }
         }
     }
@@ -7958,10 +8047,13 @@
 
         StringBuilder sb = new StringBuilder();
         for (int i = firstInteresting; i <= lastInteresting; i++) {
-            sb.append(trace[i]);
-            if (i != lastInteresting) {
+            if (i != firstInteresting) {
                 sb.append('\n');
             }
+            if (sb.length() + trace[i].toString().length() > 600) {
+                break;
+            }
+            sb.append(trace[i]);
         }
 
         return sb.toString();
@@ -8089,6 +8181,22 @@
     }
 
     /**
+     * Pulls current AppOps access report and picks package and op to watch for next access report
+     *
+     * @hide
+     */
+    @SystemApi
+    @TestApi
+    @RequiresPermission(Manifest.permission.GET_APP_OPS_STATS)
+    public @Nullable RuntimeAppOpAccessMessage collectRuntimeAppOpAccessMessage() {
+        try {
+            return mService.collectRuntimeAppOpAccessMessage();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Returns all supported operation names.
      * @hide
      */
@@ -8297,4 +8405,12 @@
 
         return AppOpsManager.MODE_DEFAULT;
     }
+
+    /**
+     * Calculate left circular distance for two numbers modulo size.
+     * @hide
+     */
+    public static int leftCircularDistance(int from, int to, int size) {
+        return (to + size - from) % size;
+    }
 }
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index 180507c..3c475c1 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -315,11 +315,6 @@
     void positionTaskInStack(int taskId, int stackId, int position);
     void reportSizeConfigurations(in IBinder token, in int[] horizontalSizeConfiguration,
             in int[] verticalSizeConfigurations, in int[] smallestWidthConfigurations);
-    /**
-     * Dismisses split-screen multi-window mode.
-     * {@param toTop} If true the current primary split-screen stack will be placed or left on top.
-     */
-    void dismissSplitScreenMode(boolean toTop);
 
     /**
      * Dismisses PiP
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
index 06288c0..37bdda0 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -204,4 +204,12 @@
      * @param frozen if true, Recents Tasks list is currently frozen, false otherwise
      */
     void onRecentTaskListFrozenChanged(boolean frozen);
+
+    /**
+     * Called when a task gets or loses focus.
+     *
+     * @param taskId id of the task.
+     * @param {@code true} if the task got focus, {@code false} if it lost it.
+     */
+    void onTaskFocusChanged(int taskId, boolean focused);
 }
diff --git a/core/java/android/app/NotificationHistory.java b/core/java/android/app/NotificationHistory.java
index f26e628..d16120d 100644
--- a/core/java/android/app/NotificationHistory.java
+++ b/core/java/android/app/NotificationHistory.java
@@ -21,6 +21,7 @@
 import android.graphics.drawable.Icon;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.text.TextUtils;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -51,6 +52,7 @@
         private String mTitle;
         private String mText;
         private Icon mIcon;
+        private String mConversationId;
 
         private HistoricalNotification() {}
 
@@ -94,6 +96,10 @@
             return mPackage + "|" + mUid + "|" + mPostedTimeMs;
         }
 
+        public String getConversationId() {
+            return mConversationId;
+        }
+
         @Override
         public String toString() {
             return "HistoricalNotification{" +
@@ -104,6 +110,7 @@
                     ", mTitle='" + mTitle + '\'' +
                     ", mText='" + mText + '\'' +
                     ", mIcon=" + mIcon +
+                    ", mConversationId=" + mConversationId +
                     '}';
         }
 
@@ -123,6 +130,7 @@
                     Objects.equals(getChannelId(), that.getChannelId()) &&
                     Objects.equals(getTitle(), that.getTitle()) &&
                     Objects.equals(getText(), that.getText()) &&
+                    Objects.equals(getConversationId(), that.getConversationId()) &&
                     iconsAreSame;
         }
 
@@ -130,7 +138,7 @@
         public int hashCode() {
             return Objects.hash(getPackage(), getChannelName(), getChannelId(), getUid(),
                     getUserId(),
-                    getPostedTimeMs(), getTitle(), getText(), getIcon());
+                    getPostedTimeMs(), getTitle(), getText(), getIcon(), getConversationId());
         }
 
         public static final class Builder {
@@ -143,6 +151,7 @@
             private String mTitle;
             private String mText;
             private Icon mIcon;
+            private String mConversationId;
 
             public Builder() {}
 
@@ -191,6 +200,11 @@
                 return this;
             }
 
+            public Builder setConversationId(String conversationId) {
+                mConversationId = conversationId;
+                return this;
+            }
+
             public HistoricalNotification build() {
                 HistoricalNotification n = new HistoricalNotification();
                 n.mPackage = mPackage;
@@ -202,6 +216,7 @@
                 n.mTitle = mTitle;
                 n.mText = mText;
                 n.mIcon = mIcon;
+                n.mConversationId = mConversationId;
                 return n;
             }
         }
@@ -299,6 +314,9 @@
             mStringsToWrite.add(notification.getPackage());
             mStringsToWrite.add(notification.getChannelName());
             mStringsToWrite.add(notification.getChannelId());
+            if (!TextUtils.isEmpty(notification.getConversationId())) {
+                mStringsToWrite.add(notification.getConversationId());
+            }
         }
     }
 
@@ -423,9 +441,17 @@
             channelIdIndex = -1;
         }
 
+        final int conversationIdIndex;
+        if (!TextUtils.isEmpty(notification.getConversationId())) {
+            conversationIdIndex = findStringIndex(notification.getConversationId());
+        } else {
+            conversationIdIndex = -1;
+        }
+
         p.writeInt(packageIndex);
         p.writeInt(channelNameIndex);
         p.writeInt(channelIdIndex);
+        p.writeInt(conversationIdIndex);
         p.writeInt(notification.getUid());
         p.writeInt(notification.getUserId());
         p.writeLong(notification.getPostedTimeMs());
@@ -461,6 +487,13 @@
             notificationOut.setChannelId(null);
         }
 
+        final int conversationIdIndex = p.readInt();
+        if (conversationIdIndex >= 0) {
+            notificationOut.setConversationId(mStringPool[conversationIdIndex]);
+        } else {
+            notificationOut.setConversationId(null);
+        }
+
         notificationOut.setUid(p.readInt());
         notificationOut.setUserId(p.readInt());
         notificationOut.setPostedTimeMs(p.readLong());
diff --git a/core/java/android/app/Presentation.java b/core/java/android/app/Presentation.java
index f864fb5..eaee060 100644
--- a/core/java/android/app/Presentation.java
+++ b/core/java/android/app/Presentation.java
@@ -116,7 +116,9 @@
  * The display manager keeps track of all displays in the system.  However, not all
  * displays are appropriate for showing presentations.  For example, if an activity
  * attempted to show a presentation on the main display it might obscure its own content
- * (it's like opening a dialog on top of your activity).
+ * (it's like opening a dialog on top of your activity).  Creating a presentation on the main
+ * display will result in {@link android.view.WindowManager.InvalidDisplayException} being thrown
+ * when invoking {@link #show()}.
  * </p><p>
  * Here's how to identify suitable displays for showing presentations using
  * {@link DisplayManager#getDisplays(String)} and the
@@ -243,7 +245,7 @@
     /**
      * Inherited from {@link Dialog#show}. Will throw
      * {@link android.view.WindowManager.InvalidDisplayException} if the specified secondary
-     * {@link Display} can't be found.
+     * {@link Display} can't be found or if it does not have {@link Display#FLAG_PRESENTATION} set.
      */
     @Override
     public void show() {
diff --git a/core/java/com/android/internal/view/animation/NativeInterpolatorFactory.java b/core/java/android/app/RuntimeAppOpAccessMessage.aidl
similarity index 74%
copy from core/java/com/android/internal/view/animation/NativeInterpolatorFactory.java
copy to core/java/android/app/RuntimeAppOpAccessMessage.aidl
index fcacd52..68e8819 100644
--- a/core/java/com/android/internal/view/animation/NativeInterpolatorFactory.java
+++ b/core/java/android/app/RuntimeAppOpAccessMessage.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2019 The Android Open 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,8 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.internal.view.animation;
+package android.app;
 
-public interface NativeInterpolatorFactory {
-    long createNativeInterpolator();
-}
+parcelable RuntimeAppOpAccessMessage;
diff --git a/core/java/android/app/RuntimeAppOpAccessMessage.java b/core/java/android/app/RuntimeAppOpAccessMessage.java
new file mode 100644
index 0000000..a81b8e7
--- /dev/null
+++ b/core/java/android/app/RuntimeAppOpAccessMessage.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.annotations.Immutable;
+import com.android.internal.util.DataClass;
+
+/**
+ * Message for noted runtime permission access.
+ * @hide
+ */
+@Immutable
+@TestApi
+@SystemApi
+/*@DataClass(genConstructor = false)
+@DataClass.Suppress("getOpCode")*/
+public final class RuntimeAppOpAccessMessage implements Parcelable {
+    /** Uid of package for which runtime app op access message was collected */
+    private final @IntRange(from = 0L) int mUid;
+    /** Op code of operation access which was collected */
+    private final @IntRange(from = 0L, to = AppOpsManager._NUM_OP - 1) int mOpCode;
+    /** Name of package for which runtime app op access message was collected */
+    private final @NonNull String mPackageName;
+    /** Feature of package for which runtime app op access message was collected */
+    private final @Nullable String mFeatureId;
+    /** Message collected (including stacktrace for synchronous ops) */
+    private final @NonNull String mMessage;
+    /** Sampling strategy used to collect this message. */
+    private final @AppOpsManager.SamplingStrategy int mSamplingStrategy;
+
+    public @NonNull String getOp() {
+        return AppOpsManager.opToPublicName(mOpCode);
+    }
+
+    /**
+     * Creates a new RuntimeAppOpAccessMessage.
+     *
+     * @param uid
+     *   Uid of package for which runtime app op access message was collected
+     * @param opCode
+     *   Op code of operation access which was collected
+     * @param packageName
+     *   Name of package for which runtime app op access message was collected
+     * @param featureId
+     *   Feature of package for which runtime app op access message was collected
+     * @param message
+     *   Message collected (including stacktrace for synchronous ops)
+     * @param samplingStrategy
+     *   Sampling strategy used to collect this message.
+     */
+    @DataClass.Generated.Member
+    public RuntimeAppOpAccessMessage(
+            @IntRange(from = 0L) int uid,
+            @IntRange(from = 0L) int opCode,
+            @NonNull String packageName,
+            @Nullable String featureId,
+            @NonNull String message,
+            @AppOpsManager.SamplingStrategy int samplingStrategy) {
+        this.mUid = uid;
+        com.android.internal.util.AnnotationValidations.validate(
+                IntRange.class, null, mUid,
+                "from", 0L);
+        this.mOpCode = opCode;
+        com.android.internal.util.AnnotationValidations.validate(
+                IntRange.class, null, mOpCode,
+                "from", 0L,
+                "to", AppOpsManager._NUM_OP - 1);
+        this.mPackageName = packageName;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mPackageName);
+        this.mFeatureId = featureId;
+        this.mMessage = message;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mMessage);
+        this.mSamplingStrategy = samplingStrategy;
+        com.android.internal.util.AnnotationValidations.validate(
+                AppOpsManager.SamplingStrategy.class, null, mSamplingStrategy);
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+
+
+
+    // Code below generated by codegen v1.0.14.
+    //
+    // DO NOT MODIFY!
+    // CHECKSTYLE:OFF Generated code
+    //
+    // To regenerate run:
+    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/app/RuntimeAppOpAccessMessage.java
+    //
+    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+    //   Settings > Editor > Code Style > Formatter Control
+    //@formatter:off
+
+
+    /**
+     * Uid of package for which runtime app op access message was collected
+     */
+    @DataClass.Generated.Member
+    public @IntRange(from = 0L) int getUid() {
+        return mUid;
+    }
+
+    /**
+     * Name of package for which runtime app op access message was collected
+     */
+    @DataClass.Generated.Member
+    public @NonNull String getPackageName() {
+        return mPackageName;
+    }
+
+    /**
+     * Feature of package for which runtime app op access message was collected
+     */
+    @DataClass.Generated.Member
+    public @Nullable String getFeatureId() {
+        return mFeatureId;
+    }
+
+    /**
+     * Message collected (including stacktrace for synchronous ops)
+     */
+    @DataClass.Generated.Member
+    public @NonNull String getMessage() {
+        return mMessage;
+    }
+
+    /**
+     * Sampling strategy used to collect this message.
+     */
+    @DataClass.Generated.Member
+    public @AppOpsManager.SamplingStrategy int getSamplingStrategy() {
+        return mSamplingStrategy;
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        // You can override field parcelling by defining methods like:
+        // void parcelFieldName(Parcel dest, int flags) { ... }
+
+        byte flg = 0;
+        if (mFeatureId != null) flg |= 0x8;
+        dest.writeByte(flg);
+        dest.writeInt(mUid);
+        dest.writeInt(mOpCode);
+        dest.writeString(mPackageName);
+        if (mFeatureId != null) dest.writeString(mFeatureId);
+        dest.writeString(mMessage);
+        dest.writeInt(mSamplingStrategy);
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public int describeContents() { return 0; }
+
+    /** @hide */
+    @SuppressWarnings({"unchecked", "RedundantCast"})
+    @DataClass.Generated.Member
+    /* package-private */ RuntimeAppOpAccessMessage(@NonNull Parcel in) {
+        // You can override field unparcelling by defining methods like:
+        // static FieldType unparcelFieldName(Parcel in) { ... }
+
+        byte flg = in.readByte();
+        int uid = in.readInt();
+        int opCode = in.readInt();
+        String packageName = in.readString();
+        String featureId = (flg & 0x8) == 0 ? null : in.readString();
+        String message = in.readString();
+        int samplingStrategy = in.readInt();
+
+        this.mUid = uid;
+        com.android.internal.util.AnnotationValidations.validate(
+                IntRange.class, null, mUid,
+                "from", 0L);
+        this.mOpCode = opCode;
+        com.android.internal.util.AnnotationValidations.validate(
+                IntRange.class, null, mOpCode,
+                "from", 0L,
+                "to", AppOpsManager._NUM_OP - 1);
+        this.mPackageName = packageName;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mPackageName);
+        this.mFeatureId = featureId;
+        this.mMessage = message;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mMessage);
+        this.mSamplingStrategy = samplingStrategy;
+        com.android.internal.util.AnnotationValidations.validate(
+                AppOpsManager.SamplingStrategy.class, null, mSamplingStrategy);
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    @DataClass.Generated.Member
+    public static final @NonNull Parcelable.Creator<RuntimeAppOpAccessMessage> CREATOR
+            = new Parcelable.Creator<RuntimeAppOpAccessMessage>() {
+        @Override
+        public RuntimeAppOpAccessMessage[] newArray(int size) {
+            return new RuntimeAppOpAccessMessage[size];
+        }
+
+        @Override
+        public RuntimeAppOpAccessMessage createFromParcel(@NonNull Parcel in) {
+            return new RuntimeAppOpAccessMessage(in);
+        }
+    };
+
+    /*@DataClass.Generated(
+            time = 1581517099127L,
+            codegenVersion = "1.0.14",
+            sourceFile = "frameworks/base/core/java/android/app/RuntimeAppOpAccessMessage.java",
+            inputSignatures = "private final @android.annotation.IntRange(from=0L) int mUid\nprivate final @android.annotation.IntRange(from=0L, to=AppOpsManager._NUM_OP - 1) int mOpCode\nprivate final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.Nullable java.lang.String mFeatureId\nprivate final @android.annotation.NonNull java.lang.String mMessage\nprivate final @android.app.AppOpsManager.SamplingStrategy int mSamplingStrategy\npublic @android.annotation.NonNull java.lang.String getOp()\nclass RuntimeAppOpAccessMessage extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false)")*/
+    @Deprecated
+    private void __metadata() {}
+
+
+    //@formatter:on
+    // End of generated code
+
+}
diff --git a/core/java/com/android/internal/view/animation/NativeInterpolatorFactory.java b/core/java/android/app/SyncNotedAppOp.aidl
similarity index 74%
copy from core/java/com/android/internal/view/animation/NativeInterpolatorFactory.java
copy to core/java/android/app/SyncNotedAppOp.aidl
index fcacd52..ab062d2 100644
--- a/core/java/com/android/internal/view/animation/NativeInterpolatorFactory.java
+++ b/core/java/android/app/SyncNotedAppOp.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2019 The Android Open 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,8 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.internal.view.animation;
+package android.app;
 
-public interface NativeInterpolatorFactory {
-    long createNativeInterpolator();
-}
+parcelable SyncNotedAppOp;
diff --git a/core/java/android/app/SyncNotedAppOp.java b/core/java/android/app/SyncNotedAppOp.java
index 065d5de..aa11b95 100644
--- a/core/java/android/app/SyncNotedAppOp.java
+++ b/core/java/android/app/SyncNotedAppOp.java
@@ -19,8 +19,10 @@
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.os.Parcelable;
 
 import com.android.internal.annotations.Immutable;
+import com.android.internal.util.DataClass;
 
 /**
  * Description of an app-op that was noted for the current process.
@@ -32,48 +34,154 @@
  * itself}.
  */
 @Immutable
-public final class SyncNotedAppOp {
-    private final int mOpCode;
+/*@DataClass(
+        genEqualsHashCode = true,
+        genConstructor = false
+)
+@DataClass.Suppress("getOpCode")*/
+public final class SyncNotedAppOp implements Parcelable {
+
+    /** op code of synchronous appop noted */
+    private final @IntRange(from = 0L, to = AppOpsManager._NUM_OP - 1) int mOpCode;
+    /** featureId of synchronous appop noted */
     private final @Nullable String mFeatureId;
 
     /**
+     * Creates a new SyncNotedAppOp.
+     *
+     * @param opCode
+     *   op code of synchronous appop noted
+     * @param featureId
+     *   featureId of synchronous appop noted
+     */
+    public SyncNotedAppOp(@IntRange(from = 0L) int opCode, @Nullable String featureId) {
+        this.mOpCode = opCode;
+        com.android.internal.util.AnnotationValidations.validate(
+                IntRange.class, null, mOpCode,
+                "from", 0,
+                "to", AppOpsManager._NUM_OP - 1);
+        this.mFeatureId = featureId;
+    }
+
+    /**
      * @return The op that was noted.
      */
     public @NonNull String getOp() {
         return AppOpsManager.opToPublicName(mOpCode);
     }
 
+    // Code below generated by codegen v1.0.14.
+    //
+    // DO NOT MODIFY!
+    // CHECKSTYLE:OFF Generated code
+    //
+    // To regenerate run:
+    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/app/SyncNotedAppOp.java
+    //
+    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+    //   Settings > Editor > Code Style > Formatter Control
+    //@formatter:off
+
+
     /**
-     * @return The {@link android.content.Context#createFeatureContext Feature} in the app
+     * featureId of synchronous appop noted
      */
+    @DataClass.Generated.Member
     public @Nullable String getFeatureId() {
         return mFeatureId;
     }
 
-    /**
-     * Create a new sync op description
-     *
-     * @param opCode The op that was noted
-     *
-     * @hide
-     */
-    public SyncNotedAppOp(@IntRange(from = 0, to = AppOpsManager._NUM_OP - 1) int opCode,
-            @Nullable String featureId) {
-        mOpCode = opCode;
-        mFeatureId = featureId;
+    @Override
+    @DataClass.Generated.Member
+    public boolean equals(@Nullable Object o) {
+        // You can override field equality logic by defining either of the methods like:
+        // boolean fieldNameEquals(SyncNotedAppOp other) { ... }
+        // boolean fieldNameEquals(FieldType otherValue) { ... }
+
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        @SuppressWarnings("unchecked")
+        SyncNotedAppOp that = (SyncNotedAppOp) o;
+        //noinspection PointlessBooleanExpression
+        return true
+                && mOpCode == that.mOpCode
+                && java.util.Objects.equals(mFeatureId, that.mFeatureId);
     }
 
     @Override
-    public boolean equals(Object other) {
-        if (!(other instanceof SyncNotedAppOp)) {
-            return false;
+    @DataClass.Generated.Member
+    public int hashCode() {
+        // You can override field hashCode logic by defining methods like:
+        // int fieldNameHashCode() { ... }
+
+        int _hash = 1;
+        _hash = 31 * _hash + mOpCode;
+        _hash = 31 * _hash + java.util.Objects.hashCode(mFeatureId);
+        return _hash;
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
+        // You can override field parcelling by defining methods like:
+        // void parcelFieldName(Parcel dest, int flags) { ... }
+
+        byte flg = 0;
+        if (mFeatureId != null) flg |= 0x2;
+        dest.writeByte(flg);
+        dest.writeInt(mOpCode);
+        if (mFeatureId != null) dest.writeString(mFeatureId);
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public int describeContents() { return 0; }
+
+    /** @hide */
+    @SuppressWarnings({"unchecked", "RedundantCast"})
+    @DataClass.Generated.Member
+    /* package-private */ SyncNotedAppOp(@NonNull android.os.Parcel in) {
+        // You can override field unparcelling by defining methods like:
+        // static FieldType unparcelFieldName(Parcel in) { ... }
+
+        byte flg = in.readByte();
+        int opCode = in.readInt();
+        String featureId = (flg & 0x2) == 0 ? null : in.readString();
+
+        this.mOpCode = opCode;
+        com.android.internal.util.AnnotationValidations.validate(
+                IntRange.class, null, mOpCode,
+                "from", 0,
+                "to", AppOpsManager._NUM_OP - 1);
+        this.mFeatureId = featureId;
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    @DataClass.Generated.Member
+    public static final @NonNull Parcelable.Creator<SyncNotedAppOp> CREATOR
+            = new Parcelable.Creator<SyncNotedAppOp>() {
+        @Override
+        public SyncNotedAppOp[] newArray(int size) {
+            return new SyncNotedAppOp[size];
         }
 
-        return mOpCode == ((SyncNotedAppOp) other).mOpCode;
-    }
+        @Override
+        public SyncNotedAppOp createFromParcel(@NonNull android.os.Parcel in) {
+            return new SyncNotedAppOp(in);
+        }
+    };
 
-    @Override
-    public int hashCode() {
-        return mOpCode;
-    }
+    /*@DataClass.Generated(
+            time = 1579188889960L,
+            codegenVersion = "1.0.14",
+            sourceFile = "frameworks/base/core/java/android/app/SyncNotedAppOp.java",
+            inputSignatures = "private final @android.annotation.IntRange(from=0L, to=AppOpsManager._NUM_OP - 1) int mOpCode\nprivate final @android.annotation.Nullable java.lang.String mFeatureId\npublic @android.annotation.NonNull java.lang.String getOp()\npublic @android.annotation.SystemApi int getOpCode()\nclass SyncNotedAppOp extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genConstructor=false)")*/
+    @Deprecated
+    private void __metadata() {}
+
+
+    //@formatter:on
+    // End of generated code
+
 }
diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java
index 343b386..da0aadb 100644
--- a/core/java/android/app/TaskStackListener.java
+++ b/core/java/android/app/TaskStackListener.java
@@ -199,4 +199,8 @@
     @Override
     public void onRecentTaskListFrozenChanged(boolean frozen) {
     }
+
+    @Override
+    public void onTaskFocusChanged(int taskId, boolean focused) {
+    }
 }
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 4a5a23a..d9b9c56 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -8497,6 +8497,11 @@
      * From {@link android.os.Build.VERSION_CODES#N} the profile or device owner can still use
      * {@link android.accounts.AccountManager} APIs to add or remove accounts when account
      * management for a specific type is disabled.
+     * <p>
+     * This method may be called on the {@code DevicePolicyManager} instance returned from
+     * {@link #getParentProfileInstance(ComponentName)} by the profile owner on an
+     * organization-owned device, to restrict accounts that may not be managed on the primary
+     * profile.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param accountType For which account management is disabled or enabled.
@@ -8506,10 +8511,10 @@
      */
     public void setAccountManagementDisabled(@NonNull ComponentName admin, String accountType,
             boolean disabled) {
-        throwIfParentInstance("setAccountManagementDisabled");
         if (mService != null) {
             try {
-                mService.setAccountManagementDisabled(admin, accountType, disabled);
+                mService.setAccountManagementDisabled(admin, accountType, disabled,
+                        mParentInstance);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -8517,28 +8522,43 @@
     }
 
     /**
-     * Gets the array of accounts for which account management is disabled by the profile owner.
+     * Gets the array of accounts for which account management is disabled by the profile owner
+     * or device owner.
      *
      * <p> Account management can be disabled/enabled by calling
      * {@link #setAccountManagementDisabled}.
+     * <p>
+     * This method may be called on the {@code DevicePolicyManager} instance returned from
+     * {@link #getParentProfileInstance(ComponentName)}. Note that only a profile owner on
+     * an organization-deviced can affect account types on the parent profile instance.
      *
      * @return a list of account types for which account management has been disabled.
      *
      * @see #setAccountManagementDisabled
      */
     public @Nullable String[] getAccountTypesWithManagementDisabled() {
-        throwIfParentInstance("getAccountTypesWithManagementDisabled");
-        return getAccountTypesWithManagementDisabledAsUser(myUserId());
+        return getAccountTypesWithManagementDisabledAsUser(myUserId(), mParentInstance);
+    }
+
+    /**
+     * @see #getAccountTypesWithManagementDisabled()
+     * Note that calling this method on the parent profile instance will return the same
+     * value as calling it on the main {@code DevicePolicyManager} instance.
+     * @hide
+     */
+    public @Nullable String[] getAccountTypesWithManagementDisabledAsUser(int userId) {
+        return getAccountTypesWithManagementDisabledAsUser(userId, false);
     }
 
     /**
      * @see #getAccountTypesWithManagementDisabled()
      * @hide
      */
-    public @Nullable String[] getAccountTypesWithManagementDisabledAsUser(int userId) {
+    public @Nullable String[] getAccountTypesWithManagementDisabledAsUser(
+            int userId, boolean parentInstance) {
         if (mService != null) {
             try {
-                return mService.getAccountTypesWithManagementDisabledAsUser(userId);
+                return mService.getAccountTypesWithManagementDisabledAsUser(userId, parentInstance);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -9876,6 +9896,7 @@
      * <li>{@link #setTrustAgentConfiguration}</li>
      * <li>{@link #getRequiredStrongAuthTimeout}</li>
      * <li>{@link #setRequiredStrongAuthTimeout}</li>
+     * <li>{@link #getAccountTypesWithManagementDisabled}</li>
      * </ul>
      * <p>
      * The following methods are supported for the parent instance but can only be called by the
@@ -9884,6 +9905,7 @@
      * <li>{@link #getPasswordComplexity}</li>
      * <li>{@link #setCameraDisabled}</li>
      * <li>{@link #getCameraDisabled}</li>
+     * <li>{@link #setAccountManagementDisabled(ComponentName, String, boolean)}</li>
      * </ul>
      *
      * <p>The following methods can be called by the profile owner of a managed profile
@@ -11580,13 +11602,16 @@
     }
 
     /**
-     * Sets the set of package names that are allowed to request user consent for cross-profile
-     * communication.
+     * Sets the set of admin-whitelisted package names that are allowed to request user consent for
+     * cross-profile communication.
      *
      * <p>Assumes that the caller is a profile owner and is the given {@code admin}.
      *
      * <p>Previous calls are overridden by each subsequent call to this method.
      *
+     * <p>Note that other apps may be able to request user consent for cross-profile communication
+     * if they have been explicitly whitelisted by the OEM.
+     *
      * <p>When previously-set cross-profile packages are missing from {@code packageNames}, the
      * app-op for {@code INTERACT_ACROSS_PROFILES} will be reset for those packages. This will not
      * occur for packages that are whitelisted by the OEM.
@@ -11608,15 +11633,18 @@
 
     /**
      * Returns the set of package names that the admin has previously set as allowed to request user
-     * consent for cross-profile communication, via {@link
-     * #setCrossProfilePackages(ComponentName, Set)}.
+     * consent for cross-profile communication, via {@link #setCrossProfilePackages(ComponentName,
+     * Set)}.
      *
      * <p>Assumes that the caller is a profile owner and is the given {@code admin}.
      *
+     * <p>Note that other apps not included in the returned set may be able to request user consent
+     * for cross-profile communication if they have been explicitly whitelisted by the OEM.
+     *
      * @param admin the {@link DeviceAdminReceiver} this request is associated with
      * @return the set of package names the admin has previously set as allowed to request user
-     * consent for cross-profile communication, via {@link
-     * #setCrossProfilePackages(ComponentName, Set)}
+     * consent for cross-profile communication, via {@link #setCrossProfilePackages(ComponentName,
+     * Set)}
      */
     public @NonNull Set<String> getCrossProfilePackages(@NonNull ComponentName admin) {
         throwIfParentInstance("getCrossProfilePackages");
@@ -11634,18 +11662,17 @@
      * Returns the combined set of the following:
      * <ul>
      * <li>The package names that the admin has previously set as allowed to request user consent
-     * for cross-profile communication, via {@link
-     * #setCrossProfilePackages(ComponentName, Set)}.</li>
+     * for cross-profile communication, via {@link #setCrossProfilePackages(ComponentName,
+     * Set)}.</li>
      * <li>The default package names set by the OEM that are allowed to request user consent for
-     * cross-profile communication without being explicitly enabled by the admin, via
-     * {@link com.android.internal.R.array#cross_profile_apps} and
-     * {@link com.android.internal.R.array#vendor_cross_profile_apps}.</li>
+     * cross-profile communication without being explicitly enabled by the admin, via {@link
+     * com.android.internal.R.array#cross_profile_apps} and {@link com.android.internal.R.array
+     * #vendor_cross_profile_apps}.</li>
      * </ul>
      *
      * @return the combined set of whitelisted package names set via
-     * {@link #setCrossProfilePackages(ComponentName, Set)},
-     * {@link com.android.internal.R.array#cross_profile_apps},
-     * and {@link com.android.internal.R.array#vendor_cross_profile_apps}.
+     * {@link #setCrossProfilePackages(ComponentName, Set)}, {@link com.android.internal.R.array
+     * #cross_profile_apps}, and {@link com.android.internal.R.array#vendor_cross_profile_apps}.
      *
      * @hide
      */
@@ -11668,9 +11695,9 @@
 
     /**
      * Returns the default package names set by the OEM that are allowed to request user consent for
-     * cross-profile communication without being explicitly enabled by the admin, via
-     * {@link com.android.internal.R.array#cross_profile_apps} and
-     * {@link com.android.internal.R.array#vendor_cross_profile_apps}.
+     * cross-profile communication without being explicitly enabled by the admin, via {@link
+     * com.android.internal.R.array#cross_profile_apps} and {@link com.android.internal.R.array
+     * #vendor_cross_profile_apps}.
      *
      * @hide
      */
diff --git a/core/java/android/app/admin/FactoryResetProtectionPolicy.java b/core/java/android/app/admin/FactoryResetProtectionPolicy.java
index ed74779..954db04 100644
--- a/core/java/android/app/admin/FactoryResetProtectionPolicy.java
+++ b/core/java/android/app/admin/FactoryResetProtectionPolicy.java
@@ -53,17 +53,17 @@
 
     private static final String KEY_FACTORY_RESET_PROTECTION_ACCOUNT =
             "factory_reset_protection_account";
-    private static final String KEY_FACTORY_RESET_PROTECTION_DISABLED =
-            "factory_reset_protection_disabled";
+    private static final String KEY_FACTORY_RESET_PROTECTION_ENABLED =
+            "factory_reset_protection_enabled";
     private static final String ATTR_VALUE = "value";
 
     private final List<String> mFactoryResetProtectionAccounts;
-    private final boolean mFactoryResetProtectionDisabled;
+    private final boolean mFactoryResetProtectionEnabled;
 
     private FactoryResetProtectionPolicy(List<String> factoryResetProtectionAccounts,
-            boolean factoryResetProtectionDisabled) {
+            boolean factoryResetProtectionEnabled) {
         mFactoryResetProtectionAccounts = factoryResetProtectionAccounts;
-        mFactoryResetProtectionDisabled = factoryResetProtectionDisabled;
+        mFactoryResetProtectionEnabled = factoryResetProtectionEnabled;
     }
 
     /**
@@ -74,10 +74,10 @@
     }
 
     /**
-     * Return whether factory reset protection for the device is disabled or not.
+     * Return whether factory reset protection for the device is enabled or not.
      */
-    public boolean isFactoryResetProtectionDisabled() {
-        return mFactoryResetProtectionDisabled;
+    public boolean isFactoryResetProtectionEnabled() {
+        return mFactoryResetProtectionEnabled;
     }
 
     /**
@@ -85,12 +85,13 @@
      */
     public static class Builder {
         private List<String> mFactoryResetProtectionAccounts;
-        private boolean mFactoryResetProtectionDisabled;
+        private boolean mFactoryResetProtectionEnabled;
 
         /**
          * Initialize a new Builder to construct a {@link FactoryResetProtectionPolicy}.
          */
         public Builder() {
+            mFactoryResetProtectionEnabled = true;
         };
 
         /**
@@ -113,18 +114,19 @@
         }
 
         /**
-         * Sets whether factory reset protection is disabled or not.
+         * Sets whether factory reset protection is enabled or not.
          * <p>
          * Once disabled, factory reset protection will not kick in all together when the device
          * goes through untrusted factory reset. This applies to both the consumer unlock flow and
-         * the admin account overrides via {@link #setFactoryResetProtectionAccounts}
+         * the admin account overrides via {@link #setFactoryResetProtectionAccounts}. By default,
+         * factory reset protection is enabled.
          *
-         * @param factoryResetProtectionDisabled Whether the policy is disabled or not.
+         * @param factoryResetProtectionEnabled Whether the policy is enabled or not.
          * @return the same Builder instance.
          */
         @NonNull
-        public Builder setFactoryResetProtectionDisabled(boolean factoryResetProtectionDisabled) {
-            mFactoryResetProtectionDisabled = factoryResetProtectionDisabled;
+        public Builder setFactoryResetProtectionEnabled(boolean factoryResetProtectionEnabled) {
+            mFactoryResetProtectionEnabled = factoryResetProtectionEnabled;
             return this;
         }
 
@@ -136,7 +138,7 @@
         @NonNull
         public FactoryResetProtectionPolicy build() {
             return new FactoryResetProtectionPolicy(mFactoryResetProtectionAccounts,
-                    mFactoryResetProtectionDisabled);
+                    mFactoryResetProtectionEnabled);
         }
     }
 
@@ -144,7 +146,7 @@
     public String toString() {
         return "FactoryResetProtectionPolicy{"
                 + "mFactoryResetProtectionAccounts=" + mFactoryResetProtectionAccounts
-                + ", mFactoryResetProtectionDisabled=" + mFactoryResetProtectionDisabled
+                + ", mFactoryResetProtectionEnabled=" + mFactoryResetProtectionEnabled
                 + '}';
     }
 
@@ -155,7 +157,7 @@
         for (String account: mFactoryResetProtectionAccounts) {
             dest.writeString(account);
         }
-        dest.writeBoolean(mFactoryResetProtectionDisabled);
+        dest.writeBoolean(mFactoryResetProtectionEnabled);
     }
 
     @Override
@@ -173,10 +175,10 @@
                     for (int i = 0; i < accountsCount; i++) {
                         factoryResetProtectionAccounts.add(in.readString());
                     }
-                    boolean factoryResetProtectionDisabled = in.readBoolean();
+                    boolean factoryResetProtectionEnabled = in.readBoolean();
 
                     return new FactoryResetProtectionPolicy(factoryResetProtectionAccounts,
-                            factoryResetProtectionDisabled);
+                            factoryResetProtectionEnabled);
                 }
 
                 @Override
@@ -195,8 +197,8 @@
     @Nullable
     public static FactoryResetProtectionPolicy readFromXml(@NonNull XmlPullParser parser) {
         try {
-            boolean factoryResetProtectionDisabled = Boolean.parseBoolean(
-                    parser.getAttributeValue(null, KEY_FACTORY_RESET_PROTECTION_DISABLED));
+            boolean factoryResetProtectionEnabled = Boolean.parseBoolean(
+                    parser.getAttributeValue(null, KEY_FACTORY_RESET_PROTECTION_ENABLED));
 
             List<String> factoryResetProtectionAccounts = new ArrayList<>();
             int outerDepth = parser.getDepth();
@@ -214,7 +216,7 @@
             }
 
             return new FactoryResetProtectionPolicy(factoryResetProtectionAccounts,
-                    factoryResetProtectionDisabled);
+                    factoryResetProtectionEnabled);
         } catch (XmlPullParserException | IOException e) {
             Log.w(LOG_TAG, "Reading from xml failed", e);
         }
@@ -225,8 +227,8 @@
      * @hide
      */
     public void writeToXml(@NonNull XmlSerializer out) throws IOException {
-        out.attribute(null, KEY_FACTORY_RESET_PROTECTION_DISABLED,
-                Boolean.toString(mFactoryResetProtectionDisabled));
+        out.attribute(null, KEY_FACTORY_RESET_PROTECTION_ENABLED,
+                Boolean.toString(mFactoryResetProtectionEnabled));
         for (String account : mFactoryResetProtectionAccounts) {
             out.startTag(null, KEY_FACTORY_RESET_PROTECTION_ACCOUNT);
             out.attribute(null, ATTR_VALUE, account);
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 0aed39c..84332ca 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -248,9 +248,9 @@
     int enableSystemAppWithIntent(in ComponentName admin, in String callerPackage, in Intent intent);
     boolean installExistingPackage(in ComponentName admin, in String callerPackage, in String packageName);
 
-    void setAccountManagementDisabled(in ComponentName who, in String accountType, in boolean disabled);
+    void setAccountManagementDisabled(in ComponentName who, in String accountType, in boolean disabled, in boolean parent);
     String[] getAccountTypesWithManagementDisabled();
-    String[] getAccountTypesWithManagementDisabledAsUser(int userId);
+    String[] getAccountTypesWithManagementDisabledAsUser(int userId, in boolean parent);
 
     void setSecondaryLockscreenEnabled(in ComponentName who, boolean enabled);
     boolean isSecondaryLockscreenEnabled(int userId);
diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java
index 9c4a8f4..5b98188 100644
--- a/core/java/android/app/usage/NetworkStatsManager.java
+++ b/core/java/android/app/usage/NetworkStatsManager.java
@@ -526,15 +526,17 @@
     }
 
     /**
-     * Registers a custom provider of {@link android.net.NetworkStats} to combine the network
-     * statistics that cannot be seen by the kernel to system. To unregister, invoke
-     * {@link NetworkStatsProviderCallback#unregister()}.
+     * Registers a custom provider of {@link android.net.NetworkStats} to provide network statistics
+     * to the system. To unregister, invoke {@link NetworkStatsProviderCallback#unregister()}.
+     * Note that no de-duplication of statistics between providers is performed, so each provider
+     * must only report network traffic that is not being reported by any other provider.
      *
-     * @param tag a human readable identifier of the custom network stats provider.
-     * @param provider a custom implementation of {@link AbstractNetworkStatsProvider} that needs to
-     *                 be registered to the system.
+     * @param tag a human readable identifier of the custom network stats provider. This is only
+     *            used for debugging.
+     * @param provider the subclass of {@link AbstractNetworkStatsProvider} that needs to be
+     *                 registered to the system.
      * @return a {@link NetworkStatsProviderCallback}, which can be used to report events to the
-     *         system.
+     *         system or unregister the provider.
      * @hide
      */
     @SystemApi
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 0f88c90..2e591ca 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -6767,7 +6767,7 @@
                     this.mClipData = new ClipData(o.mClipData);
                 }
             } else {
-                if (o.mExtras != null && !o.mExtras.maybeIsEmpty()) {
+                if (o.mExtras != null && !o.mExtras.isDefinitelyEmpty()) {
                     this.mExtras = Bundle.STRIPPED;
                 }
 
diff --git a/core/java/android/content/pm/CrossProfileApps.java b/core/java/android/content/pm/CrossProfileApps.java
index 50841c3..eb1da67 100644
--- a/core/java/android/content/pm/CrossProfileApps.java
+++ b/core/java/android/content/pm/CrossProfileApps.java
@@ -47,8 +47,15 @@
 public class CrossProfileApps {
 
     /**
-     * Broadcast signalling that the receiving app's ability to interact across profiles has
-     * changed, as defined by the return value of {@link #canInteractAcrossProfiles()}.
+     * Broadcast signalling that the receiving app's permission to interact across profiles has
+     * changed. This includes the user, admin, or OEM changing their consent such that the
+     * permission for the app to interact across profiles has changed.
+     *
+     * <p>This broadcast is not sent when other circumstances result in a change to being able to
+     * interact across profiles in practice, such as the profile being turned off or removed, apps
+     * being uninstalled, etc. The methods {@link #canInteractAcrossProfiles()} and {@link
+     * #canRequestInteractAcrossProfiles()} can be used by apps prior to attempting to interact
+     * across profiles or attempting to request user consent to interact across profiles.
      *
      * <p>Apps that have set the {@code android:crossProfile} manifest attribute to {@code true}
      * can receive this broadcast in manifest broadcast receivers. Otherwise, it can only be
@@ -99,8 +106,11 @@
     /**
      * Starts the specified activity of the caller package in the specified profile.
      *
-     * <p>The caller must have the {@link android.Manifest.permission#INTERACT_ACROSS_PROFILES}
-     * permission and both the caller and target user profiles must be in the same profile group.
+     * <p>The caller must have the {@link android.Manifest.permission#INTERACT_ACROSS_PROFILES},
+     * {@code android.Manifest.permission#INTERACT_ACROSS_USERS}, or {@code
+     * android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permission. Both the caller and
+     * target user profiles must be in the same profile group. The target user must be a valid user
+     * returned from {@link #getTargetUserProfiles()}.
      *
      * @param intent The intent to launch. A component in the caller package must be specified.
      * @param targetUser The {@link UserHandle} of the profile; must be one of the users returned by
@@ -219,10 +229,11 @@
     }
 
     /**
-     * Returns whether the calling package can request to interact across profiles.
+     * Returns whether the calling package can request user consent to interact across profiles.
      *
-     * <p>The package's current ability to interact across profiles can be checked with
-     * {@link #canInteractAcrossProfiles()}.
+     * <p>If {@code true}, user consent can be obtained via {@link
+     * #createRequestInteractAcrossProfilesIntent()}. The package can then listen to {@link
+     * #ACTION_CAN_INTERACT_ACROSS_PROFILES_CHANGED} broadcasts.
      *
      * <p>Specifically, returns whether the following are all true:
      * <ul>
@@ -235,6 +246,10 @@
      * </li>
      * </ul>
      *
+     * <p>Note that user consent could already be granted if given a return value of {@code true}.
+     * The package's current ability to interact across profiles can be checked with {@link
+     * #canInteractAcrossProfiles()}.
+     *
      * @return true if the calling package can request to interact across profiles.
      */
     public boolean canRequestInteractAcrossProfiles() {
@@ -247,10 +262,7 @@
 
     /**
      * Returns whether the calling package can interact across profiles.
-     *
-     * <p>The package's current ability to request to interact across profiles can be checked with
-     * {@link #canRequestInteractAcrossProfiles()}.
-     *
+
      * <p>Specifically, returns whether the following are all true:
      * <ul>
      * <li>{@link #getTargetUserProfiles()} returns a non-empty list for the calling user.</li>
@@ -262,6 +274,11 @@
      * </li>
      * </ul>
      *
+     * <p>If {@code false}, the package's current ability to request user consent to interact across
+     * profiles can be checked with {@link #canRequestInteractAcrossProfiles()}. If {@code true},
+     * user consent can be obtained via {@link #createRequestInteractAcrossProfilesIntent()}. The
+     * package can then listen to {@link #ACTION_CAN_INTERACT_ACROSS_PROFILES_CHANGED} broadcasts.
+     *
      * @return true if the calling package can interact across profiles.
      * @throws SecurityException if {@code mContext.getPackageName()} does not belong to the
      * calling UID.
@@ -276,11 +293,15 @@
 
     /**
      * Returns an {@link Intent} to open the settings page that allows the user to decide whether
-     * the calling app can interact across profiles. The current state is given by
-     * {@link #canInteractAcrossProfiles()}.
+     * the calling app can interact across profiles.
      *
      * <p>Returns {@code null} if {@link #canRequestInteractAcrossProfiles()} is {@code false}.
      *
+     * <p>Note that the user may already have given consent and the app may already be able to
+     * interact across profiles, even if {@link #canRequestInteractAcrossProfiles()} is {@code
+     * true}. The current ability to interact across profiles is given by {@link
+     * #canInteractAcrossProfiles()}.
+     *
      * @return an {@link Intent} to open the settings page that allows the user to decide whether
      * the app can interact across profiles
      *
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 7b484b7..03ed373 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3012,6 +3012,17 @@
             "android.software.incremental_delivery";
 
     /**
+     * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
+     * The device has tuner hardware to support tuner operations.
+     *
+     * <p>This feature implies that the device has the tuner HAL implementation.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_TUNER = "android.hardware.tv.tuner";
+
+    /**
      * Extra field name for the URI to a verification file. Passed to a package
      * verifier.
      *
diff --git a/core/java/android/content/pm/parsing/AndroidPackage.java b/core/java/android/content/pm/parsing/AndroidPackage.java
index da17ff3..b93c3a2 100644
--- a/core/java/android/content/pm/parsing/AndroidPackage.java
+++ b/core/java/android/content/pm/parsing/AndroidPackage.java
@@ -397,6 +397,8 @@
 
     boolean hasComponentClassName(String className);
 
+    boolean hasPreserveLegacyExternalStorage();
+
     // App Info
 
     boolean hasRequestedLegacyExternalStorage();
diff --git a/core/java/android/content/pm/parsing/ApkParseUtils.java b/core/java/android/content/pm/parsing/ApkParseUtils.java
index a267113..905794b 100644
--- a/core/java/android/content/pm/parsing/ApkParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkParseUtils.java
@@ -2101,6 +2101,10 @@
             parsingPackage.setAllowNativeHeapPointerTagging(sa.getBoolean(
                     R.styleable.AndroidManifestApplication_allowNativeHeapPointerTagging, true));
 
+            parsingPackage.setPreserveLegacyExternalStorage(sa.getBoolean(
+                            R.styleable.AndroidManifestApplication_preserveLegacyExternalStorage,
+                            false));
+
             parsingPackage
                     .setMaxAspectRatio(
                             sa.getFloat(R.styleable.AndroidManifestApplication_maxAspectRatio, 0))
diff --git a/core/java/android/content/pm/parsing/PackageImpl.java b/core/java/android/content/pm/parsing/PackageImpl.java
index 778d7b8..180714a 100644
--- a/core/java/android/content/pm/parsing/PackageImpl.java
+++ b/core/java/android/content/pm/parsing/PackageImpl.java
@@ -289,6 +289,7 @@
     private String[] usesLibraryFiles;
     private List<SharedLibraryInfo> usesLibraryInfos;
     private String zygotePreloadName;
+    private boolean preserveLegacyExternalStorage;
 
     @VisibleForTesting
     public PackageImpl(
@@ -1519,6 +1520,12 @@
     }
 
     @Override
+    public PackageImpl setPreserveLegacyExternalStorage(boolean preserveLegacyExternalStorage) {
+        this.preserveLegacyExternalStorage = preserveLegacyExternalStorage;
+        return this;
+    }
+
+    @Override
     public PackageImpl setUsesNonSdkApi(boolean usesNonSdkApi) {
         this.privateFlags = usesNonSdkApi
                 ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_USES_NON_SDK_API
@@ -2999,6 +3006,11 @@
         return queriesProviders;
     }
 
+    @Override
+    public boolean hasPreserveLegacyExternalStorage() {
+        return preserveLegacyExternalStorage;
+    }
+
     private static void internStringArrayList(List<String> list) {
         if (list != null) {
             final int N = list.size();
diff --git a/core/java/android/content/pm/parsing/ParsingPackage.java b/core/java/android/content/pm/parsing/ParsingPackage.java
index 954d65c..74a2640 100644
--- a/core/java/android/content/pm/parsing/ParsingPackage.java
+++ b/core/java/android/content/pm/parsing/ParsingPackage.java
@@ -192,6 +192,8 @@
     ParsingPackage setRequestLegacyExternalStorage(boolean requestLegacyExternalStorage);
 
     ParsingPackage setAllowNativeHeapPointerTagging(boolean allowNativeHeapPointerTagging);
+  
+    ParsingPackage setPreserveLegacyExternalStorage(boolean preserveLegacyExternalStorage);
 
     ParsingPackage setRestoreAnyVersion(boolean restoreAnyVersion);
 
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 25b84c5..65f45d8 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -80,7 +80,7 @@
      * Display category: Presentation displays.
      * <p>
      * This category can be used to identify secondary displays that are suitable for
-     * use as presentation displays such as HDMI or Wireless displays.  Applications
+     * use as presentation displays such as external or wireless displays.  Applications
      * may automatically project their content to presentation displays to provide
      * richer second screen experiences.
      * </p>
@@ -100,7 +100,7 @@
      * When this flag is set, the virtual display is public.
      * </p><p>
      * A public virtual display behaves just like most any other display that is connected
-     * to the system such as an HDMI or Wireless display.  Applications can open
+     * to the system such as an external or wireless display.  Applications can open
      * windows on the display and the system may mirror the contents of other displays
      * onto it.
      * </p><p>
@@ -364,7 +364,7 @@
                     addAllDisplaysLocked(mTempDisplays, displayIds);
                 } else if (category.equals(DISPLAY_CATEGORY_PRESENTATION)) {
                     addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_WIFI);
-                    addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_HDMI);
+                    addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_EXTERNAL);
                     addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_OVERLAY);
                     addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_VIRTUAL);
                 }
diff --git a/core/java/android/inputmethodservice/InlineSuggestionSession.java b/core/java/android/inputmethodservice/InlineSuggestionSession.java
new file mode 100644
index 0000000..edae06a
--- /dev/null
+++ b/core/java/android/inputmethodservice/InlineSuggestionSession.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.inputmethodservice;
+
+import static android.inputmethodservice.InputMethodService.DEBUG;
+
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
+import android.annotation.NonNull;
+import android.content.ComponentName;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.inputmethod.InlineSuggestionsRequest;
+import android.view.inputmethod.InlineSuggestionsResponse;
+
+import com.android.internal.view.IInlineSuggestionsRequestCallback;
+import com.android.internal.view.IInlineSuggestionsResponseCallback;
+
+import java.lang.ref.WeakReference;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+/**
+ * Maintains an active inline suggestion session.
+ *
+ * <p>
+ * Each session corresponds to one inline suggestion request, but there may be multiple callbacks
+ * with the inline suggestions response.
+ */
+class InlineSuggestionSession {
+
+    private static final String TAG = InlineSuggestionSession.class.getSimpleName();
+
+    private final Handler mHandler = new Handler(Looper.getMainLooper(), null, true);
+
+    @NonNull
+    private final ComponentName mComponentName;
+    @NonNull
+    private final IInlineSuggestionsRequestCallback mCallback;
+    @NonNull
+    private final InlineSuggestionsResponseCallbackImpl mResponseCallback;
+    @NonNull
+    private final Supplier<String> mClientPackageNameSupplier;
+    @NonNull
+    private final Supplier<InlineSuggestionsRequest> mRequestSupplier;
+    @NonNull
+    private final Supplier<IBinder> mHostInputTokenSupplier;
+    @NonNull
+    private final Consumer<InlineSuggestionsResponse> mResponseConsumer;
+
+    private volatile boolean mInvalidated = false;
+
+    InlineSuggestionSession(@NonNull ComponentName componentName,
+            @NonNull IInlineSuggestionsRequestCallback callback,
+            @NonNull Supplier<String> clientPackageNameSupplier,
+            @NonNull Supplier<InlineSuggestionsRequest> requestSupplier,
+            @NonNull Supplier<IBinder> hostInputTokenSupplier,
+            @NonNull Consumer<InlineSuggestionsResponse> responseConsumer) {
+        mComponentName = componentName;
+        mCallback = callback;
+        mResponseCallback = new InlineSuggestionsResponseCallbackImpl(this);
+        mClientPackageNameSupplier = clientPackageNameSupplier;
+        mRequestSupplier = requestSupplier;
+        mHostInputTokenSupplier = hostInputTokenSupplier;
+        mResponseConsumer = responseConsumer;
+
+        makeInlineSuggestionsRequest();
+    }
+
+    /**
+     * This needs to be called before creating a new session, such that the later response callbacks
+     * will be discarded.
+     */
+    void invalidateSession() {
+        mInvalidated = true;
+    }
+
+    /**
+     * Sends an {@link InlineSuggestionsRequest} obtained from {@cocde supplier} to the current
+     * Autofill Session through
+     * {@link IInlineSuggestionsRequestCallback#onInlineSuggestionsRequest}.
+     */
+    private void makeInlineSuggestionsRequest() {
+        try {
+            final InlineSuggestionsRequest request = mRequestSupplier.get();
+            if (request == null) {
+                if (DEBUG) {
+                    Log.d(TAG, "onCreateInlineSuggestionsRequest() returned null request");
+                }
+                mCallback.onInlineSuggestionsUnsupported();
+            } else {
+                request.setHostInputToken(mHostInputTokenSupplier.get());
+                mCallback.onInlineSuggestionsRequest(request, mResponseCallback);
+            }
+        } catch (RemoteException e) {
+            Log.w(TAG, "makeInlinedSuggestionsRequest() remote exception:" + e);
+        }
+    }
+
+    private void handleOnInlineSuggestionsResponse(@NonNull InlineSuggestionsResponse response) {
+        if (mInvalidated) {
+            if (DEBUG) {
+                Log.d(TAG, "handleOnInlineSuggestionsResponse() called on invalid session");
+            }
+            return;
+        }
+        // TODO(b/149522488): checking the current focused input field to make sure we don't send
+        //  inline responses for previous input field
+        if (!mComponentName.getPackageName().equals(mClientPackageNameSupplier.get())) {
+            if (DEBUG) {
+                Log.d(TAG, "handleOnInlineSuggestionsResponse() called on the wrong package name");
+            }
+            return;
+        }
+        mResponseConsumer.accept(response);
+    }
+
+    /**
+     * Internal implementation of {@link IInlineSuggestionsResponseCallback}.
+     */
+    static final class InlineSuggestionsResponseCallbackImpl
+            extends IInlineSuggestionsResponseCallback.Stub {
+        private final WeakReference<InlineSuggestionSession> mInlineSuggestionSession;
+
+        private InlineSuggestionsResponseCallbackImpl(
+                InlineSuggestionSession inlineSuggestionSession) {
+            mInlineSuggestionSession = new WeakReference<>(inlineSuggestionSession);
+        }
+
+        @Override
+        public void onInlineSuggestionsResponse(InlineSuggestionsResponse response)
+                throws RemoteException {
+            final InlineSuggestionSession session = mInlineSuggestionSession.get();
+            if (session != null) {
+                session.mHandler.sendMessage(obtainMessage(
+                        InlineSuggestionSession::handleOnInlineSuggestionsResponse, session,
+                        response));
+            }
+        }
+    }
+}
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 49e1d5e..b1aa67e 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -22,8 +22,6 @@
 import static android.view.WindowInsets.Type.navigationBars;
 import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
 
-import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
-
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
 import android.annotation.AnyThread;
@@ -51,7 +49,6 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.SystemClock;
@@ -102,13 +99,11 @@
 import com.android.internal.inputmethod.InputMethodPrivilegedOperations;
 import com.android.internal.inputmethod.InputMethodPrivilegedOperationsRegistry;
 import com.android.internal.view.IInlineSuggestionsRequestCallback;
-import com.android.internal.view.IInlineSuggestionsResponseCallback;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.lang.ref.WeakReference;
 import java.util.Collections;
 
 /**
@@ -450,7 +445,7 @@
     final int[] mTmpLocation = new int[2];
 
     @Nullable
-    private InlineSuggestionsRequestInfo mInlineSuggestionsRequestInfo = null;
+    private InlineSuggestionSession mInlineSuggestionSession;
 
     private boolean mAutomotiveHideNavBarForKeyboard;
     private boolean mIsAutomotive;
@@ -465,8 +460,6 @@
      */
     private IBinder mCurShowInputToken;
 
-    private final Handler mHandler = new Handler(Looper.getMainLooper(), null, true);
-
     final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsComputer = info -> {
         onComputeInsets(mTmpInsets);
         if (isExtractViewShown()) {
@@ -538,7 +531,7 @@
             if (DEBUG) {
                 Log.d(TAG, "InputMethodService received onCreateInlineSuggestionsRequest()");
             }
-            handleOnCreateInlineSuggestionsRequest(componentName, autofillId, cb);
+            handleOnCreateInlineSuggestionsRequest(componentName, cb);
         }
 
         /**
@@ -770,39 +763,9 @@
         return false;
     }
 
-    /**
-     * Sends an {@link InlineSuggestionsRequest} obtained from
-     * {@link #onCreateInlineSuggestionsRequest()} to the current Autofill Session through
-     * {@link IInlineSuggestionsRequestCallback#onInlineSuggestionsRequest}.
-     */
-    private void makeInlineSuggestionsRequest() {
-        if (mInlineSuggestionsRequestInfo == null) {
-            Log.w(TAG, "makeInlineSuggestionsRequest() called with null requestInfo cache");
-            return;
-        }
-
-        final IInlineSuggestionsRequestCallback requestCallback =
-                mInlineSuggestionsRequestInfo.mCallback;
-        try {
-            final InlineSuggestionsRequest request = onCreateInlineSuggestionsRequest();
-            if (request == null) {
-                Log.w(TAG, "onCreateInlineSuggestionsRequest() returned null request");
-                requestCallback.onInlineSuggestionsUnsupported();
-            } else {
-                final IInlineSuggestionsResponseCallback inlineSuggestionsResponseCallback =
-                        new InlineSuggestionsResponseCallbackImpl(this,
-                                mInlineSuggestionsRequestInfo.mComponentName,
-                                mInlineSuggestionsRequestInfo.mFocusedId);
-                requestCallback.onInlineSuggestionsRequest(request,
-                        inlineSuggestionsResponseCallback);
-            }
-        } catch (RemoteException e) {
-            Log.w(TAG, "makeInlinedSuggestionsRequest() remote exception:" + e);
-        }
-    }
-
+    @MainThread
     private void handleOnCreateInlineSuggestionsRequest(@NonNull ComponentName componentName,
-            @NonNull AutofillId autofillId, @NonNull IInlineSuggestionsRequestCallback callback) {
+            @NonNull IInlineSuggestionsRequestCallback callback) {
         if (!mInputStarted) {
             try {
                 Log.w(TAG, "onStartInput() not called yet");
@@ -813,24 +776,32 @@
             return;
         }
 
-        mInlineSuggestionsRequestInfo = new InlineSuggestionsRequestInfo(componentName, autofillId,
-                callback);
-
-        makeInlineSuggestionsRequest();
+        if (mInlineSuggestionSession != null) {
+            mInlineSuggestionSession.invalidateSession();
+        }
+        mInlineSuggestionSession = new InlineSuggestionSession(componentName, callback,
+                this::getEditorInfoPackageName, this::onCreateInlineSuggestionsRequest,
+                this::getHostInputToken, this::onInlineSuggestionsResponse);
     }
 
-    private void handleOnInlineSuggestionsResponse(@NonNull ComponentName componentName,
-            @NonNull AutofillId autofillId, @NonNull InlineSuggestionsResponse response) {
-        if (!mInlineSuggestionsRequestInfo.validate(componentName)) {
-            if (DEBUG) {
-                Log.d(TAG,
-                        "Response component=" + componentName + " differs from request component="
-                                + mInlineSuggestionsRequestInfo.mComponentName
-                                + ", ignoring response");
-            }
-            return;
+    @Nullable
+    private String getEditorInfoPackageName() {
+        if (mInputEditorInfo != null) {
+            return mInputEditorInfo.packageName;
         }
-        onInlineSuggestionsResponse(response);
+        return null;
+    }
+
+    /**
+     * Returns the {@link IBinder} input token from the host view root.
+     */
+    @Nullable
+    private IBinder getHostInputToken() {
+        ViewRootImpl viewRoot = null;
+        if (mRootView != null) {
+            viewRoot = mRootView.getViewRootImpl();
+        }
+        return viewRoot == null ? null : viewRoot.getInputToken();
     }
 
     private void notifyImeHidden() {
@@ -851,63 +822,6 @@
     }
 
     /**
-     * Internal implementation of {@link IInlineSuggestionsResponseCallback}.
-     */
-    private static final class InlineSuggestionsResponseCallbackImpl
-            extends IInlineSuggestionsResponseCallback.Stub {
-        private final WeakReference<InputMethodService> mInputMethodService;
-
-        private final ComponentName mRequestComponentName;
-        private final AutofillId mRequestAutofillId;
-
-        private InlineSuggestionsResponseCallbackImpl(InputMethodService inputMethodService,
-                ComponentName componentName, AutofillId autofillId) {
-            mInputMethodService = new WeakReference<>(inputMethodService);
-            mRequestComponentName = componentName;
-            mRequestAutofillId = autofillId;
-        }
-
-        @Override
-        public void onInlineSuggestionsResponse(InlineSuggestionsResponse response)
-                throws RemoteException {
-            final InputMethodService service = mInputMethodService.get();
-            if (service != null) {
-                service.mHandler.sendMessage(obtainMessage(
-                        InputMethodService::handleOnInlineSuggestionsResponse, service,
-                        mRequestComponentName, mRequestAutofillId, response));
-            }
-        }
-    }
-
-    /**
-     * Information about incoming requests from Autofill Frameworks for inline suggestions.
-     */
-    private static final class InlineSuggestionsRequestInfo {
-        final ComponentName mComponentName;
-        final AutofillId mFocusedId;
-        final IInlineSuggestionsRequestCallback mCallback;
-
-        InlineSuggestionsRequestInfo(ComponentName componentName, AutofillId focusedId,
-                IInlineSuggestionsRequestCallback callback) {
-            this.mComponentName = componentName;
-            this.mFocusedId = focusedId;
-            this.mCallback = callback;
-        }
-
-        /**
-         * Returns whether the cached {@link ComponentName} matches the passed in activity.
-         */
-        public boolean validate(ComponentName componentName) {
-            final boolean result = componentName.equals(mComponentName);
-            if (DEBUG && !result) {
-                Log.d(TAG, "Cached request info ComponentName=" + mComponentName
-                        + " differs from received ComponentName=" + componentName);
-            }
-            return result;
-        }
-    }
-
-    /**
      * Concrete implementation of
      * {@link AbstractInputMethodService.AbstractInputMethodSessionImpl} that provides
      * all of the standard behavior for an input method session.
diff --git a/core/java/android/net/DhcpResults.java b/core/java/android/net/DhcpResults.java
index 059cd94..5ab0354 100644
--- a/core/java/android/net/DhcpResults.java
+++ b/core/java/android/net/DhcpResults.java
@@ -16,6 +16,7 @@
 
 package android.net;
 
+import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.net.shared.InetAddressUtils;
 import android.os.Parcel;
@@ -66,6 +67,9 @@
 
     public String serverHostName;
 
+    @Nullable
+    public String captivePortalApiUrl;
+
     public DhcpResults() {
         super();
     }
@@ -100,6 +104,7 @@
             leaseDuration = source.leaseDuration;
             mtu = source.mtu;
             serverHostName = source.serverHostName;
+            captivePortalApiUrl = source.captivePortalApiUrl;
         }
     }
 
@@ -133,6 +138,7 @@
         leaseDuration = 0;
         mtu = 0;
         serverHostName = null;
+        captivePortalApiUrl = null;
     }
 
     @Override
@@ -144,6 +150,9 @@
         str.append(" lease ").append(leaseDuration).append(" seconds");
         if (mtu != 0) str.append(" MTU ").append(mtu);
         str.append(" Servername ").append(serverHostName);
+        if (captivePortalApiUrl != null) {
+            str.append(" CaptivePortalApiUrl ").append(captivePortalApiUrl);
+        }
 
         return str.toString();
     }
@@ -161,7 +170,8 @@
                 && Objects.equals(vendorInfo, target.vendorInfo)
                 && Objects.equals(serverHostName, target.serverHostName)
                 && leaseDuration == target.leaseDuration
-                && mtu == target.mtu;
+                && mtu == target.mtu
+                && Objects.equals(captivePortalApiUrl, target.captivePortalApiUrl);
     }
 
     /**
@@ -186,6 +196,7 @@
         InetAddressUtils.parcelInetAddress(dest, serverAddress, flags);
         dest.writeString(vendorInfo);
         dest.writeString(serverHostName);
+        dest.writeString(captivePortalApiUrl);
     }
 
     @Override
@@ -201,6 +212,7 @@
         dhcpResults.serverAddress = (Inet4Address) InetAddressUtils.unparcelInetAddress(in);
         dhcpResults.vendorInfo = in.readString();
         dhcpResults.serverHostName = in.readString();
+        dhcpResults.captivePortalApiUrl = in.readString();
         return dhcpResults;
     }
 
@@ -305,4 +317,12 @@
     public void setMtu(int mtu) {
         this.mtu = mtu;
     }
+
+    public String getCaptivePortalApiUrl() {
+        return captivePortalApiUrl;
+    }
+
+    public void setCaptivePortalApiUrl(String url) {
+        captivePortalApiUrl = url;
+    }
 }
diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java
index 6453af8..81deba4 100644
--- a/core/java/android/os/BaseBundle.java
+++ b/core/java/android/os/BaseBundle.java
@@ -365,12 +365,16 @@
     }
 
     /**
+     * This method returns true when the parcel is 'definitely' empty.
+     * That is, it may return false for an empty parcel. But will never return true for a non-empty
+     * one.
+     *
      * @hide this should probably be the implementation of isEmpty().  To do that we
      * need to ensure we always use the special empty parcel form when the bundle is
      * empty.  (This may already be the case, but to be safe we'll do this later when
      * we aren't trying to stabilize.)
      */
-    public boolean maybeIsEmpty() {
+    public boolean isDefinitelyEmpty() {
         if (isParcelled()) {
             return isEmptyParcel();
         } else {
@@ -402,6 +406,9 @@
         if (other == null) {
             return false;
         }
+        if (isDefinitelyEmpty() && other.isDefinitelyEmpty()) {
+            return true;
+        }
         if (isParcelled() != other.isParcelled()) {
             // Big kind-of here!
             return false;
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index bb1dafc..8d04df0 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -215,6 +215,20 @@
     public static final String ACTION_MANAGE_STORAGE = "android.os.storage.action.MANAGE_STORAGE";
 
     /**
+     * Activity Action: Allows the user to free up space by clearing app external cache directories.
+     * The intent doesn't automatically clear cache, but shows a dialog and lets the user decide.
+     * <p>
+     * This intent should be launched using
+     * {@link Activity#startActivityForResult(Intent, int)} so that the user
+     * knows which app is requesting to clear cache. The returned result will
+     * be {@link Activity#RESULT_OK} if the activity was launched and the user accepted to clear
+     * cache, or {@link Activity#RESULT_CANCELED} otherwise.
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_EXTERNAL_STORAGE)
+    @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_CLEAR_APP_CACHE = "android.os.storage.action.CLEAR_APP_CACHE";
+
+    /**
      * Extra {@link UUID} used to indicate the storage volume where an
      * application is interested in allocating or managing disk space.
      *
diff --git a/core/java/android/os/storage/StorageManagerInternal.java b/core/java/android/os/storage/StorageManagerInternal.java
index 5cac5f5..e78aef5 100644
--- a/core/java/android/os/storage/StorageManagerInternal.java
+++ b/core/java/android/os/storage/StorageManagerInternal.java
@@ -118,4 +118,10 @@
      * @param userId the userId for which to reset storage
      */
     public abstract void resetUser(int userId);
+
+    /**
+     * Returns {@code true} if the immediate last installed version of an app with {@code uid} had
+     * legacy storage, {@code false} otherwise.
+     */
+    public abstract boolean hasLegacyExternalStorage(int uid);
 }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 37efec3..f6072f9 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2055,6 +2055,19 @@
     public static final String ACTION_MANAGE_DOMAIN_URLS = "android.settings.MANAGE_DOMAIN_URLS";
 
     /**
+     * Activity Action: Show screen that let user select enable (or disable) tethering.
+     * <p>
+     * Input: Nothing.
+     * <p>
+     * Output: Nothing
+     *
+     * @hide
+     */
+    @SystemApi
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_TETHER_SETTINGS = "android.settings.TETHER_SETTINGS";
+
+    /**
      * Broadcast to trigger notification of asking user to enable MMS.
      * Need to specify {@link #EXTRA_ENABLE_MMS_DATA_REQUEST_REASON} and {@link #EXTRA_SUB_ID}.
      *
@@ -6449,6 +6462,7 @@
          * @hide
          */
         @SystemApi
+        @TestApi
         public static final String LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS =
                 "lock_screen_allow_private_notifications";
 
@@ -7867,6 +7881,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @TestApi
         public static final String NFC_PAYMENT_DEFAULT_COMPONENT = "nfc_payment_default_component";
 
         /**
@@ -8069,6 +8084,7 @@
          * @hide
          */
         @SystemApi
+        @TestApi
         public static final String LOCK_SCREEN_SHOW_NOTIFICATIONS =
                 "lock_screen_show_notifications";
 
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index 7032825..e8e1223 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -75,6 +75,7 @@
     private final @Nullable SaveInfo mSaveInfo;
     private final @Nullable Bundle mClientState;
     private final @Nullable RemoteViews mPresentation;
+    private final @Nullable InlinePresentation mInlinePresentation;
     private final @Nullable RemoteViews mHeader;
     private final @Nullable RemoteViews mFooter;
     private final @Nullable IntentSender mAuthentication;
@@ -95,6 +96,7 @@
         mSaveInfo = builder.mSaveInfo;
         mClientState = builder.mClientState;
         mPresentation = builder.mPresentation;
+        mInlinePresentation = builder.mInlinePresentation;
         mHeader = builder.mHeader;
         mFooter = builder.mFooter;
         mAuthentication = builder.mAuthentication;
@@ -131,6 +133,11 @@
     }
 
     /** @hide */
+    public @Nullable InlinePresentation getInlinePresentation() {
+        return mInlinePresentation;
+    }
+
+    /** @hide */
     public @Nullable RemoteViews getHeader() {
         return mHeader;
     }
@@ -219,6 +226,7 @@
         private SaveInfo mSaveInfo;
         private Bundle mClientState;
         private RemoteViews mPresentation;
+        private InlinePresentation mInlinePresentation;
         private RemoteViews mHeader;
         private RemoteViews mFooter;
         private IntentSender mAuthentication;
@@ -318,6 +326,67 @@
         }
 
         /**
+         * Triggers a custom UI before before autofilling the screen with any data set in this
+         * response.
+         *
+         * <p><b>Note:</b> Although the name of this method suggests that it should be used just for
+         * authentication flow, it can be used for other advanced flows; see {@link AutofillService}
+         * for examples.
+         *
+         * <p>This method is similar to
+         * {@link #setAuthentication(AutofillId[], IntentSender, RemoteViews)}, but also accepts
+         * an {@link InlinePresentation} presentation which is required for authenticating through
+         * the inline autofill flow.
+         *
+         * <p><b>Note:</b> {@link #setHeader(RemoteViews)} or {@link #setFooter(RemoteViews)} does
+         * not work with {@link InlinePresentation}.</p>
+         *
+         * @param authentication Intent to an activity with your authentication flow.
+         * @param presentation The presentation to visualize the response.
+         * @param inlinePresentation The inlinePresentation to visualize the response inline.
+         * @param ids id of Views that when focused will display the authentication UI.
+         *
+         * @return This builder.
+         *
+         * @throws IllegalArgumentException if any of the following occurs:
+         * <ul>
+         *   <li>{@code ids} is {@code null}</li>
+         *   <li>{@code ids} is empty</li>
+         *   <li>{@code ids} contains a {@code null} element</li>
+         *   <li>both {@code authentication} and {@code presentation} are {@code null}</li>
+         *   <li>both {@code authentication} and {@code presentation} are non-{@code null}</li>
+         *   <li>both {@code authentication} and {@code inlinePresentation} are {@code null}</li>
+         *   <li>both {@code authentication} and {@code inlinePresentation} are
+         *   non-{@code null}</li>
+         * </ul>
+         *
+         * @throws IllegalStateException if a {@link #setHeader(RemoteViews) header} or a
+         * {@link #setFooter(RemoteViews) footer} are already set for this builder.
+         *
+         * @see android.app.PendingIntent#getIntentSender()
+         */
+        @NonNull
+        public Builder setAuthentication(@NonNull AutofillId[] ids,
+                @Nullable IntentSender authentication, @Nullable RemoteViews presentation,
+                @Nullable InlinePresentation inlinePresentation) {
+            throwIfDestroyed();
+            throwIfDisableAutofillCalled();
+            if (mHeader != null || mFooter != null) {
+                throw new IllegalStateException("Already called #setHeader() or #setFooter()");
+            }
+
+            if (authentication == null ^ (presentation == null && inlinePresentation == null)) {
+                throw new IllegalArgumentException("authentication and presentation "
+                        + "(dropdown or inline), must be both non-null or null");
+            }
+            mAuthentication = authentication;
+            mPresentation = presentation;
+            mInlinePresentation = inlinePresentation;
+            mAuthenticationIds = assertValid(ids);
+            return this;
+        }
+
+        /**
          * Specifies views that should not trigger new
          * {@link AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal,
          * FillCallback)} requests.
@@ -644,6 +713,8 @@
                         break;
                     }
                 }
+            } else if (mInlinePresentation != null) {
+                mSupportsInlineSuggestions = true;
             }
 
             mDestroyed = true;
@@ -691,6 +762,9 @@
         if (mPresentation != null) {
             builder.append(", hasPresentation");
         }
+        if (mInlinePresentation != null) {
+            builder.append(", hasInlinePresentation");
+        }
         if (mHeader != null) {
             builder.append(", hasHeader");
         }
@@ -740,6 +814,7 @@
         parcel.writeParcelableArray(mAuthenticationIds, flags);
         parcel.writeParcelable(mAuthentication, flags);
         parcel.writeParcelable(mPresentation, flags);
+        parcel.writeParcelable(mInlinePresentation, flags);
         parcel.writeParcelable(mHeader, flags);
         parcel.writeParcelable(mFooter, flags);
         parcel.writeParcelable(mUserData, flags);
@@ -774,8 +849,10 @@
                     AutofillId.class);
             final IntentSender authentication = parcel.readParcelable(null);
             final RemoteViews presentation = parcel.readParcelable(null);
+            final InlinePresentation inlinePresentation = parcel.readParcelable(null);
             if (authenticationIds != null) {
-                builder.setAuthentication(authenticationIds, authentication, presentation);
+                builder.setAuthentication(authenticationIds, authentication, presentation,
+                        inlinePresentation);
             }
             final RemoteViews header = parcel.readParcelable(null);
             if (header != null) {
diff --git a/core/java/android/service/autofill/IInlineSuggestionRenderService.aidl b/core/java/android/service/autofill/IInlineSuggestionRenderService.aidl
index decdcf5..c389b1a 100644
--- a/core/java/android/service/autofill/IInlineSuggestionRenderService.aidl
+++ b/core/java/android/service/autofill/IInlineSuggestionRenderService.aidl
@@ -16,6 +16,7 @@
 
 package android.service.autofill;
 
+import android.os.IBinder;
 import android.service.autofill.IInlineSuggestionUiCallback;
 import android.service.autofill.InlinePresentation;
 
@@ -25,6 +26,7 @@
  * @hide
  */
 oneway interface IInlineSuggestionRenderService {
-    void renderSuggestion(in IInlineSuggestionUiCallback callback, in InlinePresentation presentation,
-                     int width, int height);
+    void renderSuggestion(in IInlineSuggestionUiCallback callback,
+                          in InlinePresentation presentation, int width, int height,
+                          in IBinder hostInputToken);
 }
diff --git a/core/java/android/service/autofill/IInlineSuggestionUiCallback.aidl b/core/java/android/service/autofill/IInlineSuggestionUiCallback.aidl
index a55a2ce..210f95f 100644
--- a/core/java/android/service/autofill/IInlineSuggestionUiCallback.aidl
+++ b/core/java/android/service/autofill/IInlineSuggestionUiCallback.aidl
@@ -16,6 +16,7 @@
 
 package android.service.autofill;
 
+import android.os.IBinder;
 import android.view.SurfaceControl;
 
 /**
@@ -24,6 +25,8 @@
  * @hide
  */
 oneway interface IInlineSuggestionUiCallback {
-    void autofill();
+    void onAutofill();
     void onContent(in SurfaceControl surface);
+    void onError();
+    void onTransferTouchFocusToImeWindow(in IBinder sourceInputToken, int displayId);
 }
diff --git a/core/java/android/service/autofill/InlineSuggestionRenderService.java b/core/java/android/service/autofill/InlineSuggestionRenderService.java
index 2593aab..4aafb63 100644
--- a/core/java/android/service/autofill/InlineSuggestionRenderService.java
+++ b/core/java/android/service/autofill/InlineSuggestionRenderService.java
@@ -24,11 +24,16 @@
 import android.app.Service;
 import android.app.slice.Slice;
 import android.content.Intent;
+import android.graphics.PixelFormat;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
+import android.os.RemoteException;
 import android.util.Log;
+import android.view.SurfaceControl;
+import android.view.SurfaceControlViewHost;
 import android.view.View;
+import android.view.WindowManager;
 
 /**
  * A service that renders an inline presentation given the {@link InlinePresentation} containing
@@ -55,8 +60,40 @@
     private final Handler mHandler = new Handler(Looper.getMainLooper(), null, true);
 
     private void handleRenderSuggestion(IInlineSuggestionUiCallback callback,
-            InlinePresentation presentation, int width, int height) {
-        //TODO(b/146453086): implementation in ExtService
+            InlinePresentation presentation, int width, int height, IBinder hostInputToken) {
+        if (hostInputToken == null) {
+            try {
+                callback.onError();
+            } catch (RemoteException e) {
+                Log.w(TAG, "RemoteException calling onError()");
+            }
+            return;
+        }
+        final SurfaceControlViewHost host = new SurfaceControlViewHost(this, this.getDisplay(),
+                hostInputToken);
+        final SurfaceControl surface = host.getSurfacePackage().getSurfaceControl();
+
+        final View suggestionView = onRenderSuggestion(presentation, width, height);
+
+        final InlineSuggestionRoot suggestionRoot = new InlineSuggestionRoot(this, callback);
+        suggestionRoot.addView(suggestionView);
+        suggestionRoot.setOnClickListener((v) -> {
+            try {
+                callback.onAutofill();
+            } catch (RemoteException e) {
+                Log.w(TAG, "RemoteException calling onAutofill()");
+            }
+        });
+
+        WindowManager.LayoutParams lp =
+                new WindowManager.LayoutParams(width, height,
+                        WindowManager.LayoutParams.TYPE_APPLICATION, 0, PixelFormat.TRANSPARENT);
+        host.addView(suggestionRoot, lp);
+        try {
+            callback.onContent(surface);
+        } catch (RemoteException e) {
+            Log.w(TAG, "RemoteException calling onContent(" + surface + ")");
+        }
     }
 
     @Override
@@ -66,11 +103,12 @@
             return new IInlineSuggestionRenderService.Stub() {
                 @Override
                 public void renderSuggestion(@NonNull IInlineSuggestionUiCallback callback,
-                        @NonNull InlinePresentation presentation, int width, int height) {
+                        @NonNull InlinePresentation presentation, int width, int height,
+                        @Nullable IBinder hostInputToken) {
                     mHandler.sendMessage(obtainMessage(
                             InlineSuggestionRenderService::handleRenderSuggestion,
                             InlineSuggestionRenderService.this, callback, presentation,
-                            width, height));
+                            width, height, hostInputToken));
                 }
             }.asBinder();
         }
diff --git a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionRoot.java b/core/java/android/service/autofill/InlineSuggestionRoot.java
similarity index 65%
rename from services/autofill/java/com/android/server/autofill/ui/InlineSuggestionRoot.java
rename to core/java/android/service/autofill/InlineSuggestionRoot.java
index e813dae..bdcc253 100644
--- a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionRoot.java
+++ b/core/java/android/service/autofill/InlineSuggestionRoot.java
@@ -14,39 +14,39 @@
  * limitations under the License.
  */
 
-package com.android.server.autofill.ui;
+package android.service.autofill;
 
 import android.annotation.NonNull;
 import android.annotation.SuppressLint;
 import android.content.Context;
+import android.os.RemoteException;
 import android.util.Log;
 import android.util.MathUtils;
 import android.view.MotionEvent;
 import android.view.ViewConfiguration;
 import android.widget.FrameLayout;
 
-import com.android.server.LocalServices;
-import com.android.server.wm.WindowManagerInternal;
-
 /**
  * This class is the root view for an inline suggestion. It is responsible for
  * detecting the click on the item and to also transfer input focus to the IME
  * window if we detect the user is scrolling.
+ *
+ * @hide
  */
- // TODO(b/146453086) Move to ExtServices and add @SystemApi to transfer touch focus
 @SuppressLint("ViewConstructor")
-class InlineSuggestionRoot extends FrameLayout {
-    private static final String LOG_TAG = InlineSuggestionRoot.class.getSimpleName();
+public class InlineSuggestionRoot extends FrameLayout {
+    private static final String TAG = "InlineSuggestionRoot";
 
-    private final @NonNull Runnable mOnErrorCallback;
+    private final @NonNull IInlineSuggestionUiCallback mCallback;
     private final int mTouchSlop;
 
     private float mDownX;
     private float mDownY;
 
-    InlineSuggestionRoot(@NonNull Context context, @NonNull Runnable onErrorCallback) {
+    public InlineSuggestionRoot(@NonNull Context context,
+            @NonNull IInlineSuggestionUiCallback callback) {
         super(context);
-        mOnErrorCallback = onErrorCallback;
+        mCallback = callback;
         mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
         setFocusable(false);
     }
@@ -64,20 +64,15 @@
                 final float distance = MathUtils.dist(mDownX, mDownY,
                         event.getX(), event.getY());
                 if (distance > mTouchSlop) {
-                    transferTouchFocusToImeWindow();
+                    try {
+                        mCallback.onTransferTouchFocusToImeWindow(getViewRootImpl().getInputToken(),
+                                getContext().getDisplayId());
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "RemoteException transferring touch focus to IME");
+                    }
                 }
             } break;
         }
         return super.onTouchEvent(event);
     }
-
-    private void transferTouchFocusToImeWindow() {
-        final WindowManagerInternal windowManagerInternal = LocalServices.getService(
-                WindowManagerInternal.class);
-        if (!windowManagerInternal.transferTouchFocusToImeWindow(getViewRootImpl().getInputToken(),
-                getContext().getDisplayId())) {
-            Log.e(LOG_TAG, "Cannot transfer touch focus from suggestion to IME");
-            mOnErrorCallback.run();
-        }
-    }
 }
diff --git a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
index 79852d3..672b501 100644
--- a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
+++ b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
@@ -89,6 +89,8 @@
 
     private SparseArray<AutofillProxy> mAutofillProxies;
 
+    private AutofillProxy mAutofillProxyForLastRequest;
+
     // Used for metrics / debug only
     private ComponentName mServiceComponentName;
 
@@ -158,6 +160,38 @@
     }
 
     /**
+     * The child class of the service can call this method to initiate an Autofill flow.
+     *
+     * <p> The request would be respected only if the previous augmented autofill request was
+     * made for the same {@code activityComponent} and {@code autofillId}, and the field is
+     * currently on focus.
+     *
+     * <p> The request would start a new autofill flow. It doesn't guarantee that the
+     * {@link AutofillManager} will proceed with the request.
+     *
+     * @param activityComponent the client component for which the autofill is requested for
+     * @param autofillId        the client field id for which the autofill is requested for
+     * @return true if the request makes the {@link AutofillManager} start a new Autofill flow,
+     * false otherwise.
+     */
+    public final boolean requestAutofill(@NonNull ComponentName activityComponent,
+            @NonNull AutofillId autofillId) {
+        // TODO(b/149531989): revisit this. The request should start a new autofill session
+        //  rather than reusing the existing session.
+        final AutofillProxy proxy = mAutofillProxyForLastRequest;
+        if (proxy == null || !proxy.mComponentName.equals(activityComponent)
+                || !proxy.mFocusedId.equals(autofillId)) {
+            return false;
+        }
+        try {
+            return proxy.requestAutofill();
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+        return false;
+    }
+
+    /**
      * Asks the service to handle an "augmented" autofill request.
      *
      * <p>This method is called when the "stantard" autofill service cannot handle a request, which
@@ -241,6 +275,7 @@
         } catch (RemoteException e) {
             e.rethrowFromSystemServer();
         }
+        mAutofillProxyForLastRequest = proxy;
         onFillRequest(new FillRequest(proxy, inlineSuggestionsRequest), cancellationSignal,
                 new FillController(proxy), new FillCallback(proxy));
     }
@@ -268,6 +303,7 @@
                 proxy.destroy();
             }
             mAutofillProxies.clear();
+            mAutofillProxyForLastRequest = null;
         }
     }
 
@@ -287,6 +323,7 @@
             }
         }
         mAutofillProxies = null;
+        mAutofillProxyForLastRequest = null;
     }
 
     @Override
@@ -481,6 +518,11 @@
             mClient.requestHideFillUi(mSessionId, mFocusedId);
         }
 
+
+        private boolean requestAutofill() throws RemoteException {
+            return mClient.requestAutofill(mSessionId, mFocusedId);
+        }
+
         private void update(@NonNull AutofillId focusedId, @NonNull AutofillValue focusedValue,
                 @NonNull IFillCallback callback, @NonNull CancellationSignal cancellationSignal) {
             synchronized (mLock) {
diff --git a/core/java/android/service/quickaccesswallet/GetWalletCardsCallback.java b/core/java/android/service/quickaccesswallet/GetWalletCardsCallback.java
index 9d210cd..f6a86d9 100644
--- a/core/java/android/service/quickaccesswallet/GetWalletCardsCallback.java
+++ b/core/java/android/service/quickaccesswallet/GetWalletCardsCallback.java
@@ -17,28 +17,11 @@
 package android.service.quickaccesswallet;
 
 import android.annotation.NonNull;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.util.Log;
 
 /**
  * Handles response from the {@link QuickAccessWalletService} for {@link GetWalletCardsRequest}
  */
-public final class GetWalletCardsCallback {
-
-    private static final String TAG = "QAWalletCallback";
-
-    private final IQuickAccessWalletServiceCallbacks mCallback;
-    private final Handler mHandler;
-    private boolean mCalled;
-
-    /**
-     * @hide
-     */
-    GetWalletCardsCallback(IQuickAccessWalletServiceCallbacks callback, Handler handler) {
-        mCallback = callback;
-        mHandler = handler;
-    }
+public interface GetWalletCardsCallback {
 
     /**
      * Notifies the Android System that an {@link QuickAccessWalletService#onWalletCardsRequested}
@@ -46,11 +29,10 @@
      *
      * @param response The response contains the list of {@link WalletCard walletCards} to be shown
      *                 to the user as well as the index of the card that should initially be
-     *                 presented as the selected card.
+     *                 presented as the selected card. The list should not contain more than the
+     *                 maximum number of cards requested.
      */
-    public void onSuccess(@NonNull GetWalletCardsResponse response) {
-        mHandler.post(() -> onSuccessInternal(response));
-    }
+    void onSuccess(@NonNull GetWalletCardsResponse response);
 
     /**
      * Notifies the Android System that an {@link QuickAccessWalletService#onWalletCardsRequested}
@@ -60,33 +42,5 @@
      *              (Personally Identifiable Information, such as username or email address).
      * @throws IllegalStateException if this method or {@link #onSuccess} was already called.
      */
-    public void onFailure(@NonNull GetWalletCardsError error) {
-        mHandler.post(() -> onFailureInternal(error));
-    }
-
-    private void onSuccessInternal(GetWalletCardsResponse response) {
-        if (mCalled) {
-            Log.w(TAG, "already called");
-            return;
-        }
-        mCalled = true;
-        try {
-            mCallback.onGetWalletCardsSuccess(response);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error returning wallet cards", e);
-        }
-    }
-
-    private void onFailureInternal(GetWalletCardsError error) {
-        if (mCalled) {
-            Log.w(TAG, "already called");
-            return;
-        }
-        mCalled = true;
-        try {
-            mCallback.onGetWalletCardsFailure(error);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error returning failure message", e);
-        }
-    }
+    void onFailure(@NonNull GetWalletCardsError error);
 }
diff --git a/core/java/android/service/quickaccesswallet/GetWalletCardsCallbackImpl.java b/core/java/android/service/quickaccesswallet/GetWalletCardsCallbackImpl.java
new file mode 100644
index 0000000..d2494a5
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/GetWalletCardsCallbackImpl.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.quickaccesswallet;
+
+import android.annotation.NonNull;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Icon;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.List;
+
+/**
+ * Handles response from the {@link QuickAccessWalletService} for {@link GetWalletCardsRequest}
+ *
+ * @hide
+ */
+final class GetWalletCardsCallbackImpl implements GetWalletCardsCallback {
+
+    private static final String TAG = "QAWalletCallback";
+
+    private final IQuickAccessWalletServiceCallbacks mCallback;
+    private final GetWalletCardsRequest mRequest;
+    private final Handler mHandler;
+    private boolean mCalled;
+
+    GetWalletCardsCallbackImpl(GetWalletCardsRequest request,
+            IQuickAccessWalletServiceCallbacks callback, Handler handler) {
+        mRequest = request;
+        mCallback = callback;
+        mHandler = handler;
+    }
+
+    /**
+     * Notifies the Android System that an {@link QuickAccessWalletService#onWalletCardsRequested}
+     * was successfully handled by the service.
+     *
+     * @param response The response contains the list of {@link WalletCard walletCards} to be shown
+     *                 to the user as well as the index of the card that should initially be
+     *                 presented as the selected card.
+     */
+    public void onSuccess(@NonNull GetWalletCardsResponse response) {
+        Log.i(TAG, "onSuccess");
+        if (isValidResponse(response)) {
+            mHandler.post(() -> onSuccessInternal(response));
+        } else {
+            Log.w(TAG, "Invalid GetWalletCards response");
+            mHandler.post(() -> onFailureInternal(new GetWalletCardsError(null, null)));
+        }
+    }
+
+    /**
+     * Notifies the Android System that an {@link QuickAccessWalletService#onWalletCardsRequested}
+     * could not be handled by the service.
+     *
+     * @param error The error message. <b>Note: </b> this message should <b>not</b> contain PII
+     *              (Personally Identifiable Information, such as username or email address).
+     * @throws IllegalStateException if this method or {@link #onSuccess} was already called.
+     */
+    public void onFailure(@NonNull GetWalletCardsError error) {
+        mHandler.post(() -> onFailureInternal(error));
+    }
+
+    private void onSuccessInternal(GetWalletCardsResponse response) {
+        Log.i(TAG, "onSuccessInternal");
+        if (mCalled) {
+            Log.w(TAG, "already called");
+            return;
+        }
+        mCalled = true;
+        try {
+            mCallback.onGetWalletCardsSuccess(response);
+            Log.i(TAG, "onSuccessInternal: returned response");
+        } catch (RemoteException e) {
+            Log.w(TAG, "Error returning wallet cards", e);
+        }
+    }
+
+    private void onFailureInternal(GetWalletCardsError error) {
+        if (mCalled) {
+            Log.w(TAG, "already called");
+            return;
+        }
+        mCalled = true;
+        try {
+            mCallback.onGetWalletCardsFailure(error);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error returning failure message", e);
+        }
+    }
+
+    private boolean isValidResponse(@NonNull GetWalletCardsResponse response) {
+        return response != null
+                && response.getWalletCards() != null
+                && response.getSelectedIndex() >= 0
+                && (response.getWalletCards().isEmpty() // selectedIndex may be 0 when list is empty
+                || response.getSelectedIndex() < response.getWalletCards().size())
+                && response.getWalletCards().size() < mRequest.getMaxCards()
+                && areValidCards(response.getWalletCards());
+    }
+
+    private boolean areValidCards(List<WalletCard> walletCards) {
+        for (WalletCard walletCard : walletCards) {
+            if (walletCard == null
+                    || walletCard.getCardId() == null
+                    || walletCard.getCardImage() == null
+                    || TextUtils.isEmpty(walletCard.getContentDescription())
+                    || walletCard.getPendingIntent() == null) {
+                return false;
+            }
+            Icon cardImage = walletCard.getCardImage();
+            if (cardImage.getType() == Icon.TYPE_BITMAP
+                    && walletCard.getCardImage().getBitmap().getConfig()
+                    != Bitmap.Config.HARDWARE) {
+                Log.w(TAG, "WalletCard bitmaps should be hardware bitmaps");
+            }
+        }
+        return true;
+    }
+}
diff --git a/core/java/android/service/quickaccesswallet/GetWalletCardsResponse.java b/core/java/android/service/quickaccesswallet/GetWalletCardsResponse.java
index 996622a..0551e27 100644
--- a/core/java/android/service/quickaccesswallet/GetWalletCardsResponse.java
+++ b/core/java/android/service/quickaccesswallet/GetWalletCardsResponse.java
@@ -35,9 +35,13 @@
     /**
      * Construct a new response.
      *
-     * @param walletCards   The list of wallet cards.
+     * @param walletCards   The list of wallet cards. The list may be empty but must NOT be larger
+     *                      than {@link GetWalletCardsRequest#getMaxCards()}. The list may not
+     *                      contain null values.
      * @param selectedIndex The index of the card that should be presented as the initially
-     *                      'selected' card
+     *                      'selected' card. The index must be greater than or equal to zero and
+     *                      less than the size of the list of walletCards (unless the list is empty
+     *                      in which case the value may be 0).
      */
     public GetWalletCardsResponse(@NonNull List<WalletCard> walletCards, int selectedIndex) {
         this.mWalletCards = walletCards;
diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java
index cfc6d57..be9ab11 100644
--- a/core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java
@@ -18,16 +18,16 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TestApi;
 import android.content.Context;
 import android.content.Intent;
 
-import java.util.function.Consumer;
-
 /**
  * Facilitates accessing cards from the {@link QuickAccessWalletService}.
  *
  * @hide
  */
+@TestApi
 public interface QuickAccessWalletClient {
 
     /**
@@ -40,17 +40,65 @@
     }
 
     /**
-     * @return true if the {@link QuickAccessWalletService} is available.
+     * @return true if the {@link QuickAccessWalletService} is available. This means that the
+     * default NFC payment application has an exported service that can provide cards to the Quick
+     * Access Wallet. However, it does not mean that (1) the call will necessarily be successful,
+     * nor does it mean that cards may be displayed at this time. Addition checks are required:
+     * <ul>
+     *     <li>If {@link #isWalletFeatureAvailable()} is false, cards should not be displayed
+     *     <li>If the device is locked and {@link #isWalletFeatureAvailableWhenDeviceLocked} is
+     *     false, cards should not be displayed while the device remains locked. (A message
+     *     prompting the user to unlock to view cards may be appropriate).</li>
+     * </ul>
      */
     boolean isWalletServiceAvailable();
 
     /**
+     * Wallet cards should not be displayed if:
+     * <ul>
+     *     <li>The wallet service is unavailable</li>
+     *     <li>The device is not provisioned, ie user setup is incomplete</li>
+     *     <li>If the wallet feature has been disabled by the user</li>
+     *     <li>If the phone has been put into lockdown mode</li>
+     * </ul>
+     * <p>
+     * Quick Access Wallet implementers should call this method before calling
+     * {@link #getWalletCards} to ensure that cards may be displayed.
+     */
+    boolean isWalletFeatureAvailable();
+
+    /**
+     * Wallet cards may not be displayed on the lock screen if the user has opted to hide
+     * notifications or sensitive content on the lock screen.
+     * <ul>
+     *     <li>The device is not provisioned, ie user setup is incomplete</li>
+     *     <li>If the wallet feature has been disabled by the user</li>
+     *     <li>If the phone has been put into lockdown mode</li>
+     * </ul>
+     *
+     * <p>
+     * Quick Access Wallet implementers should call this method before calling
+     * {@link #getWalletCards} if the device is currently locked.
+     *
+     * @return true if cards may be displayed on the lock screen.
+     */
+    boolean isWalletFeatureAvailableWhenDeviceLocked();
+
+    /**
      * Get wallet cards from the {@link QuickAccessWalletService}.
      */
     void getWalletCards(
             @NonNull GetWalletCardsRequest request,
-            @NonNull Consumer<GetWalletCardsResponse> onSuccessListener,
-            @NonNull Consumer<GetWalletCardsError> onFailureListener);
+            @NonNull OnWalletCardsRetrievedCallback callback);
+
+    /**
+     * Callback for getWalletCards
+     */
+    interface OnWalletCardsRetrievedCallback {
+        void onWalletCardsRetrieved(@NonNull GetWalletCardsResponse response);
+
+        void onWalletCardRetrievalError(@NonNull GetWalletCardsError error);
+    }
 
     /**
      * Notify the {@link QuickAccessWalletService} service that a wallet card was selected.
@@ -65,12 +113,24 @@
     /**
      * Unregister event listener.
      */
-    void registerWalletServiceEventListener(Consumer<WalletServiceEvent> listener);
+    void addWalletServiceEventListener(@NonNull WalletServiceEventListener listener);
 
     /**
      * Unregister event listener
      */
-    void unregisterWalletServiceEventListener(Consumer<WalletServiceEvent> listener);
+    void removeWalletServiceEventListener(@NonNull WalletServiceEventListener listener);
+
+    /**
+     * A listener for {@link WalletServiceEvent walletServiceEvents}
+     */
+    interface WalletServiceEventListener {
+        void onWalletServiceEvent(@NonNull WalletServiceEvent event);
+    }
+
+    /**
+     * Unregister all event listeners and disconnect from the service.
+     */
+    void disconnect();
 
     /**
      * The manifest entry for the QuickAccessWalletService may also publish information about the
@@ -78,12 +138,12 @@
      * application.
      */
     @Nullable
-    Intent getWalletActivity();
+    Intent createWalletIntent();
 
     /**
      * The manifest entry for the {@link QuickAccessWalletService} may publish the activity that
      * hosts the settings
      */
     @Nullable
-    Intent getSettingsActivity();
+    Intent createWalletSettingsIntent();
 }
diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java
index 17c287f..37a8703 100644
--- a/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java
@@ -20,6 +20,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.ActivityManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -27,79 +28,225 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
-import android.os.Message;
 import android.os.RemoteException;
+import android.os.UserHandle;
+import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Log;
 
+import com.android.internal.widget.LockPatternUtils;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.Map;
 import java.util.Queue;
 import java.util.UUID;
-import java.util.function.Consumer;
 
 /**
+ * Implements {@link QuickAccessWalletClient}. The client connects, performs requests, waits for
+ * responses, and disconnects automatically after a short period of time. The client may
  * @hide
  */
-@SuppressWarnings("AndroidJdkLibsChecker")
-class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Handler.Callback,
-        ServiceConnection {
+public class QuickAccessWalletClientImpl implements QuickAccessWalletClient, ServiceConnection {
 
     private static final String TAG = "QAWalletSClient";
     private final Handler mHandler;
     private final Context mContext;
     private final Queue<ApiCaller> mRequestQueue;
-    private final Map<Consumer<WalletServiceEvent>, String> mEventListeners;
+    private final Map<WalletServiceEventListener, String> mEventListeners;
     private boolean mIsConnected;
+    /**
+     * Timeout for active service connections (1 minute)
+     */
+    private static final long SERVICE_CONNECTION_TIMEOUT_MS = 60 * 1000;
     @Nullable
     private IQuickAccessWalletService mService;
 
-
     @Nullable
     private final QuickAccessWalletServiceInfo mServiceInfo;
 
-    private static final int MSG_CONNECT = 1;
-    private static final int MSG_CONNECTED = 2;
-    private static final int MSG_EXECUTE = 3;
-    private static final int MSG_DISCONNECT = 4;
+    private static final int MSG_TIMEOUT_SERVICE = 5;
 
     QuickAccessWalletClientImpl(@NonNull Context context) {
         mContext = context.getApplicationContext();
         mServiceInfo = QuickAccessWalletServiceInfo.tryCreate(context);
-        mHandler = new Handler(Looper.getMainLooper(), this);
+        mHandler = new Handler(Looper.getMainLooper());
         mRequestQueue = new LinkedList<>();
         mEventListeners = new HashMap<>(1);
     }
 
     @Override
-    public boolean handleMessage(Message msg) {
-        switch (msg.what) {
-            case MSG_CONNECT:
-                connectInternal();
-                break;
-            case MSG_CONNECTED:
-                onConnectedInternal((IQuickAccessWalletService) msg.obj);
-                break;
-            case MSG_EXECUTE:
-                executeInternal((ApiCaller) msg.obj);
-                break;
-            case MSG_DISCONNECT:
-                disconnectInternal();
-                break;
-            default:
-                Log.w(TAG, "Unknown what: " + msg.what);
-                return false;
+    public boolean isWalletServiceAvailable() {
+        boolean available = mServiceInfo != null;
+        Log.i(TAG, "isWalletServiceAvailable: " + available);
+        return available;
+    }
+
+    @Override
+    public boolean isWalletFeatureAvailable() {
+        int currentUser = ActivityManager.getCurrentUser();
+        return checkUserSetupComplete()
+                && checkSecureSetting(Settings.Secure.GLOBAL_ACTIONS_PANEL_ENABLED)
+                && !new LockPatternUtils(mContext).isUserInLockdown(currentUser);
+    }
+
+    @Override
+    public boolean isWalletFeatureAvailableWhenDeviceLocked() {
+        return checkSecureSetting(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS)
+                && checkSecureSetting(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS);
+    }
+
+    @Override
+    public void getWalletCards(
+            @NonNull GetWalletCardsRequest request,
+            @NonNull OnWalletCardsRetrievedCallback callback) {
+
+        Log.i(TAG, "getWalletCards");
+
+        if (!isWalletServiceAvailable()) {
+            callback.onWalletCardRetrievalError(new GetWalletCardsError(null, null));
+            return;
         }
-        return true;
+
+        BaseCallbacks serviceCallback = new BaseCallbacks() {
+            @Override
+            public void onGetWalletCardsSuccess(GetWalletCardsResponse response) {
+                mHandler.post(() -> callback.onWalletCardsRetrieved(response));
+            }
+
+            @Override
+            public void onGetWalletCardsFailure(GetWalletCardsError error) {
+                mHandler.post(() -> callback.onWalletCardRetrievalError(error));
+            }
+        };
+
+        executeApiCall(new ApiCaller("onWalletCardsRequested") {
+            @Override
+            public void performApiCall(IQuickAccessWalletService service) throws RemoteException {
+                service.onWalletCardsRequested(request, serviceCallback);
+            }
+
+            @Override
+            public void onApiError() {
+                serviceCallback.onGetWalletCardsFailure(new GetWalletCardsError(null, null));
+            }
+        });
+    }
+
+    @Override
+    public void selectWalletCard(@NonNull SelectWalletCardRequest request) {
+        Log.i(TAG, "selectWalletCard");
+        if (!isWalletServiceAvailable()) {
+            return;
+        }
+        executeApiCall(new ApiCaller("onWalletCardSelected") {
+            @Override
+            public void performApiCall(IQuickAccessWalletService service) throws RemoteException {
+                service.onWalletCardSelected(request);
+            }
+        });
+    }
+
+    @Override
+    public void notifyWalletDismissed() {
+        if (!isWalletServiceAvailable()) {
+            return;
+        }
+        Log.i(TAG, "notifyWalletDismissed");
+        executeApiCall(new ApiCaller("onWalletDismissed") {
+            @Override
+            public void performApiCall(IQuickAccessWalletService service) throws RemoteException {
+                service.onWalletDismissed();
+            }
+        });
+    }
+
+    @Override
+    public void addWalletServiceEventListener(WalletServiceEventListener listener) {
+        if (!isWalletServiceAvailable()) {
+            return;
+        }
+        Log.i(TAG, "registerWalletServiceEventListener");
+        BaseCallbacks callback = new BaseCallbacks() {
+            @Override
+            public void onWalletServiceEvent(WalletServiceEvent event) {
+                Log.i(TAG, "onWalletServiceEvent");
+                mHandler.post(() -> listener.onWalletServiceEvent(event));
+            }
+        };
+
+        executeApiCall(new ApiCaller("registerListener") {
+            @Override
+            public void performApiCall(IQuickAccessWalletService service) throws RemoteException {
+                String listenerId = UUID.randomUUID().toString();
+                WalletServiceEventListenerRequest request =
+                        new WalletServiceEventListenerRequest(listenerId);
+                mEventListeners.put(listener, listenerId);
+                service.registerWalletServiceEventListener(request, callback);
+            }
+        });
+    }
+
+    @Override
+    public void removeWalletServiceEventListener(WalletServiceEventListener listener) {
+        if (!isWalletServiceAvailable()) {
+            return;
+        }
+        Log.i(TAG, "unregisterWalletServiceEventListener");
+        executeApiCall(new ApiCaller("unregisterListener") {
+            @Override
+            public void performApiCall(IQuickAccessWalletService service) throws RemoteException {
+                String listenerId = mEventListeners.remove(listener);
+                if (listenerId == null) {
+                    return;
+                }
+                WalletServiceEventListenerRequest request =
+                        new WalletServiceEventListenerRequest(listenerId);
+                service.unregisterWalletServiceEventListener(request);
+            }
+        });
+    }
+
+    @Override
+    public void disconnect() {
+        Log.i(TAG, "disconnect");
+        mHandler.post(() -> disconnectInternal(true));
+    }
+
+    @Override
+    @Nullable
+    public Intent createWalletIntent() {
+        if (mServiceInfo == null || TextUtils.isEmpty(mServiceInfo.getWalletActivity())) {
+            return null;
+        }
+        return new Intent(QuickAccessWalletService.ACTION_VIEW_WALLET)
+                .setComponent(
+                        new ComponentName(
+                                mServiceInfo.getComponentName().getPackageName(),
+                                mServiceInfo.getWalletActivity()));
+    }
+
+    @Override
+    @Nullable
+    public Intent createWalletSettingsIntent() {
+        if (mServiceInfo == null || TextUtils.isEmpty(mServiceInfo.getSettingsActivity())) {
+            return null;
+        }
+        return new Intent(QuickAccessWalletService.ACTION_VIEW_WALLET_SETTINGS)
+                .setComponent(
+                        new ComponentName(
+                                mServiceInfo.getComponentName().getPackageName(),
+                                mServiceInfo.getSettingsActivity()));
     }
 
     private void connect() {
-        mHandler.sendMessage(mHandler.obtainMessage(MSG_CONNECT));
+        Log.i(TAG, "connect");
+        mHandler.post(this::connectInternal);
     }
 
     private void connectInternal() {
+        Log.i(TAG, "connectInternal");
         if (mServiceInfo == null) {
             Log.w(TAG, "Wallet service unavailable");
             return;
@@ -113,15 +260,18 @@
         intent.setComponent(mServiceInfo.getComponentName());
         int flags = Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY;
         mContext.bindService(intent, this, flags);
+        resetServiceConnectionTimeout();
     }
 
     private void onConnectedInternal(IQuickAccessWalletService service) {
+        Log.i(TAG, "onConnectedInternal");
         if (!mIsConnected) {
             Log.w(TAG, "onConnectInternal but connection closed");
             mService = null;
             return;
         }
         mService = service;
+        Log.i(TAG, "onConnectedInternal success: request queue size " + mRequestQueue.size());
         for (ApiCaller apiCaller : new ArrayList<>(mRequestQueue)) {
             try {
                 apiCaller.performApiCall(mService);
@@ -135,15 +285,33 @@
         }
     }
 
-    private void disconnect() {
-        mHandler.sendMessage(mHandler.obtainMessage(MSG_DISCONNECT));
+    /**
+     * Resets the idle timeout for this connection by removing any pending timeout messages and
+     * posting a new delayed message.
+     */
+    private void resetServiceConnectionTimeout() {
+        Log.i(TAG, "resetServiceConnectionTimeout");
+        mHandler.removeMessages(MSG_TIMEOUT_SERVICE);
+        mHandler.postDelayed(
+                () -> disconnectInternal(true),
+                MSG_TIMEOUT_SERVICE,
+                SERVICE_CONNECTION_TIMEOUT_MS);
     }
 
-    private void disconnectInternal() {
+    private void disconnectInternal(boolean clearEventListeners) {
+        Log.i(TAG, "disconnectInternal: " + clearEventListeners);
         if (!mIsConnected) {
             Log.w(TAG, "already disconnected");
             return;
         }
+        if (clearEventListeners && !mEventListeners.isEmpty()) {
+            Log.i(TAG, "disconnectInternal: clear event listeners");
+            for (WalletServiceEventListener listener : mEventListeners.keySet()) {
+                removeWalletServiceEventListener(listener);
+            }
+            mHandler.post(() -> disconnectInternal(false));
+            return;
+        }
         mIsConnected = false;
         mContext.unbindService(/*conn=*/this);
         mService = null;
@@ -151,181 +319,81 @@
         mRequestQueue.clear();
     }
 
-    private void execute(ApiCaller apiCaller) {
-        mHandler.sendMessage(mHandler.obtainMessage(MSG_EXECUTE, apiCaller));
+    private void executeApiCall(ApiCaller apiCaller) {
+        Log.i(TAG, "execute: " + apiCaller.mDesc);
+        mHandler.post(() -> executeInternal(apiCaller));
     }
 
     private void executeInternal(ApiCaller apiCall) {
+        Log.i(TAG, "executeInternal: " + apiCall.mDesc);
         if (mIsConnected && mService != null) {
             try {
                 apiCall.performApiCall(mService);
+                Log.i(TAG, "executeInternal success: " + apiCall.mDesc);
+                resetServiceConnectionTimeout();
             } catch (RemoteException e) {
-                Log.w(TAG, "executeInternal error", e);
+                Log.w(TAG, "executeInternal error: " + apiCall.mDesc, e);
                 apiCall.onApiError();
                 disconnect();
             }
         } else {
+            Log.i(TAG, "executeInternal: queued" + apiCall.mDesc);
             mRequestQueue.add(apiCall);
             connect();
         }
     }
 
-    public boolean isWalletServiceAvailable() {
-        return mServiceInfo != null;
-    }
-
     private abstract static class ApiCaller {
+        private final String mDesc;
+
+        private ApiCaller(String desc) {
+            this.mDesc = desc;
+        }
+
         abstract void performApiCall(IQuickAccessWalletService service) throws RemoteException;
 
         void onApiError() {
-            Log.w(TAG, "api error");
+            Log.w(TAG, "api error: " + mDesc);
         }
     }
 
-    public void getWalletCards(
-            @NonNull GetWalletCardsRequest request,
-            @NonNull Consumer<GetWalletCardsResponse> onSuccessListener,
-            @NonNull Consumer<GetWalletCardsError> onFailureListener) {
-
-        BaseCallbacks callback = new BaseCallbacks() {
-            @Override
-            public void onGetWalletCardsSuccess(GetWalletCardsResponse response) {
-                mHandler.post(() -> onSuccessListener.accept(response));
-            }
-
-            @Override
-            public void onGetWalletCardsFailure(GetWalletCardsError error) {
-                mHandler.post(() -> onFailureListener.accept(error));
-            }
-        };
-
-        execute(new ApiCaller() {
-            @Override
-            public void performApiCall(IQuickAccessWalletService service) throws RemoteException {
-                service.onWalletCardsRequested(request, callback);
-            }
-
-            @Override
-            public void onApiError() {
-                callback.onGetWalletCardsFailure(new GetWalletCardsError(null, null));
-            }
-        });
-    }
-
-    public void selectWalletCard(@NonNull SelectWalletCardRequest request) {
-        execute(new ApiCaller() {
-            @Override
-            public void performApiCall(IQuickAccessWalletService service) throws RemoteException {
-                service.onWalletCardSelected(request);
-            }
-        });
-    }
-
-    public void notifyWalletDismissed() {
-        execute(new ApiCaller() {
-            @Override
-            public void performApiCall(IQuickAccessWalletService service) throws RemoteException {
-                service.onWalletDismissed();
-                mHandler.sendMessage(mHandler.obtainMessage(MSG_DISCONNECT));
-            }
-        });
-    }
-
-    @Override
-    public void registerWalletServiceEventListener(Consumer<WalletServiceEvent> listener) {
-
-        BaseCallbacks callback = new BaseCallbacks() {
-            @Override
-            public void onWalletServiceEvent(WalletServiceEvent event) {
-                Log.i(TAG, "onWalletServiceEvent");
-                mHandler.post(() -> listener.accept(event));
-            }
-        };
-
-        execute(new ApiCaller() {
-            @Override
-            public void performApiCall(IQuickAccessWalletService service) throws RemoteException {
-                String listenerId = UUID.randomUUID().toString();
-                WalletServiceEventListenerRequest request =
-                        new WalletServiceEventListenerRequest(listenerId);
-                mEventListeners.put(listener, listenerId);
-                service.registerWalletServiceEventListener(request, callback);
-            }
-        });
-    }
-
-    @Override
-    public void unregisterWalletServiceEventListener(Consumer<WalletServiceEvent> listener) {
-        execute(new ApiCaller() {
-            @Override
-            public void performApiCall(IQuickAccessWalletService service) throws RemoteException {
-                String listenerId = mEventListeners.get(listener);
-                if (listenerId == null) {
-                    return;
-                }
-                WalletServiceEventListenerRequest request =
-                        new WalletServiceEventListenerRequest(listenerId);
-                service.unregisterWalletServiceEventListener(request);
-            }
-        });
-    }
-
-    @Override
-    @Nullable
-    public Intent getWalletActivity() {
-        if (mServiceInfo == null || TextUtils.isEmpty(mServiceInfo.getWalletActivity())) {
-            return null;
-        }
-        return new Intent(QuickAccessWalletService.ACTION_VIEW_WALLET)
-                .setComponent(
-                        new ComponentName(
-                                mServiceInfo.getComponentName().getPackageName(),
-                                mServiceInfo.getWalletActivity()));
-    }
-
-    @Override
-    @Nullable
-    public Intent getSettingsActivity() {
-        if (mServiceInfo == null || TextUtils.isEmpty(mServiceInfo.getSettingsActivity())) {
-            return null;
-        }
-        return new Intent(QuickAccessWalletService.ACTION_VIEW_WALLET_SETTINGS)
-                .setComponent(
-                        new ComponentName(
-                                mServiceInfo.getComponentName().getPackageName(),
-                                mServiceInfo.getSettingsActivity()));
-    }
-
-    /**
-     * Connection to the {@link QuickAccessWalletService}
-     */
-
-
-    @Override
+    @Override // ServiceConnection
     public void onServiceConnected(ComponentName name, IBinder binder) {
+        Log.i(TAG, "onServiceConnected: " + name);
         IQuickAccessWalletService service = IQuickAccessWalletService.Stub.asInterface(binder);
-        mHandler.sendMessage(mHandler.obtainMessage(MSG_CONNECTED, service));
+        mHandler.post(() -> onConnectedInternal(service));
     }
 
-    @Override
+    @Override // ServiceConnection
     public void onServiceDisconnected(ComponentName name) {
         // Do not disconnect, as we may later be re-connected
         Log.w(TAG, "onServiceDisconnected");
     }
 
-    @Override
+    @Override // ServiceConnection
     public void onBindingDied(ComponentName name) {
         // This is a recoverable error but the client will need to reconnect.
         Log.w(TAG, "onBindingDied");
         disconnect();
     }
 
-    @Override
+    @Override // ServiceConnection
     public void onNullBinding(ComponentName name) {
         Log.w(TAG, "onNullBinding");
         disconnect();
     }
 
+    private boolean checkSecureSetting(String name) {
+        return Settings.Secure.getInt(mContext.getContentResolver(), name, 0) == 1;
+    }
+
+    private boolean checkUserSetupComplete() {
+        return Settings.Secure.getIntForUser(
+                mContext.getContentResolver(),
+                Settings.Secure.USER_SETUP_COMPLETE, 0,
+                UserHandle.USER_CURRENT) == 1;
+    }
+
     private static class BaseCallbacks extends IQuickAccessWalletServiceCallbacks.Stub {
         public void onGetWalletCardsSuccess(GetWalletCardsResponse response) {
             throw new IllegalStateException();
diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletService.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletService.java
index d968405..aba5611 100644
--- a/core/java/android/service/quickaccesswallet/QuickAccessWalletService.java
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletService.java
@@ -45,8 +45,9 @@
  *   android.permission.BIND_NFC_SERVICE permission.
  *   <li>The user explicitly selected the application as the default payment application in
  *   the Tap &amp; pay settings screen.
- *   <li>The application requires the {@code android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE}
- *   permission in its manifest.
+ *   <li>The QuickAccessWalletService requires that the binding application hold the
+ *   {@code android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE} permission, which only the System
+ *   Service can hold.
  *   <li>The user explicitly enables it using Android Settings (the
  *       {@link Settings#ACTION_QUICK_ACCESS_WALLET_SETTINGS} intent can be used to launch it).
  * </ol>
@@ -73,6 +74,11 @@
  *   a new card is selected, the Android System will notify the service through
  *   {@link #onWalletCardSelected} and will provide the {@link WalletCard#getCardId() cardId} of the
  *   card that is now selected.
+ *   <li>If the user commences an NFC payment, the service may send a {@link WalletServiceEvent}
+ *   to the System indicating that the wallet application now needs to show the activity associated
+ *   with making a payment. Sending a {@link WalletServiceEvent} of type
+ *   {@link WalletServiceEvent#TYPE_NFC_PAYMENT_STARTED} should cause the quick access wallet UI
+ *   to be dismissed.
  *   <li>When the wallet is dismissed, the Android System will notify the service through
  *   {@link #onWalletDismissed}.
  * </ol>
@@ -110,6 +116,7 @@
  *     android:permission="android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE">
  *     <intent-filter>
  *         <action android:name="android.service.quickaccesswallet.QuickAccessWalletService" />
+ *         <category android:name="android.intent.category.DEFAULT"/>
  *     </intent-filter>
  *     <meta-data android:name="android.quickaccesswallet"
  *          android:resource="@xml/quickaccesswallet_configuration" />;
@@ -166,29 +173,6 @@
             "android.service.quickaccesswallet.action.VIEW_WALLET_SETTINGS";
 
     /**
-     * Broadcast Action: Sent by the wallet application to dismiss the Quick Access Wallet.
-     * <p>
-     * The Quick Access Wallet may be shown in a system window on top of other Activities. If the
-     * user selects a payment card from the Quick Access Wallet and then holds their phone to an NFC
-     * terminal, the wallet application will need to show a payment Activity. But if the Quick
-     * Access Wallet is still being shown, it may obscure the payment Activity. To avoid this, the
-     * wallet application can send a broadcast to the Android System with this action to request
-     * that the Quick Access Wallet be dismissed.
-     * <p>
-     * This broadcast must use the {@code android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE}
-     * permission to ensure that it is only delivered to System UI. Furthermore, your application
-     * must require the {@code android.permission.DISMISS_QUICK_ACCESS_WALLET}
-     * <p>
-     * <pre class="prettyprint">
-     * context.sendBroadcast(
-     *     new Intent(ACTION_DISMISS_WALLET), Manifest.permission.BIND_QUICK_ACCESS_WALLET_SERVICE);
-     * </pre>
-     */
-    @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_DISMISS_WALLET =
-            "android.service.quickaccesswallet.action.DISMISS_WALLET";
-
-    /**
      * Name under which a QuickAccessWalletService component publishes information about itself.
      * This meta-data should reference an XML resource containing a
      * <code>&lt;{@link
@@ -202,8 +186,20 @@
     public static final String SERVICE_META_DATA = "android.quickaccesswallet";
 
     private final Handler mHandler = new Handler(Looper.getMainLooper());
+
+    /**
+     * The service currently only supports one listener at a time. Multiple connections that
+     * register different listeners will clobber the listener. This field may only be accessed from
+     * the main thread.
+     */
     @Nullable
     private String mEventListenerId;
+
+    /**
+     * The service currently only supports one listener at a time. Multiple connections that
+     * register different listeners will clobber the listener. This field may only be accessed from
+     * the main thread.
+     */
     @Nullable
     private IQuickAccessWalletServiceCallbacks mEventListener;
 
@@ -240,7 +236,8 @@
     private void onWalletCardsRequestedInternal(
             GetWalletCardsRequest request,
             IQuickAccessWalletServiceCallbacks callback) {
-        onWalletCardsRequested(request, new GetWalletCardsCallback(callback, mHandler));
+        onWalletCardsRequested(request,
+                new GetWalletCardsCallbackImpl(request, callback, mHandler));
     }
 
     @Override
@@ -250,14 +247,14 @@
             // Binding to the QuickAccessWalletService is protected by the
             // android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE permission, which is defined in
             // R. Pre-R devices can have other side-loaded applications that claim this permission.
-            // This ensures that the service is only available when properly permission protected.
+            // Ensures that the service is only enabled when properly permission protected.
             Log.w(TAG, "Warning: binding on pre-R device");
         }
-        if (SERVICE_INTERFACE.equals(intent.getAction())) {
-            return mInterface.asBinder();
+        if (!SERVICE_INTERFACE.equals(intent.getAction())) {
+            Log.w(TAG, "Wrong action");
+            return null;
         }
-        Log.w(TAG, "Tried to bind to wrong intent (should be " + SERVICE_INTERFACE + ": " + intent);
-        return null;
+        return mInterface.asBinder();
     }
 
     /**
diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java
index 8793f28..23173a8 100644
--- a/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java
@@ -77,8 +77,9 @@
         }
 
         if (!Manifest.permission.BIND_QUICK_ACCESS_WALLET_SERVICE.equals(serviceInfo.permission)) {
-            Log.w(TAG, String.format("QuickAccessWalletService from %s does not have permission %s",
-                    serviceInfo.packageName, Manifest.permission.BIND_QUICK_ACCESS_WALLET_SERVICE));
+            Log.w(TAG, String.format("%s.%s does not require permission %s",
+                    serviceInfo.packageName, serviceInfo.name,
+                    Manifest.permission.BIND_QUICK_ACCESS_WALLET_SERVICE));
             return null;
         }
 
diff --git a/core/java/android/service/quickaccesswallet/WalletCard.java b/core/java/android/service/quickaccesswallet/WalletCard.java
index c3b1a4b..e6ae0ab 100644
--- a/core/java/android/service/quickaccesswallet/WalletCard.java
+++ b/core/java/android/service/quickaccesswallet/WalletCard.java
@@ -174,22 +174,25 @@
          * @param cardId             The card id must be non-null and unique within the list of
          *                           cards returned. <b>Note:
          *                           </b> this card ID should <b>not</b> contain PII (Personally
-         *                           Identifiable Information, * such as username or email
-         *                           address).
+         *                           Identifiable Information, such as username or email address).
          * @param cardImage          The visual representation of the card. If the card image Icon
          *                           is a bitmap, it should have a width of {@link
          *                           GetWalletCardsRequest#getCardWidthPx()} and a height of {@link
          *                           GetWalletCardsRequest#getCardHeightPx()}. If the card image
          *                           does not have these dimensions, it may appear distorted when it
-         *                           is scaled to fit these dimensions on screen.
+         *                           is scaled to fit these dimensions on screen. Bitmaps should be
+         *                           of type {@link android.graphics.Bitmap.Config#HARDWARE} for
+         *                           performance reasons.
          * @param contentDescription The content description of the card image. This field is
-         *                           required.
+         *                           required and may not be null or empty.
          *                           <b>Note: </b> this message should <b>not</b> contain PII
          *                           (Personally Identifiable Information, such as username or email
          *                           address).
          * @param pendingIntent      If the user performs a click on the card, this PendingIntent
          *                           will be sent. If the device is locked, the wallet will first
-         *                           request device unlock before sending the pending intent.
+         *                           request device unlock before sending the pending intent. It is
+         *                           recommended that the pending intent be immutable (use {@link
+         *                           PendingIntent#FLAG_IMMUTABLE}).
          */
         public Builder(@NonNull String cardId,
                 @NonNull Icon cardImage,
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 44e7ae6..c60f714 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -59,7 +59,7 @@
         DEFAULT_FLAGS = new HashMap<>();
         DEFAULT_FLAGS.put("settings_audio_switcher", "true");
         DEFAULT_FLAGS.put("settings_systemui_theme", "true");
-        DEFAULT_FLAGS.put(SETTINGS_FUSE_FLAG, "false");
+        DEFAULT_FLAGS.put(SETTINGS_FUSE_FLAG, "true");
         DEFAULT_FLAGS.put(DYNAMIC_SYSTEM, "false");
         DEFAULT_FLAGS.put(SEAMLESS_TRANSFER, "false");
         DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false");
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index f61217d..d1edf58 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -67,7 +67,7 @@
  * </ul>
  * </p><p>
  * A logical display does not necessarily represent a particular physical display device
- * such as the built-in screen or an external monitor.  The contents of a logical
+ * such as the internal display or an external display.  The contents of a logical
  * display may be presented on one or more physical displays according to the devices
  * that are currently attached and whether mirroring has been enabled.
  * </p>
@@ -104,8 +104,7 @@
     private int mCachedAppHeightCompat;
 
     /**
-     * The default Display id, which is the id of the built-in primary display
-     * assuming there is one.
+     * The default Display id, which is the id of the primary display assuming there is one.
      */
     public static final int DEFAULT_DISPLAY = 0;
 
@@ -188,7 +187,7 @@
      * Display flag: Indicates that the display is a presentation display.
      * <p>
      * This flag identifies secondary displays that are suitable for
-     * use as presentation displays such as HDMI or Wireless displays.  Applications
+     * use as presentation displays such as external or wireless displays.  Applications
      * may automatically project their content to presentation displays to provide
      * richer second screen experiences.
      * </p>
@@ -257,17 +256,17 @@
     public static final int TYPE_UNKNOWN = 0;
 
     /**
-     * Display type: Built-in display.
+     * Display type: Physical display connected through an internal port.
      * @hide
      */
-    public static final int TYPE_BUILT_IN = 1;
+    public static final int TYPE_INTERNAL = 1;
 
     /**
-     * Display type: HDMI display.
+     * Display type: Physical display connected through an external port.
      * @hide
      */
     @UnsupportedAppUsage
-    public static final int TYPE_HDMI = 2;
+    public static final int TYPE_EXTERNAL = 2;
 
     /**
      * Display type: WiFi display.
@@ -562,8 +561,8 @@
      * @return The display type.
      *
      * @see #TYPE_UNKNOWN
-     * @see #TYPE_BUILT_IN
-     * @see #TYPE_HDMI
+     * @see #TYPE_INTERNAL
+     * @see #TYPE_EXTERNAL
      * @see #TYPE_WIFI
      * @see #TYPE_OVERLAY
      * @see #TYPE_VIRTUAL
@@ -1251,10 +1250,10 @@
         switch (type) {
             case TYPE_UNKNOWN:
                 return "UNKNOWN";
-            case TYPE_BUILT_IN:
-                return "BUILT_IN";
-            case TYPE_HDMI:
-                return "HDMI";
+            case TYPE_INTERNAL:
+                return "INTERNAL";
+            case TYPE_EXTERNAL:
+                return "EXTERNAL";
             case TYPE_WIFI:
                 return "WIFI";
             case TYPE_OVERLAY:
diff --git a/core/java/android/view/HapticFeedbackConstants.java b/core/java/android/view/HapticFeedbackConstants.java
index 37b9eb3..c62e934 100644
--- a/core/java/android/view/HapticFeedbackConstants.java
+++ b/core/java/android/view/HapticFeedbackConstants.java
@@ -90,13 +90,11 @@
 
     /**
      * The user has started a gesture (e.g. on the soft keyboard).
-     * @hide
      */
     public static final int GESTURE_START = 12;
 
     /**
      * The user has finished a gesture (e.g. on the soft keyboard).
-     * @hide
      */
     public static final int GESTURE_END = 13;
 
diff --git a/core/java/android/view/InsetsAnimationControlCallbacks.java b/core/java/android/view/InsetsAnimationControlCallbacks.java
index 0645c98..5d5edec 100644
--- a/core/java/android/view/InsetsAnimationControlCallbacks.java
+++ b/core/java/android/view/InsetsAnimationControlCallbacks.java
@@ -17,8 +17,7 @@
 package android.view;
 
 import android.view.InsetsController.LayoutInsetsDuringAnimation;
-import android.view.WindowInsetsAnimationCallback.AnimationBounds;
-import android.view.WindowInsetsAnimationCallback.InsetsAnimation;
+import android.view.WindowInsetsAnimation.Bounds;
 
 /**
  * Provide an interface to let InsetsAnimationControlImpl call back into its owner.
@@ -29,15 +28,16 @@
     /**
      * Executes the necessary code to start the animation in the correct order, including:
      * <ul>
-     *     <li>Dispatch {@link WindowInsetsAnimationCallback#onPrepare}</li>
+     *     <li>Dispatch {@link WindowInsetsAnimation.Callback#onPrepare}</li>
      *     <li>Update insets state and run layout according to {@code layoutDuringAnimation}</li>
-     *     <li>Dispatch {@link WindowInsetsAnimationCallback#onStart}</li>
+     *     <li>Dispatch {@link WindowInsetsAnimation.Callback#onStart}</li>
      *     <li>Dispatch {@link WindowInsetsAnimationControlListener#onReady}</li>
      * </ul>
      */
     void startAnimation(InsetsAnimationControlImpl controller,
-            WindowInsetsAnimationControlListener listener, int types, InsetsAnimation animation,
-            AnimationBounds bounds, @LayoutInsetsDuringAnimation int layoutDuringAnimation);
+            WindowInsetsAnimationControlListener listener, int types,
+            WindowInsetsAnimation animation,
+            Bounds bounds, @LayoutInsetsDuringAnimation int layoutDuringAnimation);
 
     /**
      * Schedule the apply by posting the animation callback.
diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java
index 0653b06..0e037c2 100644
--- a/core/java/android/view/InsetsAnimationControlImpl.java
+++ b/core/java/android/view/InsetsAnimationControlImpl.java
@@ -35,8 +35,7 @@
 import android.view.InsetsState.InternalInsetsType;
 import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams;
 import android.view.WindowInsets.Type.InsetsType;
-import android.view.WindowInsetsAnimationCallback.AnimationBounds;
-import android.view.WindowInsetsAnimationCallback.InsetsAnimation;
+import android.view.WindowInsetsAnimation.Bounds;
 import android.view.WindowManager.LayoutParams;
 import android.view.animation.Interpolator;
 
@@ -67,7 +66,7 @@
     private final InsetsState mInitialInsetsState;
     private final @InsetsType int mTypes;
     private final InsetsAnimationControlCallbacks mController;
-    private final WindowInsetsAnimationCallback.InsetsAnimation mAnimation;
+    private final WindowInsetsAnimation mAnimation;
     private final Rect mFrame;
     private final boolean mFade;
     private Insets mCurrentInsets;
@@ -100,11 +99,11 @@
         mFrame = new Rect(frame);
         buildTypeSourcesMap(mTypeSideMap, mSideSourceMap, mControls);
 
-        mAnimation = new WindowInsetsAnimationCallback.InsetsAnimation(mTypes, interpolator,
+        mAnimation = new WindowInsetsAnimation(mTypes, interpolator,
                 durationMs);
         mAnimation.setAlpha(getCurrentAlpha());
         mController.startAnimation(this, listener, types, mAnimation,
-                new AnimationBounds(mHiddenInsets, mShownInsets), layoutInsetsDuringAnimation);
+                new Bounds(mHiddenInsets, mShownInsets), layoutInsetsDuringAnimation);
     }
 
     @Override
@@ -212,7 +211,7 @@
         return mCancelled;
     }
 
-    InsetsAnimation getAnimation() {
+    WindowInsetsAnimation getAnimation() {
         return mAnimation;
     }
 
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 9cd6050e..4a6a5a0 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -46,8 +46,7 @@
 import android.view.ViewTreeObserver.OnPreDrawListener;
 import android.view.WindowInsets.Type;
 import android.view.WindowInsets.Type.InsetsType;
-import android.view.WindowInsetsAnimationCallback.AnimationBounds;
-import android.view.WindowInsetsAnimationCallback.InsetsAnimation;
+import android.view.WindowInsetsAnimation.Bounds;
 import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
 import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
@@ -58,6 +57,8 @@
 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.function.BiFunction;
 
 /**
@@ -275,6 +276,9 @@
 
     private final SparseArray<InsetsSourceControl> mTmpControlArray = new SparseArray<>();
     private final ArrayList<RunningAnimation> mRunningAnimations = new ArrayList<>();
+    private final ArrayList<WindowInsetsAnimation> mRunningInsetsAnimations = new ArrayList<>();
+    private final List<WindowInsetsAnimation> mUnmodifiableRunningInsetsAnimations =
+            Collections.unmodifiableList(mRunningInsetsAnimations);
     private final ArrayList<InsetsAnimationControlImpl> mTmpFinishedControls = new ArrayList<>();
     private WindowInsets mLastInsets;
 
@@ -337,10 +341,11 @@
                     mLastInsets.shouldAlwaysConsumeSystemBars(), mLastInsets.getDisplayCutout(),
                     mLastLegacyContentInsets, mLastLegacyStableInsets, mLastLegacySoftInputMode,
                     mLastLegacySystemUiFlags, null /* typeSideMap */);
-            mViewRoot.mView.dispatchWindowInsetsAnimationProgress(insets);
+            mViewRoot.mView.dispatchWindowInsetsAnimationProgress(insets,
+                    mUnmodifiableRunningInsetsAnimations);
 
             for (int i = mTmpFinishedControls.size() - 1; i >= 0; i--) {
-                dispatchAnimationFinished(mTmpFinishedControls.get(i).getAnimation());
+                dispatchAnimationEnd(mTmpFinishedControls.get(i).getAnimation());
             }
         };
     }
@@ -579,6 +584,7 @@
                 frame, mState, listener, typesReady, this, durationMs, interpolator, fade,
                 layoutInsetsDuringAnimation);
         mRunningAnimations.add(new RunningAnimation(controller, animationType));
+        mRunningInsetsAnimations.add(controller.getAnimation());
         cancellationSignal.setOnCancelListener(controller::onCancelled);
         return cancellationSignal;
     }
@@ -729,6 +735,7 @@
         for (int i = mRunningAnimations.size() - 1; i >= 0; i--) {
             if (mRunningAnimations.get(i).control == control) {
                 mRunningAnimations.remove(i);
+                mRunningInsetsAnimations.remove(i);
                 break;
             }
         }
@@ -875,8 +882,8 @@
     @VisibleForTesting
     @Override
     public void startAnimation(InsetsAnimationControlImpl controller,
-            WindowInsetsAnimationControlListener listener, int types, InsetsAnimation animation,
-            AnimationBounds bounds, int layoutDuringAnimation) {
+            WindowInsetsAnimationControlListener listener, int types,
+            WindowInsetsAnimation animation, Bounds bounds, int layoutDuringAnimation) {
         if (layoutDuringAnimation == LAYOUT_INSETS_DURING_ANIMATION_SHOWN) {
             showDirectly(types);
         } else {
@@ -904,8 +911,8 @@
     }
 
     @VisibleForTesting
-    public void dispatchAnimationFinished(InsetsAnimation animation) {
-        mViewRoot.mView.dispatchWindowInsetsAnimationFinish(animation);
+    public void dispatchAnimationEnd(WindowInsetsAnimation animation) {
+        mViewRoot.mView.dispatchWindowInsetsAnimationEnd(animation);
     }
 
     @VisibleForTesting
diff --git a/core/java/android/view/RenderNodeAnimator.java b/core/java/android/view/RenderNodeAnimator.java
index 0c1edac..31fdfb7 100644
--- a/core/java/android/view/RenderNodeAnimator.java
+++ b/core/java/android/view/RenderNodeAnimator.java
@@ -16,518 +16,52 @@
 
 package android.view;
 
-import android.animation.Animator;
-import android.animation.TimeInterpolator;
-import android.animation.ValueAnimator;
+import android.annotation.NonNull;
 import android.graphics.CanvasProperty;
 import android.graphics.Paint;
-import android.graphics.RecordingCanvas;
-import android.graphics.RenderNode;
-import android.os.Handler;
-import android.os.Looper;
-import android.util.SparseIntArray;
-
-import com.android.internal.util.VirtualRefBasePtr;
-import com.android.internal.view.animation.FallbackLUTInterpolator;
-import com.android.internal.view.animation.HasNativeInterpolator;
-import com.android.internal.view.animation.NativeInterpolatorFactory;
-
-import java.util.ArrayList;
 
 /**
  * @hide
  */
-public class RenderNodeAnimator extends Animator {
-    // Keep in sync with enum RenderProperty in Animator.h
-    public static final int TRANSLATION_X = 0;
-    public static final int TRANSLATION_Y = 1;
-    public static final int TRANSLATION_Z = 2;
-    public static final int SCALE_X = 3;
-    public static final int SCALE_Y = 4;
-    public static final int ROTATION = 5;
-    public static final int ROTATION_X = 6;
-    public static final int ROTATION_Y = 7;
-    public static final int X = 8;
-    public static final int Y = 9;
-    public static final int Z = 10;
-    public static final int ALPHA = 11;
-    // The last value in the enum, used for array size initialization
-    public static final int LAST_VALUE = ALPHA;
+public class RenderNodeAnimator extends android.graphics.animation.RenderNodeAnimator
+        implements android.graphics.animation.RenderNodeAnimator.ViewListener {
 
-    // Keep in sync with enum PaintFields in Animator.h
-    public static final int PAINT_STROKE_WIDTH = 0;
-
-    /**
-     * Field for the Paint alpha channel, which should be specified as a value
-     * between 0 and 255.
-     */
-    public static final int PAINT_ALPHA = 1;
-
-    // ViewPropertyAnimator uses a mask for its values, we need to remap them
-    // to the enum values here. RenderPropertyAnimator can't use the mask values
-    // directly as internally it uses a lookup table so it needs the values to
-    // be sequential starting from 0
-    private static final SparseIntArray sViewPropertyAnimatorMap = new SparseIntArray(15) {{
-        put(ViewPropertyAnimator.TRANSLATION_X, TRANSLATION_X);
-        put(ViewPropertyAnimator.TRANSLATION_Y, TRANSLATION_Y);
-        put(ViewPropertyAnimator.TRANSLATION_Z, TRANSLATION_Z);
-        put(ViewPropertyAnimator.SCALE_X, SCALE_X);
-        put(ViewPropertyAnimator.SCALE_Y, SCALE_Y);
-        put(ViewPropertyAnimator.ROTATION, ROTATION);
-        put(ViewPropertyAnimator.ROTATION_X, ROTATION_X);
-        put(ViewPropertyAnimator.ROTATION_Y, ROTATION_Y);
-        put(ViewPropertyAnimator.X, X);
-        put(ViewPropertyAnimator.Y, Y);
-        put(ViewPropertyAnimator.Z, Z);
-        put(ViewPropertyAnimator.ALPHA, ALPHA);
-    }};
-
-    private VirtualRefBasePtr mNativePtr;
-
-    private Handler mHandler;
-    private RenderNode mTarget;
     private View mViewTarget;
-    private int mRenderProperty = -1;
-    private float mFinalValue;
-    private TimeInterpolator mInterpolator;
-
-    private static final int STATE_PREPARE = 0;
-    private static final int STATE_DELAYED = 1;
-    private static final int STATE_RUNNING = 2;
-    private static final int STATE_FINISHED = 3;
-    private int mState = STATE_PREPARE;
-
-    private long mUnscaledDuration = 300;
-    private long mUnscaledStartDelay = 0;
-    // If this is true, we will run any start delays on the UI thread. This is
-    // the safe default, and is necessary to ensure start listeners fire at
-    // the correct time. Animators created by RippleDrawable (the
-    // CanvasProperty<> ones) do not have this expectation, and as such will
-    // set this to false so that the renderthread handles the startdelay instead
-    private final boolean mUiThreadHandlesDelay;
-    private long mStartDelay = 0;
-    private long mStartTime;
-
-    public static int mapViewPropertyToRenderProperty(int viewProperty) {
-        return sViewPropertyAnimatorMap.get(viewProperty);
-    }
 
     public RenderNodeAnimator(int property, float finalValue) {
-        mRenderProperty = property;
-        mFinalValue = finalValue;
-        mUiThreadHandlesDelay = true;
-        init(nCreateAnimator(property, finalValue));
+        super(property, finalValue);
     }
 
     public RenderNodeAnimator(CanvasProperty<Float> property, float finalValue) {
-        init(nCreateCanvasPropertyFloatAnimator(
-                property.getNativeContainer(), finalValue));
-        mUiThreadHandlesDelay = false;
+        super(property, finalValue);
     }
 
-    /**
-     * Creates a new render node animator for a field on a Paint property.
-     *
-     * @param property The paint property to target
-     * @param paintField Paint field to animate, one of {@link #PAINT_ALPHA} or
-     *            {@link #PAINT_STROKE_WIDTH}
-     * @param finalValue The target value for the property
-     */
     public RenderNodeAnimator(CanvasProperty<Paint> property, int paintField, float finalValue) {
-        init(nCreateCanvasPropertyPaintAnimator(
-                property.getNativeContainer(), paintField, finalValue));
-        mUiThreadHandlesDelay = false;
+        super(property, paintField, finalValue);
     }
 
     public RenderNodeAnimator(int x, int y, float startRadius, float endRadius) {
-        init(nCreateRevealAnimator(x, y, startRadius, endRadius));
-        mUiThreadHandlesDelay = true;
-    }
-
-    private void init(long ptr) {
-        mNativePtr = new VirtualRefBasePtr(ptr);
-    }
-
-    private void checkMutable() {
-        if (mState != STATE_PREPARE) {
-            throw new IllegalStateException("Animator has already started, cannot change it now!");
-        }
-        if (mNativePtr == null) {
-            throw new IllegalStateException("Animator's target has been destroyed "
-                    + "(trying to modify an animation after activity destroy?)");
-        }
-    }
-
-    static boolean isNativeInterpolator(TimeInterpolator interpolator) {
-        return interpolator.getClass().isAnnotationPresent(HasNativeInterpolator.class);
-    }
-
-    private void applyInterpolator() {
-        if (mInterpolator == null || mNativePtr == null) return;
-
-        long ni;
-        if (isNativeInterpolator(mInterpolator)) {
-            ni = ((NativeInterpolatorFactory)mInterpolator).createNativeInterpolator();
-        } else {
-            long duration = nGetDuration(mNativePtr.get());
-            ni = FallbackLUTInterpolator.createNativeInterpolator(mInterpolator, duration);
-        }
-        nSetInterpolator(mNativePtr.get(), ni);
+        super(x, y, startRadius, endRadius);
     }
 
     @Override
-    public void start() {
-        if (mTarget == null) {
-            throw new IllegalStateException("Missing target!");
-        }
-
-        if (mState != STATE_PREPARE) {
-            throw new IllegalStateException("Already started!");
-        }
-
-        mState = STATE_DELAYED;
-        if (mHandler == null) {
-            mHandler = new Handler(true);
-        }
-        applyInterpolator();
-
-        if (mNativePtr == null) {
-            // It's dead, immediately cancel
-            cancel();
-        } else if (mStartDelay <= 0 || !mUiThreadHandlesDelay) {
-            nSetStartDelay(mNativePtr.get(), mStartDelay);
-            doStart();
-        } else {
-            getHelper().addDelayedAnimation(this);
-        }
-    }
-
-    private void doStart() {
+    public void onAlphaAnimationStart(float finalAlpha) {
         // Alpha is a special snowflake that has the canonical value stored
         // in mTransformationInfo instead of in RenderNode, so we need to update
         // it with the final value here.
-        if (mRenderProperty == RenderNodeAnimator.ALPHA) {
-            mViewTarget.ensureTransformationInfo();
-            mViewTarget.setAlphaInternal(mFinalValue);
-        }
-
-        moveToRunningState();
-
-        if (mViewTarget != null) {
-            // Kick off a frame to start the process
-            mViewTarget.invalidateViewProperty(true, false);
-        }
-    }
-
-    private void moveToRunningState() {
-        mState = STATE_RUNNING;
-        if (mNativePtr != null) {
-            nStart(mNativePtr.get());
-        }
-        notifyStartListeners();
-    }
-
-    private void notifyStartListeners() {
-        final ArrayList<AnimatorListener> listeners = cloneListeners();
-        final int numListeners = listeners == null ? 0 : listeners.size();
-        for (int i = 0; i < numListeners; i++) {
-            listeners.get(i).onAnimationStart(this);
-        }
+        mViewTarget.ensureTransformationInfo();
+        mViewTarget.setAlphaInternal(finalAlpha);
     }
 
     @Override
-    public void cancel() {
-        if (mState != STATE_PREPARE && mState != STATE_FINISHED) {
-            if (mState == STATE_DELAYED) {
-                getHelper().removeDelayedAnimation(this);
-                moveToRunningState();
-            }
-
-            final ArrayList<AnimatorListener> listeners = cloneListeners();
-            final int numListeners = listeners == null ? 0 : listeners.size();
-            for (int i = 0; i < numListeners; i++) {
-                listeners.get(i).onAnimationCancel(this);
-            }
-
-            end();
-        }
-    }
-
-    @Override
-    public void end() {
-        if (mState != STATE_FINISHED) {
-            if (mState < STATE_RUNNING) {
-                getHelper().removeDelayedAnimation(this);
-                doStart();
-            }
-            if (mNativePtr != null) {
-                nEnd(mNativePtr.get());
-                if (mViewTarget != null) {
-                    // Kick off a frame to flush the state change
-                    mViewTarget.invalidateViewProperty(true, false);
-                }
-            } else {
-                // It's already dead, jump to onFinish
-                onFinished();
-            }
-        }
-    }
-
-    @Override
-    public void pause() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void resume() {
-        throw new UnsupportedOperationException();
+    public void invalidateParent(boolean forceRedraw) {
+        mViewTarget.invalidateViewProperty(true, false);
     }
 
     /** @hide */
-    public void setTarget(View view) {
+    public void setTarget(@NonNull View view) {
         mViewTarget = view;
+        setViewListener(this);
         setTarget(mViewTarget.mRenderNode);
     }
-
-    /** Sets the animation target to the owning view of the RecordingCanvas */
-    public void setTarget(RecordingCanvas canvas) {
-        setTarget(canvas.mNode);
-    }
-
-    /** @hide */
-    public void setTarget(DisplayListCanvas canvas) {
-        setTarget((RecordingCanvas) canvas);
-    }
-
-    private void setTarget(RenderNode node) {
-        checkMutable();
-        if (mTarget != null) {
-            throw new IllegalStateException("Target already set!");
-        }
-        nSetListener(mNativePtr.get(), this);
-        mTarget = node;
-        mTarget.addAnimator(this);
-    }
-
-    public void setStartValue(float startValue) {
-        checkMutable();
-        nSetStartValue(mNativePtr.get(), startValue);
-    }
-
-    @Override
-    public void setStartDelay(long startDelay) {
-        checkMutable();
-        if (startDelay < 0) {
-            throw new IllegalArgumentException("startDelay must be positive; " + startDelay);
-        }
-        mUnscaledStartDelay = startDelay;
-        mStartDelay = (long) (ValueAnimator.getDurationScale() * startDelay);
-    }
-
-    @Override
-    public long getStartDelay() {
-        return mUnscaledStartDelay;
-    }
-
-    @Override
-    public RenderNodeAnimator setDuration(long duration) {
-        checkMutable();
-        if (duration < 0) {
-            throw new IllegalArgumentException("duration must be positive; " + duration);
-        }
-        mUnscaledDuration = duration;
-        nSetDuration(mNativePtr.get(), (long) (duration * ValueAnimator.getDurationScale()));
-        return this;
-    }
-
-    @Override
-    public long getDuration() {
-        return mUnscaledDuration;
-    }
-
-    @Override
-    public long getTotalDuration() {
-        return mUnscaledDuration + mUnscaledStartDelay;
-    }
-
-    @Override
-    public boolean isRunning() {
-        return mState == STATE_DELAYED || mState == STATE_RUNNING;
-    }
-
-    @Override
-    public boolean isStarted() {
-        return mState != STATE_PREPARE;
-    }
-
-    @Override
-    public void setInterpolator(TimeInterpolator interpolator) {
-        checkMutable();
-        mInterpolator = interpolator;
-    }
-
-    @Override
-    public TimeInterpolator getInterpolator() {
-        return mInterpolator;
-    }
-
-    protected void onFinished() {
-        if (mState == STATE_PREPARE) {
-            // Unlikely but possible, the native side has been destroyed
-            // before we have started.
-            releaseNativePtr();
-            return;
-        }
-        if (mState == STATE_DELAYED) {
-            getHelper().removeDelayedAnimation(this);
-            notifyStartListeners();
-        }
-        mState = STATE_FINISHED;
-
-        final ArrayList<AnimatorListener> listeners = cloneListeners();
-        final int numListeners = listeners == null ? 0 : listeners.size();
-        for (int i = 0; i < numListeners; i++) {
-            listeners.get(i).onAnimationEnd(this);
-        }
-
-        // Release the native object, as it has a global reference to us. This
-        // breaks the cyclic reference chain, and allows this object to be
-        // GC'd
-        releaseNativePtr();
-    }
-
-    private void releaseNativePtr() {
-        if (mNativePtr != null) {
-            mNativePtr.release();
-            mNativePtr = null;
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    private ArrayList<AnimatorListener> cloneListeners() {
-        ArrayList<AnimatorListener> listeners = getListeners();
-        if (listeners != null) {
-            listeners = (ArrayList<AnimatorListener>) listeners.clone();
-        }
-        return listeners;
-    }
-
-    public long getNativeAnimator() {
-        return mNativePtr.get();
-    }
-
-    /**
-     * @return true if the animator was started, false if still delayed
-     */
-    private boolean processDelayed(long frameTimeMs) {
-        if (mStartTime == 0) {
-            mStartTime = frameTimeMs;
-        } else if ((frameTimeMs - mStartTime) >= mStartDelay) {
-            doStart();
-            return true;
-        }
-        return false;
-    }
-
-    private static DelayedAnimationHelper getHelper() {
-        DelayedAnimationHelper helper = sAnimationHelper.get();
-        if (helper == null) {
-            helper = new DelayedAnimationHelper();
-            sAnimationHelper.set(helper);
-        }
-        return helper;
-    }
-
-    private static ThreadLocal<DelayedAnimationHelper> sAnimationHelper =
-            new ThreadLocal<DelayedAnimationHelper>();
-
-    private static class DelayedAnimationHelper implements Runnable {
-
-        private ArrayList<RenderNodeAnimator> mDelayedAnims = new ArrayList<RenderNodeAnimator>();
-        private final Choreographer mChoreographer;
-        private boolean mCallbackScheduled;
-
-        public DelayedAnimationHelper() {
-            mChoreographer = Choreographer.getInstance();
-        }
-
-        public void addDelayedAnimation(RenderNodeAnimator animator) {
-            mDelayedAnims.add(animator);
-            scheduleCallback();
-        }
-
-        public void removeDelayedAnimation(RenderNodeAnimator animator) {
-            mDelayedAnims.remove(animator);
-        }
-
-        private void scheduleCallback() {
-            if (!mCallbackScheduled) {
-                mCallbackScheduled = true;
-                mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, this, null);
-            }
-        }
-
-        @Override
-        public void run() {
-            long frameTimeMs = mChoreographer.getFrameTime();
-            mCallbackScheduled = false;
-
-            int end = 0;
-            for (int i = 0; i < mDelayedAnims.size(); i++) {
-                RenderNodeAnimator animator = mDelayedAnims.get(i);
-                if (!animator.processDelayed(frameTimeMs)) {
-                    if (end != i) {
-                        mDelayedAnims.set(end, animator);
-                    }
-                    end++;
-                }
-            }
-            while (mDelayedAnims.size() > end) {
-                mDelayedAnims.remove(mDelayedAnims.size() - 1);
-            }
-
-            if (mDelayedAnims.size() > 0) {
-                scheduleCallback();
-            }
-        }
-    }
-
-    // Called by native
-    private static void callOnFinished(RenderNodeAnimator animator) {
-        if (animator.mHandler != null) {
-            animator.mHandler.post(animator::onFinished);
-        } else {
-            new Handler(Looper.getMainLooper(), null, true).post(animator::onFinished);
-        }
-    }
-
-    @Override
-    public Animator clone() {
-        throw new IllegalStateException("Cannot clone this animator");
-    }
-
-    @Override
-    public void setAllowRunningAsynchronously(boolean mayRunAsync) {
-        checkMutable();
-        nSetAllowRunningAsync(mNativePtr.get(), mayRunAsync);
-    }
-
-    private static native long nCreateAnimator(int property, float finalValue);
-    private static native long nCreateCanvasPropertyFloatAnimator(
-            long canvasProperty, float finalValue);
-    private static native long nCreateCanvasPropertyPaintAnimator(
-            long canvasProperty, int paintField, float finalValue);
-    private static native long nCreateRevealAnimator(
-            int x, int y, float startRadius, float endRadius);
-
-    private static native void nSetStartValue(long nativePtr, float startValue);
-    private static native void nSetDuration(long nativePtr, long duration);
-    private static native long nGetDuration(long nativePtr);
-    private static native void nSetStartDelay(long nativePtr, long startDelay);
-    private static native void nSetInterpolator(long animPtr, long interpolatorPtr);
-    private static native void nSetAllowRunningAsync(long animPtr, boolean mayRunAsync);
-    private static native void nSetListener(long animPtr, RenderNodeAnimator listener);
-
-    private static native void nStart(long animPtr);
-    private static native void nEnd(long animPtr);
 }
diff --git a/core/java/android/view/RenderNodeAnimatorSetHelper.java b/core/java/android/view/RenderNodeAnimatorSetHelper.java
deleted file mode 100644
index d222e07..0000000
--- a/core/java/android/view/RenderNodeAnimatorSetHelper.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.view;
-
-import android.animation.TimeInterpolator;
-import android.graphics.RecordingCanvas;
-import android.graphics.RenderNode;
-
-import com.android.internal.view.animation.FallbackLUTInterpolator;
-import com.android.internal.view.animation.NativeInterpolatorFactory;
-import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
-
-/**
- * This is a helper class to get access to methods and fields needed for RenderNodeAnimatorSet
- * that are internal or package private to android.view package.
- *
- * @hide
- */
-public class RenderNodeAnimatorSetHelper {
-
-    /** checkstyle @hide */
-    public static RenderNode getTarget(RecordingCanvas recordingCanvas) {
-        return recordingCanvas.mNode;
-    }
-
-    /** checkstyle @hide */
-    public static long createNativeInterpolator(TimeInterpolator interpolator, long
-            duration) {
-        if (interpolator == null) {
-            // create LinearInterpolator
-            return NativeInterpolatorFactoryHelper.createLinearInterpolator();
-        } else if (RenderNodeAnimator.isNativeInterpolator(interpolator)) {
-            return ((NativeInterpolatorFactory)interpolator).createNativeInterpolator();
-        } else {
-            return FallbackLUTInterpolator.createNativeInterpolator(interpolator, duration);
-        }
-    }
-
-}
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index fe9e36e..cf48c52 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -321,14 +321,12 @@
     public static final int FX_SURFACE_NORMAL   = 0x00000000;
 
     /**
-     * Surface creation flag: Creates a Dim surface.
-     * Everything behind this surface is dimmed by the amount specified
-     * in {@link Transaction#setAlpha(SurfaceControl, float)}.  It is an error to lock a Dim
-     * surface, since it doesn't have a backing store.
+     * Surface creation flag: Creates a effect surface which
+     * represents a solid color and or shadows.
      *
      * @hide
      */
-    public static final int FX_SURFACE_DIM = 0x00020000;
+    public static final int FX_SURFACE_EFFECT = 0x00020000;
 
     /**
      * Surface creation flag: Creates a container surface.
@@ -739,11 +737,11 @@
          */
         public Builder setColorLayer() {
             unsetBufferSize();
-            return setFlags(FX_SURFACE_DIM, FX_SURFACE_MASK);
+            return setFlags(FX_SURFACE_EFFECT, FX_SURFACE_MASK);
         }
 
         private boolean isColorLayerSet() {
-            return  (mFlags & FX_SURFACE_DIM) == FX_SURFACE_DIM;
+            return  (mFlags & FX_SURFACE_EFFECT) == FX_SURFACE_EFFECT;
         }
 
         /**
@@ -1285,12 +1283,15 @@
      * @hide
      */
     public static final class DisplayInfo {
+        public boolean isInternal;
         public float density;
         public boolean secure;
 
         @Override
         public String toString() {
-            return "DisplayInfo{density=" + density + ", secure=" + secure + "}";
+            return "DisplayInfo{isInternal=" + isInternal
+                    + ", density=" + density
+                    + ", secure=" + secure + "}";
         }
     }
 
@@ -2075,6 +2076,7 @@
 
         private final ArrayMap<SurfaceControl, Point> mResizedSurfaces = new ArrayMap<>();
         Runnable mFreeNativeResources;
+        private static final float[] INVALID_COLOR = {-1, -1, -1};
 
         /**
          * @hide
@@ -2530,8 +2532,9 @@
         }
 
         /**
-         * Sets a color for the Surface.
-         * @param color A float array with three values to represent r, g, b in range [0..1]
+         * Fills the surface with the specified color.
+         * @param color A float array with three values to represent r, g, b in range [0..1]. An
+         * invalid color will remove the color fill.
          * @hide
          */
         @UnsupportedAppUsage
@@ -2542,6 +2545,16 @@
         }
 
         /**
+         * Removes color fill.
+        * @hide
+        */
+        public Transaction unsetColor(SurfaceControl sc) {
+            checkPreconditions(sc);
+            nativeSetColor(mNativeObject, sc.mNativeObject, INVALID_COLOR);
+            return this;
+        }
+
+        /**
          * Sets the security of the surface.  Setting the flag is equivalent to creating the
          * Surface with the {@link #SECURE} flag.
          * @hide
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 47ffd3e..5566e0e 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -1643,8 +1643,9 @@
     }
 
     private void updateScreenMatrixForEmbeddedHierarchy() {
+        getBoundsOnScreen(mTmpRect, true);
         mTmpMatrix.reset();
-        mTmpMatrix.setTranslate(mScreenRect.left, mScreenRect.top);
+        mTmpMatrix.setTranslate(mTmpRect.left, mTmpRect.top);
         mTmpMatrix.postScale(mScreenRect.width() / (float) mSurfaceWidth,
                 mScreenRect.height() / (float) mSurfaceHeight);
 
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index f99c965..c7f850a 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -112,8 +112,7 @@
 import android.view.ContextMenu.ContextMenuInfo;
 import android.view.Window.OnContentApplyWindowInsetsListener;
 import android.view.WindowInsets.Type;
-import android.view.WindowInsetsAnimationCallback.AnimationBounds;
-import android.view.WindowInsetsAnimationCallback.InsetsAnimation;
+import android.view.WindowInsetsAnimation.Bounds;
 import android.view.WindowManager.LayoutParams;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityEventSource;
@@ -4672,7 +4671,7 @@
 
         private ArrayList<OnUnhandledKeyEventListener> mUnhandledKeyListeners;
 
-        WindowInsetsAnimationCallback mWindowInsetsAnimationCallback;
+        WindowInsetsAnimation.Callback mWindowInsetsAnimationCallback;
 
         /**
          * This lives here since it's only valid for interactive views.
@@ -11200,43 +11199,45 @@
     }
 
     /**
-     * Sets a {@link WindowInsetsAnimationCallback} to be notified about animations of windows that
+     * Sets a {@link WindowInsetsAnimation.Callback} to be notified about animations of windows that
      * cause insets.
      * <p>
-     * When setting a listener, it's {@link WindowInsetsAnimationCallback#getDispatchMode() dispatch
-     * mode} will be retrieved and recorded until another listener will be set.
+     * The callback's {@link WindowInsetsAnimation.Callback#getDispatchMode()
+     * dispatch mode} will affect whether animation callbacks are dispatched to the children of
+     * this view.
      * </p>
-     * @param listener The listener to set.
+     * @param callback The callback to set.
      */
-    public void setWindowInsetsAnimationCallback(@Nullable WindowInsetsAnimationCallback listener) {
-        getListenerInfo().mWindowInsetsAnimationCallback = listener;
+    public void setWindowInsetsAnimationCallback(
+            @Nullable WindowInsetsAnimation.Callback callback) {
+        getListenerInfo().mWindowInsetsAnimationCallback = callback;
     }
 
     /**
-     * Dispatches {@link WindowInsetsAnimationCallback#onPrepare(InsetsAnimation)}
+     * Dispatches {@link WindowInsetsAnimation.Callback#onPrepare(WindowInsetsAnimation)}
      * when Window Insets animation is being prepared.
      * @param animation current animation
      *
-     * @see WindowInsetsAnimationCallback#onPrepare(InsetsAnimation)
+     * @see WindowInsetsAnimation.Callback#onPrepare(WindowInsetsAnimation)
      */
     public void dispatchWindowInsetsAnimationPrepare(
-            @NonNull InsetsAnimation animation) {
+            @NonNull WindowInsetsAnimation animation) {
         if (mListenerInfo != null && mListenerInfo.mWindowInsetsAnimationCallback != null) {
             mListenerInfo.mWindowInsetsAnimationCallback.onPrepare(animation);
         }
     }
 
     /**
-     * Dispatches {@link WindowInsetsAnimationCallback#onStart(InsetsAnimation, AnimationBounds)}
+     * Dispatches {@link WindowInsetsAnimation.Callback#onStart(WindowInsetsAnimation, Bounds)}
      * when Window Insets animation is started.
      * @param animation current animation
-     * @param bounds the upper and lower {@link AnimationBounds} that provides range of
-     *  {@link InsetsAnimation}.
-     * @return the upper and lower {@link AnimationBounds}.
+     * @param bounds the upper and lower {@link Bounds} that provides range of
+     *  {@link WindowInsetsAnimation}.
+     * @return the upper and lower {@link Bounds}.
      */
     @NonNull
-    public AnimationBounds dispatchWindowInsetsAnimationStart(
-            @NonNull InsetsAnimation animation, @NonNull AnimationBounds bounds) {
+    public Bounds dispatchWindowInsetsAnimationStart(
+            @NonNull WindowInsetsAnimation animation, @NonNull Bounds bounds) {
         if (mListenerInfo != null && mListenerInfo.mWindowInsetsAnimationCallback != null) {
             return mListenerInfo.mWindowInsetsAnimationCallback.onStart(animation, bounds);
         }
@@ -11244,28 +11245,31 @@
     }
 
     /**
-     * Dispatches {@link WindowInsetsAnimationCallback#onProgress(WindowInsets)}
+     * Dispatches {@link WindowInsetsAnimation.Callback#onProgress(WindowInsets, List)}
      * when Window Insets animation makes progress.
      * @param insets The current {@link WindowInsets}.
+     * @param runningAnimations The currently running {@link WindowInsetsAnimation}s.
      * @return current {@link WindowInsets}.
      */
     @NonNull
-    public WindowInsets dispatchWindowInsetsAnimationProgress(@NonNull WindowInsets insets) {
+    public WindowInsets dispatchWindowInsetsAnimationProgress(@NonNull WindowInsets insets,
+            @NonNull List<WindowInsetsAnimation> runningAnimations) {
         if (mListenerInfo != null && mListenerInfo.mWindowInsetsAnimationCallback != null) {
-            return mListenerInfo.mWindowInsetsAnimationCallback.onProgress(insets);
+            return mListenerInfo.mWindowInsetsAnimationCallback.onProgress(insets,
+                    runningAnimations);
         } else {
             return insets;
         }
     }
 
     /**
-     * Dispatches {@link WindowInsetsAnimationCallback#onFinish(InsetsAnimation)}
-     * when Window Insets animation finishes.
-     * @param animation The current ongoing {@link InsetsAnimation}.
+     * Dispatches {@link WindowInsetsAnimation.Callback#onEnd(WindowInsetsAnimation)}
+     * when Window Insets animation ends.
+     * @param animation The current ongoing {@link WindowInsetsAnimation}.
      */
-    public void dispatchWindowInsetsAnimationFinish(@NonNull InsetsAnimation animation) {
+    public void dispatchWindowInsetsAnimationEnd(@NonNull WindowInsetsAnimation animation) {
         if (mListenerInfo != null && mListenerInfo.mWindowInsetsAnimationCallback != null) {
-            mListenerInfo.mWindowInsetsAnimationCallback.onFinish(animation);
+            mListenerInfo.mWindowInsetsAnimationCallback.onEnd(animation);
         }
     }
 
@@ -28787,11 +28791,6 @@
         int mDisabledSystemUiVisibility;
 
         /**
-         * Last global system UI visibility reported by the window manager.
-         */
-        int mGlobalSystemUiVisibility = -1;
-
-        /**
          * True if a view in this hierarchy has an OnSystemUiVisibilityChangeListener
          * attached.
          */
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index d416d42..0367536 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -17,8 +17,8 @@
 package android.view;
 
 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
-import static android.view.WindowInsetsAnimationCallback.DISPATCH_MODE_CONTINUE_ON_SUBTREE;
-import static android.view.WindowInsetsAnimationCallback.DISPATCH_MODE_STOP;
+import static android.view.WindowInsetsAnimation.Callback.DISPATCH_MODE_CONTINUE_ON_SUBTREE;
+import static android.view.WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP;
 
 import android.animation.LayoutTransition;
 import android.annotation.CallSuper;
@@ -48,17 +48,14 @@
 import android.os.Bundle;
 import android.os.Parcelable;
 import android.os.SystemClock;
-import android.util.ArraySet;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Pools;
 import android.util.Pools.SynchronizedPool;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
-import android.view.Window.OnContentApplyWindowInsetsListener;
-import android.view.WindowInsetsAnimationCallback.AnimationBounds;
-import android.view.WindowInsetsAnimationCallback.DispatchMode;
-import android.view.WindowInsetsAnimationCallback.InsetsAnimation;
+import android.view.WindowInsetsAnimation.Bounds;
+import android.view.WindowInsetsAnimation.Callback.DispatchMode;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
@@ -615,7 +612,7 @@
     /**
      * Current dispatch mode of animation events
      *
-     * @see WindowInsetsAnimationCallback#getDispatchMode()
+     * @see WindowInsetsAnimation.Callback#getDispatchMode()
      */
     private @DispatchMode int mInsetsAnimationDispatchMode = DISPATCH_MODE_CONTINUE_ON_SUBTREE;
 
@@ -7228,16 +7225,17 @@
     }
 
     @Override
-    public void setWindowInsetsAnimationCallback(@Nullable WindowInsetsAnimationCallback listener) {
-        super.setWindowInsetsAnimationCallback(listener);
-        mInsetsAnimationDispatchMode = listener != null
-                ? listener.getDispatchMode()
+    public void setWindowInsetsAnimationCallback(
+            @Nullable WindowInsetsAnimation.Callback callback) {
+        super.setWindowInsetsAnimationCallback(callback);
+        mInsetsAnimationDispatchMode = callback != null
+                ? callback.getDispatchMode()
                 : DISPATCH_MODE_CONTINUE_ON_SUBTREE;
     }
 
     @Override
     public void dispatchWindowInsetsAnimationPrepare(
-            @NonNull InsetsAnimation animation) {
+            @NonNull WindowInsetsAnimation animation) {
         super.dispatchWindowInsetsAnimationPrepare(animation);
 
         // If we are root-level content view that fits insets, set dispatch mode to stop to imitate
@@ -7262,8 +7260,8 @@
 
     @Override
     @NonNull
-    public AnimationBounds dispatchWindowInsetsAnimationStart(
-            @NonNull InsetsAnimation animation, @NonNull AnimationBounds bounds) {
+    public Bounds dispatchWindowInsetsAnimationStart(
+            @NonNull WindowInsetsAnimation animation, @NonNull Bounds bounds) {
         bounds = super.dispatchWindowInsetsAnimationStart(animation, bounds);
         if (mInsetsAnimationDispatchMode == DISPATCH_MODE_STOP) {
             return bounds;
@@ -7277,27 +7275,28 @@
 
     @Override
     @NonNull
-    public WindowInsets dispatchWindowInsetsAnimationProgress(@NonNull WindowInsets insets) {
-        insets = super.dispatchWindowInsetsAnimationProgress(insets);
+    public WindowInsets dispatchWindowInsetsAnimationProgress(@NonNull WindowInsets insets,
+            @NonNull List<WindowInsetsAnimation> runningAnimations) {
+        insets = super.dispatchWindowInsetsAnimationProgress(insets, runningAnimations);
         if (mInsetsAnimationDispatchMode == DISPATCH_MODE_STOP) {
             return insets;
         }
         final int count = getChildCount();
         for (int i = 0; i < count; i++) {
-            getChildAt(i).dispatchWindowInsetsAnimationProgress(insets);
+            getChildAt(i).dispatchWindowInsetsAnimationProgress(insets, runningAnimations);
         }
         return insets;
     }
 
     @Override
-    public void dispatchWindowInsetsAnimationFinish(@NonNull InsetsAnimation animation) {
-        super.dispatchWindowInsetsAnimationFinish(animation);
+    public void dispatchWindowInsetsAnimationEnd(@NonNull WindowInsetsAnimation animation) {
+        super.dispatchWindowInsetsAnimationEnd(animation);
         if (mInsetsAnimationDispatchMode == DISPATCH_MODE_STOP) {
             return;
         }
         final int count = getChildCount();
         for (int i = 0; i < count; i++) {
-            getChildAt(i).dispatchWindowInsetsAnimationFinish(animation);
+            getChildAt(i).dispatchWindowInsetsAnimationEnd(animation);
         }
     }
 
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index b971a20..e9a12a8 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -436,6 +436,8 @@
     @UnsupportedAppUsage
     final View.AttachInfo mAttachInfo;
     final SystemUiVisibilityInfo mCompatibleVisibilityInfo;
+    int mDispatchedSystemUiVisibility =
+            ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_FULL ? 0 : -1;
     InputQueue.Callback mInputQueueCallback;
     InputQueue mInputQueue;
     @UnsupportedAppUsage
@@ -1705,12 +1707,13 @@
     }
 
     Surface getOrCreateBLASTSurface(int width, int height) {
-        if (mSurfaceControl == null || !mSurfaceControl.isValid()) {
+        if (mSurfaceControl == null
+                || !mSurfaceControl.isValid()
+                || mBlastSurfaceControl == null
+                || !mBlastSurfaceControl.isValid()) {
             return null;
         }
-        if ((mBlastSurfaceControl != null)
-                && (mBlastBufferQueue == null)
-                && mBlastSurfaceControl.isValid()) {
+        if (mBlastBufferQueue == null) {
             mBlastBufferQueue = new BLASTBufferQueue(
                 mBlastSurfaceControl, width, height);
         }
@@ -1945,11 +1948,33 @@
         } else {
             info.globalVisibility |= systemUiFlag;
         }
-        if (mAttachInfo.mGlobalSystemUiVisibility != info.globalVisibility) {
+        if (mDispatchedSystemUiVisibility != info.globalVisibility) {
             scheduleTraversals();
         }
     }
 
+    private void handleDispatchSystemUiVisibilityChanged(SystemUiVisibilityInfo args) {
+        if (mSeq != args.seq && sNewInsetsMode != NEW_INSETS_MODE_FULL) {
+            // The sequence has changed, so we need to update our value and make
+            // sure to do a traversal afterward so the window manager is given our
+            // most recent data.
+            mSeq = args.seq;
+            mAttachInfo.mForceReportNewAttributes = true;
+            scheduleTraversals();
+        }
+        if (mView == null) return;
+        if (args.localChanges != 0) {
+            mView.updateLocalSystemUiVisibility(args.localValue, args.localChanges);
+            args.localChanges = 0;
+        }
+
+        final int visibility = args.globalVisibility & View.SYSTEM_UI_CLEARABLE_FLAGS;
+        if (mDispatchedSystemUiVisibility != visibility) {
+            mDispatchedSystemUiVisibility = visibility;
+            mView.dispatchSystemUiVisibilityChanged(visibility);
+        }
+    }
+
     @VisibleForTesting
     public static void adjustLayoutParamsForCompatibility(WindowManager.LayoutParams inOutParams) {
         if (sNewInsetsMode != NEW_INSETS_MODE_FULL) {
@@ -7182,28 +7207,6 @@
         event.recycle();
     }
 
-    public void handleDispatchSystemUiVisibilityChanged(SystemUiVisibilityInfo args) {
-        if (mSeq != args.seq && sNewInsetsMode != NEW_INSETS_MODE_FULL) {
-            // The sequence has changed, so we need to update our value and make
-            // sure to do a traversal afterward so the window manager is given our
-            // most recent data.
-            mSeq = args.seq;
-            mAttachInfo.mForceReportNewAttributes = true;
-            scheduleTraversals();
-        }
-        if (mView == null) return;
-        if (args.localChanges != 0) {
-            mView.updateLocalSystemUiVisibility(args.localValue, args.localChanges);
-            args.localChanges = 0;
-        }
-
-        int visibility = args.globalVisibility&View.SYSTEM_UI_CLEARABLE_FLAGS;
-        if (visibility != mAttachInfo.mGlobalSystemUiVisibility) {
-            mAttachInfo.mGlobalSystemUiVisibility = visibility;
-            mView.dispatchSystemUiVisibilityChanged(visibility);
-        }
-    }
-
     /**
      * Notify that the window title changed
      */
@@ -8373,6 +8376,7 @@
         mHandler.sendMessage(msg);
     }
 
+    // TODO(118118435): Remove this after migration
     public void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility,
             int localValue, int localChanges) {
         SystemUiVisibilityInfo args = new SystemUiVisibilityInfo();
diff --git a/core/java/android/view/WindowInsetsAnimation.java b/core/java/android/view/WindowInsetsAnimation.java
new file mode 100644
index 0000000..396da4a
--- /dev/null
+++ b/core/java/android/view/WindowInsetsAnimation.java
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.annotation.FloatRange;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.graphics.Insets;
+import android.view.animation.Interpolator;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+
+/**
+ * Class representing an animation of a set of windows that cause insets.
+ */
+public final class WindowInsetsAnimation {
+
+    @WindowInsets.Type.InsetsType
+    private final int mTypeMask;
+    private float mFraction;
+    @Nullable
+    private final Interpolator mInterpolator;
+    private final long mDurationMillis;
+    private float mAlpha;
+
+    /**
+     * Creates a new {@link WindowInsetsAnimation} object.
+     * <p>
+     * This should only be used for testing, as usually the system creates this object for the
+     * application to listen to with {@link Callback}.
+     * </p>
+     * @param typeMask The bitmask of {@link WindowInsets.Type}s that are animating.
+     * @param interpolator The interpolator of the animation.
+     * @param durationMillis The duration of the animation in
+     *                   {@link java.util.concurrent.TimeUnit#MILLISECONDS}.
+     */
+    public WindowInsetsAnimation(
+            @WindowInsets.Type.InsetsType int typeMask, @Nullable Interpolator interpolator,
+            long durationMillis) {
+        mTypeMask = typeMask;
+        mInterpolator = interpolator;
+        mDurationMillis = durationMillis;
+    }
+
+    /**
+     * @return The bitmask of {@link WindowInsets.Type.InsetsType}s that are animating.
+     */
+    @WindowInsets.Type.InsetsType
+    public int getTypeMask() {
+        return mTypeMask;
+    }
+
+    /**
+     * Returns the raw fractional progress of this animation between
+     * start state of the animation and the end state of the animation. Note
+     * that this progress is the global progress of the animation, whereas
+     * {@link Callback#onProgress} will only dispatch the insets that may
+     * be inset with {@link WindowInsets#inset} by parents of views in the hierarchy.
+     * Progress per insets animation is global for the entire animation. One animation animates
+     * all things together (in, out, ...). If they don't animate together, we'd have
+     * multiple animations.
+     * <p>
+     * Note: In case the application is controlling the animation, the valued returned here will
+     * be the same as the application passed into
+     * {@link WindowInsetsAnimationController#setInsetsAndAlpha(Insets, float, float)}.
+     * </p>
+     * @return The current progress of this animation.
+     */
+    @FloatRange(from = 0f, to = 1f)
+    public float getFraction() {
+        return mFraction;
+    }
+
+    /**
+     * Returns the interpolated fractional progress of this animation between
+     * start state of the animation and the end state of the animation. Note
+     * that this progress is the global progress of the animation, whereas
+     * {@link Callback#onProgress} will only dispatch the insets that may
+     * be inset with {@link WindowInsets#inset} by parents of views in the hierarchy.
+     * Progress per insets animation is global for the entire animation. One animation animates
+     * all things together (in, out, ...). If they don't animate together, we'd have
+     * multiple animations.
+     * <p>
+     * Note: In case the application is controlling the animation, the valued returned here will
+     * be the same as the application passed into
+     * {@link WindowInsetsAnimationController#setInsetsAndAlpha(Insets, float, float)},
+     * interpolated with the interpolator passed into
+     * {@link WindowInsetsController#controlWindowInsetsAnimation}.
+     * </p>
+     * <p>
+     * Note: For system-initiated animations, this will always return a valid value between 0
+     * and 1.
+     * </p>
+     * @see #getFraction() for raw fraction.
+     * @return The current interpolated progress of this animation. -1 if interpolator isn't
+     *         specified.
+     */
+    public float getInterpolatedFraction() {
+        if (mInterpolator != null) {
+            return mInterpolator.getInterpolation(mFraction);
+        }
+        return -1;
+    }
+
+    /**
+     * Retrieves the interpolator used for this animation, or {@code null} if this animation
+     * doesn't follow an interpolation curved. For system-initiated animations, this will never
+     * return {@code null}.
+     *
+     * @return The interpolator used for this animation.
+     */
+    @Nullable
+    public Interpolator getInterpolator() {
+        return mInterpolator;
+    }
+
+    /**
+     * @return duration of animation in {@link java.util.concurrent.TimeUnit#MILLISECONDS}, or
+     *         -1 if the animation doesn't have a fixed duration.
+     */
+    public long getDurationMillis() {
+        return mDurationMillis;
+    }
+
+    /**
+     * Set fraction of the progress if {@link WindowInsets.Type.InsetsType} animation is
+     * controlled by the app.
+     * <p>
+     * Note: This should only be used for testing, as the system fills in the fraction for the
+     * application or the fraction that was passed into
+     * {@link WindowInsetsAnimationController#setInsetsAndAlpha(Insets, float, float)} is being
+     * used.
+     * </p>
+     * @param fraction fractional progress between 0 and 1 where 0 represents hidden and
+     *                zero progress and 1 represent fully shown final state.
+     * @see #getFraction()
+     */
+    public void setFraction(@FloatRange(from = 0f, to = 1f) float fraction) {
+        mFraction = fraction;
+    }
+
+    /**
+     * Retrieves the translucency of the windows that are animating.
+     *
+     * @return Alpha of windows that cause insets of type {@link WindowInsets.Type.InsetsType}.
+     */
+    @FloatRange(from = 0f, to = 1f)
+    public float getAlpha() {
+        return mAlpha;
+    }
+
+    /**
+     * Sets the translucency of the windows that are animating.
+     * <p>
+     * Note: This should only be used for testing, as the system fills in the alpha for the
+     * application or the alpha that was passed into
+     * {@link WindowInsetsAnimationController#setInsetsAndAlpha(Insets, float, float)} is being
+     * used.
+     * </p>
+     * @param alpha Alpha of windows that cause insets of type
+     *              {@link WindowInsets.Type.InsetsType}.
+     * @see #getAlpha()
+     */
+    public void setAlpha(@FloatRange(from = 0f, to = 1f) float alpha) {
+        mAlpha = alpha;
+    }
+
+    /**
+     * Class representing the range of an {@link WindowInsetsAnimation}
+     */
+    public static final class Bounds {
+
+        private final Insets mLowerBound;
+        private final Insets mUpperBound;
+
+        public Bounds(@NonNull Insets lowerBound, @NonNull Insets upperBound) {
+            mLowerBound = lowerBound;
+            mUpperBound = upperBound;
+        }
+
+        /**
+         * Queries the lower inset bound of the animation. If the animation is about showing or
+         * hiding a window that cause insets, the lower bound is {@link Insets#NONE} and the upper
+         * bound is the same as {@link WindowInsets#getInsets(int)} for the fully shown state. This
+         * is the same as {@link WindowInsetsAnimationController#getHiddenStateInsets} and
+         * {@link WindowInsetsAnimationController#getShownStateInsets} in case the listener gets
+         * invoked because of an animation that originates from
+         * {@link WindowInsetsAnimationController}.
+         * <p>
+         * However, if the size of a window that causes insets is changing, these are the
+         * lower/upper bounds of that size animation.
+         * </p>
+         * There are no overlapping animations for a specific type, but there may be multiple
+         * animations running at the same time for different inset types.
+         *
+         * @see #getUpperBound()
+         * @see WindowInsetsAnimationController#getHiddenStateInsets
+         */
+        @NonNull
+        public Insets getLowerBound() {
+            return mLowerBound;
+        }
+
+        /**
+         * Queries the upper inset bound of the animation. If the animation is about showing or
+         * hiding a window that cause insets, the lower bound is {@link Insets#NONE}
+         * nd the upper bound is the same as {@link WindowInsets#getInsets(int)} for the fully
+         * shown state. This is the same as
+         * {@link WindowInsetsAnimationController#getHiddenStateInsets} and
+         * {@link WindowInsetsAnimationController#getShownStateInsets} in case the listener gets
+         * invoked because of an animation that originates from
+         * {@link WindowInsetsAnimationController}.
+         * <p>
+         * However, if the size of a window that causes insets is changing, these are the
+         * lower/upper bounds of that size animation.
+         * <p>
+         * There are no overlapping animations for a specific type, but there may be multiple
+         * animations running at the same time for different inset types.
+         *
+         * @see #getLowerBound()
+         * @see WindowInsetsAnimationController#getShownStateInsets
+         */
+        @NonNull
+        public Insets getUpperBound() {
+            return mUpperBound;
+        }
+
+        /**
+         * Insets both the lower and upper bound by the specified insets. This is to be used in
+         * {@link Callback#onStart} to indicate that a part of the insets has
+         * been used to offset or clip its children, and the children shouldn't worry about that
+         * part anymore.
+         *
+         * @param insets The amount to inset.
+         * @return A copy of this instance inset in the given directions.
+         * @see WindowInsets#inset
+         * @see Callback#onStart
+         */
+        @NonNull
+        public Bounds inset(@NonNull Insets insets) {
+            return new Bounds(
+                    // TODO: refactor so that WindowInsets.insetInsets() is in a more appropriate
+                    //  place eventually.
+                    WindowInsets.insetInsets(
+                            mLowerBound, insets.left, insets.top, insets.right, insets.bottom),
+                    WindowInsets.insetInsets(
+                            mUpperBound, insets.left, insets.top, insets.right, insets.bottom));
+        }
+    }
+
+    /**
+     * Interface that allows the application to listen to animation events for windows that cause
+     * insets.
+     */
+    @SuppressLint("CallbackMethodName") // TODO(b/149430296) Should be on method, not class.
+    public abstract static class Callback {
+
+        /**
+         * Return value for {@link #getDispatchMode()}: Dispatching of animation events should
+         * stop at this level in the view hierarchy, and no animation events should be dispatch to
+         * the subtree of the view hierarchy.
+         */
+        public static final int DISPATCH_MODE_STOP = 0;
+
+        /**
+         * Return value for {@link #getDispatchMode()}: Dispatching of animation events should
+         * continue in the view hierarchy.
+         */
+        public static final int DISPATCH_MODE_CONTINUE_ON_SUBTREE = 1;
+
+        /** @hide */
+        @IntDef(prefix = { "DISPATCH_MODE_" }, value = {
+                DISPATCH_MODE_STOP,
+                DISPATCH_MODE_CONTINUE_ON_SUBTREE
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface DispatchMode {}
+
+        @DispatchMode
+        private final int mDispatchMode;
+
+        /**
+         * Creates a new {@link WindowInsetsAnimation} callback with the given
+         * {@link #getDispatchMode() dispatch mode}.
+         *
+         * @param dispatchMode The dispatch mode for this callback. See {@link #getDispatchMode()}.
+         */
+        public Callback(@DispatchMode int dispatchMode) {
+            mDispatchMode = dispatchMode;
+        }
+
+        /**
+         * Retrieves the dispatch mode of this listener. Dispatch of the all animation events is
+         * hierarchical: It will starts at the root of the view hierarchy and then traverse it and
+         * invoke the callback of the specific {@link View} that is being traversed.
+         * The method may return either {@link #DISPATCH_MODE_CONTINUE_ON_SUBTREE} to indicate that
+         * animation events should be propagated to the subtree of the view hierarchy, or
+         * {@link #DISPATCH_MODE_STOP} to stop dispatching. In that case, all animation callbacks
+         * related to the animation passed in will be stopped from propagating to the subtree of the
+         * hierarchy.
+         * <p>
+         * Also note that {@link #DISPATCH_MODE_STOP} behaves the same way as
+         * returning {@link WindowInsets#CONSUMED} during the regular insets dispatch in
+         * {@link View#onApplyWindowInsets}.
+         *
+         * @return Either {@link #DISPATCH_MODE_CONTINUE_ON_SUBTREE} to indicate that dispatching of
+         *         animation events will continue to the subtree of the view hierarchy, or
+         *         {@link #DISPATCH_MODE_STOP} to indicate that animation events will stop
+         *         dispatching.
+         */
+        @DispatchMode
+        @SuppressLint("CallbackMethodName") // TODO(b/149430296) False positive: not a callback.
+        public final int getDispatchMode() {
+            return mDispatchMode;
+        }
+
+        /**
+         * Called when an insets animation is about to start and before the views have been laid out
+         * in the end state of the animation. The ordering of events during an insets animation is
+         * the following:
+         * <p>
+         * <ul>
+         *     <li>Application calls {@link WindowInsetsController#hide(int)},
+         *     {@link WindowInsetsController#show(int)},
+         *     {@link WindowInsetsController#controlWindowInsetsAnimation}</li>
+         *     <li>onPrepare is called on the view hierarchy listeners</li>
+         *     <li>{@link View#onApplyWindowInsets} will be called with the end state of the
+         *     animation</li>
+         *     <li>View hierarchy gets laid out according to the changes the application has
+         *     requested due to the new insets being dispatched</li>
+         *     <li>{@link #onStart} is called <em>before</em> the view
+         *     hierarchy gets drawn in the new laid out state</li>
+         *     <li>{@link #onProgress} is called immediately after with the animation start
+         *     state</li>
+         *     <li>The frame gets drawn.</li>
+         * </ul>
+         * <p>
+         * This ordering allows the application to inspect the end state after the animation has
+         * finished, and then revert to the starting state of the animation in the first
+         * {@link #onProgress} callback by using post-layout view properties like {@link View#setX}
+         * and related methods.
+         * <p>
+         * Note: If the animation is application controlled by using
+         * {@link WindowInsetsController#controlWindowInsetsAnimation}, the end state of the
+         * animation is undefined as the application may decide on the end state only by passing in
+         * {@code shown} parameter when calling {@link WindowInsetsAnimationController#finish}. In
+         * this situation, the system will dispatch the insets in the opposite visibility state
+         * before the animation starts. Example: When controlling the input method with
+         * {@link WindowInsetsController#controlWindowInsetsAnimation} and the input method is
+         * currently showing, {@link View#onApplyWindowInsets} will receive a {@link WindowInsets}
+         * instance for which {@link WindowInsets#isVisible} will return {@code false} for
+         * {@link WindowInsets.Type#ime}.
+         *
+         * @param animation The animation that is about to start.
+         */
+        public void onPrepare(@NonNull WindowInsetsAnimation animation) {
+        }
+
+        /**
+         * Called when an insets animation gets started.
+         * <p>
+         * Note that, like {@link #onProgress}, dispatch of the animation start event is
+         * hierarchical: It will starts at the root of the view hierarchy and then traverse it
+         * and invoke the callback of the specific {@link View} that is being traversed.
+         * The method may return a modified
+         * instance of the bounds by calling {@link Bounds#inset} to indicate that a part of
+         * the insets have been used to offset or clip its children, and the children shouldn't
+         * worry about that part anymore. Furthermore, if {@link #getDispatchMode()} returns
+         * {@link #DISPATCH_MODE_STOP}, children of this view will not receive the callback anymore.
+         *
+         * @param animation The animation that is about to start.
+         * @param bounds The bounds in which animation happens.
+         * @return The animation representing the part of the insets that should be dispatched to
+         *         the subtree of the hierarchy.
+         */
+        @NonNull
+        public Bounds onStart(
+                @NonNull WindowInsetsAnimation animation, @NonNull Bounds bounds) {
+            return bounds;
+        }
+
+        /**
+         * Called when the insets change as part of running an animation. Note that even if multiple
+         * animations for different types are running, there will only be one progress callback per
+         * frame. The {@code insets} passed as an argument represents the overall state and will
+         * include all types, regardless of whether they are animating or not.
+         * <p>
+         * Note that insets dispatch is hierarchical: It will start at the root of the view
+         * hierarchy, and then traverse it and invoke the callback of the specific {@link View}
+         * being traversed. The method may return a modified instance by calling
+         * {@link WindowInsets#inset(int, int, int, int)} to indicate that a part of the insets have
+         * been used to offset or clip its children, and the children shouldn't worry about that
+         * part anymore. Furthermore, if {@link #getDispatchMode()} returns
+         * {@link #DISPATCH_MODE_STOP}, children of this view will not receive the callback anymore.
+         *
+         * @param insets The current insets.
+         * @param runningAnimations The currently running animations.
+         * @return The insets to dispatch to the subtree of the hierarchy.
+         */
+        @NonNull
+        public abstract WindowInsets onProgress(@NonNull WindowInsets insets,
+                @NonNull List<WindowInsetsAnimation> runningAnimations);
+
+        /**
+         * Called when an insets animation has ended.
+         *
+         * @param animation The animation that has ended. This will be the same instance
+         *                  as passed into {@link #onStart}
+         */
+        public void onEnd(@NonNull WindowInsetsAnimation animation) {
+        }
+
+    }
+}
diff --git a/core/java/android/view/WindowInsetsAnimationCallback.java b/core/java/android/view/WindowInsetsAnimationCallback.java
deleted file mode 100644
index 4c8463b3..0000000
--- a/core/java/android/view/WindowInsetsAnimationCallback.java
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import android.annotation.FloatRange;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.graphics.Insets;
-import android.view.WindowInsets.Type;
-import android.view.WindowInsets.Type.InsetsType;
-import android.view.animation.Interpolator;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Interface that allows the application to listen to animation events for windows that cause
- * insets.
- */
-public interface WindowInsetsAnimationCallback {
-
-    /**
-     * Return value for {@link #getDispatchMode()}: Dispatching of animation events should
-     * stop at this level in the view hierarchy, and no animation events should be dispatch to the
-     * subtree of the view hierarchy.
-     */
-    int DISPATCH_MODE_STOP = 0;
-
-    /**
-     * Return value for {@link #getDispatchMode()}: Dispatching of animation events should
-     * continue in the view hierarchy.
-     */
-    int DISPATCH_MODE_CONTINUE_ON_SUBTREE = 1;
-
-    /** @hide */
-    @IntDef(prefix = { "DISPATCH_MODE_" }, value = {
-            DISPATCH_MODE_STOP,
-            DISPATCH_MODE_CONTINUE_ON_SUBTREE
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    @interface DispatchMode {}
-
-    /**
-     * Retrieves the dispatch mode of this listener. Dispatch of the all animation events is
-     * hierarchical: It will starts at the root of the view hierarchy and then traverse it and
-     * invoke the callback of the specific {@link View} that is being traversed.
-     * The method may return either {@link #DISPATCH_MODE_CONTINUE_ON_SUBTREE} to indicate that
-     * animation events should be propagated to the subtree of the view hierarchy, or
-     * {@link #DISPATCH_MODE_STOP} to stop dispatching. In that case, all animation callbacks
-     * related to the animation passed in will be stopped from propagating to the subtree of the
-     * hierarchy.
-     * <p>
-     * Note that this method will only be invoked once when
-     * {@link View#setWindowInsetsAnimationCallback setting the listener} and then the framework
-     * will use the recorded result.
-     * <p>
-     * Also note that returning {@link #DISPATCH_MODE_STOP} here behaves the same way as returning
-     * {@link WindowInsets#CONSUMED} during the regular insets dispatch in
-     * {@link View#onApplyWindowInsets}.
-     *
-     * @return Either {@link #DISPATCH_MODE_CONTINUE_ON_SUBTREE} to indicate that dispatching of
-     *         animation events will continue to the subtree of the view hierarchy, or
-     *         {@link #DISPATCH_MODE_STOP} to indicate that animation events will stop dispatching.
-     */
-    @DispatchMode
-    int getDispatchMode();
-
-    /**
-     * Called when an insets animation is about to start and before the views have been laid out in
-     * the end state of the animation. The ordering of events during an insets animation is the
-     * following:
-     * <p>
-     * <ul>
-     *     <li>Application calls {@link WindowInsetsController#hide(int)},
-     *     {@link WindowInsetsController#show(int)},
-     *     {@link WindowInsetsController#controlWindowInsetsAnimation}</li>
-     *     <li>onPrepare is called on the view hierarchy listeners</li>
-     *     <li>{@link View#onApplyWindowInsets} will be called with the end state of the
-     *     animation</li>
-     *     <li>View hierarchy gets laid out according to the changes the application has requested
-     *     due to the new insets being dispatched</li>
-     *     <li>{@link #onStart} is called <em>before</em> the view
-     *     hierarchy gets drawn in the new laid out state</li>
-     *     <li>{@link #onProgress} is called immediately after with the animation start state</li>
-     *     <li>The frame gets drawn.</li>
-     * </ul>
-     * <p>
-     * This ordering allows the application to inspect the end state after the animation has
-     * finished, and then revert to the starting state of the animation in the first
-     * {@link #onProgress} callback by using post-layout view properties like {@link View#setX} and
-     * related methods.
-     * <p>
-     * Note: If the animation is application controlled by using
-     * {@link WindowInsetsController#controlWindowInsetsAnimation}, the end state of the animation
-     * is undefined as the application may decide on the end state only by passing in the
-     * {@code shown} parameter when calling {@link WindowInsetsAnimationController#finish}. In this
-     * situation, the system will dispatch the insets in the opposite visibility state before the
-     * animation starts. Example: When controlling the input method with
-     * {@link WindowInsetsController#controlWindowInsetsAnimation} and the input method is currently
-     * showing, {@link View#onApplyWindowInsets} will receive a {@link WindowInsets} instance for
-     * which {@link WindowInsets#isVisible} will return {@code false} for {@link Type#ime}.
-     *
-     * @param animation The animation that is about to start.
-     */
-    default void onPrepare(@NonNull InsetsAnimation animation) {
-    }
-
-    /**
-     * Called when an insets animation gets started.
-     * <p>
-     * Note that, like {@link #onProgress}, dispatch of the animation start event is hierarchical:
-     * It will starts at the root of the view hierarchy and then traverse it and invoke the callback
-     * of the specific {@link View} that is being traversed. The method may return a modified
-     * instance of the bounds by calling {@link AnimationBounds#inset} to indicate that a part of
-     * the insets have been used to offset or clip its children, and the children shouldn't worry
-     * about that part anymore. Furthermore, if {@link #getDispatchMode()} returns
-     * {@link #DISPATCH_MODE_STOP}, children of this view will not receive the callback anymore.
-     *
-     * @param animation The animation that is about to start.
-     * @param bounds The bounds in which animation happens.
-     * @return The animation representing the part of the insets that should be dispatched to the
-     *         subtree of the hierarchy.
-     */
-    @NonNull
-    default AnimationBounds onStart(
-            @NonNull InsetsAnimation animation, @NonNull AnimationBounds bounds) {
-        return bounds;
-    }
-
-    /**
-     * Called when the insets change as part of running an animation. Note that even if multiple
-     * animations for different types are running, there will only be one progress callback per
-     * frame. The {@code insets} passed as an argument represents the overall state and will include
-     * all types, regardless of whether they are animating or not.
-     * <p>
-     * Note that insets dispatch is hierarchical: It will start at the root of the view hierarchy,
-     * and then traverse it and invoke the callback of the specific {@link View} being traversed.
-     * The method may return a modified instance by calling
-     * {@link WindowInsets#inset(int, int, int, int)} to indicate that a part of the insets have
-     * been used to offset or clip its children, and the children shouldn't worry about that part
-     * anymore. Furthermore, if {@link #getDispatchMode()} returns
-     * {@link #DISPATCH_MODE_STOP}, children of this view will not receive the callback anymore.
-     *
-     * TODO: Introduce a way to map (type -> InsetAnimation) so app developer can query animation
-     *  for a given type e.g. callback.getAnimation(type) OR controller.getAnimation(type).
-     *  Or on the controller directly?
-     * @param insets The current insets.
-     * @return The insets to dispatch to the subtree of the hierarchy.
-     */
-    @NonNull
-    WindowInsets onProgress(@NonNull WindowInsets insets);
-
-    /**
-     * Called when an insets animation has finished.
-     *
-     * @param animation The animation that has finished running. This will be the same instance as
-     *                  passed into {@link #onStart}
-     */
-    default void onFinish(@NonNull InsetsAnimation animation) {
-    }
-
-    /**
-     * Class representing an animation of a set of windows that cause insets.
-     */
-    final class InsetsAnimation {
-
-        private final @InsetsType int mTypeMask;
-        private float mFraction;
-        @Nullable private final Interpolator mInterpolator;
-        private final long mDurationMillis;
-        private float mAlpha;
-
-        /**
-         * Creates a new {@link InsetsAnimation} object.
-         * <p>
-         * This should only be used for testing, as usually the system creates this object for the
-         * application to listen to with {@link WindowInsetsAnimationCallback}.
-         * </p>
-         * @param typeMask The bitmask of {@link WindowInsets.Type}s that are animating.
-         * @param interpolator The interpolator of the animation.
-         * @param durationMillis The duration of the animation in
-         *                   {@link java.util.concurrent.TimeUnit#MILLISECONDS}.
-         */
-        public InsetsAnimation(
-                @InsetsType int typeMask, @Nullable Interpolator interpolator,
-                long durationMillis) {
-            mTypeMask = typeMask;
-            mInterpolator = interpolator;
-            mDurationMillis = durationMillis;
-        }
-
-        /**
-         * @return The bitmask of {@link WindowInsets.Type.InsetsType}s that are animating.
-         */
-        public @InsetsType int getTypeMask() {
-            return mTypeMask;
-        }
-
-        /**
-         * Returns the raw fractional progress of this animation between
-         * start state of the animation and the end state of the animation. Note
-         * that this progress is the global progress of the animation, whereas
-         * {@link WindowInsetsAnimationCallback#onProgress} will only dispatch the insets that may
-         * be inset with {@link WindowInsets#inset} by parents of views in the hierarchy.
-         * Progress per insets animation is global for the entire animation. One animation animates
-         * all things together (in, out, ...). If they don't animate together, we'd have
-         * multiple animations.
-         * <p>
-         * Note: In case the application is controlling the animation, the valued returned here will
-         * be the same as the application passed into
-         * {@link WindowInsetsAnimationController#setInsetsAndAlpha(Insets, float, float)}.
-         * </p>
-         * @return The current progress of this animation.
-         */
-        @FloatRange(from = 0f, to = 1f)
-        public float getFraction() {
-            return mFraction;
-        }
-
-        /**
-         * Returns the interpolated fractional progress of this animation between
-         * start state of the animation and the end state of the animation. Note
-         * that this progress is the global progress of the animation, whereas
-         * {@link WindowInsetsAnimationCallback#onProgress} will only dispatch the insets that may
-         * be inset with {@link WindowInsets#inset} by parents of views in the hierarchy.
-         * Progress per insets animation is global for the entire animation. One animation animates
-         * all things together (in, out, ...). If they don't animate together, we'd have
-         * multiple animations.
-         * <p>
-         * Note: In case the application is controlling the animation, the valued returned here will
-         * be the same as the application passed into
-         * {@link WindowInsetsAnimationController#setInsetsAndAlpha(Insets, float, float)},
-         * interpolated with the interpolator passed into
-         * {@link WindowInsetsController#controlWindowInsetsAnimation}.
-         * </p>
-         * <p>
-         * Note: For system-initiated animations, this will always return a valid value between 0
-         * and 1.
-         * </p>
-         * @see #getFraction() for raw fraction.
-         * @return The current interpolated progress of this animation. -1 if interpolator isn't
-         *         specified.
-         */
-        public float getInterpolatedFraction() {
-            if (mInterpolator != null) {
-                return mInterpolator.getInterpolation(mFraction);
-            }
-            return -1;
-        }
-
-        /**
-         * Retrieves the interpolator used for this animation, or {@code null} if this animation
-         * doesn't follow an interpolation curved. For system-initiated animations, this will never
-         * return {@code null}.
-         *
-         * @return The interpolator used for this animation.
-         */
-        @Nullable
-        public Interpolator getInterpolator() {
-            return mInterpolator;
-        }
-
-        /**
-         * @return duration of animation in {@link java.util.concurrent.TimeUnit#MILLISECONDS}, or
-         *         -1 if the animation doesn't have a fixed duration.
-         */
-        public long getDurationMillis() {
-            return mDurationMillis;
-        }
-
-        /**
-         * Set fraction of the progress if {@link WindowInsets.Type.InsetsType} animation is
-         * controlled by the app.
-         * <p>
-         * Note: This should only be used for testing, as the system fills in the fraction for the
-         * application or the fraction that was passed into
-         * {@link WindowInsetsAnimationController#setInsetsAndAlpha(Insets, float, float)} is being
-         * used.
-         * </p>
-         * @param fraction fractional progress between 0 and 1 where 0 represents hidden and
-         *                zero progress and 1 represent fully shown final state.
-         * @see #getFraction()
-         */
-        public void setFraction(@FloatRange(from = 0f, to = 1f) float fraction) {
-            mFraction = fraction;
-        }
-
-        /**
-         * Retrieves the translucency of the windows that are animating.
-         *
-         * @return Alpha of windows that cause insets of type {@link WindowInsets.Type.InsetsType}.
-         */
-        @FloatRange(from = 0f, to = 1f)
-        public float getAlpha() {
-            return mAlpha;
-        }
-
-        /**
-         * Sets the translucency of the windows that are animating.
-         * <p>
-         * Note: This should only be used for testing, as the system fills in the alpha for the
-         * application or the alpha that was passed into
-         * {@link WindowInsetsAnimationController#setInsetsAndAlpha(Insets, float, float)} is being
-         * used.
-         * </p>
-         * @param alpha Alpha of windows that cause insets of type
-         *              {@link WindowInsets.Type.InsetsType}.
-         * @see #getAlpha()
-         */
-        public void setAlpha(@FloatRange(from = 0f, to = 1f) float alpha) {
-            mAlpha = alpha;
-        }
-    }
-
-    /**
-     * Class representing the range of an {@link InsetsAnimation}
-     */
-    final class AnimationBounds {
-
-        private final Insets mLowerBound;
-        private final Insets mUpperBound;
-
-        public AnimationBounds(@NonNull Insets lowerBound, @NonNull Insets upperBound) {
-            mLowerBound = lowerBound;
-            mUpperBound = upperBound;
-        }
-
-        /**
-         * Queries the lower inset bound of the animation. If the animation is about showing or
-         * hiding a window that cause insets, the lower bound is {@link Insets#NONE} and the upper
-         * bound is the same as {@link WindowInsets#getInsets(int)} for the fully shown state. This
-         * is the same as {@link WindowInsetsAnimationController#getHiddenStateInsets} and
-         * {@link WindowInsetsAnimationController#getShownStateInsets} in case the listener gets
-         * invoked because of an animation that originates from
-         * {@link WindowInsetsAnimationController}.
-         * <p>
-         * However, if the size of a window that causes insets is changing, these are the
-         * lower/upper bounds of that size animation.
-         * </p>
-         * There are no overlapping animations for a specific type, but there may be multiple
-         * animations running at the same time for different inset types.
-         *
-         * @see #getUpperBound()
-         * @see WindowInsetsAnimationController#getHiddenStateInsets
-         */
-        @NonNull
-        public Insets getLowerBound() {
-            return mLowerBound;
-        }
-
-        /**
-         * Queries the upper inset bound of the animation. If the animation is about showing or
-         * hiding a window that cause insets, the lower bound is {@link Insets#NONE}
-         * nd the upper bound is the same as {@link WindowInsets#getInsets(int)} for the fully
-         * shown state. This is the same as
-         * {@link WindowInsetsAnimationController#getHiddenStateInsets} and
-         * {@link WindowInsetsAnimationController#getShownStateInsets} in case the listener gets
-         * invoked because of an animation that originates from
-         * {@link WindowInsetsAnimationController}.
-         * <p>
-         * However, if the size of a window that causes insets is changing, these are the
-         * lower/upper bounds of that size animation.
-         * <p>
-         * There are no overlapping animations for a specific type, but there may be multiple
-         * animations running at the same time for different inset types.
-         *
-         * @see #getLowerBound()
-         * @see WindowInsetsAnimationController#getShownStateInsets
-         */
-        @NonNull
-        public Insets getUpperBound() {
-            return mUpperBound;
-        }
-
-        /**
-         * Insets both the lower and upper bound by the specified insets. This is to be used in
-         * {@link WindowInsetsAnimationCallback#onStart} to indicate that a part of the insets has
-         * been used to offset or clip its children, and the children shouldn't worry about that
-         * part anymore.
-         *
-         * @param insets The amount to inset.
-         * @return A copy of this instance inset in the given directions.
-         * @see WindowInsets#inset
-         * @see WindowInsetsAnimationCallback#onStart
-         */
-        @NonNull
-        public AnimationBounds inset(@NonNull Insets insets) {
-            return new AnimationBounds(
-                    // TODO: refactor so that WindowInsets.insetInsets() is in a more appropriate
-                    //  place eventually.
-                    WindowInsets.insetInsets(
-                            mLowerBound, insets.left, insets.top, insets.right, insets.bottom),
-                    WindowInsets.insetInsets(
-                            mUpperBound, insets.left, insets.top, insets.right, insets.bottom));
-        }
-    }
-}
diff --git a/core/java/android/view/WindowInsetsAnimationController.java b/core/java/android/view/WindowInsetsAnimationController.java
index 4a864be..2c7880b 100644
--- a/core/java/android/view/WindowInsetsAnimationController.java
+++ b/core/java/android/view/WindowInsetsAnimationController.java
@@ -22,8 +22,7 @@
 import android.annotation.SuppressLint;
 import android.graphics.Insets;
 import android.view.WindowInsets.Type.InsetsType;
-import android.view.WindowInsetsAnimationCallback.AnimationBounds;
-import android.view.animation.Interpolator;
+import android.view.WindowInsetsAnimation.Bounds;
 
 /**
  * Controller for app-driven animation of system windows.
@@ -35,7 +34,7 @@
  *  <p>
  *  Control is obtained through {@link WindowInsetsController#controlWindowInsetsAnimation}.
  */
-@SuppressLint("NotClosable")
+@SuppressLint("NotCloseable")
 public interface WindowInsetsAnimationController {
 
     /**
@@ -45,12 +44,12 @@
      * to {@link View#getRootView}
      * <p>
      * If there are any animation listeners registered, this value is the same as
-     * {@link AnimationBounds#getLowerBound()} that is being be passed into the root view of the
+     * {@link Bounds#getLowerBound()} that is being be passed into the root view of the
      * hierarchy.
      *
      * @return Insets when the windows this animation is controlling are fully hidden.
      *
-     * @see AnimationBounds#getLowerBound()
+     * @see Bounds#getLowerBound()
      */
     @NonNull Insets getHiddenStateInsets();
 
@@ -61,11 +60,11 @@
      * to {@link View#getRootView}
      * <p>
      * If there are any animation listeners registered, this value is the same as
-     * {@link AnimationBounds#getUpperBound()} that is being passed into the root view of hierarchy.
+     * {@link Bounds#getUpperBound()} that is being passed into the root view of hierarchy.
      *
      * @return Insets when the windows this animation is controlling are fully shown.
      *
-     * @see AnimationBounds#getUpperBound()
+     * @see Bounds#getUpperBound()
      */
     @NonNull Insets getShownStateInsets();
 
@@ -114,9 +113,9 @@
      * Also note that this will <b>not</b> inform the view system of a full inset change via
      * {@link View#dispatchApplyWindowInsets} in order to avoid a full layout pass during the
      * animation. If you'd like to animate views during a window inset animation, register a
-     * {@link WindowInsetsAnimationCallback} by calling
-     * {@link View#setWindowInsetsAnimationCallback(WindowInsetsAnimationCallback)} that will be
-     * notified about any insets change via {@link WindowInsetsAnimationCallback#onProgress} during
+     * {@link WindowInsetsAnimation.Callback} by calling
+     * {@link View#setWindowInsetsAnimationCallback(WindowInsetsAnimation.Callback)} that will be
+     * notified about any insets change via {@link WindowInsetsAnimation.Callback#onProgress} during
      * the animation.
      * <p>
      * {@link View#dispatchApplyWindowInsets} will instead be called once the animation has
@@ -131,10 +130,10 @@
      *               If you intend on changing alpha only, pass null or {@link #getCurrentInsets()}.
      * @param alpha  The new alpha to apply to the inset side.
      * @param fraction instantaneous animation progress. This value is dispatched to
-     *                 {@link WindowInsetsAnimationCallback}.
+     *                 {@link WindowInsetsAnimation.Callback}.
      *
-     * @see WindowInsetsAnimationCallback
-     * @see View#setWindowInsetsAnimationCallback(WindowInsetsAnimationCallback)
+     * @see WindowInsetsAnimation.Callback
+     * @see View#setWindowInsetsAnimationCallback(WindowInsetsAnimation.Callback)
      */
     void setInsetsAndAlpha(@Nullable Insets insets, @FloatRange(from = 0f, to = 1f) float alpha,
             @FloatRange(from = 0f, to = 1f) float fraction);
diff --git a/core/java/android/view/WindowInsetsController.java b/core/java/android/view/WindowInsetsController.java
index 27e92e5..b7ca037 100644
--- a/core/java/android/view/WindowInsetsController.java
+++ b/core/java/android/view/WindowInsetsController.java
@@ -22,7 +22,6 @@
 import android.graphics.Insets;
 import android.os.CancellationSignal;
 import android.view.WindowInsets.Type.InsetsType;
-import android.view.WindowInsetsAnimationCallback.InsetsAnimation;
 import android.view.animation.Interpolator;
 
 import java.lang.annotation.Retention;
@@ -148,19 +147,19 @@
      * @param durationMillis Duration of animation in
      *                       {@link java.util.concurrent.TimeUnit#MILLISECONDS}, or -1 if the
      *                       animation doesn't have a predetermined duration. This value will be
-     *                       passed to {@link InsetsAnimation#getDurationMillis()}
+     *                       passed to {@link WindowInsetsAnimation#getDurationMillis()}
      * @param interpolator The interpolator used for this animation, or {@code null} if this
      *                     animation doesn't follow an interpolation curve. This value will be
-     *                     passed to {@link InsetsAnimation#getInterpolator()} and used to calculate
-     *                     {@link InsetsAnimation#getInterpolatedFraction()}.
+     *                     passed to {@link WindowInsetsAnimation#getInterpolator()} and used to
+     *                     calculate {@link WindowInsetsAnimation#getInterpolatedFraction()}.
      * @param listener The {@link WindowInsetsAnimationControlListener} that gets called when the
      *                 windows are ready to be controlled, among other callbacks.
      * @return A cancellation signal that the caller can use to cancel the request to obtain
      *         control, or once they have control, to cancel the control.
-     * @see InsetsAnimation#getFraction()
-     * @see InsetsAnimation#getInterpolatedFraction()
-     * @see InsetsAnimation#getInterpolator()
-     * @see InsetsAnimation#getDurationMillis()
+     * @see WindowInsetsAnimation#getFraction()
+     * @see WindowInsetsAnimation#getInterpolatedFraction()
+     * @see WindowInsetsAnimation#getInterpolator()
+     * @see WindowInsetsAnimation#getDurationMillis()
      */
     @NonNull
     CancellationSignal controlWindowInsetsAnimation(@InsetsType int types, long durationMillis,
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 3274449..56683dd 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -16,9 +16,6 @@
 
 package android.view;
 
-import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
-import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
-
 import android.annotation.NonNull;
 import android.app.ResourcesManager;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -70,6 +67,10 @@
 
     private IBinder mDefaultToken;
 
+    private boolean mIsViewAdded;
+    private View mLastView;
+    private WindowManager.LayoutParams mLastParams;
+
     public WindowManagerImpl(Context context) {
         this(context, null);
     }
@@ -101,6 +102,9 @@
     public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
         applyDefaultToken(params);
         mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
+        mIsViewAdded = true;
+        mLastView = view;
+        mLastParams = (WindowManager.LayoutParams) params;
     }
 
     @Override
@@ -246,15 +250,18 @@
         // TODO(window-context): This can only be properly implemented
         //  once we flip the new insets mode flag.
         if (mParentWindow != null) {
+            if (mParentWindow.getDecorView().isAttachedToWindow()) {
+                return mParentWindow.getDecorView().getViewRootImpl()
+                        .getWindowInsets(true /* forceConstruct */);
+            }
             return getWindowInsetsFromServer(mParentWindow.getAttributes());
         }
-        return getWindowInsetsFromServer(getDefaultParams());
-    }
+        if (mIsViewAdded) {
+            return mLastView.getViewRootImpl().getWindowInsets(true /* forceConstruct */);
+        } else {
+            return getWindowInsetsFromServer(new WindowManager.LayoutParams());
+        }
 
-    private static WindowManager.LayoutParams getDefaultParams() {
-        final WindowManager.LayoutParams params = new WindowManager.LayoutParams();
-        params.flags = FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
-        return params;
     }
 
     private WindowInsets getWindowInsetsFromServer(WindowManager.LayoutParams attrs) {
diff --git a/core/java/android/view/animation/AccelerateDecelerateInterpolator.java b/core/java/android/view/animation/AccelerateDecelerateInterpolator.java
index 21d5a5b..a2bbc5c 100644
--- a/core/java/android/view/animation/AccelerateDecelerateInterpolator.java
+++ b/core/java/android/view/animation/AccelerateDecelerateInterpolator.java
@@ -17,19 +17,18 @@
 package android.view.animation;
 
 import android.content.Context;
+import android.graphics.animation.HasNativeInterpolator;
+import android.graphics.animation.NativeInterpolator;
+import android.graphics.animation.NativeInterpolatorFactory;
 import android.util.AttributeSet;
 
-import com.android.internal.view.animation.HasNativeInterpolator;
-import com.android.internal.view.animation.NativeInterpolatorFactory;
-import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
-
 /**
  * An interpolator where the rate of change starts and ends slowly but
  * accelerates through the middle.
  */
 @HasNativeInterpolator
 public class AccelerateDecelerateInterpolator extends BaseInterpolator
-        implements NativeInterpolatorFactory {
+        implements NativeInterpolator {
     public AccelerateDecelerateInterpolator() {
     }
 
@@ -44,6 +43,6 @@
     /** @hide */
     @Override
     public long createNativeInterpolator() {
-        return NativeInterpolatorFactoryHelper.createAccelerateDecelerateInterpolator();
+        return NativeInterpolatorFactory.createAccelerateDecelerateInterpolator();
     }
 }
diff --git a/core/java/android/view/animation/AccelerateInterpolator.java b/core/java/android/view/animation/AccelerateInterpolator.java
index 6c8d7b1..9d4cd32 100644
--- a/core/java/android/view/animation/AccelerateInterpolator.java
+++ b/core/java/android/view/animation/AccelerateInterpolator.java
@@ -20,12 +20,12 @@
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
+import android.graphics.animation.HasNativeInterpolator;
+import android.graphics.animation.NativeInterpolator;
+import android.graphics.animation.NativeInterpolatorFactory;
 import android.util.AttributeSet;
 
 import com.android.internal.R;
-import com.android.internal.view.animation.HasNativeInterpolator;
-import com.android.internal.view.animation.NativeInterpolatorFactory;
-import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
 
 /**
  * An interpolator where the rate of change starts out slowly and
@@ -33,7 +33,7 @@
  *
  */
 @HasNativeInterpolator
-public class AccelerateInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
+public class AccelerateInterpolator extends BaseInterpolator implements NativeInterpolator {
     private final float mFactor;
     private final double mDoubleFactor;
 
@@ -85,6 +85,6 @@
     /** @hide */
     @Override
     public long createNativeInterpolator() {
-        return NativeInterpolatorFactoryHelper.createAccelerateInterpolator(mFactor);
+        return NativeInterpolatorFactory.createAccelerateInterpolator(mFactor);
     }
 }
diff --git a/core/java/android/view/animation/AnticipateInterpolator.java b/core/java/android/view/animation/AnticipateInterpolator.java
index 7a837c3..d146394 100644
--- a/core/java/android/view/animation/AnticipateInterpolator.java
+++ b/core/java/android/view/animation/AnticipateInterpolator.java
@@ -20,18 +20,18 @@
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
+import android.graphics.animation.HasNativeInterpolator;
+import android.graphics.animation.NativeInterpolator;
+import android.graphics.animation.NativeInterpolatorFactory;
 import android.util.AttributeSet;
 
 import com.android.internal.R;
-import com.android.internal.view.animation.HasNativeInterpolator;
-import com.android.internal.view.animation.NativeInterpolatorFactory;
-import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
 
 /**
  * An interpolator where the change starts backward then flings forward.
  */
 @HasNativeInterpolator
-public class AnticipateInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
+public class AnticipateInterpolator extends BaseInterpolator implements NativeInterpolator {
     private final float mTension;
 
     public AnticipateInterpolator() {
@@ -73,6 +73,6 @@
     /** @hide */
     @Override
     public long createNativeInterpolator() {
-        return NativeInterpolatorFactoryHelper.createAnticipateInterpolator(mTension);
+        return NativeInterpolatorFactory.createAnticipateInterpolator(mTension);
     }
 }
diff --git a/core/java/android/view/animation/AnticipateOvershootInterpolator.java b/core/java/android/view/animation/AnticipateOvershootInterpolator.java
index 9a75134..4d6a390 100644
--- a/core/java/android/view/animation/AnticipateOvershootInterpolator.java
+++ b/core/java/android/view/animation/AnticipateOvershootInterpolator.java
@@ -24,11 +24,11 @@
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
+import android.graphics.animation.HasNativeInterpolator;
+import android.graphics.animation.NativeInterpolator;
+import android.graphics.animation.NativeInterpolatorFactory;
 import android.util.AttributeSet;
 
-import com.android.internal.view.animation.HasNativeInterpolator;
-import com.android.internal.view.animation.NativeInterpolatorFactory;
-import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
 
 /**
  * An interpolator where the change starts backward then flings forward and overshoots
@@ -36,7 +36,7 @@
  */
 @HasNativeInterpolator
 public class AnticipateOvershootInterpolator extends BaseInterpolator
-        implements NativeInterpolatorFactory {
+        implements NativeInterpolator {
     private final float mTension;
 
     public AnticipateOvershootInterpolator() {
@@ -103,6 +103,6 @@
     /** @hide */
     @Override
     public long createNativeInterpolator() {
-        return NativeInterpolatorFactoryHelper.createAnticipateOvershootInterpolator(mTension);
+        return NativeInterpolatorFactory.createAnticipateOvershootInterpolator(mTension);
     }
 }
diff --git a/core/java/android/view/animation/BounceInterpolator.java b/core/java/android/view/animation/BounceInterpolator.java
index 909eaa4..d3f6a3f 100644
--- a/core/java/android/view/animation/BounceInterpolator.java
+++ b/core/java/android/view/animation/BounceInterpolator.java
@@ -17,17 +17,16 @@
 package android.view.animation;
 
 import android.content.Context;
+import android.graphics.animation.HasNativeInterpolator;
+import android.graphics.animation.NativeInterpolator;
+import android.graphics.animation.NativeInterpolatorFactory;
 import android.util.AttributeSet;
 
-import com.android.internal.view.animation.HasNativeInterpolator;
-import com.android.internal.view.animation.NativeInterpolatorFactory;
-import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
-
 /**
  * An interpolator where the change bounces at the end.
  */
 @HasNativeInterpolator
-public class BounceInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
+public class BounceInterpolator extends BaseInterpolator implements NativeInterpolator {
     public BounceInterpolator() {
     }
 
@@ -56,6 +55,6 @@
     /** @hide */
     @Override
     public long createNativeInterpolator() {
-        return NativeInterpolatorFactoryHelper.createBounceInterpolator();
+        return NativeInterpolatorFactory.createBounceInterpolator();
     }
 }
\ No newline at end of file
diff --git a/core/java/android/view/animation/CycleInterpolator.java b/core/java/android/view/animation/CycleInterpolator.java
index 72d64a1..6b1a80a 100644
--- a/core/java/android/view/animation/CycleInterpolator.java
+++ b/core/java/android/view/animation/CycleInterpolator.java
@@ -20,12 +20,12 @@
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
+import android.graphics.animation.HasNativeInterpolator;
+import android.graphics.animation.NativeInterpolator;
+import android.graphics.animation.NativeInterpolatorFactory;
 import android.util.AttributeSet;
 
 import com.android.internal.R;
-import com.android.internal.view.animation.HasNativeInterpolator;
-import com.android.internal.view.animation.NativeInterpolatorFactory;
-import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
 
 /**
  * Repeats the animation for a specified number of cycles. The
@@ -33,7 +33,7 @@
  *
  */
 @HasNativeInterpolator
-public class CycleInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
+public class CycleInterpolator extends BaseInterpolator implements NativeInterpolator {
     public CycleInterpolator(float cycles) {
         mCycles = cycles;
     }
@@ -65,6 +65,6 @@
     /** @hide */
     @Override
     public long createNativeInterpolator() {
-        return NativeInterpolatorFactoryHelper.createCycleInterpolator(mCycles);
+        return NativeInterpolatorFactory.createCycleInterpolator(mCycles);
     }
 }
diff --git a/core/java/android/view/animation/DecelerateInterpolator.java b/core/java/android/view/animation/DecelerateInterpolator.java
index 2d1249d..2d2f770 100644
--- a/core/java/android/view/animation/DecelerateInterpolator.java
+++ b/core/java/android/view/animation/DecelerateInterpolator.java
@@ -20,12 +20,12 @@
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
+import android.graphics.animation.HasNativeInterpolator;
+import android.graphics.animation.NativeInterpolator;
+import android.graphics.animation.NativeInterpolatorFactory;
 import android.util.AttributeSet;
 
 import com.android.internal.R;
-import com.android.internal.view.animation.HasNativeInterpolator;
-import com.android.internal.view.animation.NativeInterpolatorFactory;
-import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
 
 /**
  * An interpolator where the rate of change starts out quickly and
@@ -33,7 +33,7 @@
  *
  */
 @HasNativeInterpolator
-public class DecelerateInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
+public class DecelerateInterpolator extends BaseInterpolator implements NativeInterpolator {
     public DecelerateInterpolator() {
     }
 
@@ -81,6 +81,6 @@
     /** @hide */
     @Override
     public long createNativeInterpolator() {
-        return NativeInterpolatorFactoryHelper.createDecelerateInterpolator(mFactor);
+        return NativeInterpolatorFactory.createDecelerateInterpolator(mFactor);
     }
 }
diff --git a/core/java/android/view/animation/LinearInterpolator.java b/core/java/android/view/animation/LinearInterpolator.java
index 2a047b4..f6a820c 100644
--- a/core/java/android/view/animation/LinearInterpolator.java
+++ b/core/java/android/view/animation/LinearInterpolator.java
@@ -17,17 +17,16 @@
 package android.view.animation;
 
 import android.content.Context;
+import android.graphics.animation.HasNativeInterpolator;
+import android.graphics.animation.NativeInterpolator;
+import android.graphics.animation.NativeInterpolatorFactory;
 import android.util.AttributeSet;
 
-import com.android.internal.view.animation.HasNativeInterpolator;
-import com.android.internal.view.animation.NativeInterpolatorFactory;
-import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
-
 /**
  * An interpolator where the rate of change is constant
  */
 @HasNativeInterpolator
-public class LinearInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
+public class LinearInterpolator extends BaseInterpolator implements NativeInterpolator {
 
     public LinearInterpolator() {
     }
@@ -42,6 +41,6 @@
     /** @hide */
     @Override
     public long createNativeInterpolator() {
-        return NativeInterpolatorFactoryHelper.createLinearInterpolator();
+        return NativeInterpolatorFactory.createLinearInterpolator();
     }
 }
diff --git a/core/java/android/view/animation/OvershootInterpolator.java b/core/java/android/view/animation/OvershootInterpolator.java
index 306688a..e6445d7 100644
--- a/core/java/android/view/animation/OvershootInterpolator.java
+++ b/core/java/android/view/animation/OvershootInterpolator.java
@@ -20,19 +20,19 @@
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
+import android.graphics.animation.HasNativeInterpolator;
+import android.graphics.animation.NativeInterpolator;
+import android.graphics.animation.NativeInterpolatorFactory;
 import android.util.AttributeSet;
 
 import com.android.internal.R;
-import com.android.internal.view.animation.HasNativeInterpolator;
-import com.android.internal.view.animation.NativeInterpolatorFactory;
-import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
 
 /**
  * An interpolator where the change flings forward and overshoots the last value
  * then comes back.
  */
 @HasNativeInterpolator
-public class OvershootInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
+public class OvershootInterpolator extends BaseInterpolator implements NativeInterpolator {
     private final float mTension;
 
     public OvershootInterpolator() {
@@ -76,6 +76,6 @@
     /** @hide */
     @Override
     public long createNativeInterpolator() {
-        return NativeInterpolatorFactoryHelper.createOvershootInterpolator(mTension);
+        return NativeInterpolatorFactory.createOvershootInterpolator(mTension);
     }
 }
diff --git a/core/java/android/view/animation/PathInterpolator.java b/core/java/android/view/animation/PathInterpolator.java
index 924437a..99d6b9c 100644
--- a/core/java/android/view/animation/PathInterpolator.java
+++ b/core/java/android/view/animation/PathInterpolator.java
@@ -20,14 +20,14 @@
 import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
 import android.graphics.Path;
+import android.graphics.animation.HasNativeInterpolator;
+import android.graphics.animation.NativeInterpolator;
+import android.graphics.animation.NativeInterpolatorFactory;
 import android.util.AttributeSet;
 import android.util.PathParser;
 import android.view.InflateException;
 
 import com.android.internal.R;
-import com.android.internal.view.animation.HasNativeInterpolator;
-import com.android.internal.view.animation.NativeInterpolatorFactory;
-import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
 
 /**
  * An interpolator that can traverse a Path that extends from <code>Point</code>
@@ -46,7 +46,7 @@
  * </pre></blockquote></p>
  */
 @HasNativeInterpolator
-public class PathInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
+public class PathInterpolator extends BaseInterpolator implements NativeInterpolator {
 
     // This governs how accurate the approximation of the Path is.
     private static final float PRECISION = 0.002f;
@@ -237,7 +237,7 @@
     /** @hide **/
     @Override
     public long createNativeInterpolator() {
-        return NativeInterpolatorFactoryHelper.createPathInterpolator(mX, mY);
+        return NativeInterpolatorFactory.createPathInterpolator(mX, mY);
     }
 
 }
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index c159f89..54bdb88 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -86,9 +86,10 @@
 import java.util.Objects;
 import java.util.Set;
 
-//TODO: use java.lang.ref.Cleaner once Android supports Java 9
 import sun.misc.Cleaner;
 
+//TODO: use java.lang.ref.Cleaner once Android supports Java 9
+
 /**
  * <p>The {@link AutofillManager} class provides ways for apps and custom views to
  * integrate with the Autofill Framework lifecycle.
@@ -547,7 +548,7 @@
          * @param fillInIntent The authentication fill-in intent.
          */
         void autofillClientAuthenticate(int authenticationId, IntentSender intent,
-                Intent fillInIntent);
+                Intent fillInIntent, boolean authenticateInline);
 
         /**
          * Tells the client this manager has state to be reset.
@@ -2070,7 +2071,7 @@
     }
 
     private void authenticate(int sessionId, int authenticationId, IntentSender intent,
-            Intent fillInIntent) {
+            Intent fillInIntent, boolean authenticateInline) {
         synchronized (mLock) {
             if (sessionId == mSessionId) {
                 final AutofillClient client = getClient();
@@ -2078,7 +2079,8 @@
                     // clear mOnInvisibleCalled and we will see if receive onInvisibleForAutofill()
                     // before onAuthenticationResult()
                     mOnInvisibleCalled = false;
-                    client.autofillClientAuthenticate(authenticationId, intent, fillInIntent);
+                    client.autofillClientAuthenticate(authenticationId, intent, fillInIntent,
+                            authenticateInline);
                 }
             }
         }
@@ -3250,10 +3252,11 @@
 
         @Override
         public void authenticate(int sessionId, int authenticationId, IntentSender intent,
-                Intent fillInIntent) {
+                Intent fillInIntent, boolean authenticateInline) {
             final AutofillManager afm = mAfm.get();
             if (afm != null) {
-                afm.post(() -> afm.authenticate(sessionId, authenticationId, intent, fillInIntent));
+                afm.post(() -> afm.authenticate(sessionId, authenticationId, intent, fillInIntent,
+                        authenticateInline));
             }
         }
 
@@ -3363,14 +3366,8 @@
             final AutofillManager afm = mAfm.get();
             if (afm == null) return null;
 
-            final AutofillClient client = afm.getClient();
-            if (client == null) {
-                Log.w(TAG, "getViewCoordinates(" + id + "): no autofill client");
-                return null;
-            }
-            final View view = client.autofillClientFindViewByAutofillIdTraversal(id);
+            final View view = getView(afm, id);
             if (view == null) {
-                Log.w(TAG, "getViewCoordinates(" + id + "): could not find view");
                 return null;
             }
             final Rect windowVisibleDisplayFrame = new Rect();
@@ -3411,5 +3408,42 @@
                 afm.post(() -> afm.requestHideFillUi(id, false));
             }
         }
+
+        @Override
+        public boolean requestAutofill(int sessionId, AutofillId id) {
+            final AutofillManager afm = mAfm.get();
+            if (afm == null || afm.mSessionId != sessionId) {
+                if (sDebug) {
+                    Slog.d(TAG, "Autofill not available or sessionId doesn't match");
+                }
+                return false;
+            }
+            final View view = getView(afm, id);
+            if (view == null || !view.isFocused()) {
+                if (sDebug) {
+                    Slog.d(TAG, "View not available or is not on focus");
+                }
+                return false;
+            }
+            if (sVerbose) {
+                Log.v(TAG, "requestAutofill() by AugmentedAutofillService.");
+            }
+            afm.post(() -> afm.requestAutofill(view));
+            return true;
+        }
+
+        @Nullable
+        private View getView(@NonNull AutofillManager afm, @NonNull AutofillId id) {
+            final AutofillClient client = afm.getClient();
+            if (client == null) {
+                Log.w(TAG, "getView(" + id + "): no autofill client");
+                return null;
+            }
+            View view = client.autofillClientFindViewByAutofillIdTraversal(id);
+            if (view == null) {
+                Log.w(TAG, "getView(" + id + "): could not find view");
+            }
+            return view;
+        }
     }
 }
diff --git a/core/java/android/view/autofill/IAugmentedAutofillManagerClient.aidl b/core/java/android/view/autofill/IAugmentedAutofillManagerClient.aidl
index 140507c..03054df 100644
--- a/core/java/android/view/autofill/IAugmentedAutofillManagerClient.aidl
+++ b/core/java/android/view/autofill/IAugmentedAutofillManagerClient.aidl
@@ -50,4 +50,10 @@
       * Requests hiding the fill UI.
       */
     void requestHideFillUi(int sessionId, in AutofillId id);
+
+    /**
+      * Requests to start a new autofill flow. Returns true if the autofill request is made to
+      * {@link AutofillManager#requestAutofill(View)}.
+      */
+    boolean requestAutofill(int sessionId, in AutofillId id);
 }
diff --git a/core/java/android/view/autofill/IAutoFillManagerClient.aidl b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
index 84949c8..3903665 100644
--- a/core/java/android/view/autofill/IAutoFillManagerClient.aidl
+++ b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
@@ -50,7 +50,7 @@
       * Authenticates a fill response or a data set.
       */
     void authenticate(int sessionId, int authenticationId, in IntentSender intent,
-            in Intent fillInIntent);
+            in Intent fillInIntent, boolean authenticateInline);
 
     /**
       * Sets the views to track. If saveOnAllViewsInvisible is set and all these view are invisible
diff --git a/core/java/android/view/inline/InlinePresentationSpec.java b/core/java/android/view/inline/InlinePresentationSpec.java
index a85b5f1..406e599 100644
--- a/core/java/android/view/inline/InlinePresentationSpec.java
+++ b/core/java/android/view/inline/InlinePresentationSpec.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.os.Parcelable;
 import android.util.Size;
 
@@ -55,6 +56,7 @@
     /**
      * @hide
      */
+    @SystemApi
     public @Nullable String getStyle() {
         return mStyle;
     }
@@ -281,10 +283,10 @@
     }
 
     @DataClass.Generated(
-            time = 1577145109444L,
+            time = 1581117017522L,
             codegenVersion = "1.0.14",
             sourceFile = "frameworks/base/core/java/android/view/inline/InlinePresentationSpec.java",
-            inputSignatures = "private final @android.annotation.NonNull android.util.Size mMinSize\nprivate final @android.annotation.NonNull android.util.Size mMaxSize\nprivate final @android.annotation.Nullable java.lang.String mStyle\nprivate static  java.lang.String defaultStyle()\npublic @android.annotation.Nullable java.lang.String getStyle()\nclass InlinePresentationSpec extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genBuilder=true)\nclass BaseBuilder extends java.lang.Object implements []")
+            inputSignatures = "private final @android.annotation.NonNull android.util.Size mMinSize\nprivate final @android.annotation.NonNull android.util.Size mMaxSize\nprivate final @android.annotation.Nullable java.lang.String mStyle\nprivate static  java.lang.String defaultStyle()\npublic @android.annotation.SystemApi @android.annotation.Nullable java.lang.String getStyle()\nclass InlinePresentationSpec extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genBuilder=true)\nclass BaseBuilder extends java.lang.Object implements []")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/view/inputmethod/InlineSuggestion.java b/core/java/android/view/inputmethod/InlineSuggestion.java
index a32ea4b..ec485d3 100644
--- a/core/java/android/view/inputmethod/InlineSuggestion.java
+++ b/core/java/android/view/inputmethod/InlineSuggestion.java
@@ -22,6 +22,7 @@
 import android.annotation.TestApi;
 import android.content.Context;
 import android.os.AsyncTask;
+import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.RemoteException;
 import android.util.Size;
@@ -32,6 +33,7 @@
 import android.view.inline.InlinePresentationSpec;
 
 import com.android.internal.util.DataClass;
+import com.android.internal.util.Parcelling;
 import com.android.internal.view.inline.IInlineContentCallback;
 import com.android.internal.view.inline.IInlineContentProvider;
 
@@ -62,6 +64,14 @@
     private final @Nullable IInlineContentProvider mContentProvider;
 
     /**
+     * Used to keep a strong reference to the callback so it doesn't get garbage collected.
+     *
+     * @hide
+     */
+    @DataClass.ParcelWith(InlineContentCallbackImplParceling.class)
+    private @Nullable InlineContentCallbackImpl mInlineContentCallback;
+
+    /**
      * Creates a new {@link InlineSuggestion}, for testing purpose.
      *
      * @hide
@@ -69,9 +79,19 @@
     @TestApi
     @NonNull
     public static InlineSuggestion newInlineSuggestion(@NonNull InlineSuggestionInfo info) {
-        return new InlineSuggestion(info, null);
+        return new InlineSuggestion(info, null, /* inlineContentCallback */ null);
     }
 
+    /**
+     * Creates a new {@link InlineSuggestion}.
+     *
+     * @hide
+     */
+    public InlineSuggestion(
+            @NonNull InlineSuggestionInfo info,
+            @Nullable IInlineContentProvider contentProvider) {
+        this(info, contentProvider, /* inlineContentCallback */ null);
+    }
 
 
 
@@ -79,12 +99,14 @@
      * Inflates a view with the content of this suggestion at a specific size.
      * The size must be between the {@link InlinePresentationSpec#getMinSize() min size}
      * and the {@link InlinePresentationSpec#getMaxSize() max size} of the presentation
-     * spec returned by {@link InlineSuggestionInfo#getPresentationSpec()}. If an invalid
-     * argument is passed an exception is thrown.
+     * spec returned by {@link InlineSuggestionInfo#getPresentationSpec()}.
      *
      * @param context Context in which to inflate the view.
      * @param size The size at which to inflate the suggestion.
      * @param callback Callback for receiving the inflated view.
+     *
+     * @throws IllegalArgumentException If an invalid argument is passed.
+     * @throws IllegalStateException if this method is already called.
      */
     public void inflate(@NonNull Context context, @NonNull Size size,
             @NonNull @CallbackExecutor Executor callbackExecutor,
@@ -96,19 +118,15 @@
             throw new IllegalArgumentException("size not between min:"
                     + minSize + " and max:" + maxSize);
         }
+        mInlineContentCallback = getInlineContentCallback(context, callbackExecutor, callback);
         AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
             if (mContentProvider == null) {
                 callback.accept(/* view */ null);
                 return;
             }
-            // TODO(b/137800469): keep a strong reference to the contentCallback so it doesn't
-            //  get GC'd. Also add a isInflated() method and make sure the view can only be
-            //  inflated once.
             try {
-                InlineContentCallbackImpl contentCallback = new InlineContentCallbackImpl(context,
-                        callbackExecutor, callback);
                 mContentProvider.provideContent(size.getWidth(), size.getHeight(),
-                        new InlineContentCallbackWrapper(contentCallback));
+                        new InlineContentCallbackWrapper(mInlineContentCallback));
             } catch (RemoteException e) {
                 Slog.w(TAG, "Error creating suggestion content surface: " + e);
                 callback.accept(/* view */ null);
@@ -116,6 +134,14 @@
         });
     }
 
+    private synchronized InlineContentCallbackImpl getInlineContentCallback(Context context,
+            Executor callbackExecutor, Consumer<View> callback) {
+        if (mInlineContentCallback != null) {
+            throw new IllegalStateException("Already called #inflate()");
+        }
+        return new InlineContentCallbackImpl(context, callbackExecutor, callback);
+    }
+
     private static final class InlineContentCallbackWrapper extends IInlineContentCallback.Stub {
 
         private final WeakReference<InlineContentCallbackImpl> mCallbackImpl;
@@ -157,6 +183,22 @@
         }
     }
 
+    /**
+     * This class used to provide parcelling logic for InlineContentCallbackImpl. It's intended to
+     * make this parcelling a no-op, since it can't be parceled and we don't need to parcel it.
+     */
+    private static class InlineContentCallbackImplParceling implements
+            Parcelling<InlineContentCallbackImpl> {
+        @Override
+        public void parcel(InlineContentCallbackImpl item, Parcel dest, int parcelFlags) {
+        }
+
+        @Override
+        public InlineContentCallbackImpl unparcel(Parcel source) {
+            return null;
+        }
+    }
+
 
 
     // Code below generated by codegen v1.0.14.
@@ -175,16 +217,20 @@
     /**
      * Creates a new InlineSuggestion.
      *
+     * @param inlineContentCallback
+     *   Used to keep a strong reference to the callback so it doesn't get garbage collected.
      * @hide
      */
     @DataClass.Generated.Member
     public InlineSuggestion(
             @NonNull InlineSuggestionInfo info,
-            @Nullable IInlineContentProvider contentProvider) {
+            @Nullable IInlineContentProvider contentProvider,
+            @Nullable InlineContentCallbackImpl inlineContentCallback) {
         this.mInfo = info;
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, mInfo);
         this.mContentProvider = contentProvider;
+        this.mInlineContentCallback = inlineContentCallback;
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -194,6 +240,16 @@
         return mInfo;
     }
 
+    /**
+     * Used to keep a strong reference to the callback so it doesn't get garbage collected.
+     *
+     * @hide
+     */
+    @DataClass.Generated.Member
+    public @Nullable InlineContentCallbackImpl getInlineContentCallback() {
+        return mInlineContentCallback;
+    }
+
     @Override
     @DataClass.Generated.Member
     public String toString() {
@@ -202,7 +258,8 @@
 
         return "InlineSuggestion { " +
                 "info = " + mInfo + ", " +
-                "contentProvider = " + mContentProvider +
+                "contentProvider = " + mContentProvider + ", " +
+                "inlineContentCallback = " + mInlineContentCallback +
         " }";
     }
 
@@ -220,7 +277,8 @@
         //noinspection PointlessBooleanExpression
         return true
                 && java.util.Objects.equals(mInfo, that.mInfo)
-                && java.util.Objects.equals(mContentProvider, that.mContentProvider);
+                && java.util.Objects.equals(mContentProvider, that.mContentProvider)
+                && java.util.Objects.equals(mInlineContentCallback, that.mInlineContentCallback);
     }
 
     @Override
@@ -232,20 +290,34 @@
         int _hash = 1;
         _hash = 31 * _hash + java.util.Objects.hashCode(mInfo);
         _hash = 31 * _hash + java.util.Objects.hashCode(mContentProvider);
+        _hash = 31 * _hash + java.util.Objects.hashCode(mInlineContentCallback);
         return _hash;
     }
 
+    @DataClass.Generated.Member
+    static Parcelling<InlineContentCallbackImpl> sParcellingForInlineContentCallback =
+            Parcelling.Cache.get(
+                    InlineContentCallbackImplParceling.class);
+    static {
+        if (sParcellingForInlineContentCallback == null) {
+            sParcellingForInlineContentCallback = Parcelling.Cache.put(
+                    new InlineContentCallbackImplParceling());
+        }
+    }
+
     @Override
     @DataClass.Generated.Member
-    public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
         // You can override field parcelling by defining methods like:
         // void parcelFieldName(Parcel dest, int flags) { ... }
 
         byte flg = 0;
         if (mContentProvider != null) flg |= 0x2;
+        if (mInlineContentCallback != null) flg |= 0x4;
         dest.writeByte(flg);
         dest.writeTypedObject(mInfo, flags);
         if (mContentProvider != null) dest.writeStrongInterface(mContentProvider);
+        sParcellingForInlineContentCallback.parcel(mInlineContentCallback, dest, flags);
     }
 
     @Override
@@ -255,18 +327,20 @@
     /** @hide */
     @SuppressWarnings({"unchecked", "RedundantCast"})
     @DataClass.Generated.Member
-    /* package-private */ InlineSuggestion(@NonNull android.os.Parcel in) {
+    /* package-private */ InlineSuggestion(@NonNull Parcel in) {
         // You can override field unparcelling by defining methods like:
         // static FieldType unparcelFieldName(Parcel in) { ... }
 
         byte flg = in.readByte();
         InlineSuggestionInfo info = (InlineSuggestionInfo) in.readTypedObject(InlineSuggestionInfo.CREATOR);
         IInlineContentProvider contentProvider = (flg & 0x2) == 0 ? null : IInlineContentProvider.Stub.asInterface(in.readStrongBinder());
+        InlineContentCallbackImpl inlineContentCallback = sParcellingForInlineContentCallback.unparcel(in);
 
         this.mInfo = info;
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, mInfo);
         this.mContentProvider = contentProvider;
+        this.mInlineContentCallback = inlineContentCallback;
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -280,16 +354,16 @@
         }
 
         @Override
-        public InlineSuggestion createFromParcel(@NonNull android.os.Parcel in) {
+        public InlineSuggestion createFromParcel(@NonNull Parcel in) {
             return new InlineSuggestion(in);
         }
     };
 
     @DataClass.Generated(
-            time = 1578972138081L,
+            time = 1581929285156L,
             codegenVersion = "1.0.14",
             sourceFile = "frameworks/base/core/java/android/view/inputmethod/InlineSuggestion.java",
-            inputSignatures = "private static final  java.lang.String TAG\nprivate final @android.annotation.NonNull android.view.inputmethod.InlineSuggestionInfo mInfo\nprivate final @android.annotation.Nullable com.android.internal.view.inline.IInlineContentProvider mContentProvider\npublic static @android.annotation.TestApi @android.annotation.NonNull android.view.inputmethod.InlineSuggestion newInlineSuggestion(android.view.inputmethod.InlineSuggestionInfo)\npublic  void inflate(android.content.Context,android.util.Size,java.util.concurrent.Executor,java.util.function.Consumer<android.view.View>)\nclass InlineSuggestion extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genHiddenConstDefs=true, genHiddenConstructor=true)")
+            inputSignatures = "private static final  java.lang.String TAG\nprivate final @android.annotation.NonNull android.view.inputmethod.InlineSuggestionInfo mInfo\nprivate final @android.annotation.Nullable com.android.internal.view.inline.IInlineContentProvider mContentProvider\nprivate @com.android.internal.util.DataClass.ParcelWith(android.view.inputmethod.InlineSuggestion.InlineContentCallbackImplParceling.class) @android.annotation.Nullable android.view.inputmethod.InlineSuggestion.InlineContentCallbackImpl mInlineContentCallback\npublic static @android.annotation.TestApi @android.annotation.NonNull android.view.inputmethod.InlineSuggestion newInlineSuggestion(android.view.inputmethod.InlineSuggestionInfo)\npublic  void inflate(android.content.Context,android.util.Size,java.util.concurrent.Executor,java.util.function.Consumer<android.view.View>)\nprivate synchronized  android.view.inputmethod.InlineSuggestion.InlineContentCallbackImpl getInlineContentCallback(android.content.Context,java.util.concurrent.Executor,java.util.function.Consumer<android.view.View>)\nclass InlineSuggestion extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genHiddenConstDefs=true, genHiddenConstructor=true)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/view/inputmethod/InlineSuggestionsRequest.java b/core/java/android/view/inputmethod/InlineSuggestionsRequest.java
index 860ce90..be9370a 100644
--- a/core/java/android/view/inputmethod/InlineSuggestionsRequest.java
+++ b/core/java/android/view/inputmethod/InlineSuggestionsRequest.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityThread;
+import android.os.IBinder;
 import android.os.Parcelable;
 import android.view.inline.InlinePresentationSpec;
 
@@ -59,6 +60,14 @@
     private @NonNull String mHostPackageName;
 
     /**
+     * The host input token of the IME that made the request. This will be set by the system for
+     * safety reasons.
+     *
+     * @hide
+     */
+    private @Nullable IBinder mHostInputToken;
+
+    /**
      * @hide
      * @see {@link #mHostPackageName}.
      */
@@ -66,6 +75,14 @@
         mHostPackageName = hostPackageName;
     }
 
+    /**
+     * @hide
+     * @see {@link #mHostInputToken}.
+     */
+    public void setHostInputToken(IBinder hostInputToken) {
+        mHostInputToken = hostInputToken;
+    }
+
     private void onConstructed() {
         Preconditions.checkState(mMaxSuggestionCount >= mPresentationSpecs.size());
     }
@@ -78,11 +95,17 @@
         return ActivityThread.currentPackageName();
     }
 
+    private static IBinder defaultHostInputToken() {
+        return null;
+    }
+
     /** @hide */
     abstract static class BaseBuilder {
         abstract Builder setPresentationSpecs(@NonNull List<InlinePresentationSpec> value);
 
         abstract Builder setHostPackageName(@Nullable String value);
+
+        abstract Builder setHostInputToken(IBinder hostInputToken);
     }
 
 
@@ -104,7 +127,8 @@
     /* package-private */ InlineSuggestionsRequest(
             int maxSuggestionCount,
             @NonNull List<InlinePresentationSpec> presentationSpecs,
-            @NonNull String hostPackageName) {
+            @NonNull String hostPackageName,
+            @Nullable IBinder hostInputToken) {
         this.mMaxSuggestionCount = maxSuggestionCount;
         this.mPresentationSpecs = presentationSpecs;
         com.android.internal.util.AnnotationValidations.validate(
@@ -112,6 +136,7 @@
         this.mHostPackageName = hostPackageName;
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, mHostPackageName);
+        this.mHostInputToken = hostInputToken;
 
         onConstructed();
     }
@@ -145,6 +170,17 @@
         return mHostPackageName;
     }
 
+    /**
+     * The host input token of the IME that made the request. This will be set by the system for
+     * safety reasons.
+     *
+     * @hide
+     */
+    @DataClass.Generated.Member
+    public @Nullable IBinder getHostInputToken() {
+        return mHostInputToken;
+    }
+
     @Override
     @DataClass.Generated.Member
     public String toString() {
@@ -154,7 +190,8 @@
         return "InlineSuggestionsRequest { " +
                 "maxSuggestionCount = " + mMaxSuggestionCount + ", " +
                 "presentationSpecs = " + mPresentationSpecs + ", " +
-                "hostPackageName = " + mHostPackageName +
+                "hostPackageName = " + mHostPackageName + ", " +
+                "hostInputToken = " + mHostInputToken +
         " }";
     }
 
@@ -173,7 +210,8 @@
         return true
                 && mMaxSuggestionCount == that.mMaxSuggestionCount
                 && java.util.Objects.equals(mPresentationSpecs, that.mPresentationSpecs)
-                && java.util.Objects.equals(mHostPackageName, that.mHostPackageName);
+                && java.util.Objects.equals(mHostPackageName, that.mHostPackageName)
+                && java.util.Objects.equals(mHostInputToken, that.mHostInputToken);
     }
 
     @Override
@@ -186,6 +224,7 @@
         _hash = 31 * _hash + mMaxSuggestionCount;
         _hash = 31 * _hash + java.util.Objects.hashCode(mPresentationSpecs);
         _hash = 31 * _hash + java.util.Objects.hashCode(mHostPackageName);
+        _hash = 31 * _hash + java.util.Objects.hashCode(mHostInputToken);
         return _hash;
     }
 
@@ -195,9 +234,13 @@
         // You can override field parcelling by defining methods like:
         // void parcelFieldName(Parcel dest, int flags) { ... }
 
+        byte flg = 0;
+        if (mHostInputToken != null) flg |= 0x8;
+        dest.writeByte(flg);
         dest.writeInt(mMaxSuggestionCount);
         dest.writeParcelableList(mPresentationSpecs, flags);
         dest.writeString(mHostPackageName);
+        if (mHostInputToken != null) dest.writeStrongBinder(mHostInputToken);
     }
 
     @Override
@@ -211,10 +254,12 @@
         // You can override field unparcelling by defining methods like:
         // static FieldType unparcelFieldName(Parcel in) { ... }
 
+        byte flg = in.readByte();
         int maxSuggestionCount = in.readInt();
         List<InlinePresentationSpec> presentationSpecs = new ArrayList<>();
         in.readParcelableList(presentationSpecs, InlinePresentationSpec.class.getClassLoader());
         String hostPackageName = in.readString();
+        IBinder hostInputToken = (flg & 0x8) == 0 ? null : in.readStrongBinder();
 
         this.mMaxSuggestionCount = maxSuggestionCount;
         this.mPresentationSpecs = presentationSpecs;
@@ -223,6 +268,7 @@
         this.mHostPackageName = hostPackageName;
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, mHostPackageName);
+        this.mHostInputToken = hostInputToken;
 
         onConstructed();
     }
@@ -251,6 +297,7 @@
         private int mMaxSuggestionCount;
         private @NonNull List<InlinePresentationSpec> mPresentationSpecs;
         private @NonNull String mHostPackageName;
+        private @Nullable IBinder mHostInputToken;
 
         private long mBuilderFieldsSet = 0L;
 
@@ -320,10 +367,25 @@
             return this;
         }
 
+        /**
+         * The host input token of the IME that made the request. This will be set by the system for
+         * safety reasons.
+         *
+         * @hide
+         */
+        @DataClass.Generated.Member
+        @Override
+        @NonNull Builder setHostInputToken(@Nullable IBinder value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x8;
+            mHostInputToken = value;
+            return this;
+        }
+
         /** Builds the instance. This builder should not be touched after calling this! */
         public @NonNull InlineSuggestionsRequest build() {
             checkNotUsed();
-            mBuilderFieldsSet |= 0x8; // Mark builder used
+            mBuilderFieldsSet |= 0x10; // Mark builder used
 
             if ((mBuilderFieldsSet & 0x1) == 0) {
                 mMaxSuggestionCount = defaultMaxSuggestionCount();
@@ -331,15 +393,19 @@
             if ((mBuilderFieldsSet & 0x4) == 0) {
                 mHostPackageName = defaultHostPackageName();
             }
+            if ((mBuilderFieldsSet & 0x8) == 0) {
+                mHostInputToken = defaultHostInputToken();
+            }
             InlineSuggestionsRequest o = new InlineSuggestionsRequest(
                     mMaxSuggestionCount,
                     mPresentationSpecs,
-                    mHostPackageName);
+                    mHostPackageName,
+                    mHostInputToken);
             return o;
         }
 
         private void checkNotUsed() {
-            if ((mBuilderFieldsSet & 0x8) != 0) {
+            if ((mBuilderFieldsSet & 0x10) != 0) {
                 throw new IllegalStateException(
                         "This Builder should not be reused. Use a new Builder instance instead");
             }
@@ -347,10 +413,10 @@
     }
 
     @DataClass.Generated(
-            time = 1578948035951L,
+            time = 1581555687721L,
             codegenVersion = "1.0.14",
             sourceFile = "frameworks/base/core/java/android/view/inputmethod/InlineSuggestionsRequest.java",
-            inputSignatures = "public static final  int SUGGESTION_COUNT_UNLIMITED\nprivate final  int mMaxSuggestionCount\nprivate final @android.annotation.NonNull java.util.List<android.view.inline.InlinePresentationSpec> mPresentationSpecs\nprivate @android.annotation.NonNull java.lang.String mHostPackageName\npublic  void setHostPackageName(java.lang.String)\nprivate  void onConstructed()\nprivate static  int defaultMaxSuggestionCount()\nprivate static  java.lang.String defaultHostPackageName()\nclass InlineSuggestionsRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genBuilder=true)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setPresentationSpecs(java.util.List<android.view.inline.InlinePresentationSpec>)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostPackageName(java.lang.String)\nclass BaseBuilder extends java.lang.Object implements []")
+            inputSignatures = "public static final  int SUGGESTION_COUNT_UNLIMITED\nprivate final  int mMaxSuggestionCount\nprivate final @android.annotation.NonNull java.util.List<android.view.inline.InlinePresentationSpec> mPresentationSpecs\nprivate @android.annotation.NonNull java.lang.String mHostPackageName\nprivate @android.annotation.Nullable android.os.IBinder mHostInputToken\npublic  void setHostPackageName(java.lang.String)\npublic  void setHostInputToken(android.os.IBinder)\nprivate  void onConstructed()\nprivate static  int defaultMaxSuggestionCount()\nprivate static  java.lang.String defaultHostPackageName()\nprivate static  android.os.IBinder defaultHostInputToken()\nclass InlineSuggestionsRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genBuilder=true)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setPresentationSpecs(java.util.List<android.view.inline.InlinePresentationSpec>)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostPackageName(java.lang.String)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostInputToken(android.os.IBinder)\nclass BaseBuilder extends java.lang.Object implements []")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java
index 3824c22..ff80ef7 100644
--- a/core/java/android/webkit/CookieManager.java
+++ b/core/java/android/webkit/CookieManager.java
@@ -102,6 +102,9 @@
      * path and name will be replaced with the new cookie. The cookie being set
      * will be ignored if it is expired.
      *
+     * <p class="note"><b>Note:</b> if specifying a {@code value} containing the {@code "Secure"}
+     * attribute, {@code url} must use the {@code "https://"} scheme.
+     *
      * @param url the URL for which the cookie is to be set
      * @param value the cookie as a string, using the format of the 'Set-Cookie'
      *              HTTP response header
@@ -122,6 +125,9 @@
      * completes or whether it succeeded, and in this case it is safe to call the method from a
      * thread without a Looper.
      *
+     * <p class="note"><b>Note:</b> if specifying a {@code value} containing the {@code "Secure"}
+     * attribute, {@code url} must use the {@code "https://"} scheme.
+     *
      * @param url the URL for which the cookie is to be set
      * @param value the cookie as a string, using the format of the 'Set-Cookie'
      *              HTTP response header
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 469ab2e..0182975 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8282,9 +8282,9 @@
         if (getKeyListener() != null && !mSingleLine && mEditor != null
                 && (mEditor.mInputType & EditorInfo.TYPE_MASK_CLASS)
                         == EditorInfo.TYPE_CLASS_TEXT) {
-            int variation = mEditor.mInputType & EditorInfo.TYPE_MASK_VARIATION;
-            if (variation == EditorInfo.TYPE_TEXT_FLAG_IME_MULTI_LINE
-                    || variation == EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE) {
+            int multilineFlags = EditorInfo.TYPE_TEXT_FLAG_IME_MULTI_LINE
+                    | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
+            if ((mEditor.mInputType & multilineFlags) != 0) {
                 return false;
             }
         }
diff --git a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
index a1c22e9..bb40465 100644
--- a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
+++ b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
@@ -262,8 +262,6 @@
         String toastMessage = String.format(toastMessageFormatString, serviceName);
         Toast warningToast = mFrameworkObjectProvider.makeToastFromText(
                 mContext, toastMessage, Toast.LENGTH_LONG);
-        warningToast.getWindowParams().privateFlags |=
-                WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
         warningToast.show();
     }
 
diff --git a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
index 78e8518..e8f84aa 100644
--- a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
@@ -61,6 +61,7 @@
     private Set<Integer> mLoadedPages;
     private final UserHandle mPersonalProfileUserHandle;
     private final UserHandle mWorkProfileUserHandle;
+    private Injector mInjector;
 
     AbstractMultiProfilePagerAdapter(Context context, int currentPage,
             UserHandle personalProfileUserHandle,
@@ -70,6 +71,33 @@
         mLoadedPages = new HashSet<>();
         mPersonalProfileUserHandle = personalProfileUserHandle;
         mWorkProfileUserHandle = workProfileUserHandle;
+        UserManager userManager = context.getSystemService(UserManager.class);
+        mInjector = new Injector() {
+            @Override
+            public boolean hasCrossProfileIntents(List<Intent> intents, int sourceUserId,
+                    int targetUserId) {
+                return AbstractMultiProfilePagerAdapter.this
+                        .hasCrossProfileIntents(intents, sourceUserId, targetUserId);
+            }
+
+            @Override
+            public boolean isQuietModeEnabled(UserHandle workProfileUserHandle) {
+                return userManager.isQuietModeEnabled(workProfileUserHandle);
+            }
+
+            @Override
+            public void requestQuietModeEnabled(boolean enabled, UserHandle workProfileUserHandle) {
+                userManager.requestQuietModeEnabled(enabled, workProfileUserHandle);
+            }
+        };
+    }
+
+    /**
+     * Overrides the default {@link Injector} for testing purposes.
+     */
+    @VisibleForTesting
+    public void setInjector(Injector injector) {
+        mInjector = injector;
     }
 
     void setOnProfileSelectedListener(OnProfileSelectedListener listener) {
@@ -252,19 +280,18 @@
 
     private boolean rebuildTab(ResolverListAdapter activeListAdapter, boolean doPostProcessing) {
         UserHandle listUserHandle = activeListAdapter.getUserHandle();
-        UserManager userManager = mContext.getSystemService(UserManager.class);
         if (listUserHandle == mWorkProfileUserHandle
-                && userManager.isQuietModeEnabled(mWorkProfileUserHandle)) {
+                && mInjector.isQuietModeEnabled(mWorkProfileUserHandle)) {
             showEmptyState(activeListAdapter,
                     R.drawable.ic_work_apps_off,
                     R.string.resolver_turn_on_work_apps,
                     R.string.resolver_turn_on_work_apps_explanation,
                     (View.OnClickListener) v ->
-                            userManager.requestQuietModeEnabled(false, mWorkProfileUserHandle));
+                            mInjector.requestQuietModeEnabled(false, mWorkProfileUserHandle));
             return false;
         }
         if (UserHandle.myUserId() != listUserHandle.getIdentifier()) {
-            if (!hasCrossProfileIntents(activeListAdapter.getIntents(),
+            if (!mInjector.hasCrossProfileIntents(activeListAdapter.getIntents(),
                     UserHandle.myUserId(), listUserHandle.getIdentifier())) {
                 if (listUserHandle == mPersonalProfileUserHandle) {
                     showEmptyState(activeListAdapter,
@@ -280,6 +307,7 @@
                 return false;
             }
         }
+        showListView(activeListAdapter);
         return activeListAdapter.rebuildList(doPostProcessing);
     }
 
@@ -322,6 +350,14 @@
         button.setOnClickListener(buttonOnClick);
     }
 
+    private void showListView(ResolverListAdapter activeListAdapter) {
+        ProfileDescriptor descriptor = getItem(
+                userHandleToPageIndex(activeListAdapter.getUserHandle()));
+        descriptor.rootView.findViewById(R.id.resolver_list).setVisibility(View.VISIBLE);
+        View emptyStateView = descriptor.rootView.findViewById(R.id.resolver_empty_state);
+        emptyStateView.setVisibility(View.GONE);
+    }
+
     private boolean hasCrossProfileIntents(List<Intent> intents, int source, int target) {
         IPackageManager packageManager = AppGlobals.getPackageManager();
         ContentResolver contentResolver = mContext.getContentResolver();
@@ -366,4 +402,26 @@
          */
         void onProfileSelected(int profileIndex);
     }
+
+    /**
+     * Describes an injector to be used for cross profile functionality. Overridable for testing.
+     */
+    @VisibleForTesting
+    public interface Injector {
+        /**
+         * Returns {@code true} if at least one of the provided {@code intents} can be forwarded
+         * from {@code sourceUserId} to {@code targetUserId}.
+         */
+        boolean hasCrossProfileIntents(List<Intent> intents, int sourceUserId, int targetUserId);
+
+        /**
+         * Returns whether the given profile is in quiet mode or not.
+         */
+        boolean isQuietModeEnabled(UserHandle workProfileUserHandle);
+
+        /**
+         * Enables or disables quiet mode for a managed profile.
+         */
+        void requestQuietModeEnabled(boolean enabled, UserHandle workProfileUserHandle);
+    }
 }
\ No newline at end of file
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 07ca79a..dc801a9 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -1476,7 +1476,6 @@
 
     @Override
     public void addUseDifferentAppLabelIfNecessary(ResolverListAdapter adapter) {
-        mChooserMultiProfilePagerAdapter.getActiveAdapterView().setVisibility(View.VISIBLE);
         if (mCallerChooserTargets != null && mCallerChooserTargets.length > 0) {
             mChooserMultiProfilePagerAdapter.getActiveListAdapter().addServiceResults(
                     /* origTarget */ null,
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index dabaf5a..1c1c254 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -18,6 +18,8 @@
 
 import android.app.AppOpsManager;
 import android.app.AsyncNotedAppOp;
+import android.app.SyncNotedAppOp;
+import android.app.RuntimeAppOpAccessMessage;
 import android.content.pm.ParceledListSlice;
 import android.os.Bundle;
 import android.os.RemoteCallback;
@@ -25,6 +27,7 @@
 import com.android.internal.app.IAppOpsActiveCallback;
 import com.android.internal.app.IAppOpsAsyncNotedCallback;
 import com.android.internal.app.IAppOpsNotedCallback;
+import com.android.internal.app.MessageSamplingConfig;
 
 interface IAppOpsService {
     // These methods are also called by native code, so must
@@ -54,6 +57,9 @@
 
     // Remaining methods are only used in Java.
     int checkPackage(int uid, String packageName);
+    RuntimeAppOpAccessMessage collectRuntimeAppOpAccessMessage();
+    MessageSamplingConfig reportRuntimeAppOpAccessMessageAndGetConfig(String packageName,
+            in SyncNotedAppOp appOp, String message);
     @UnsupportedAppUsage
     List<AppOpsManager.PackageOps> getPackagesForOps(in int[] ops);
     @UnsupportedAppUsage
diff --git a/core/java/com/android/internal/view/animation/NativeInterpolatorFactory.java b/core/java/com/android/internal/app/MessageSamplingConfig.aidl
similarity index 75%
rename from core/java/com/android/internal/view/animation/NativeInterpolatorFactory.java
rename to core/java/com/android/internal/app/MessageSamplingConfig.aidl
index fcacd52..ab89ca2 100644
--- a/core/java/com/android/internal/view/animation/NativeInterpolatorFactory.java
+++ b/core/java/com/android/internal/app/MessageSamplingConfig.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2019 The Android Open 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,8 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.internal.view.animation;
+package com.android.internal.app;
 
-public interface NativeInterpolatorFactory {
-    long createNativeInterpolator();
-}
+parcelable MessageSamplingConfig;
diff --git a/core/java/com/android/internal/app/MessageSamplingConfig.java b/core/java/com/android/internal/app/MessageSamplingConfig.java
new file mode 100644
index 0000000..5300c1c
--- /dev/null
+++ b/core/java/com/android/internal/app/MessageSamplingConfig.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.app.AppOpsManager;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.annotations.Immutable;
+import com.android.internal.util.DataClass;
+
+/**
+ * Configuration for AppOps access messages sampling.
+ */
+@Immutable
+/*@DataClass*/
+public final class MessageSamplingConfig implements Parcelable {
+    /** Op code targeted during current sampling session */
+    private final @IntRange(from = -1L, to = AppOpsManager._NUM_OP - 1) int mSampledOpCode;
+    /** Range of ops which should be reported during current sampling session */
+    private final @IntRange(from = 0L, to = AppOpsManager._NUM_OP - 1) int mAcceptableLeftDistance;
+    /** Expiration time for this sampling config */
+    private final @IntRange(from = 0L) long mExpirationTimeSinceBootMillis;
+
+
+
+
+
+
+
+    // Code below generated by codegen v1.0.14.
+    //
+    // DO NOT MODIFY!
+    // CHECKSTYLE:OFF Generated code
+    //
+    // To regenerate run:
+    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/com/android/internal/app/MessageSamplingConfig.java
+    //
+    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+    //   Settings > Editor > Code Style > Formatter Control
+    //@formatter:off
+
+
+    /**
+     * Creates a new MessageSamplingConfig.
+     *
+     * @param sampledOpCode
+     *   Op code targeted during current sampling session
+     * @param acceptableLeftDistance
+     *   Range of ops which should be reported during current sampling session
+     * @param expirationTimeSinceBootMillis
+     *   Expiration time for this sampling config
+     */
+    @DataClass.Generated.Member
+    public MessageSamplingConfig(
+            @IntRange(from = -1L, to = AppOpsManager._NUM_OP - 1) int sampledOpCode,
+            @IntRange(from = 0L, to = AppOpsManager._NUM_OP - 1) int acceptableLeftDistance,
+            @IntRange(from = 0L) long expirationTimeSinceBootMillis) {
+        this.mSampledOpCode = sampledOpCode;
+        com.android.internal.util.AnnotationValidations.validate(
+                IntRange.class, null, mSampledOpCode,
+                "from", -1L,
+                "to", AppOpsManager._NUM_OP - 1);
+        this.mAcceptableLeftDistance = acceptableLeftDistance;
+        com.android.internal.util.AnnotationValidations.validate(
+                IntRange.class, null, mAcceptableLeftDistance,
+                "from", 0L,
+                "to", AppOpsManager._NUM_OP - 1);
+        this.mExpirationTimeSinceBootMillis = expirationTimeSinceBootMillis;
+        com.android.internal.util.AnnotationValidations.validate(
+                IntRange.class, null, mExpirationTimeSinceBootMillis,
+                "from", 0L);
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    /**
+     * Op code targeted during current sampling session
+     */
+    @DataClass.Generated.Member
+    public @IntRange(from = -1L, to = AppOpsManager._NUM_OP - 1) int getSampledOpCode() {
+        return mSampledOpCode;
+    }
+
+    /**
+     * Range of ops which should be reported during current sampling session
+     */
+    @DataClass.Generated.Member
+    public @IntRange(from = 0L, to = AppOpsManager._NUM_OP - 1) int getAcceptableLeftDistance() {
+        return mAcceptableLeftDistance;
+    }
+
+    /**
+     * Expiration time for this sampling config
+     */
+    @DataClass.Generated.Member
+    public @IntRange(from = 0L) long getExpirationTimeSinceBootMillis() {
+        return mExpirationTimeSinceBootMillis;
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        // You can override field parcelling by defining methods like:
+        // void parcelFieldName(Parcel dest, int flags) { ... }
+
+        dest.writeInt(mSampledOpCode);
+        dest.writeInt(mAcceptableLeftDistance);
+        dest.writeLong(mExpirationTimeSinceBootMillis);
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public int describeContents() { return 0; }
+
+    /** @hide */
+    @SuppressWarnings({"unchecked", "RedundantCast"})
+    @DataClass.Generated.Member
+    /* package-private */ MessageSamplingConfig(@NonNull Parcel in) {
+        // You can override field unparcelling by defining methods like:
+        // static FieldType unparcelFieldName(Parcel in) { ... }
+
+        int sampledOpCode = in.readInt();
+        int acceptableLeftDistance = in.readInt();
+        long expirationTimeSinceBootMillis = in.readLong();
+
+        this.mSampledOpCode = sampledOpCode;
+        com.android.internal.util.AnnotationValidations.validate(
+                IntRange.class, null, mSampledOpCode,
+                "from", -1L,
+                "to", AppOpsManager._NUM_OP - 1);
+        this.mAcceptableLeftDistance = acceptableLeftDistance;
+        com.android.internal.util.AnnotationValidations.validate(
+                IntRange.class, null, mAcceptableLeftDistance,
+                "from", 0L,
+                "to", AppOpsManager._NUM_OP - 1);
+        this.mExpirationTimeSinceBootMillis = expirationTimeSinceBootMillis;
+        com.android.internal.util.AnnotationValidations.validate(
+                IntRange.class, null, mExpirationTimeSinceBootMillis,
+                "from", 0L);
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    @DataClass.Generated.Member
+    public static final @NonNull Parcelable.Creator<MessageSamplingConfig> CREATOR
+            = new Parcelable.Creator<MessageSamplingConfig>() {
+        @Override
+        public MessageSamplingConfig[] newArray(int size) {
+            return new MessageSamplingConfig[size];
+        }
+
+        @Override
+        public MessageSamplingConfig createFromParcel(@NonNull Parcel in) {
+            return new MessageSamplingConfig(in);
+        }
+    };
+
+    /*@DataClass.Generated(
+            time = 1580691255495L,
+            codegenVersion = "1.0.14",
+            sourceFile = "frameworks/base/core/java/com/android/internal/app/MessageSamplingConfig.java",
+            inputSignatures = "private final @android.annotation.IntRange(from=-1L, to=AppOpsManager._NUM_OP - 1) int mSampledOpCode\nprivate final @android.annotation.IntRange(from=0L, to=AppOpsManager._NUM_OP - 1) int mAcceptableLeftDistance\nprivate final @android.annotation.IntRange(from=0L) long mExpirationTimeSinceBootMillis\nclass MessageSamplingConfig extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass")*/
+    @Deprecated
+    private void __metadata() {}
+
+
+    //@formatter:on
+    // End of generated code
+
+}
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index c2c9fff..5dc8b0b 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -34,6 +34,7 @@
 import android.app.VoiceInteractor.PickOptionRequest.Option;
 import android.app.VoiceInteractor.Prompt;
 import android.compat.annotation.UnsupportedAppUsage;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -169,6 +170,8 @@
     // Intent extra for connected audio devices
     public static final String EXTRA_IS_AUDIO_CAPTURE_DEVICE = "is_audio_capture_device";
 
+    private BroadcastReceiver mWorkProfileStateReceiver;
+
     /**
      * Get the string resource to be used as a label for the link to the resolver activity for an
      * action.
@@ -387,10 +390,12 @@
                     | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
             rdl.setOnApplyWindowInsetsListener(this::onApplyWindowInsets);
 
-            rdl.setMaxCollapsedHeight(hasWorkProfile() && ENABLE_TABBED_VIEW
-                    ? getResources().getDimensionPixelSize(
-                            R.dimen.resolver_empty_state_height_with_tabs)
-                    : getResources().getDimensionPixelSize(R.dimen.resolver_empty_state_height));
+            if (hasWorkProfile() && ENABLE_TABBED_VIEW) {
+                rdl.setMaxCollapsedHeight(getResources().getDimensionPixelSize(
+                        R.dimen.resolver_empty_state_height_with_tabs));
+                findViewById(R.id.profile_pager).setMinimumHeight(
+                        getResources().getDimensionPixelSize(R.dimen.resolver_empty_state_height));
+            }
 
             mResolverDrawerLayout = rdl;
         }
@@ -738,6 +743,22 @@
     }
 
     @Override
+    protected void onStart() {
+        super.onStart();
+        if (hasWorkProfile() && ENABLE_TABBED_VIEW) {
+            mWorkProfileStateReceiver = createWorkProfileStateReceiver();
+            registerWorkProfileStateReceiver();
+        }
+    }
+
+    private void registerWorkProfileStateReceiver() {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
+        filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
+        registerReceiverAsUser(mWorkProfileStateReceiver, UserHandle.ALL, filter, null, null);
+    }
+
+    @Override
     protected void onStop() {
         super.onStop();
         if (mRegistered) {
@@ -761,6 +782,10 @@
                 finish();
             }
         }
+        if (mWorkPackageMonitor != null) {
+            unregisterReceiver(mWorkProfileStateReceiver);
+            mWorkPackageMonitor = null;
+        }
     }
 
     @Override
@@ -1679,6 +1704,25 @@
         }
     }
 
+    private BroadcastReceiver createWorkProfileStateReceiver() {
+        return new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                String action = intent.getAction();
+                if (!TextUtils.equals(action, Intent.ACTION_MANAGED_PROFILE_AVAILABLE)
+                        && !TextUtils.equals(action, Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)) {
+                    return;
+                }
+                if (mMultiProfilePagerAdapter.getCurrentUserHandle()
+                        == getWorkProfileUserHandle()) {
+                    mMultiProfilePagerAdapter.rebuildActiveTab(true);
+                } else {
+                    mMultiProfilePagerAdapter.clearInactiveProfileCache();
+                }
+            }
+        };
+    }
+
     @VisibleForTesting
     public static final class ResolvedComponentInfo {
         public final ComponentName name;
diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java
index 140c410..75eb4aa 100644
--- a/core/java/com/android/internal/logging/MetricsLogger.java
+++ b/core/java/com/android/internal/logging/MetricsLogger.java
@@ -55,8 +55,11 @@
     protected void saveLog(LogMaker log) {
         // TODO(b/116684537): Flag guard logging to event log and statsd socket.
         EventLogTags.writeSysuiMultiAction(log.serialize());
-        FrameworkStatsLog.write(FrameworkStatsLog.KEY_VALUE_PAIRS_ATOM,
-                /* UID is retrieved from statsd side */ 0, log.getEntries());
+        if (log.getCategory() != MetricsEvent.RESERVED_FOR_LOGBUILDER_COUNTER
+                && log.getCategory() != MetricsEvent.RESERVED_FOR_LOGBUILDER_HISTOGRAM) {
+            FrameworkStatsLog.write(FrameworkStatsLog.KEY_VALUE_PAIRS_ATOM,
+                    /* UID is retrieved from statsd side */ 0, log.getEntries());
+        }
     }
 
     public static final int VIEW_UNKNOWN = MetricsEvent.VIEW_UNKNOWN;
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 5565864..94924a5 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -24,7 +24,6 @@
 import android.net.Credentials;
 import android.net.LocalServerSocket;
 import android.net.LocalSocket;
-import android.os.Build;
 import android.os.FactoryTest;
 import android.os.IVold;
 import android.os.Process;
@@ -291,7 +290,7 @@
     static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
             int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
             int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
-            int targetSdkVersion, boolean isTopApp, String[] pkgDataInfoList) {
+            boolean isTopApp, String[] pkgDataInfoList) {
         ZygoteHooks.preFork();
 
         int pid = nativeForkAndSpecialize(
@@ -299,8 +298,6 @@
                 fdsToIgnore, startChildZygote, instructionSet, appDataDir, isTopApp,
                 pkgDataInfoList);
         if (pid == 0) {
-            Zygote.disableExecuteOnly(targetSdkVersion);
-
             // Note that this event ends at the end of handleChildProc,
             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
         }
@@ -696,8 +693,6 @@
                                  args.mInstructionSet, args.mAppDataDir, args.mIsTopApp,
                                  args.mPkgDataInfoList);
 
-            disableExecuteOnly(args.mTargetSdkVersion);
-
             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 
             return ZygoteInit.zygoteInit(args.mTargetSdkVersion,
@@ -777,17 +772,6 @@
     }
 
     /**
-     * Mark execute-only segments of libraries read+execute for apps with targetSdkVersion<Q.
-     */
-    private static void disableExecuteOnly(int targetSdkVersion) {
-        if ((targetSdkVersion < Build.VERSION_CODES.Q) && !nativeDisableExecuteOnly()) {
-            Log.e("Zygote", "Failed to set libraries to read+execute.");
-        }
-    }
-
-    private static native boolean nativeDisableExecuteOnly();
-
-    /**
      * @return  Raw file descriptors for the read-end of USAP reporting pipes.
      */
     static int[] getUsapPipeFDs() {
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index c91c661..4949811 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -257,8 +257,8 @@
         pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
                 parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
                 parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
-                parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion,
-                parsedArgs.mIsTopApp, parsedArgs.mPkgDataInfoList);
+                parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mIsTopApp,
+                parsedArgs.mPkgDataInfoList);
 
         try {
             if (pid == 0) {
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index e34aa97..a47bd17 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -653,17 +653,18 @@
         String classPathForElement = "";
         boolean compiledSomething = false;
         for (String classPathElement : classPathElements) {
-            // System server is fully AOTed and never profiled
-            // for profile guided compilation.
+            // We default to the verify filter because the compilation will happen on /data and
+            // system server cannot load executable code outside /system.
             String systemServerFilter = SystemProperties.get(
-                    "dalvik.vm.systemservercompilerfilter", "speed");
+                    "dalvik.vm.systemservercompilerfilter", "verify");
 
+            String classLoaderContext =
+                        getSystemServerClassLoaderContext(classPathForElement);
             int dexoptNeeded;
             try {
                 dexoptNeeded = DexFile.getDexOptNeeded(
                         classPathElement, instructionSet, systemServerFilter,
-                        null /* classLoaderContext */, false /* newProfile */,
-                        false /* downgrade */);
+                        classLoaderContext, false /* newProfile */, false /* downgrade */);
             } catch (FileNotFoundException ignored) {
                 // Do not add to the classpath.
                 Log.w(TAG, "Missing classpath element for system server: " + classPathElement);
@@ -684,8 +685,6 @@
                 final String compilerFilter = systemServerFilter;
                 final String uuid = StorageManager.UUID_PRIVATE_INTERNAL;
                 final String seInfo = null;
-                final String classLoaderContext =
-                        getSystemServerClassLoaderContext(classPathForElement);
                 final int targetSdkVersion = 0;  // SystemServer targets the system's SDK version
                 try {
                     installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName,
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index adb4036..36025e3 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -1627,9 +1627,12 @@
 
         int opacity = PixelFormat.OPAQUE;
         final WindowConfiguration winConfig = getResources().getConfiguration().windowConfiguration;
+        // TODO(b/149585281) remove when root task has the correct bounds for freeform
+        final boolean renderShadowsInCompositor = mWindow.mRenderShadowsInCompositor
+                && winConfig.getWindowingMode() != WINDOWING_MODE_FREEFORM;
         // If we draw shadows in the compositor we don't need to force the surface to be
         // translucent.
-        if (winConfig.hasWindowShadow() && !mWindow.mRenderShadowsInCompositor) {
+        if (winConfig.hasWindowShadow() && !renderShadowsInCompositor) {
             // If the window has a shadow, it must be translucent.
             opacity = PixelFormat.TRANSLUCENT;
         } else{
@@ -2414,16 +2417,18 @@
     }
 
     private void updateElevation() {
+        final int windowingMode =
+                getResources().getConfiguration().windowConfiguration.getWindowingMode();
+        final boolean renderShadowsInCompositor = mWindow.mRenderShadowsInCompositor
+                && windowingMode != WINDOWING_MODE_FREEFORM;
         // If rendering shadows in the compositor, don't set an elevation on the view
-        if (mWindow.mRenderShadowsInCompositor) {
+        if (renderShadowsInCompositor) {
             return;
         }
         float elevation = 0;
         final boolean wasAdjustedForStack = mElevationAdjustedForStack;
         // Do not use a shadow when we are in resizing mode (mBackdropFrameRenderer not null)
         // since the shadow is bound to the content size and not the target size.
-        final int windowingMode =
-                getResources().getConfiguration().windowConfiguration.getWindowingMode();
         if ((windowingMode == WINDOWING_MODE_FREEFORM) && !isResizing()) {
             elevation = hasWindowFocus() ?
                     DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP : DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP;
diff --git a/core/java/com/android/internal/policy/DockedDividerUtils.java b/core/java/com/android/internal/policy/DockedDividerUtils.java
index c68e506..b61b9de 100644
--- a/core/java/com/android/internal/policy/DockedDividerUtils.java
+++ b/core/java/com/android/internal/policy/DockedDividerUtils.java
@@ -16,14 +16,15 @@
 
 package com.android.internal.policy;
 
-import android.graphics.Rect;
-
 import static android.view.WindowManager.DOCKED_BOTTOM;
 import static android.view.WindowManager.DOCKED_INVALID;
 import static android.view.WindowManager.DOCKED_LEFT;
 import static android.view.WindowManager.DOCKED_RIGHT;
 import static android.view.WindowManager.DOCKED_TOP;
 
+import android.content.res.Resources;
+import android.graphics.Rect;
+
 /**
  * Utility functions for docked stack divider used by both window manager and System UI.
  *
@@ -105,23 +106,6 @@
         return start + (end - start) / 2 - dividerSize / 2;
     }
 
-    public static int getDockSideFromCreatedMode(boolean dockOnTopOrLeft,
-            boolean isHorizontalDivision) {
-        if (dockOnTopOrLeft) {
-            if (isHorizontalDivision) {
-                return DOCKED_TOP;
-            } else {
-                return DOCKED_LEFT;
-            }
-        } else {
-            if (isHorizontalDivision) {
-                return DOCKED_BOTTOM;
-            } else {
-                return DOCKED_RIGHT;
-            }
-        }
-    }
-
     public static int invertDockSide(int dockSide) {
         switch (dockSide) {
             case DOCKED_LEFT:
@@ -136,4 +120,21 @@
                 return DOCKED_INVALID;
         }
     }
+
+    /** Returns the inset distance from the divider window edge to the dividerview. */
+    public static int getDividerInsets(Resources res) {
+        return res.getDimensionPixelSize(com.android.internal.R.dimen.docked_stack_divider_insets);
+    }
+
+    /** Returns the size of the divider */
+    public static int getDividerSize(Resources res, int dividerInsets) {
+        final int windowWidth = res.getDimensionPixelSize(
+                com.android.internal.R.dimen.docked_stack_divider_thickness);
+        return windowWidth - 2 * dividerInsets;
+    }
+
+    /** Returns the docked-stack side */
+    public static int getDockSide(int displayWidth, int displayHeight) {
+        return displayWidth > displayHeight ? DOCKED_LEFT : DOCKED_TOP;
+    }
 }
diff --git a/core/java/com/android/internal/view/animation/NativeInterpolatorFactoryHelper.java b/core/java/com/android/internal/view/animation/NativeInterpolatorFactoryHelper.java
deleted file mode 100644
index ebeec40..0000000
--- a/core/java/com/android/internal/view/animation/NativeInterpolatorFactoryHelper.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.view.animation;
-
-/**
- * Static utility class for constructing native interpolators to keep the
- * JNI simpler
- */
-public final class NativeInterpolatorFactoryHelper {
-    private NativeInterpolatorFactoryHelper() {}
-
-    public static native long createAccelerateDecelerateInterpolator();
-    public static native long createAccelerateInterpolator(float factor);
-    public static native long createAnticipateInterpolator(float tension);
-    public static native long createAnticipateOvershootInterpolator(float tension);
-    public static native long createBounceInterpolator();
-    public static native long createCycleInterpolator(float cycles);
-    public static native long createDecelerateInterpolator(float factor);
-    public static native long createLinearInterpolator();
-    public static native long createOvershootInterpolator(float tension);
-    public static native long createPathInterpolator(float[] x, float[] y);
-    public static native long createLutInterpolator(float[] values);
-}
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 30d0d1d..900445c 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -42,9 +42,7 @@
         "android_util_StringBlock.cpp",
         "android_util_XmlBlock.cpp",
         "android_util_jar_StrictJarFile.cpp",
-        "android_view_RenderNodeAnimator.cpp",
         "com_android_internal_util_VirtualRefBasePtr.cpp",
-        "com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp",
     ],
 
     include_dirs: [
@@ -236,6 +234,7 @@
                 "libui",
                 "libgraphicsenv",
                 "libgui",
+                "libmediandk",
                 "libsensor",
                 "libinput",
                 "libcamera_client",
@@ -273,7 +272,6 @@
                 "libnativewindow",
                 "libdl",
                 "libdl_android",
-                "libstats_jni",
                 "libstatslog",
                 "server_configurable_flags",
                 "libstatspull",
@@ -351,6 +349,8 @@
         "android/graphics/apex/android_paint.cpp",
         "android/graphics/apex/android_region.cpp",
 
+        "android_graphics_animation_NativeInterpolatorFactory.cpp",
+        "android_graphics_animation_RenderNodeAnimator.cpp",
         "android_graphics_Canvas.cpp",
         "android_graphics_ColorSpace.cpp",
         "android_graphics_drawable_AnimatedVectorDrawable.cpp",
@@ -449,9 +449,10 @@
             ],
             shared_libs: [
                 "libandroidfw",
+                "libEGL",
+                "libmediandk",
                 "libnativedisplay",
                 "libnativewindow",
-                "libgui",
                 "libpdfium",
             ],
             static_libs: [
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 19f6e27..d790ada 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -108,7 +108,6 @@
 extern int register_android_app_admin_SecurityLog(JNIEnv* env);
 extern int register_android_content_AssetManager(JNIEnv* env);
 extern int register_android_util_EventLog(JNIEnv* env);
-extern int register_android_util_StatsLog(JNIEnv* env);
 extern int register_android_util_StatsLogInternal(JNIEnv* env);
 extern int register_android_util_Log(JNIEnv* env);
 extern int register_android_util_MemoryIntArray(JNIEnv* env);
@@ -119,13 +118,11 @@
 extern int register_android_view_DisplayEventReceiver(JNIEnv* env);
 extern int register_android_view_InputApplicationHandle(JNIEnv* env);
 extern int register_android_view_InputWindowHandle(JNIEnv* env);
-extern int register_android_view_RenderNodeAnimator(JNIEnv* env);
 extern int register_android_view_Surface(JNIEnv* env);
 extern int register_android_view_SurfaceControl(JNIEnv* env);
 extern int register_android_view_SurfaceSession(JNIEnv* env);
 extern int register_android_view_CompositionSamplingListener(JNIEnv* env);
 extern int register_android_view_TextureView(JNIEnv* env);
-extern int register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper(JNIEnv *env);
 extern int register_android_database_CursorWindow(JNIEnv* env);
 extern int register_android_database_SQLiteConnection(JNIEnv* env);
 extern int register_android_database_SQLiteGlobal(JNIEnv* env);
@@ -1434,7 +1431,6 @@
         REG_JNI(register_android_util_EventLog),
         REG_JNI(register_android_util_Log),
         REG_JNI(register_android_util_MemoryIntArray),
-        REG_JNI(register_android_util_StatsLog),
         REG_JNI(register_android_util_StatsLogInternal),
         REG_JNI(register_android_app_admin_SecurityLog),
         REG_JNI(register_android_content_AssetManager),
@@ -1461,7 +1457,6 @@
         REG_JNI(register_android_os_VintfRuntimeInfo),
         REG_JNI(register_android_service_DataLoaderService),
         REG_JNI(register_android_view_DisplayEventReceiver),
-        REG_JNI(register_android_view_RenderNodeAnimator),
         REG_JNI(register_android_view_InputApplicationHandle),
         REG_JNI(register_android_view_InputWindowHandle),
         REG_JNI(register_android_view_Surface),
@@ -1469,7 +1464,6 @@
         REG_JNI(register_android_view_SurfaceSession),
         REG_JNI(register_android_view_CompositionSamplingListener),
         REG_JNI(register_android_view_TextureView),
-        REG_JNI(register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper),
         REG_JNI(register_com_google_android_gles_jni_EGLImpl),
         REG_JNI(register_com_google_android_gles_jni_GLImpl),
         REG_JNI(register_android_opengl_jni_EGL14),
diff --git a/core/jni/LayoutlibLoader.cpp b/core/jni/LayoutlibLoader.cpp
index 7ceef98..7ee509b 100644
--- a/core/jni/LayoutlibLoader.cpp
+++ b/core/jni/LayoutlibLoader.cpp
@@ -65,6 +65,8 @@
 extern int register_android_graphics_PathMeasure(JNIEnv* env);
 extern int register_android_graphics_Picture(JNIEnv* env);
 extern int register_android_graphics_Region(JNIEnv* env);
+extern int register_android_graphics_animation_NativeInterpolatorFactory(JNIEnv* env);
+extern int register_android_graphics_animation_RenderNodeAnimator(JNIEnv* env);
 extern int register_android_graphics_drawable_AnimatedVectorDrawable(JNIEnv* env);
 extern int register_android_graphics_drawable_VectorDrawable(JNIEnv* env);
 extern int register_android_graphics_fonts_Font(JNIEnv* env);
@@ -82,10 +84,8 @@
 extern int register_android_util_PathParser(JNIEnv* env);
 extern int register_android_util_jar_StrictJarFile(JNIEnv* env);
 extern int register_android_view_RenderNode(JNIEnv* env);
-extern int register_android_view_RenderNodeAnimator(JNIEnv* env);
 extern int register_android_view_DisplayListCanvas(JNIEnv* env);
 extern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env);
-extern int register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper(JNIEnv *env);
 
 #define REG_JNI(name)      { name }
 struct RegJNIRec {
@@ -130,6 +130,10 @@
         {"android.graphics.Region", REG_JNI(register_android_graphics_Region)},
         {"android.graphics.Shader", REG_JNI(register_android_graphics_Shader)},
         {"android.graphics.Typeface", REG_JNI(register_android_graphics_Typeface)},
+        {"android.graphics.animation.NativeInterpolatorFactory",
+         REG_JNI(register_android_graphics_animation_NativeInterpolatorFactory)},
+        {"android.graphics.animation.RenderNodeAnimator",
+         REG_JNI(register_android_graphics_animation_RenderNodeAnimator)},
         {"android.graphics.drawable.AnimatedVectorDrawable",
          REG_JNI(register_android_graphics_drawable_AnimatedVectorDrawable)},
         {"android.graphics.drawable.VectorDrawable",
@@ -151,11 +155,8 @@
         {"android.util.Log", REG_JNI(register_android_util_Log)},
         {"android.util.PathParser", REG_JNI(register_android_util_PathParser)},
         {"android.util.jar.StrictJarFile", REG_JNI(register_android_util_jar_StrictJarFile)},
-        {"android.view.RenderNodeAnimator", REG_JNI(register_android_view_RenderNodeAnimator)},
         {"com.android.internal.util.VirtualRefBasePtr",
          REG_JNI(register_com_android_internal_util_VirtualRefBasePtr)},
-        {"com.android.internal.view.animation.NativeInterpolatorFactoryHelper",
-         REG_JNI(register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper)},
 };
 // Vector to store the names of classes that need delegates of their native methods
 static vector<string> classesToDelegate;
diff --git a/core/jni/android/graphics/apex/jni_runtime.cpp b/core/jni/android/graphics/apex/jni_runtime.cpp
index 1f66153..35c997d 100644
--- a/core/jni/android/graphics/apex/jni_runtime.cpp
+++ b/core/jni/android/graphics/apex/jni_runtime.cpp
@@ -60,6 +60,8 @@
 extern int register_android_graphics_Picture(JNIEnv*);
 extern int register_android_graphics_Region(JNIEnv* env);
 extern int register_android_graphics_SurfaceTexture(JNIEnv* env);
+extern int register_android_graphics_animation_NativeInterpolatorFactory(JNIEnv* env);
+extern int register_android_graphics_animation_RenderNodeAnimator(JNIEnv* env);
 extern int register_android_graphics_drawable_AnimatedVectorDrawable(JNIEnv* env);
 extern int register_android_graphics_drawable_VectorDrawable(JNIEnv* env);
 extern int register_android_graphics_fonts_Font(JNIEnv* env);
@@ -123,6 +125,8 @@
     REG_JNI(register_android_graphics_SurfaceTexture),
     REG_JNI(register_android_graphics_Typeface),
     REG_JNI(register_android_graphics_YuvImage),
+    REG_JNI(register_android_graphics_animation_NativeInterpolatorFactory),
+    REG_JNI(register_android_graphics_animation_RenderNodeAnimator),
     REG_JNI(register_android_graphics_drawable_AnimatedVectorDrawable),
     REG_JNI(register_android_graphics_drawable_VectorDrawable),
     REG_JNI(register_android_graphics_fonts_Font),
diff --git a/core/jni/com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp b/core/jni/android_graphics_animation_NativeInterpolatorFactory.cpp
similarity index 95%
rename from core/jni/com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp
rename to core/jni/android_graphics_animation_NativeInterpolatorFactory.cpp
index f4d2e7b..2073ac2 100644
--- a/core/jni/com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp
+++ b/core/jni/android_graphics_animation_NativeInterpolatorFactory.cpp
@@ -90,7 +90,7 @@
 // JNI Glue
 // ----------------------------------------------------------------------------
 
-const char* const kClassPathName = "com/android/internal/view/animation/NativeInterpolatorFactoryHelper";
+const char* const kClassPathName = "android/graphics/animation/NativeInterpolatorFactory";
 
 static const JNINativeMethod gMethods[] = {
     { "createAccelerateDecelerateInterpolator", "()J", (void*) createAccelerateDecelerateInterpolator },
@@ -106,7 +106,7 @@
     { "createLutInterpolator", "([F)J", (void*) createLutInterpolator },
 };
 
-int register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper(JNIEnv* env) {
+int register_android_graphics_animation_NativeInterpolatorFactory(JNIEnv* env) {
     return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
 }
 
diff --git a/core/jni/android_view_RenderNodeAnimator.cpp b/core/jni/android_graphics_animation_RenderNodeAnimator.cpp
similarity index 96%
rename from core/jni/android_view_RenderNodeAnimator.cpp
rename to core/jni/android_graphics_animation_RenderNodeAnimator.cpp
index ca32b00..878d4fc 100644
--- a/core/jni/android_view_RenderNodeAnimator.cpp
+++ b/core/jni/android_graphics_animation_RenderNodeAnimator.cpp
@@ -190,7 +190,7 @@
 // JNI Glue
 // ----------------------------------------------------------------------------
 
-const char* const kClassPathName = "android/view/RenderNodeAnimator";
+const char* const kClassPathName = "android/graphics/animation/RenderNodeAnimator";
 
 static const JNINativeMethod gMethods[] = {
     { "nCreateAnimator", "(IF)J", (void*) createAnimator },
@@ -203,12 +203,12 @@
     { "nSetStartDelay", "(JJ)V", (void*) setStartDelay },
     { "nSetInterpolator", "(JJ)V", (void*) setInterpolator },
     { "nSetAllowRunningAsync", "(JZ)V", (void*) setAllowRunningAsync },
-    { "nSetListener", "(JLandroid/view/RenderNodeAnimator;)V", (void*) setListener},
+    { "nSetListener", "(JLandroid/graphics/animation/RenderNodeAnimator;)V", (void*) setListener},
     { "nStart", "(J)V", (void*) start},
     { "nEnd", "(J)V", (void*) end },
 };
 
-int register_android_view_RenderNodeAnimator(JNIEnv* env) {
+int register_android_graphics_animation_RenderNodeAnimator(JNIEnv* env) {
     sLifecycleChecker.incStrong(0);
     gRenderNodeAnimatorClassInfo.clazz = FindClassOrDie(env, kClassPathName);
     gRenderNodeAnimatorClassInfo.clazz = MakeGlobalRefOrDie(env,
@@ -216,7 +216,7 @@
 
     gRenderNodeAnimatorClassInfo.callOnFinished = GetStaticMethodIDOrDie(
             env, gRenderNodeAnimatorClassInfo.clazz, "callOnFinished",
-            "(Landroid/view/RenderNodeAnimator;)V");
+            "(Landroid/graphics/animation/RenderNodeAnimator;)V");
 
     return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
 }
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 87be5f6..d8f30e9 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -566,10 +566,10 @@
     return (jint) status;
 }
 
-static jint
-android_media_AudioSystem_setPhoneState(JNIEnv *env, jobject thiz, jint state)
-{
-    return (jint) check_AudioSystem_Command(AudioSystem::setPhoneState((audio_mode_t) state));
+static jint android_media_AudioSystem_setPhoneState(JNIEnv *env, jobject thiz, jint state,
+                                                    jint uid) {
+    return (jint)check_AudioSystem_Command(
+            AudioSystem::setPhoneState((audio_mode_t)state, (uid_t)uid));
 }
 
 static jint
@@ -2434,7 +2434,7 @@
           (void *)android_media_AudioSystem_getDeviceConnectionState},
          {"handleDeviceConfigChange", "(ILjava/lang/String;Ljava/lang/String;I)I",
           (void *)android_media_AudioSystem_handleDeviceConfigChange},
-         {"setPhoneState", "(I)I", (void *)android_media_AudioSystem_setPhoneState},
+         {"setPhoneState", "(II)I", (void *)android_media_AudioSystem_setPhoneState},
          {"setForceUse", "(II)I", (void *)android_media_AudioSystem_setForceUse},
          {"getForceUse", "(I)I", (void *)android_media_AudioSystem_getForceUse},
          {"initStreamVolume", "(III)I", (void *)android_media_AudioSystem_initStreamVolume},
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index f564d75..ce9a048 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -65,6 +65,7 @@
 static struct {
     jclass clazz;
     jmethodID ctor;
+    jfieldID isInternal;
     jfieldID density;
     jfieldID secure;
 } gDisplayInfoClassInfo;
@@ -781,6 +782,8 @@
     }
 
     jobject object = env->NewObject(gDisplayInfoClassInfo.clazz, gDisplayInfoClassInfo.ctor);
+    env->SetBooleanField(object, gDisplayInfoClassInfo.isInternal,
+                         info.connectionType == DisplayConnectionType::Internal);
     env->SetFloatField(object, gDisplayInfoClassInfo.density, info.density);
     env->SetBooleanField(object, gDisplayInfoClassInfo.secure, info.secure);
     return object;
@@ -1528,6 +1531,7 @@
     jclass infoClazz = FindClassOrDie(env, "android/view/SurfaceControl$DisplayInfo");
     gDisplayInfoClassInfo.clazz = MakeGlobalRefOrDie(env, infoClazz);
     gDisplayInfoClassInfo.ctor = GetMethodIDOrDie(env, infoClazz, "<init>", "()V");
+    gDisplayInfoClassInfo.isInternal = GetFieldIDOrDie(env, infoClazz, "isInternal", "Z");
     gDisplayInfoClassInfo.density = GetFieldIDOrDie(env, infoClazz, "density", "F");
     gDisplayInfoClassInfo.secure = GetFieldIDOrDie(env, infoClazz, "secure", "Z");
 
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 5a8225c..27c5a73 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -17,40 +17,34 @@
 #define LOG_TAG "ThreadedRenderer"
 #define ATRACE_TAG ATRACE_TAG_VIEW
 
-#include <algorithm>
-#include <atomic>
-#include <inttypes.h>
-
-#include "jni.h"
-#include <nativehelper/JNIHelp.h>
-#include "core_jni_helpers.h"
-#include <GraphicsJNI.h>
-
-#include <gui/BufferItemConsumer.h>
-#include <gui/BufferQueue.h>
-#include <gui/Surface.h>
-
-#include "android_graphics_HardwareRendererObserver.h"
-
-#include <private/EGL/cache.h>
-
-#include <utils/RefBase.h>
-#include <utils/StrongPointer.h>
-#include <utils/Timers.h>
-#include <utils/TraceUtils.h>
-#include <android_runtime/android_view_Surface.h>
-#include <system/window.h>
-
 #include <FrameInfo.h>
+#include <GraphicsJNI.h>
 #include <Picture.h>
 #include <Properties.h>
 #include <RootRenderNode.h>
+#include <dlfcn.h>
+#include <inttypes.h>
+#include <media/NdkImage.h>
+#include <media/NdkImageReader.h>
+#include <nativehelper/JNIHelp.h>
+#include <pipeline/skia/ShaderCache.h>
+#include <private/EGL/cache.h>
 #include <renderthread/CanvasContext.h>
 #include <renderthread/RenderProxy.h>
 #include <renderthread/RenderTask.h>
 #include <renderthread/RenderThread.h>
-#include <pipeline/skia/ShaderCache.h>
 #include <utils/Color.h>
+#include <utils/RefBase.h>
+#include <utils/StrongPointer.h>
+#include <utils/Timers.h>
+#include <utils/TraceUtils.h>
+
+#include <algorithm>
+#include <atomic>
+
+#include "android_graphics_HardwareRendererObserver.h"
+#include "core_jni_helpers.h"
+#include "jni.h"
 
 namespace android {
 
@@ -78,6 +72,9 @@
     return env;
 }
 
+typedef ANativeWindow* (*ANW_fromSurface)(JNIEnv* env, jobject surface);
+ANW_fromSurface fromSurface;
+
 class JvmErrorReporter : public ErrorHandler {
 public:
     JvmErrorReporter(JNIEnv* env) {
@@ -178,9 +175,9 @@
 static void android_view_ThreadedRenderer_setSurface(JNIEnv* env, jobject clazz,
         jlong proxyPtr, jobject jsurface, jboolean discardBuffer) {
     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
-    sp<Surface> surface;
+    ANativeWindow* window = nullptr;
     if (jsurface) {
-        surface = android_view_Surface_getSurface(env, jsurface);
+        window = fromSurface(env, jsurface);
     }
     bool enableTimeout = true;
     if (discardBuffer) {
@@ -188,7 +185,7 @@
         enableTimeout = false;
         proxy->setSwapBehavior(SwapBehavior::kSwap_discardBuffer);
     }
-    proxy->setSurface(surface, enableTimeout);
+    proxy->setSurface(window, enableTimeout);
 }
 
 static jboolean android_view_ThreadedRenderer_pause(JNIEnv* env, jobject clazz,
@@ -458,8 +455,10 @@
         jint right, jint bottom, jlong bitmapPtr) {
     SkBitmap bitmap;
     bitmap::toBitmap(bitmapPtr).getSkBitmap(&bitmap);
-    sp<Surface> surface = android_view_Surface_getSurface(env, jsurface);
-    return RenderProxy::copySurfaceInto(surface, left, top, right, bottom, &bitmap);
+    ANativeWindow* window = fromSurface(env, jsurface);
+    jint result = RenderProxy::copySurfaceInto(window, left, top, right, bottom, &bitmap);
+    ANativeWindow_release(window);
+    return result;
 }
 
 class ContextFactory : public IContextFactory {
@@ -480,23 +479,35 @@
     uint32_t width = jwidth;
     uint32_t height = jheight;
 
-    // Create a Surface wired up to a BufferItemConsumer
-    sp<IGraphicBufferProducer> producer;
-    sp<IGraphicBufferConsumer> rawConsumer;
-    BufferQueue::createBufferQueue(&producer, &rawConsumer);
-    // We only need 1 buffer but some drivers have bugs so workaround it by setting max count to 2
-    rawConsumer->setMaxBufferCount(2);
-    sp<BufferItemConsumer> consumer = new BufferItemConsumer(rawConsumer,
-            GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_NEVER);
-    consumer->setDefaultBufferSize(width, height);
-    sp<Surface> surface = new Surface(producer);
+    // Create an ImageReader wired up to a BufferItemConsumer
+    AImageReader* rawReader;
+    media_status_t result =
+            AImageReader_newWithUsage(width, height, AIMAGE_FORMAT_RGBA_8888,
+                                      AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE, 2, &rawReader);
+    std::unique_ptr<AImageReader, decltype(&AImageReader_delete)> reader(rawReader,
+                                                                         AImageReader_delete);
+
+    if (result != AMEDIA_OK) {
+        ALOGW("Error creating image reader!");
+        return nullptr;
+    }
+
+    // Note that ownership of this window is maintained by AImageReader, so we
+    // shouldn't need to wrap around a smart pointer.
+    ANativeWindow* window;
+    result = AImageReader_getWindow(rawReader, &window);
+
+    if (result != AMEDIA_OK) {
+        ALOGW("Error retrieving the native window!");
+        return nullptr;
+    }
 
     // Render into the surface
     {
         ContextFactory factory;
         RenderProxy proxy{true, renderNode, &factory};
         proxy.setSwapBehavior(SwapBehavior::kSwap_discardBuffer);
-        proxy.setSurface(surface);
+        proxy.setSurface(window);
         // Shadows can't be used via this interface, so just set the light source
         // to all 0s.
         proxy.setLightAlpha(0, 0);
@@ -508,33 +519,34 @@
         proxy.syncAndDrawFrame();
     }
 
-    // Yank out the GraphicBuffer
-    BufferItem bufferItem;
-    status_t err;
-    if ((err = consumer->acquireBuffer(&bufferItem, 0, true)) != OK) {
-        ALOGW("Failed to acquireBuffer, error %d (%s)", err, strerror(-err));
+    AImage* rawImage;
+    result = AImageReader_acquireNextImage(rawReader, &rawImage);
+    std::unique_ptr<AImage, decltype(&AImage_delete)> image(rawImage, AImage_delete);
+    if (result != AMEDIA_OK) {
+        ALOGW("Error reading image: %d!", result);
         return nullptr;
     }
-    sp<GraphicBuffer> buffer = bufferItem.mGraphicBuffer;
-    // We don't really care if this fails or not since we're just going to destroy this anyway
-    consumer->releaseBuffer(bufferItem);
-    if (!buffer.get()) {
-        ALOGW("GraphicBuffer is null?");
-        return nullptr;
-    }
-    if (buffer->getWidth() != width || buffer->getHeight() != height) {
-        ALOGW("GraphicBuffer size mismatch, got %dx%d expected %dx%d",
-                buffer->getWidth(), buffer->getHeight(), width, height);
+
+    AHardwareBuffer* buffer;
+    result = AImage_getHardwareBuffer(rawImage, &buffer);
+
+    AHardwareBuffer_Desc desc;
+    AHardwareBuffer_describe(buffer, &desc);
+
+    if (desc.width != width || desc.height != height) {
+        ALOGW("AHardwareBuffer size mismatch, got %dx%d expected %dx%d", desc.width, desc.height,
+              width, height);
         // Continue I guess?
     }
 
-    sk_sp<SkColorSpace> cs = uirenderer::DataSpaceToColorSpace(bufferItem.mDataSpace);
+    sk_sp<SkColorSpace> cs = uirenderer::DataSpaceToColorSpace(
+            static_cast<android_dataspace>(ANativeWindow_getBuffersDataSpace(window)));
     if (cs == nullptr) {
         // nullptr is treated as SRGB in Skia, thus explicitly use SRGB in order to make sure
         // the returned bitmap has a color space.
         cs = SkColorSpace::MakeSRGB();
     }
-    sk_sp<Bitmap> bitmap = Bitmap::createFrom(buffer->toAHardwareBuffer(), cs);
+    sk_sp<Bitmap> bitmap = Bitmap::createFrom(buffer, cs);
     return bitmap::createBitmap(env, bitmap.release(),
             android::bitmap::kBitmapCreateFlag_Premultiplied);
 }
@@ -722,6 +734,11 @@
     gFrameCompleteCallback.onFrameComplete = GetMethodIDOrDie(env, frameCompleteClass,
             "onFrameComplete", "(J)V");
 
+    void* handle_ = dlopen("libandroid.so", RTLD_NOW | RTLD_NODELETE);
+    fromSurface = (ANW_fromSurface)dlsym(handle_, "ANativeWindow_fromSurface");
+    LOG_ALWAYS_FATAL_IF(fromSurface == nullptr,
+                        "Failed to find required symbol ANativeWindow_fromSurface!");
+
     return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
 }
 
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 9fbb8df..d91911c 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -49,7 +49,6 @@
 #include <fcntl.h>
 #include <grp.h>
 #include <inttypes.h>
-#include <link.h>
 #include <malloc.h>
 #include <mntent.h>
 #include <paths.h>
@@ -59,7 +58,6 @@
 #include <sys/capability.h>
 #include <sys/cdefs.h>
 #include <sys/eventfd.h>
-#include <sys/mman.h>
 #include <sys/personality.h>
 #include <sys/prctl.h>
 #include <sys/resource.h>
@@ -72,25 +70,23 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
+#include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/properties.h>
-#include <android-base/file.h>
 #include <android-base/stringprintf.h>
-#include <android-base/strings.h>
 #include <android-base/unique_fd.h>
 #include <bionic/malloc.h>
-#include <bionic/page.h>
 #include <cutils/fs.h>
 #include <cutils/multiuser.h>
 #include <cutils/sockets.h>
 #include <private/android_filesystem_config.h>
-#include <utils/String8.h>
-#include <utils/Trace.h>
-#include <selinux/android.h>
-#include <seccomp_policy.h>
-#include <stats_event_list.h>
 #include <processgroup/processgroup.h>
 #include <processgroup/sched_policy.h>
+#include <seccomp_policy.h>
+#include <selinux/android.h>
+#include <stats_socket.h>
+#include <utils/String8.h>
+#include <utils/Trace.h>
 
 #include "core_jni_helpers.h"
 #include <nativehelper/JNIHelp.h>
@@ -1080,7 +1076,7 @@
   // Close any logging related FDs before we start evaluating the list of
   // file descriptors.
   __android_log_close();
-  stats_log_close();
+  AStatsSocket_close();
 
   // If this is the first fork for this zygote, create the open FD table.  If
   // it isn't, we just need to check whether the list of open files has changed
@@ -1651,7 +1647,7 @@
   SetCapabilities(permitted_capabilities, effective_capabilities, permitted_capabilities, fail_fn);
 
   __android_log_close();
-  stats_log_close();
+  AStatsSocket_close();
 
   const char* se_info_ptr = se_info.has_value() ? se_info.value().c_str() : nullptr;
   const char* nice_name_ptr = nice_name.has_value() ? nice_name.value().c_str() : nullptr;
@@ -1905,25 +1901,6 @@
   UnmountTree("/storage");
 }
 
-static int DisableExecuteOnly(struct dl_phdr_info* info,
-                              size_t size [[maybe_unused]],
-                              void* data [[maybe_unused]]) {
-  // Search for any execute-only segments and mark them read+execute.
-  for (int i = 0; i < info->dlpi_phnum; i++) {
-    const auto& phdr = info->dlpi_phdr[i];
-    if ((phdr.p_type == PT_LOAD) && (phdr.p_flags == PF_X)) {
-      auto addr = reinterpret_cast<void*>(info->dlpi_addr + PAGE_START(phdr.p_vaddr));
-      size_t len = PAGE_OFFSET(phdr.p_vaddr) + phdr.p_memsz;
-      if (mprotect(addr, len, PROT_READ | PROT_EXEC) == -1) {
-        ALOGE("mprotect(%p, %zu, PROT_READ | PROT_EXEC) failed: %m", addr, len);
-        return -1;
-      }
-    }
-  }
-  // Return non-zero to exit dl_iterate_phdr.
-  return 0;
-}
-
 }  // anonymous namespace
 
 namespace android {
@@ -2286,14 +2263,6 @@
   }
 }
 
-/**
- * @param env  Managed runtime environment
- * @return  True if disable was successful.
- */
-static jboolean com_android_internal_os_Zygote_nativeDisableExecuteOnly(JNIEnv* env, jclass) {
-  return dl_iterate_phdr(DisableExecuteOnly, nullptr) == 0;
-}
-
 static void com_android_internal_os_Zygote_nativeBlockSigTerm(JNIEnv* env, jclass) {
   auto fail_fn = std::bind(ZygoteFailure, env, "usap", nullptr, _1);
   BlockSignal(SIGTERM, fail_fn);
@@ -2375,8 +2344,6 @@
         {"nativeGetUsapPoolCount", "()I",
          (void*)com_android_internal_os_Zygote_nativeGetUsapPoolCount},
         {"nativeEmptyUsapPool", "()V", (void*)com_android_internal_os_Zygote_nativeEmptyUsapPool},
-        {"nativeDisableExecuteOnly", "()Z",
-         (void*)com_android_internal_os_Zygote_nativeDisableExecuteOnly},
         {"nativeBlockSigTerm", "()V", (void*)com_android_internal_os_Zygote_nativeBlockSigTerm},
         {"nativeUnblockSigTerm", "()V", (void*)com_android_internal_os_Zygote_nativeUnblockSigTerm},
         {"nativeBoostUsapPriority", "()V",
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 03676dd..829c252 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -34,6 +34,7 @@
 import "frameworks/base/core/proto/android/providers/settings.proto";
 import "frameworks/base/core/proto/android/server/activitymanagerservice.proto";
 import "frameworks/base/core/proto/android/server/alarmmanagerservice.proto";
+import "frameworks/base/core/proto/android/server/bluetooth_manager_service.proto";
 import "frameworks/base/core/proto/android/server/fingerprint.proto";
 import "frameworks/base/core/proto/android/server/jobscheduler.proto";
 import "frameworks/base/core/proto/android/server/location/context_hub.proto";
@@ -488,6 +489,11 @@
         (section).args = "connmetrics --proto"
     ];
 
+    optional com.android.server.BluetoothManagerServiceDumpProto bluetooth_manager = 3050 [
+        (section).type = SECTION_DUMPSYS,
+        (section).args = "bluetooth_manager --proto"
+    ];
+
     optional com.android.server.location.ContextHubServiceProto context_hub = 3051 [
         (section).type = SECTION_DUMPSYS,
         (section).args = "contexthub --proto"
diff --git a/core/proto/android/server/bluetooth_manager_service.proto b/core/proto/android/server/bluetooth_manager_service.proto
new file mode 100644
index 0000000..998413f
--- /dev/null
+++ b/core/proto/android/server/bluetooth_manager_service.proto
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 com.android.server;
+
+import "frameworks/base/core/proto/android/bluetooth/enums.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
+
+option java_multiple_files = true;
+
+message BluetoothManagerServiceDumpProto {
+   option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+   message ActiveLog {
+      option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+      optional int64 timestamp_ms = 1;
+      optional bool enable = 2;
+      optional string package_name = 3;
+      optional .android.bluetooth.EnableDisableReasonEnum reason = 4;
+   }
+
+   optional bool enabled = 1;
+   optional int32 state = 2;
+   optional string state_name = 3;
+   optional string address = 4 [(.android.privacy).dest = DEST_EXPLICIT];
+   optional string name = 5 [(.android.privacy).dest = DEST_EXPLICIT];
+   optional int64 last_enabled_time_ms = 6;
+   optional int64 curr_timestamp_ms = 7;
+   repeated ActiveLog active_logs = 8;
+   optional int32 num_crashes = 9;
+   optional bool crash_log_maxed = 10;
+   repeated int64 crash_timestamps_ms = 11;
+   optional int32 num_ble_apps = 12;
+   repeated string ble_app_package_names = 13;
+}
\ No newline at end of file
diff --git a/core/proto/android/server/notificationhistory.proto b/core/proto/android/server/notificationhistory.proto
index 6749719..15f4abb 100644
--- a/core/proto/android/server/notificationhistory.proto
+++ b/core/proto/android/server/notificationhistory.proto
@@ -55,6 +55,11 @@
     // The small icon of the notification
     optional Icon icon = 12;
 
+    // The conversation id, if any, that this notification belongs to
+    optional string conversation_id = 13;
+    // conversation_id_index contains the index + 1 of the conversation id in the string pool
+    optional int32 conversation_id_index = 14;
+
     // Matches the constants of android.graphics.drawable.Icon
     enum ImageTypeEnum {
       TYPE_UNKNOWN = 0;
diff --git a/core/proto/android/server/peopleservice.proto b/core/proto/android/server/peopleservice.proto
index 294b6ef..e476c52 100644
--- a/core/proto/android/server/peopleservice.proto
+++ b/core/proto/android/server/peopleservice.proto
@@ -52,6 +52,11 @@
   optional int32 conversation_flags = 6;
 }
 
+// On disk data of events.
+message PeopleEventsProto {
+  repeated PeopleEventProto events = 1;
+}
+
 // Individual event (com.android.server.people.data.Event).
 message PeopleEventProto {
 
@@ -65,11 +70,23 @@
   optional int32 duration = 3;
 }
 
+// On disk data of event indexes.
+message PeopleEventIndexesProto {
+  repeated TypedPeopleEventIndexProto typed_indexes = 1;
+}
+
+// Mapping of event_type to event index.
+message TypedPeopleEventIndexProto {
+  optional int32 event_type = 1;
+  optional PeopleEventIndexProto index = 2;
+}
+
 // Index of events' time distributions (com.android.server.people.data.EventIndex).
 message PeopleEventIndexProto {
-    // Each long value in event_bitmaps represents a time slot, there should be 4 values. Further
-    // details can be found in class documentation.
-    repeated int64 event_bitmaps = 1;
+  // Each long value in event_bitmaps represents a time slot, there should be 4 values. Further
+  // details can be found in class documentation.
+  repeated int64 event_bitmaps = 1;
 
-    optional int64 last_updated_time = 2;
+  optional int64 last_updated_time = 2;
 }
+
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index b0b9ce6f..08db454 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -275,6 +275,7 @@
     optional float adjust_divider_amount = 25;
     optional bool animating_bounds = 26;
     optional float minimize_amount = 27;
+    optional bool created_by_organizer = 28;
 }
 
 /* represents ActivityRecordProto */
diff --git a/core/proto/android/stats/devicepolicy/device_policy_enums.proto b/core/proto/android/stats/devicepolicy/device_policy_enums.proto
index a648831..a4e2193 100644
--- a/core/proto/android/stats/devicepolicy/device_policy_enums.proto
+++ b/core/proto/android/stats/devicepolicy/device_policy_enums.proto
@@ -162,4 +162,18 @@
   SET_PERSONAL_APPS_SUSPENDED = 135;
   SET_MANAGED_PROFILE_MAXIMUM_TIME_OFF = 136;
   COMP_TO_ORG_OWNED_PO_MIGRATED = 137;
+  SET_CROSS_PROFILE_PACKAGES = 138;
+  SET_INTERACT_ACROSS_PROFILES_APP_OP = 139;
+  GET_CROSS_PROFILE_PACKAGES = 140;
+  CAN_REQUEST_INTERACT_ACROSS_PROFILES_TRUE = 141;
+  CAN_REQUEST_INTERACT_ACROSS_PROFILES_FALSE_NO_PROFILES = 142;
+  CAN_REQUEST_INTERACT_ACROSS_PROFILES_FALSE_WHITELIST = 143;
+  CAN_REQUEST_INTERACT_ACROSS_PROFILES_FALSE_PERMISSION = 144;
+  CAN_INTERACT_ACROSS_PROFILES_TRUE = 145;
+  CAN_INTERACT_ACROSS_PROFILES_FALSE_PERMISSION = 146;
+  CAN_INTERACT_ACROSS_PROFILES_FALSE_NO_PROFILES = 147;
+  CREATE_CROSS_PROFILE_INTENT = 148;
+  IS_MANAGED_PROFILE = 149;
+  START_ACTIVITY_BY_INTENT = 150;
+  BIND_CROSS_PROFILE_SERVICE = 151;
 }
diff --git a/core/res/Android.bp b/core/res/Android.bp
index 3dc74f8..b365de4 100644
--- a/core/res/Android.bp
+++ b/core/res/Android.bp
@@ -54,3 +54,22 @@
         "res/**/*",
     ],
 }
+
+// Generate a text file containing a list of permissions that non-system apps
+// are allowed to obtain.
+genrule {
+  name: "permission-list-normal",
+  out: ["permission-list-normal.txt"],
+  srcs: ["AndroidManifest.xml"],
+  cmd: "cat $(in) " +
+       // xmllint has trouble accessing attributes under the android namespace.
+       // Strip these prefixes prior to processing with xmllint.
+       " | sed -r 's/android:(name|protectionLevel)/\\1/g' " +
+       " | $(location xmllint) /dev/stdin --xpath " +
+       " '//permission[not(contains(@protectionLevel, \"signature\"))]/@name'" +
+       // The result of xmllint is name="value" pairs. Format these to just the
+       // permission name, one per-line.
+       " | sed -r 's/\\s*name=\\s*//g' | tr -d '\"'" +
+       " > $(out)",
+  tools: ["xmllint"]
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9dc40c8..6530036 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1656,7 +1656,7 @@
 
     <!-- Allows Settings and SystemUI to call methods in Networking services
          <p>Not for use by third-party or privileged applications.
-         @SystemApi
+         @SystemApi @TestApi
          @hide This should only be used by Settings and SystemUI.
     -->
     <permission android:name="android.permission.NETWORK_SETTINGS"
@@ -4941,7 +4941,13 @@
          <p>Not for use by third-party applications.
          @hide -->
     <permission android:name="android.permission.ACCESS_TV_TUNER"
-        android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature|privileged|vendorPrivileged" />
+
+    <!-- @SystemApi Allows an application to access descrambler of TV tuner HAL
+         <p>Not for use by third-party applications.
+         @hide -->
+    <permission android:name="android.permission.ACCESS_TV_DESCRAMBLER"
+        android:protectionLevel="signature|privileged|vendorPrivileged" />
 
     <!-- @hide @SystemApi Allows an application to access locusId events in the usage stats. -->
     <permission android:name="android.permission.ACCESS_LOCUS_ID_USAGE_STATS"
diff --git a/core/res/res/layout/autofill_inline_suggestion.xml b/core/res/res/layout/autofill_inline_suggestion.xml
deleted file mode 100644
index 27faea4..0000000
--- a/core/res/res/layout/autofill_inline_suggestion.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT 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"
-    style="?android:attr/autofillInlineSuggestionChip"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:gravity="center"
-    android:paddingTop="4dp"
-    android:paddingBottom="4dp"
-    android:orientation="horizontal">
-
-    <ImageView
-        android:id="@+id/autofill_inline_suggestion_start_icon"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_gravity="center"
-        android:scaleType="fitCenter"
-        android:contentDescription="autofill_inline_suggestion_start_icon" />
-
-    <LinearLayout
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:layout_gravity="center"
-        android:layout_weight="1"
-        android:paddingStart="4dp"
-        android:paddingEnd="4dp"
-        android:orientation="vertical"
-        android:gravity="center">
-
-        <TextView
-            style="?android:attr/autofillInlineSuggestionTitle"
-            android:id="@+id/autofill_inline_suggestion_title"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:ellipsize="end"
-            android:maxLines="1"/>
-
-        <TextView
-            style="?android:attr/autofillInlineSuggestionSubtitle"
-            android:id="@+id/autofill_inline_suggestion_subtitle"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:ellipsize="end"
-            android:maxLines="1"/>
-    </LinearLayout>
-
-    <ImageView
-        android:id="@+id/autofill_inline_suggestion_end_icon"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_gravity="center"
-        android:scaleType="fitCenter"
-        android:contentDescription="autofill_inline_suggestion_end_icon" />
-</LinearLayout>
diff --git a/core/res/res/layout/resolver_empty_states.xml b/core/res/res/layout/resolver_empty_states.xml
index 6959e9c..5ed4c53 100644
--- a/core/res/res/layout/resolver_empty_states.xml
+++ b/core/res/res/layout/resolver_empty_states.xml
@@ -34,7 +34,7 @@
         android:layout_marginTop="16dp"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:textAppearance="?attr/textAppearanceMedium"
+        android:fontFamily="@string/config_headlineFontFamilyMedium"
         android:textColor="@color/resolver_empty_state_text"
         android:textSize="18sp"/>
     <TextView
@@ -52,7 +52,7 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:background="@null"
-        android:textAppearance="?attr/textAppearanceMedium"
+        android:fontFamily="@string/config_headlineFontFamilyMedium"
         android:textSize="14sp"
         android:textColor="@color/resolver_tabs_active_color"/>
 </LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/resolver_list.xml b/core/res/res/layout/resolver_list.xml
index 6dfe24b..b4e6286 100644
--- a/core/res/res/layout/resolver_list.xml
+++ b/core/res/res/layout/resolver_list.xml
@@ -21,7 +21,7 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:maxWidth="@dimen/resolver_max_width"
-    android:maxCollapsedHeight="@dimen/resolver_empty_state_height"
+    android:maxCollapsedHeight="192dp"
     android:maxCollapsedHeightSmall="56dp"
     android:id="@id/contentPanel">
 
@@ -102,7 +102,6 @@
                     android:id="@+id/profile_pager"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:minHeight="@dimen/resolver_empty_state_height"
                     android:divider="?attr/dividerVertical"
                     android:footerDividersEnabled="false"
                     android:headerDividersEnabled="false"
diff --git a/core/res/res/layout/resolver_list_with_default.xml b/core/res/res/layout/resolver_list_with_default.xml
index 4f88017..b546738 100644
--- a/core/res/res/layout/resolver_list_with_default.xml
+++ b/core/res/res/layout/resolver_list_with_default.xml
@@ -183,7 +183,6 @@
                     android:id="@+id/profile_pager"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:minHeight="@dimen/resolver_empty_state_height"
                     android:dividerHeight="1dp"
                     android:divider="?attr/dividerVertical"
                     android:footerDividersEnabled="false"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 5e89533..2e93904 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrateur het toestel vir persoonlike gebruik afgestaan"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Toestel word bestuur"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Jou organisasie bestuur hierdie toestel en kan netwerkverkeer monitor. Tik vir besonderhede."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Ligginginstellings is deur jou administrateur verander"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Tik om jou ligginginstellings te sien."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Jou toestel sal uitgevee word"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Die administrasieprogram kan nie gebruik word nie. Jou toestel sal nou uitgevee word.\n\nKontak jou organisasie se administrateur as jy vrae het."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Druk is gedeaktiveer deur <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Hierdie bevoorregte | stelselprogram kan enige tyd met \'n stelselkamera foto\'s neem en video\'s opneem. Vereis dat die program ook die android.permission.CAMERA-toestemming het"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"beheer vibrasie"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Laat die program toe om die vibrator te beheer."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Stel die program in staat om toegang tot die vibreerderstand te kry."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"skakel foonnommers direk"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Laat die program toe om telefoonnommers sonder jou tussentrede te bel. Dit kan tot onverwagte heffings of oproepe lei. Let daarop dat dit nie die program toelaat om noodnommers te bel nie. Kwaadwillige programme kan jou geld kos deur oproepe sonder jou bevestiging te maak."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"toegang tot kitsboodskapoproepdiens"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Probeer weer."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Geen vingerafdrukke is geregistreer nie."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Hierdie toetstel het nie \'n vingerafdruksensor nie."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Kan nie gesig verifieer nie. Probeer weer."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Jy het nie gesigslot opgestel nie."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Gesigslot word nie op hierdie toestel gesteun nie."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Gesig <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Die voorgronddiens wat in die agtergrond begin het vanaf <xliff:g id="PACKAGENAME">%1$s</xliff:g> sal nie ingebruik-toestemming hê in toekomstige R-bouweergawes nie. Raadpleeg asseblief go/r-bg-fgs-restriction en dien \'n foutverslag in."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Verhoog volume bo aanbevole vlak?\n\nOm lang tydperke teen hoë volume te luister, kan jou gehoor beskadig."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Gebruik toeganklikheidkortpad?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Wanneer die kortpad aan is, sal \'n toeganklikheidkenmerk begin word as albei volumeknoppies 3 sekondes lank gedruk word.\n\n Bestaande toeganklikheidkenmerk:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Jy kan die kenmerk in Instellings &gt; Toeganklikheid verander."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Wysig kortpaaie"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Kanselleer"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Skakel kortpad af"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> is in die BEPERK-groep geplaas"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Persoonlik"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Werk"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index b637a63..f49e2ef 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"አስተዳዳሪ መሣሪያዎን ለግል ጥቅም ትተውታል"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"መሣሪያው የሚተዳደር ነው"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"የእርስዎ ድርጅት ይህን መሣሪያ ያስተዳድራል፣ እና የአውታረ መረብ ትራፊክን ሊከታተል ይችላል። ዝርዝሮችን ለማግኘት መታ ያድርጉ።"</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"የአካባቢ ቅንብሮች በአስተዳዳሪዎ ተቀይረዋል"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"የአካባቢ ቅንብሮችዎን ለመመልከት መታ ያድርጉ።"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"የእርስዎ መሣሪያ ይደመሰሳል"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"የአስተዳዳሪ መተግበሪያ ስራ ላይ ሊውል አይችልም። የእርስዎን መሣሪያ አሁን ይደመሰሳል።\n\nጥያቄዎች ካለዎት የድርጅትዎን አስተዳዳሪ ያነጋግሩ።"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"ማተም በ<xliff:g id="OWNER_APP">%s</xliff:g> ተሰናክሏል።"</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"ይህ ልዩ ፈቃድ ያለው | የሥርዓት መተግበሪያ በማናቸውም ጊዜ የሥርዓት ካሜራን በመጠቀም ሥዕሎችን ማንሣት እና ቪዲዮ መቅረጽ ይችላል። የ android.ፈቃድን ይጠይቃል። ካሜራ ፍቃድ በመተግበሪያውም ጭምር መያዝ ይኖርበታል"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"ነዛሪ ተቆጣጠር"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"ነዛሪውን ለመቆጣጠር ለመተግበሪያው ይፈቅዳሉ።"</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"መተግበሪያው የንዝረት ሁኔታውን እንዲደርስ ያስችለዋል።"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"በቀጥታ ስልክ ቁጥሮች ደውል"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"መተግበሪያው ያላንተ ጣልቃ ገብነት የስልክ ቁጥሮች ላይ እንዲደውል ይፈቅድለታል። ይህ ያልተጠበቁ ክፍያዎችን ወይም ጥሪዎችን ሊያስከትል ይችላል። ይህ መተግበሪያው የድንገተኛ ስልክ ቁጥሮችን እንዲደውል እንደማይፈቅድለት ልብ በል። ተንኮል አዘል መተግበሪያዎች ያላንተ ማረጋገጫ ጥሪዎችን በማድረግ ገንዘብ ሊያስወጡህ ይችላሉ።"</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"የአይኤምኤስ ጥሪ አገልግሎትን ይደርሳል"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"እንደገና ይሞክሩ።"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ምንም የጣት አሻራዎች አልተመዘገቡም።"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ይህ መሣሪያ የጣት አሻራ ዳሳሽ የለውም።"</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ጣት <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"ፊትን ማረጋገጥ አይቻልም። እንደገና ይሞክሩ።"</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"በመልክ መክፈትን አላቀናበሩም።"</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"በመልክ መክፈት መስጫ በዚህ መሣሪያ ላይ አይደገፍም።"</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"ፊት <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"ዳራው ከ<xliff:g id="PACKAGENAME">%1$s</xliff:g> የጀመረው የፊት አገልግሎት ወደፊት በሚኖሩት R ግንቦች ላይ ጥቅም ላይ እየዋለ ፈቃድ አይኖረውም። እባክዎ go/r-bg-fgs-restriction እና ፋይል ሳንካ ሪፖርትን ይመልከቱ።"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ድምጹ ከሚመከረው መጠን በላይ ከፍ ይበል?\n\nበከፍተኛ ድምጽ ለረጅም ጊዜ ማዳመጥ ጆሮዎን ሊጎዳው ይችላል።"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"የተደራሽነት አቋራጭ ጥቅም ላይ ይዋል?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"አቋራጩ ሲበራ ሁለቱንም የድምፅ አዝራሮች ለ3 ሰከንዶች ተጭኖ መቆየት የተደራሽነት ባህሪን ያስጀምረዋል።\n\n አሁን ያለ የተደራሽነት ባህሪ፦\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n ባህሪውን በቅንብሮች &gt; ተደራሽነት ውስጥ ሊለውጡት ይችላሉ።"</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"አቋራጮችን አርትዕ ያድርጉ"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"ይቅር"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"አቋራጩን አጥፋ"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ወደ የRESTRICTED ባልዲ ተከትቷል"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"የግል"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"ሥራ"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 002d61e..93f5dc1 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -199,6 +199,10 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"تنازل المشرف عن الجهاز للاستخدام الشخصي"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"تتم إدارة الجهاز"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"تدير مؤسستك هذا الجهاز ويمكنها مراقبة حركة بيانات الشبكة. يمكنك النقر للحصول على تفاصيل."</string>
+    <!-- no translation found for location_changed_notification_title (4119726617105166830) -->
+    <skip />
+    <!-- no translation found for location_changed_notification_text (198907268219396399) -->
+    <skip />
     <string name="factory_reset_warning" msgid="6858705527798047809">"سيتم محو بيانات جهازك."</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"تعذّر استخدام تطبيق المشرف. سيتم محو بيانات جهازك الآن.\n\nإذا كانت لديك أسئلة، اتصل بمشرف مؤسستك."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"تم إيقاف الطباعة بواسطة <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -210,23 +214,23 @@
     <string name="power_dialog" product="default" msgid="1107775420270203046">"خيارات الهاتف"</string>
     <string name="silent_mode" msgid="8796112363642579333">"وضع صامت"</string>
     <string name="turn_on_radio" msgid="2961717788170634233">"تشغيل اللاسلكي"</string>
-    <string name="turn_off_radio" msgid="7222573978109933360">"إيقاف تشغيل الشبكة اللاسلكية"</string>
+    <string name="turn_off_radio" msgid="7222573978109933360">"إيقاف تفعيل الشبكة اللاسلكية"</string>
     <string name="screen_lock" msgid="2072642720826409809">"قفل الشاشة"</string>
     <string name="power_off" msgid="4111692782492232778">"إيقاف التشغيل"</string>
     <string name="silent_mode_silent" msgid="5079789070221150912">"إيقاف الرنين"</string>
     <string name="silent_mode_vibrate" msgid="8821830448369552678">"اهتزاز الرنين"</string>
     <string name="silent_mode_ring" msgid="6039011004781526678">"تشغيل الرنين"</string>
-    <string name="reboot_to_update_title" msgid="2125818841916373708">"‏تحديث نظام Android"</string>
+    <string name="reboot_to_update_title" msgid="2125818841916373708">"‏إعادة تحميل نظام Android"</string>
     <string name="reboot_to_update_prepare" msgid="6978842143587422365">"جارٍ الإعداد للتحديث…"</string>
     <string name="reboot_to_update_package" msgid="4644104795527534811">"جارٍ معالجة حزمة التحديث…"</string>
     <string name="reboot_to_update_reboot" msgid="4474726009984452312">"جارٍ إعادة التشغيل…"</string>
     <string name="reboot_to_reset_title" msgid="2226229680017882787">"إعادة الضبط على الإعدادات الأصلية"</string>
     <string name="reboot_to_reset_message" msgid="3347690497972074356">"جارٍ إعادة التشغيل…"</string>
     <string name="shutdown_progress" msgid="5017145516412657345">"جارٍ إيقاف التشغيل..."</string>
-    <string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"سيتم إيقاف تشغيل الجهاز اللوحي."</string>
+    <string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"سيتم إيقاف تفعيل الجهاز اللوحي."</string>
     <string name="shutdown_confirm" product="tv" msgid="7975942887313518330">"‏سيتم إيقاف جهاز Android TV."</string>
     <string name="shutdown_confirm" product="watch" msgid="2977299851200240146">"سيتم إيقاف المشاهدة."</string>
-    <string name="shutdown_confirm" product="default" msgid="136816458966692315">"سيتم إيقاف تشغيل هاتفك."</string>
+    <string name="shutdown_confirm" product="default" msgid="136816458966692315">"سيتم إيقاف تفعيل هاتفك."</string>
     <string name="shutdown_confirm_question" msgid="796151167261608447">"هل تريد إيقاف التشغيل؟"</string>
     <string name="reboot_safemode_title" msgid="5853949122655346734">"إعادة تشغيل في الوضع الآمن"</string>
     <string name="reboot_safemode_confirm" msgid="1658357874737219624">"هل تريد إعادة تشغيل الكمبيوتر في الوضع الآمن؟ سيؤدي ذلك إلى إيقاف جميع تطبيقات الجهات الخارجية التي تم تثبيتها. ستتم استعادتها عند إعادة التشغيل مرة أخرى."</string>
@@ -441,6 +445,8 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"‏إذا حصل تطبيق النظام على هذا الإذن، سيمكن لهذا التطبيق التقاط صور وتسجيل فيديوهات باستخدام كاميرا النظام في أي وقت. ويجب أن يحصل التطبيق أيضًا على الإذن android.permission.CAMERA."</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"التحكم في الاهتزاز"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"للسماح للتطبيق بالتحكم في الهزّاز."</string>
+    <!-- no translation found for permdesc_vibrator_state (7050024956594170724) -->
+    <skip />
     <string name="permlab_callPhone" msgid="1798582257194643320">"اتصال مباشر بأرقام الهواتف"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"للسماح للتطبيق بطلب أرقام هاتفية بدون تدخل منك. وقد يؤدي ذلك إلى تحمل رسوم غير متوقعة أو إجراء مكالمات غير متوقعة. ومن الجدير بالذكر أن ذلك لا يتيح للتطبيق الاتصال بأرقام الطوارئ. وقد تؤدي التطبيقات الضارة إلى تحملك تكاليف مالية من خلال إجراء مكالمات بدون موافقة منك."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"الوصول إلى خدمة الاتصال عبر الرسائل الفورية"</string>
@@ -555,6 +561,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"أعد المحاولة."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ليست هناك بصمات إصبع مسجَّلة."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"لا يحتوي هذا الجهاز على مستشعِر بصمات إصبع."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"الإصبع <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -598,6 +606,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"يتعذّر التحقق من الوجه. حاول مرة أخرى."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"لم يسبق لك إعداد \"فتح القفل بالوجه\"."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"\"فتح القفل بالوجه\" غير متوفر على هذا الجهاز."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"الوجه <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -979,8 +989,8 @@
     <string name="searchview_description_submit" msgid="6771060386117334686">"إرسال طلب البحث"</string>
     <string name="searchview_description_voice" msgid="42360159504884679">"البحث الصوتي"</string>
     <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"‏هل تريد تفعيل ميزة Explore by Touch؟"</string>
-    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"‏يريد <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> تفعيل ميزة Explore by Touch. عند تشغيل ميزة Explore by Touch، سيكون بإمكانك سماع أو مشاهدة أوصاف لما تحت إصبعك أو إجراء إيماءات للتفاعل مع الجهاز اللوحي."</string>
-    <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"‏يريد <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> تفعيل ميزة Explore by Touch. عند تشغيل ميزة Explore by Touch، سيكون بإمكانك سماع أو مشاهدة أوصاف لما تحت إصبعك أو إجراء إيماءات للتفاعل مع الهاتف."</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"‏يريد <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> تفعيل ميزة Explore by Touch. عند تفعيل ميزة Explore by Touch، سيكون بإمكانك سماع أو مشاهدة أوصاف لما تحت إصبعك أو إجراء إيماءات للتفاعل مع الجهاز اللوحي."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"‏يريد <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> تفعيل ميزة Explore by Touch. عند تفعيل ميزة Explore by Touch، سيكون بإمكانك سماع أو مشاهدة أوصاف لما تحت إصبعك أو إجراء إيماءات للتفاعل مع الهاتف."</string>
     <string name="oneMonthDurationPast" msgid="4538030857114635777">"قبل شهر واحد"</string>
     <string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"قبل شهر واحد"</string>
     <plurals name="last_num_days" formatted="false" msgid="687443109145393632">
@@ -1264,18 +1274,18 @@
     <string name="unsupported_display_size_show" msgid="980129850974919375">"العرض دائمًا"</string>
     <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"‏تم تصميم <xliff:g id="APP_NAME">%1$s</xliff:g> لإصدار غير متوافق من نظام تشغيل Android وقد يحدث خلل في أدائه. قد يتوفّر إصدار محدّث من التطبيق."</string>
     <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"الإظهار دائمًا"</string>
-    <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"البحث عن تحديث"</string>
+    <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"البحث عن إعادة تحميل"</string>
     <string name="smv_application" msgid="3775183542777792638">"‏انتهك التطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> (العملية <xliff:g id="PROCESS">%2$s</xliff:g>) سياسة StrictMode المفروضة ذاتيًا."</string>
     <string name="smv_process" msgid="1398801497130695446">"‏انتهكت العملية <xliff:g id="PROCESS">%1$s</xliff:g> سياسة StrictMode المفروضة ذاتيًا."</string>
-    <string name="android_upgrading_title" product="default" msgid="7279077384220829683">"جارٍ تحديث الهاتف…"</string>
-    <string name="android_upgrading_title" product="tablet" msgid="4268417249079938805">"جارٍ تحديث الجهاز اللوحي…"</string>
-    <string name="android_upgrading_title" product="device" msgid="6774767702998149762">"جارٍ تحديث الجهاز…"</string>
+    <string name="android_upgrading_title" product="default" msgid="7279077384220829683">"جارٍ إعادة تحميل الهاتف…"</string>
+    <string name="android_upgrading_title" product="tablet" msgid="4268417249079938805">"جارٍ إعادة تحميل الجهاز اللوحي…"</string>
+    <string name="android_upgrading_title" product="device" msgid="6774767702998149762">"جارٍ إعادة تحميل الجهاز…"</string>
     <string name="android_start_title" product="default" msgid="4036708252778757652">"جارٍ بدء تشغيل الهاتف…"</string>
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"‏جارٍ تشغيل Android…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"جارٍ بدء تشغيل الجهاز اللوحي…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"جارٍ بدء تشغيل الجهاز…"</string>
     <string name="android_upgrading_fstrim" msgid="3259087575528515329">"جارٍ تحسين مساحة التخزين."</string>
-    <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"جارٍ إنهاء تحديث النظام…"</string>
+    <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"جارٍ إنهاء إعادة تحميل النظام…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"جارٍ ترقية <xliff:g id="APPLICATION">%1$s</xliff:g>…"</string>
     <string name="android_upgrading_apk" msgid="1339564803894466737">"جارٍ تحسين التطبيق <xliff:g id="NUMBER_0">%1$d</xliff:g> من <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"جارٍ تحضير <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
@@ -1702,7 +1712,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"‏لن يتم منح إذن الوصول إلى الموقع الجغرافي أثناء الاستخدام للخدمات التي تعمل في المقدّمة من <xliff:g id="PACKAGENAME">%1$s</xliff:g> والتي تبدأ من الخلفية في إصدارات R القادمة. يُرجى مراجعة go/r-bg-fgs-restriction وتقديم تقرير خطأ."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"هل تريد رفع مستوى الصوت فوق المستوى الموصى به؟\n\nقد يضر سماع صوت عالٍ لفترات طويلة بسمعك."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"هل تريد استخدام اختصار \"سهولة الاستخدام\"؟"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"عند تشغيل الاختصار، يؤدي الضغط على زرّي مستوى الصوت لمدة 3 ثوانٍ إلى تفعيل ميزة \"سهولة الاستخدام\".\n\n ميزة \"سهولة الاستخدام\" الحالية:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n يمكنك تغيير الميزة من \"الإعدادات\" &gt; \"سهولة الاستخدام\"."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"تعديل الاختصارات"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"إلغاء"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"إيقاف الاختصار"</string>
@@ -1984,7 +1995,7 @@
     <string name="app_blocked_title" msgid="7353262160455028160">"التطبيق غير متاح"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> غير متاح الآن."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"‏تمّ إنشاء هذا التطبيق لإصدار قديم من Android وقد لا يعمل بشكل صحيح. جرِّب البحث عن تحديثات أو الاتصال بمطوّر البرامج."</string>
-    <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"البحث عن تحديث"</string>
+    <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"البحث عن إعادة تحميل"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"لديك رسائل جديدة"</string>
     <string name="new_sms_notification_content" msgid="3197949934153460639">"‏فتح تطبيق الرسائل القصيرة SMS للعرض"</string>
     <string name="profile_encrypted_title" msgid="9001208667521266472">"قد تكون بعض الوظائف مُقيّدة."</string>
@@ -2037,9 +2048,9 @@
     <string name="autofill_save_title_with_2types" msgid="3783270967447869241">"هل تريد حفظ <xliff:g id="TYPE_0">%1$s</xliff:g> و<xliff:g id="TYPE_1">%2$s</xliff:g> في "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"؟"</string>
     <string name="autofill_save_title_with_3types" msgid="6598228952100102578">"هل تريد حفظ <xliff:g id="TYPE_0">%1$s</xliff:g> و<xliff:g id="TYPE_1">%2$s</xliff:g> و<xliff:g id="TYPE_2">%3$s</xliff:g> في "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"؟"</string>
     <string name="autofill_update_title" msgid="3630695947047069136">"هل تريد التحديث في "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"؟"</string>
-    <string name="autofill_update_title_with_type" msgid="5264152633488495704">"هل تريد تحديث <xliff:g id="TYPE">%1$s</xliff:g> في "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"؟"</string>
-    <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"هل تريد تحديث <xliff:g id="TYPE_0">%1$s</xliff:g> و<xliff:g id="TYPE_1">%2$s</xliff:g> في "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"؟"</string>
-    <string name="autofill_update_title_with_3types" msgid="1312232153076212291">"هل تريد تحديث هذه العناصر في "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g> و<xliff:g id="TYPE_1">%2$s</xliff:g> و<xliff:g id="TYPE_2">%3$s</xliff:g>؟"</string>
+    <string name="autofill_update_title_with_type" msgid="5264152633488495704">"هل تريد إعادة تحميل <xliff:g id="TYPE">%1$s</xliff:g> في "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"؟"</string>
+    <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"هل تريد إعادة تحميل <xliff:g id="TYPE_0">%1$s</xliff:g> و<xliff:g id="TYPE_1">%2$s</xliff:g> في "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"؟"</string>
+    <string name="autofill_update_title_with_3types" msgid="1312232153076212291">"هل تريد إعادة تحميل هذه العناصر في "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g> و<xliff:g id="TYPE_1">%2$s</xliff:g> و<xliff:g id="TYPE_2">%3$s</xliff:g>؟"</string>
     <string name="autofill_save_yes" msgid="8035743017382012850">"حفظ"</string>
     <string name="autofill_save_no" msgid="9212826374207023544">"لا، شكرًا"</string>
     <string name="autofill_save_notnow" msgid="2853932672029024195">"ليس الآن"</string>
@@ -2146,4 +2157,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"تم وضع <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> في الحزمة \"محظورة\"."</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"شخصي"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"عمل"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index bdf8fcf..9b42cf2 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"প্ৰশাসকে ডিভাইচটো ব্যক্তিগত ব্যৱহাৰৰ বাবে বাজেয়প্ত কৰিছে"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"পৰিচালিত ডিভাইচ"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"আপোনাৰ প্ৰতিষ্ঠানটোৱে এই ডিভাইচটো পৰিচালনা কৰে আৰু ই নেটৱৰ্কৰ ট্ৰেফিক পৰ্যবেক্ষণ কৰিব পাৰে। সবিশেষ জানিবলৈ টিপক।"</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"আপোনাৰ প্ৰশাসকে অৱস্থানৰ ছেটিংসমূহ সলনি কৰিছে"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"আপোনাৰ অৱস্থানৰ ছেটিংসমূহ চাবলৈ টিপক।"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"আপোনাৰ ডিভাইচৰ ডেটা মচা হ\'ব"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"এই প্ৰশাসক এপটো ব্যৱহাৰ কৰিব নোৱাৰি। এতিয়া আপোনাৰ ডিভাইচটোৰ ডেটা মচা হ\'ব।\n\nআপোনাৰ কিবা প্ৰশ্ন থাকিলে আপোনাৰ প্ৰতিষ্ঠানৰ প্ৰশাসকৰ সৈতে যোগাযোগ কৰক।"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"প্ৰিণ্ট কৰা কাৰ্য <xliff:g id="OWNER_APP">%s</xliff:g>এ অক্ষম কৰি ৰাখিছে।"</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"এই বিশেষাধিকাৰ প্ৰাপ্ত | ছিষ্টেম এপ্‌টোৱে এটা ছিষ্টেম কেমেৰা ব্যৱহাৰ কৰি যিকোনো সময়তে ফট’ উঠাব পাৰে আৰু ভিডিঅ’ ৰেকৰ্ড কৰিব পাৰে। লগতে এপ্‌টোৰো android.permission.CAMERAৰ অনুমতি থকাটো প্ৰয়োজনীয়"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"কম্পন নিয়ন্ত্ৰণ কৰক"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"ভাইব্ৰেটৰ নিয়ন্ত্ৰণ কৰিবলৈ এপটোক অনুমতি দিয়ে।"</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"এপ্‌টোক কম্পন স্থিতিটো এক্সেছ কৰিবলৈ অনুমতি দিয়ে।"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"পোনপটীয়াকৈ ফ\'ন নম্বৰলৈ কল কৰক"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"আপোনাৰ কোনো ব্যাঘাত নোহোৱাকৈ ফ\'ন নম্বৰবোৰত কল কৰিবলৈ এপক অনুমতি দিয়ে৷ ইয়াৰ ফলত অপ্ৰত্যাশিত মাচুল ভৰিবলগা বা কলবোৰ কৰা হ\'ব পাৰে৷ মনত ৰাখিব যে ই এপটোক জৰুৰীকালীন নম্বৰবোৰত কল কৰিবলৈ অনুমতি নিদিয়ে৷ ক্ষতিকাৰক এপসমূহে আপোনাৰ অনুমতি নোলোৱাকৈয়ে কল কৰি আপোনাক টকা খৰছ কৰাব পাৰে৷"</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"আইএমএছ কল সেৱা ব্যৱহাৰ কৰিব পাৰে"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"আকৌ চেষ্টা কৰক।"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"কোনো ফিংগাৰপ্ৰিণ্ট যোগ কৰা নহ\'ল।"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইচটোত ফিংগাৰপ্ৰিণ্ট ছেন্সৰ নাই।"</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> আঙুলি"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"মুখমণ্ডল সত্যাপন কৰিব পৰা নগ’ল। আকৌ চেষ্টা কৰক।"</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"আপুনি মুখাৱয়বৰদ্বাৰা আনলক কৰাটো ছেট আপ কৰা নাই।"</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"এই ডিভাইচটোত মুখাৱয়বৰদ্বাৰা আনলক কৰা সুবিধাটো নচলে।"</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"মুখমণ্ডল <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"নেপথ্যই <xliff:g id="PACKAGENAME">%1$s</xliff:g>ৰ পৰা আৰম্ভ কৰা অগ্ৰভূমিৰ সেৱাটোৰ ভৱিষ্যতৰ R বিল্ডসমূহত ব্যৱহাৰ হৈ থকা সম্পৰ্কীয় অনুমতি নাথাকিব। অনুগ্ৰহ কৰি go/r-bg-fgs-restriction চাওক আৰু এটা বাগৰিপ\'ৰ্ট ফাইল কৰক।"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"অনুমোদিত স্তৰতকৈ ওপৰলৈ ভলিউম বঢ়াব নেকি?\n\nদীৰ্ঘ সময়ৰ বাবে উচ্চ ভলিউমত শুনাৰ ফলত শ্ৰৱণ ক্ষমতাৰ ক্ষতি হ\'ব পাৰে।"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"দিব্যাংগসকলৰ সুবিধাৰ শ্বৰ্টকাট ব্যৱহাৰ কৰেনে?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"শ্বৰ্টকাট অন হৈ থকাৰ সময়ত দুয়োটা ভলিউম বুটামত ৩ ছেকেণ্ডৰ বাবে ছাপ দি থাকিলে দিব্যাংগসকলৰ বাবে থকা সুবিধা এটা আৰম্ভ হ\'ব। \n\n চলিত দিব্যাংগসকলৰ সুবিধা:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n আপুনি এই সুবিধাটো ছেটিংসমূহ &gt; দিব্যাংগসকলৰ বাবে সুবিধা-লৈ গৈ সলনি কৰিব পাৰে।"</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"শ্বৰ্টকাটসমূহ সম্পাদনা কৰক"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"বাতিল কৰক"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"শ্বৰ্টকাট অফ কৰক"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>ক সীমাবদ্ধ বাকেটটোত ৰখা হৈছে"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"ব্যক্তিগত"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"কৰ্মস্থান"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 6f13024..73adbd8 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Admin şəxsi istifadə üçün cihazdan imtina etdi"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Cihaz idarə olunur"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Təşkilat bu cihazı idarə edir və şəbəkənin ötürülməsinə nəzarət edə bilər. Detallar üçün klikləyin."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Məkan ayarları admininiz tərəfindən dəyişildi"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Məkan ayarlarınıza baxmaq üçün toxunun."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Cihazınız təmizlənəcəkdir"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Admin tətbiqini istifadə etmək mümkün deyil. Cihaz indi təmizlənəcək.\n\nSualınız varsa, təşkilatın admini ilə əlaqə saxlayın."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Çap <xliff:g id="OWNER_APP">%s</xliff:g> tərəfindən deaktiv edildi."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Bu icazəli | sistem tətbiqi istənilən vaxt sistem kamerasından istifadə edərək şəkil və videolar çəkə bilər. Tətbiqdə saxlanılması üçün android.permission.CAMERA icazəsini tələb edir"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"vibrasiyaya nəzarət edir"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Tətbiqə vibratoru idarə etmə icazəsi verir."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Tətbiqə vibrasiya vəziyyətinə daxil olmaq imkanı verir."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"telefon nömrələrinə birbaşa zəng edir"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Tətbiqə Sizin müdaxiləniz olmadan telefon zəngləri etməyə imkan verir. Zərərli tətbiqlər Sizdən xəbərsiz şəkildə müxtəlif zənglər edərək, Sizə maddi ziyan vura bilər. Qeyd: Bu, tətbiqlərə təcili nömrələrə zəng etməyə icazə vermir."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS zəng xidmətinə giriş"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Yenidən cəhd edin."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Barmaq izi qeydə alınmayıb."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu cihazda barmaq izi sensoru yoxdur."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Barmaq <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Üz doğrulanmadı. Yenidən cəhd edin."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Üz kilidi quraşdırmamısınız."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Üz kilidi bu cihazda dəstəklənmir."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Üz <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Arxa fonda başladılan <xliff:g id="PACKAGENAME">%1$s</xliff:g> üzrə ön plan xidmətinin gələcək R versiyalarında \"istifadə zamanı\" icazəsi olmayacaq. go/r-bg-fgs-restriction bölməsinə keçin və baq hesabatı göndərin."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Səsin həcmi tövsiyə olunan səviyyədən artıq olsun?\n\nYüksək səsi uzun zaman dinləmək eşitmə qabiliyyətinizə zərər vura bilər."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Əlçatımlılıq Qısayolu istifadə edilsin?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Qısayol aktiv olduqda hər iki səs düyməsinə 3 saniyə basıb saxlamaqla əlçatımlılıq funksiyası işə başlayacaq.\n\n Cari əlçatımlılıq funksiyası:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Funksiyanı Ayarlar və Əçatımlılıq bölməsində dəyişə bilərsiniz."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Qısayolları redaktə edin"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Ləğv edin"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Qısayolu Deaktiv edin"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> MƏHDUDLAŞDIRILMIŞ səbətinə yerləşdirilib"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Şəxsi"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"İş"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 862495a..bf250f7 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -193,6 +193,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrator je ustupio uređaj za ličnu upotrebu"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Uređajem se upravlja"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Organizacija upravlja ovim uređajem i može da nadgleda mrežni saobraćaj. Dodirnite za detalje."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Administrator je promenio podešavanja lokacije"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Dodirnite da biste videli podešavanja lokacije."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Uređaj će biti obrisan"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Ne možete da koristite ovu aplikaciju za administratore. Uređaj će sada biti obrisan.\n\nAko imate pitanja, kontaktirajte administratora organizacije."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Štampanje je onemogućila aplikacija <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -432,6 +434,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Ova privilegovana | sistemska aplikacija može da snima slike i video snimke pomoću kamere sistema u bilo kom trenutku. Aplikacija treba da ima i dozvolu android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"kontrola vibracije"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Dozvoljava aplikaciji da kontroliše vibraciju."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Dozvoljava aplikaciji da pristupa stanju vibriranja."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"direktno pozivanje brojeva telefona"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Dozvoljava aplikaciji da poziva brojeve telefona bez vaše dozvole. Ovo može da dovede do neočekivanih troškova ili poziva. Imajte na umu da ovo ne dozvoljava aplikaciji da poziva brojeve za hitne slučajeve. Zlonamerne aplikacije mogu da pozivaju bez vaše potvrde, što može da dovede do troškova."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"pristup usluzi poziva pomoću razmene trenutnih poruka"</string>
@@ -546,6 +549,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Probajte ponovo."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nije registrovan nijedan otisak prsta."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor za otisak prsta."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -589,6 +594,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Provera lica nije uspela. Probajte ponovo."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Niste podesili otključavanje licem"</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Otključavanje licem nije podržano na ovom uređaju"</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Lice <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1636,7 +1643,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Usluga u prvom planu sa <xliff:g id="PACKAGENAME">%1$s</xliff:g> koja je pokrenuta u pozadini neće imati dozvolu tokom korišćenja u budućim R verzijama. Posetite go/r-bg-fgs-restriction i pošaljite izveštaj o grešci."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Želite da pojačate zvuk iznad preporučenog nivoa?\n\nSlušanje glasne muzike duže vreme može da vam ošteti sluh."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Želite li da koristite prečicu za pristupačnost?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Kada je prečica uključena, pritisnite oba dugmeta za jačinu zvuka da biste pokrenuli funkciju pristupačnosti.\n\n Aktuelna funkcija pristupačnosti:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Možete da promenite funkciju u odeljku Podešavanja &gt; Pristupačnost."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Izmenite prečice"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Otkaži"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Isključi prečicu"</string>
@@ -2044,4 +2052,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Paket <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> je dodat u segment OGRANIČENO"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Lični"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Poslovni"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 8a02da2..454a21e 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -195,6 +195,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Адміністратар пераналадзіў прыладу для асабістага выкарыстання"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Прылада знаходзіцца пад кіраваннем"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Ваша арганізацыя кіруе гэтай прыладай і можа сачыць за сеткавым трафікам. Дакраніцеся для атрымання дадатковай інфармацыі."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Налады месцазнаходжання зменены адміністратарам"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Націсніце, каб праглядзець налады месцазнаходжання."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Даныя вашай прылады будуць сцерты"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Немагчыма выкарыстоўваць праграму адміністравання. Звесткі на вашай прыладзе будуць выдалены.\n\nКалі ў вас ёсць пытанні, звярніцеся да адміністратара арганізацыі."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Друк адключаны ўладальнікам праграмы <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -435,6 +437,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Гэта прыярытэтная | сістэмная праграма можа здымаць фота і запісваць відэа, выкарыстоўваючы сістэмную камеру. Праграме патрэбны дазвол android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"кіраванне вібрацыяй"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Дазваляе прыкладанням кіраваць вібрацыяй."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Дазваляе праграме атрымліваць доступ да вібрасігналу."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"непасрэдна набіраць тэлефонныя нумары"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Дазваляе прыкладанням званiць на тэлефонныя нумары без вашага ўмяшання. Гэта можа прывесці да нечаканага спагнання сродкаў або званкоў. Звярніце ўвагу, што прыкладанне не можа рабiць экстраныя выклікi. Шкоднасныя прыкладаннi могуць спаганяць з вас сродкi, робячы званкі без вашага пацверджання."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"атрымліваць доступ да сэрвісу выклікаў IMS"</string>
@@ -549,6 +552,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Паспрабуйце яшчэ раз."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Адбіткі пальцаў не зарэгістраваны."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На гэтай прыладзе няма сканера адбіткаў пальцаў."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Палец <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -592,6 +597,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Не ўдалося спраўдзіць твар. Паўтарыце спробу."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Вы не наладзілі распазнаванне твару."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"На гэтай прыладзе распазнаванне твару не падтрымліваецца."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Твар <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1658,7 +1665,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Запушчаны ў фонавым рэжыме асноўны сэрвіс з пакета \"<xliff:g id="PACKAGENAME">%1$s</xliff:g>\" не будзе мець дазволу while-in-use у будучых зборках на мове R. Наведайце сайт go/r-bg-fgs-restriction і адпраўце справаздачу пра памылку."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Павялiчыць гук вышэй рэкамендаванага ўзроўню?\n\nДоўгае праслухоўванне музыкi на вялiкай гучнасцi можа пашкодзiць ваш слых."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Выкарыстоўваць камбінацыю хуткага доступу для спецыяльных магчымасцей?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Калі камбінацыя хуткага доступу ўключана, вы можаце націснуць абедзве кнопкі гучнасці і ўтрымліваць іх 3 секунды, каб уключыць функцыю спецыяльных магчымасцей.\n\n Бягучая функцыя спецыяльных магчымасцей:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Вы можаце змяніць гэту функцыю ў меню \"Налады &gt; Спецыяльныя магчымасці\"."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Змяніць ярлыкі"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Скасаваць"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Дэактываваць камбінацыю хуткага доступу"</string>
@@ -2078,4 +2086,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Пакет \"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>\" дададзены ў АБМЕЖАВАНУЮ групу"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Асабістыя"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Працоўныя"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index f7830c7..ad8fdc6 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Администраторът предостави устройствотото за лична употреба"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Устройството се управлява"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Организацията ви управлява това устройство и може да наблюдава мрежовия трафик. Докоснете за подробности."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Настройките за местоположението са променени от администратора ви"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Докоснете, за да видите настройките за местоположението."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Данните на устройството ви ще бъдат изтрити"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Приложението за администриране не може да се използва. Сега данните на устройството ви ще бъдат изтрити.\n\nАко имате въпроси, свържете се с администратора на организацията си."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Отпечатването е деактивиранo от <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Това привилегировано/системно приложение може по всяко време да прави снимки и да записва видеоклипове посредством системна камера. Необходимо е също на приложението да бъде дадено разрешението android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"контролиране на вибрирането"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Разрешава на приложението да контролира устройството за вибрация."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Дава възможност на приложението да осъществява достъп до състоянието на вибриране."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"директно обаждане до телефонни номера"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Разрешава на приложението да се обажда без ваша намеса до телефонни номера, което може да доведе до неочаквано таксуване или обаждания. Обърнете внимание, че това не му позволява да извършва обаждания до спешните служби. Злонамерените приложения могат да ви въвлекат в разходи, като извършват обаждания без потвърждение от ваша страна."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"достъп до услугата за незабавни съобщения за обаждания"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Опитайте отново."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Няма регистрирани отпечатъци."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Това устройство няма сензор за отпечатъци."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Пръст <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Лицето не може да се потвърди. Опитайте отново."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Не сте настроили отключването с лице."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Отключването с лице не се поддържа на това устройство."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Лице <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Задният план, който е стартирал услуга на преден план от <xliff:g id="PACKAGENAME">%1$s</xliff:g>, няма да има разрешение при използване в бъдещите компилации R. Моля, вижте go/r-bg-fgs-restriction и подайте сигнал за програмна грешка."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Да се увеличи ли силата на звука над препоръчителното ниво?\n\nПродължителното слушане при висока сила на звука може да увреди слуха ви."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Искате ли да използвате пряк път към функцията за достъпност?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Когато прекият път е включен, можете да стартирате дадена функция за достъпност, като натиснете двата бутона за промяна на силата на звука и ги задържите 3 секунди.\n\n Текущата функция за достъпност е:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Можете да промените функцията от „Настройки“ &gt; „Достъпност“."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Редактиране на преките пътища"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Отказ"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Изключване на прекия път"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Пакетът <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> е поставен в ОГРАНИЧЕНИЯ контейнер"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Лични"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Служебни"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index af50b33..f5570c6 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -191,6 +191,10 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"ব্যক্তিগত কাজের জন্য অ্যাডমিন এই ডিভাইস ব্যবহার করার অনুমতি দেয়নি"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"ডিভাইসটি পরিচালনা করা হচ্ছে"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"আপনার প্রতিষ্ঠান এই ডিভাইসটি পরিচালনা করে এবং এটির নেটওয়ার্ক ট্রাফিকের উপরে নজর রাখতে পারে। বিশদ বিবরণের জন্য ট্যাপ করুন।,"</string>
+    <!-- no translation found for location_changed_notification_title (4119726617105166830) -->
+    <skip />
+    <!-- no translation found for location_changed_notification_text (198907268219396399) -->
+    <skip />
     <string name="factory_reset_warning" msgid="6858705527798047809">"আপনার ডিভাইসটি মুছে ফেলা হবে"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"অ্যাডমিন অ্যাপটি ব্যবহার করা যাবে না। আপনার ডিভাইসে থাকা সবকিছু এখন মুছে ফেলা হবে।\n\nকোনও প্রশ্ন থাকলে আপনার প্রতিষ্ঠানের অ্যাডমিনের সাথে যোগাযোগ করুন।"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> প্রিন্টিং বন্ধ রেখেছে।"</string>
@@ -429,6 +433,8 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"এই প্রিভিলিজ | সিস্টেম অ্যাপটি যেকোনও সময়ে সিস্টেম ক্যামেরা ব্যবহার করে ছবি তুলতে এবং ভিডিও রেকর্ড করতে পারবে। এর জন্য অ্যাপের Android.permission.CAMERA -এর অনুমতি প্রয়োজন"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"ভাইব্রেশন নিয়ন্ত্রণ করুন"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"অ্যাপ্লিকেশানকে কম্পক নিয়ন্ত্রণ করতে দেয়৷"</string>
+    <!-- no translation found for permdesc_vibrator_state (7050024956594170724) -->
+    <skip />
     <string name="permlab_callPhone" msgid="1798582257194643320">"সরাসরি ফোন নম্বরগুলিতে কল করে"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"অ্যাপ্লিকেশানটিকে আপনার হস্তক্ষেপ ছাড়াই ফোন নম্বরগুলিতে কল করতে মঞ্জুর করে৷ এটি অপ্রত্যাশিত পরিমাণ খরচা বা কলের কারণ হতে পারে৷ মনে রাখবেন, এটি অ্যাপ্লিকেশানটির দ্বারা জরুরি নম্বরগুলিতে কল করাকে অনুমতি দেয় না৷ ক্ষতিকারক অ্যাপ্লিকেশানগুলি আপনার সম্মতি ছাড়াই কল করার ফলে আপনাকে অহেতুক পেমেন্ট করতে হতে পারে৷"</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS পরিষেবাতে অ্যাক্সেস"</string>
@@ -543,6 +549,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"আবার চেষ্টা করুন৷"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"কোনও আঙ্গুলের ছাপ নথিভুক্ত করা হয়নি।"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইসে আঙ্গুলের ছাপ নেওয়ার সেন্সর নেই।"</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"আঙ্গুল <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +594,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"আপনার মুখ যাচাই করা যাচ্ছে না। আবার চেষ্টা করুন।"</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"এখনও মুখের সাহায্যে আনলক করার সুবিধা সেট-আপ করেননি।"</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"এই ডিভাইসে মুখের সাহায্যে আনলক করার সুবিধাটি কাজ করে না।"</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"<xliff:g id="FACEID">%d</xliff:g> ফেস"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1624,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> থেকে শুরু হওয়া ফোরগ্রাউন্ড পরিষেবাটির ভবিষ্যতে আর বিল্ডগুলিতে ব্যবহারের অনুমতি নেই। go/r-bg-fgs-restriction দেখুন এবং বাগরিপোর্ট জমা দিন।"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"প্রস্তাবিত স্তরের চেয়ে বেশি উঁচুতে ভলিউম বাড়াবেন?\n\nউঁচু ভলিউমে বেশি সময় ধরে কিছু শুনলে আপনার শ্রবনশক্তির ক্ষতি হতে পারে।"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"অ্যাক্সেসযোগ্যতা শর্টকাট ব্যবহার করবেন?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"শর্টকাটটি চালু থাকলে দুটি ভলিউম বোতাম একসাথে ৩ সেকেন্ড টিপে ধরে রাখলে একটি অ্যাকসেসিবিলিটি বৈশিষ্ট্য চালু হবে।\n\n বর্তমান অ্যাকসেসিবিলিটি বৈশিষ্ট্য:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n আপনি এই বৈশিষ্ট্যটি সেটিংস &gt; অ্যাকসেসিবিলিটিতে গিয়ে পরিবর্তন করতে পারবেন।"</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"শর্টকাট এডিট করুন"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"বাতিল করুন"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"শর্টকাট বন্ধ করুন"</string>
@@ -2010,4 +2021,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> সীমাবদ্ধ গ্রুপে অন্তর্ভুক্ত করা হয়েছে"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"ব্যক্তিগত"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"অফিস"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index d436c5f..fd53b69 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -193,6 +193,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrator je ustupio uređaj za ličnu upotrebu"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Uređajem se upravlja."</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Vaša organizacija upravlja ovim uređajem i može pratiti mrežni saobraćaj. Dodirnite za detalje."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Postavke lokacije je promijenio vaš administrator"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Dodirnite da vidite postavke lokacije."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Uređaj će biti izbrisan"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Nije moguće koristiti aplikaciju administratora. Potpuno će se izbrisati podaci na vašem uređaju.\n\nAko imate pitanja, obratite se administratoru svoje organizacije."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Štampanje je onemogućila aplikacija <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -432,6 +434,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Ova povlaštena | sistemska aplikacija u svakom trenutku može snimati fotografije i videozapise pomoću kamere sistema. Aplikacija također mora imati dopuštenje android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"kontrola vibracije"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Dozvoljava aplikaciji upravljanje vibracijom."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Dozvoljava aplikaciji pristup stanju vibracije."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"izravno zvanje telefonskih brojeva"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Omogućava aplikaciji pozivanje telefonskih brojeva bez vašeg angažiranja. Ovo može uzrokovati neočekivane troškove ili pozive. Imajte na umu da ovo ne daje aplikaciji mogućnost pozivanja brojeva za hitne slučajeve. Zlonamjerne aplikacije vam mogu napraviti neočekivane troškove kroz vršenje poziva bez vašeg znanja."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"pristup usluzi IMS pozivanja"</string>
@@ -546,6 +549,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Pokušajte ponovo."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nije prijavljen nijedan otisak prsta."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor za otisak prsta."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -589,6 +594,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Nije moguće potvrditi lice. Pokušajte ponovo."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Niste postavili otključavanje licem."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Otključavanje licem nije podržano na ovom uređaju."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Lice <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1638,7 +1645,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Usluge iz prvog plana započete u pozadini s web lokacije <xliff:g id="PACKAGENAME">%1$s</xliff:g> neće imati odobrenje za funkciju \"za vrijeme korištenja\" u budućim R verzijama. Pogledajte go/r-bg-fgs-restriction i podnesite izvještaj o greškama."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Želite li pojačati zvuk iznad preporučenog nivoa?\n\nDužim slušanjem glasnog zvuka možete oštetiti sluh."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Želite li koristiti Prečicu za pristupačnost?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Kada je prečica uključena, pritiskom na oba dugmeta za podešavanje jačine zvuka u trajanju od 3 sekunde pokrenut će se funkcija za pristupačnost.\n\n Trenutna funkcija za pristupačnost je:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Funkciju možete promijeniti ako odete u Postavke &gt; Pristupačnost."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Uredi prečice"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Otkaži"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Isključi prečicu"</string>
@@ -2046,4 +2054,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Paket <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> je stavljen u odjeljak OGRANIČENO"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Lično"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Posao"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index f3b416c..fdb8f45 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"L\'administrador ha cedit el dispositiu per a ús personal"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"El dispositiu està gestionat"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"La teva organització gestiona aquest dispositiu i és possible que supervisi el trànsit de xarxa. Toca per obtenir més informació."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"L\'administrador ha modificat la configuració d\'ubicació"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Toca per veure la configuració d\'ubicació."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"El contingut del dispositiu s\'esborrarà"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"No es pot utilitzar l\'aplicació d\'administració. S\'esborraran les dades del dispositiu.\n\nSi tens cap dubte, contacta amb l\'administrador de la teva organització."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ha desactivat la impressió."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Aquesta aplicació del sistema pot fer fotos i gravar vídeos amb una càmera del sistema en qualsevol moment. L\'aplicació també ha de tenir el permís android.permission.CAMERA per accedir-hi"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"controlar la vibració"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Permet que l\'aplicació controli el vibrador."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permet que l\'aplicació accedeixi a l\'estat de vibració."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"trucar directament a números de telèfon"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Permet que l\'aplicació truqui a números de telèfon sense la teva intervenció. Aquesta acció pot produir càrrecs o trucades inesperades. Tingues en compte que això no permet que l\'aplicació truqui a números d\'emergència. Les aplicacions malicioses poden fer trucades sense la teva confirmació, cosa que et pot fer gastar diners."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"accés al servei de trucades IMS"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Torna-ho a provar."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No s\'ha registrat cap empremta digital."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aquest dispositiu no té sensor d\'empremtes dactilars."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dit <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"No es pot verificar la cara. Torna-ho a provar."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"No has configurat el desbloqueig facial"</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"El desbloqueig facial no és compatible amb el dispositiu."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Cara <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"El servei en primer pla (<xliff:g id="PACKAGENAME">%1$s</xliff:g>) iniciat en segon pla no tindrà permís durant l\'ús en compilacions R posteriors. Consulta la pàgina go/r-bg-fgs-restriction i presenta un informe d\'errors."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vols apujar el volum per sobre del nivell recomanat?\n\nSi escoltes música a un volum alt durant períodes llargs, pots danyar-te l\'oïda."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Vols fer servir la drecera d\'accessibilitat?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Si la drecera està activada, prem els dos botons de volum durant 3 segons, per iniciar una funció d\'accessibilitat.\n\n Funció d\'accessibilitat actual:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Pots canviar la funció a Configuració &gt; Accessibilitat."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Edita les dreceres"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Cancel·la"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desactiva la drecera"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> s\'ha transferit al segment RESTRINGIT"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Personal"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Feina"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 754a020..a1ff467 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -195,6 +195,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrátor zařízení uvolnil k osobnímu používání"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Zařízení je spravováno"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Toto zařízení je spravováno vaší organizací, která může sledovat síťový provoz. Podrobnosti zobrazíte klepnutím."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Administrátor změnil nastavení polohy"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Klepnutím zobrazíte nastavení polohy."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Zařízení bude vymazáno"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Aplikaci pro správu nelze použít. Zařízení teď bude vymazáno.\n\nV případě dotazů vám pomůže administrátor organizace."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Aplikace <xliff:g id="OWNER_APP">%s</xliff:g> tisk zakazuje."</string>
@@ -435,6 +437,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Tato privilegovaná | systémová aplikace může pomocí fotoaparátu kdykoli pořídit snímek nebo nahrát video. Aplikace musí zároveň mít oprávnění android.permission.CAMERA."</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"ovládání vibrací"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Umožňuje aplikaci ovládat vibrace."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Umožňuje aplikaci přístup ke stavu vibrací."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"přímé volání na telefonní čísla"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Umožňuje aplikaci volat na telefonní čísla bez vašeho přičinění. Může mít za následek neočekávané poplatky nebo hovory. Toto oprávnění neumožňuje aplikaci volat na tísňová čísla. Škodlivé aplikace vás mohou připravit o peníze uskutečňováním hovorů bez vašeho svolení."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"přístup ke službě zasílání rychlých zpráv pro účely hovorů"</string>
@@ -549,6 +552,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Zkuste to znovu."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nejsou zaregistrovány žádné otisky prstů."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Toto zařízení nemá snímač otisků prstů."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -592,6 +597,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Obličej se nepodařilo ověřit. Zkuste to znovu."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Ověření obličejem nemáte nastavené."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Odemknutí obličejem na tomto zařízení není podporováno."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Obličej <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1658,7 +1665,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Služba v popředí z balíčku <xliff:g id="PACKAGENAME">%1$s</xliff:g>, která byla spuštěna na pozadí, v budoucích sestavenách typu R nebude mít oprávnění ke spuštění při používání. Přejděte na adresu go/r-bg-fgs-restriction a vyplňte zprávu o chybě."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Zvýšit hlasitost nad doporučenou úroveň?\n\nDlouhodobý poslech hlasitého zvuku může poškodit sluch."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Použít zkratku přístupnosti?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Když je tato zkratka zapnutá, můžete funkci přístupnosti spustit tím, že na tři sekundy podržíte obě tlačítka hlasitosti.\n\n Aktuální funkce přístupnosti:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Funkci můžete změnit v Nastavení &gt; Přístupnost."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Upravit zkratky"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Zrušit"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Vypnout zkratku"</string>
@@ -2078,4 +2086,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Balíček <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> byl vložen do sekce OMEZENO"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Osobní"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Pracovní"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 733c7f0..10da1e7 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administratoren har gjort personlig brug af enheden utilgængelig"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Dette er en administreret enhed"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Din organisation administrerer denne enhed og kan overvåge netværkstrafik. Tryk for at se info."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Placeringsindstillinger blev ændret af din administrator"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Tryk for at se dine placeringsindstillinger."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Enheden slettes"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Administrationsappen kan ikke bruges. Enheden vil nu blive ryddet. \n\nKontakt din organisations administrator, hvis du har spørgsmål."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Udskrivning er deaktiveret af <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Denne privilegerede app | systemapp kan tage billeder og optage video med kameraet når som helst. Appen skal også have tilladelsen android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"administrere vibration"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Tillader, at appen kan administrere vibratoren."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Tillader, at appen bruger vibration."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ringe direkte op til telefonnumre"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Tillader, at appen kan ringe til telefonnumre uden din indgriben. Dette kan resultere i uventede opkrævninger eller opkald. Bemærk, at appen med denne tilladelse ikke kan ringe til nødopkaldsnumre. Skadelige apps kan koste dig penge ved at foretage opkald uden din bekræftelse."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"få adgang til chat-opkaldstjeneste"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Prøv igen."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Der er ikke registreret nogen fingeraftryk."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Denne enhed har ingen fingeraftrykslæser."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Fingeraftryk <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Ansigtet kan ikke genkendes. Prøv igen."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Du har ikke konfigureret ansigtslås."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Ansigtslås understøttes ikke på denne enhed."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Ansigt <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Tjenesten i forgrunden fra <xliff:g id="PACKAGENAME">%1$s</xliff:g>, der starter i baggrunden, vil i fremtidige R-builds ikke have tilladelse, mens den er i brug. Se go/r-bg-fgs-restriction, og indsend en fejlrapport."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vil du skrue højere op end det anbefalede lydstyrkeniveau?\n\nDu kan skade hørelsen ved at lytte til meget høj musik over længere tid."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Vil du bruge genvejen til Hjælpefunktioner?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Når genvejen er slået til, kan du starte en hjælpefunktion ved at trykke på begge lydstyrkeknapper i tre sekunder.\n\n Nuværende hjælpefunktion:\n<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Du kan skifte funktion i Indstillinger &gt; Hjælpefunktioner."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Rediger genveje"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Annuller"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Deaktiver genvej"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> er blevet placeret i samlingen BEGRÆNSET"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Personlig"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Arbejde"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 9a4c606..98d9f92 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrator hat das Gerät zur persönlichen Nutzung abgegeben"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Dies ist ein verwaltetes Gerät"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Deine Organisation verwaltet dieses Gerät und überprüft unter Umständen den Netzwerkverkehr. Tippe hier, um weitere Informationen zu erhalten."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Standorteinstellungen durch Administrator geändert"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Tippe, um deine Standorteinstellungen anzuzeigen."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Die Daten auf deinem Gerät werden gelöscht."</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Die Admin-App kann nicht verwendet werden. Die Daten auf deinem Gerät werden nun gelöscht.\n\nBitte wende dich bei Fragen an den Administrator deiner Organisation."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Drucken wurde von <xliff:g id="OWNER_APP">%s</xliff:g> deaktiviert."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Diese privilegierte App | System-App kann jederzeit mit einer Systemkamera Bilder und Videos aufnehmen. Die App benötigt auch die Berechtigung \"android.permission.CAMERA\"."</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"Vibrationsalarm steuern"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Ermöglicht der App, den Vibrationsalarm zu steuern"</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Ermöglicht der App, auf den Vibrationsstatus zuzugreifen."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"Telefonnummern direkt anrufen"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Ermöglicht der App, ohne dein Eingreifen Telefonnummern zu wählen. Dies kann zu unerwarteten Kosten und Anrufen führen. Beachte, dass die App keine Notrufnummern wählen kann. Schädliche Apps verursachen möglicherweise Kosten, indem sie Anrufe ohne deine Bestätigung tätigen."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"Zugriff auf IMS-Anrufdienst"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Bitte versuche es noch einmal."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Keine Fingerabdrücke erfasst."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dieses Gerät hat keinen Fingerabdrucksensor."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Gesichtsprüfung nicht möglich. Noch mal versuchen."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Face Unlock ist nicht eingerichtet."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Face Unlock wird auf diesem Gerät nicht unterstützt."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Gesicht <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Der Dienst im Vordergrund von <xliff:g id="PACKAGENAME">%1$s</xliff:g>, der im Hintergrund gestartet wurde, hat in zukünftigen R-Builds keine Zugriffsberechtigung mehr während der Nutzung. Siehe dazu go/r-bg-fgs-restriction und reiche einen Fehlerbericht ein."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Lautstärke über den Schwellenwert anheben?\n\nWenn du über einen längeren Zeitraum Musik in hoher Lautstärke hörst, kann dies dein Gehör schädigen."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Verknüpfung für Bedienungshilfen verwenden?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Wenn die Verknüpfung aktiviert ist, kannst du die beiden Lautstärketasten drei Sekunden lang gedrückt halten, um eine Bedienungshilfe zu starten.\n\n Aktuelle Bedienungshilfe:\n<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Du kannst die Bedienungshilfe unter \"Einstellungen\" &gt; \"Bedienungshilfen\" ändern."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Verknüpfungen bearbeiten"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Abbrechen"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Verknüpfung deaktivieren"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> wurde in den BESCHRÄNKT-Bucket gelegt"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Privat"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Geschäftlich"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 30a8d61..e5cb635 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Συσκευή από την οποία αποσύρθηκε ο διαχειριστής για προσωπική χρήση"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Η συσκευή είναι διαχειριζόμενη"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Ο οργανισμός σας διαχειρίζεται αυτήν τη συσκευή και ενδέχεται να παρακολουθεί την επισκεψιμότητα δικτύου. Πατήστε για λεπτομέρειες."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Οι ρυθμίσεις τοποθεσίας άλλαξαν από τον διαχειριστή"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Πατήστε, για να δείτε τις ρυθμίσεις τοποθεσίας."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Η συσκευή σας θα διαγραφεί"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Δεν είναι δυνατή η χρήση της εφαρμογής διαχειριστή. Η συσκευή σας θα διαγραφεί.\n\nΕάν έχετε ερωτήσεις, επικοινωνήστε με τον διαχειριστή του οργανισμού σας."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Η εκτύπωση απενεργοποιήθηκε από τον χρήστη <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Αυτή η προνομιούχα εφαρμογή | εφαρμογή συστήματος μπορεί να τραβάει φωτογραφίες και να εγγράφει βίντεο, χρησιμοποιώντας μια κάμερα του συστήματος ανά πάσα στιγμή. Απαιτείται, επίσης, η εφαρμογή να έχει την άδεια android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"ελέγχει τη δόνηση"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Επιτρέπει στην εφαρμογή τον έλεγχο της δόνησης."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Επιτρέπει στην εφαρμογή να έχει πρόσβαση στην κατάσταση δόνησης."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"πραγματοποιεί απευθείας κλήση τηλεφωνικών αριθμών"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Επιτρέπει στην εφαρμογή την κλήση αριθμών τηλεφώνου χωρίς δική σας παρέμβαση. Αυτό μπορεί να προκαλέσει μη αναμενόμενες χρεώσεις ή κλήσεις. Έχετε υπόψη ότι δεν επιτρέπεται στην εφαρμογή η κλήση αριθμών έκτακτης ανάγκης. Οι κακόβουλες εφαρμογές ενδέχεται να σας κοστίσουν χρήματα, πραγματοποιώντας κλήσεις χωρίς την έγκρισή σας."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"έχει πρόσβαση στην υπηρεσία κλήσεων της IMS"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Δοκιμάστε ξανά."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Δεν έχουν καταχωριστεί δακτυλικά αποτυπώματα."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Αυτή η συσκευή δεν διαθέτει αισθητήρα δακτυλικού αποτυπώματος."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Δάχτυλο <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Αδύνατη επαλήθευση του προσώπου. Επανάληψη."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Δεν έχετε ρυθμίσει το Face Unlock."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Το Face Unlock δεν υποστηρίζεται σε αυτήν τη συσκευή."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Πρόσωπο <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Η υπηρεσία στο προσκήνιο που ξεκίνησε από το παρασκήνιο από το πακέτο <xliff:g id="PACKAGENAME">%1$s</xliff:g> δεν θα έχει άδεια πρόσβασης μόνο κατά τη χρήση σε μελλοντικές εκδόσεις R. Ανατρέξτε στο go/r-bg-fgs-restriction και υποβάλετε αναφορά σφάλματος."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Αυξάνετε την ένταση ήχου πάνω από το επίπεδο ασφαλείας;\n\nΑν ακούτε μουσική σε υψηλή ένταση για μεγάλο χρονικό διάστημα ενδέχεται να προκληθεί βλάβη στην ακοή σας."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Να χρησιμοποιείται η συντόμευση προσβασιμότητας;"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Όταν η συντόμευση είναι ενεργοποιημένη, το πάτημα και των δύο κουμπιών έντασης ήχου για 3 δευτερόλεπτα θα ξεκινήσει μια λειτουργία προσβασιμότητας.\n\n Τρέχουσα λειτουργία προσβασιμότητας:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Μπορείτε να αλλάξετε τη λειτουργία από τις Ρυθμίσεις &gt; Προσβασιμότητα."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Επεξεργασία συντομεύσεων"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Άκυρο"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Απενεργοποίηση συντόμευσης"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Το πακέτο <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> τοποθετήθηκε στον κάδο ΠΕΡΙΟΡΙΣΜΕΝΗΣ ΠΡΟΣΒΑΣΗΣ."</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Προσωπικό"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Εργασία"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index d15fc5a..7ee9846 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Admin relinquished device for personal use"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Device is managed"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Your organisation manages this device and may monitor network traffic. Tap for details."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Location settings changed by your admin"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Tap to see your location settings."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Your device will be erased"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"The admin app can\'t be used. Your device will now be erased.\n\nIf you have questions, contact your organisation\'s admin."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Printing disabled by <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"This privileged | system app can take pictures and record videos using a system camera at any time. Requires the android.permission.CAMERA permission to be held by the app as well"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"control vibration"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Allows the app to control the vibrator."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Allows the app to access the vibrator state."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"directly call phone numbers"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Allows the app to call phone numbers without your intervention. This may result in unexpected charges or calls. Note that this doesn\'t allow the app to call emergency numbers. Malicious apps may cost you money by making calls without your confirmation."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"access IMS call service"</string>
@@ -543,6 +546,7 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Try again."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
+    <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +590,7 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Can’t verify face. Try again."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"You haven’t set up face unlock."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Face unlock is not supported on this device."</string>
+    <string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor temporarily disabled."</string>
     <string name="face_name_template" msgid="3877037340223318119">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1619,7 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"The background started foreground service from <xliff:g id="PACKAGENAME">%1$s</xliff:g> will not have while-in-use permission in future R builds. Please see go/r-bg-fgs-restriction and file a bug report."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Raise volume above recommended level?\n\nListening at high volume for long periods may damage your hearing."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Use Accessibility Shortcut?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"When the shortcut is on, pressing both volume buttons for 3 seconds will start an accessibility feature.\n\n Current accessibility feature:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n You can change the feature in Settings &gt; Accessibility."</string>
+    <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"When the shortcut is on, pressing both volume buttons for three seconds will start an accessibility feature."</string>
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Edit shortcuts"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Cancel"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Turn off Shortcut"</string>
@@ -2010,4 +2015,12 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> has been put into the RESTRICTED bucket"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Personal"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Work"</string>
+    <string name="resolver_cant_share_with_work_apps" msgid="7539495559434146897">"Can’t share with work apps"</string>
+    <string name="resolver_cant_share_with_personal_apps" msgid="8020581735267157241">"Can’t share with personal apps"</string>
+    <string name="resolver_cant_share_cross_profile_explanation" msgid="3536237105241882679">"Your IT admin blocked sharing between personal and work apps"</string>
+    <string name="resolver_turn_on_work_apps" msgid="8987359079870455469">"Turn on work apps"</string>
+    <string name="resolver_turn_on_work_apps_explanation" msgid="6322467455509618928">"Turn on work apps to access work apps and contacts"</string>
+    <string name="resolver_no_apps_available" msgid="7710339903040989654">"No apps available"</string>
+    <string name="resolver_no_apps_available_explanation" msgid="4662694431121196560">"We couldn’t find any apps"</string>
+    <string name="resolver_switch_on_work" msgid="8294542702883688533">"Switch on work"</string>
 </resources>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index bec2e34..4ff5975 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Admin relinquished device for personal use"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Device is managed"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Your organisation manages this device and may monitor network traffic. Tap for details."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Location settings changed by your admin"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Tap to see your location settings."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Your device will be erased"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"The admin app can\'t be used. Your device will now be erased.\n\nIf you have questions, contact your organisation\'s admin."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Printing disabled by <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"This privileged | system app can take pictures and record videos using a system camera at any time. Requires the android.permission.CAMERA permission to be held by the app as well"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"control vibration"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Allows the app to control the vibrator."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Allows the app to access the vibrator state."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"directly call phone numbers"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Allows the app to call phone numbers without your intervention. This may result in unexpected charges or calls. Note that this doesn\'t allow the app to call emergency numbers. Malicious apps may cost you money by making calls without your confirmation."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"access IMS call service"</string>
@@ -543,6 +546,7 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Try again."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
+    <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +590,7 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Can’t verify face. Try again."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"You haven’t set up face unlock."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Face unlock is not supported on this device."</string>
+    <string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor temporarily disabled."</string>
     <string name="face_name_template" msgid="3877037340223318119">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1619,7 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"The background started foreground service from <xliff:g id="PACKAGENAME">%1$s</xliff:g> will not have while-in-use permission in future R builds. Please see go/r-bg-fgs-restriction and file a bug report."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Raise volume above recommended level?\n\nListening at high volume for long periods may damage your hearing."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Use Accessibility Shortcut?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"When the shortcut is on, pressing both volume buttons for 3 seconds will start an accessibility feature.\n\n Current accessibility feature:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n You can change the feature in Settings &gt; Accessibility."</string>
+    <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"When the shortcut is on, pressing both volume buttons for three seconds will start an accessibility feature."</string>
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Edit shortcuts"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Cancel"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Turn off Shortcut"</string>
@@ -2010,4 +2015,12 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> has been put into the RESTRICTED bucket"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Personal"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Work"</string>
+    <string name="resolver_cant_share_with_work_apps" msgid="7539495559434146897">"Can’t share with work apps"</string>
+    <string name="resolver_cant_share_with_personal_apps" msgid="8020581735267157241">"Can’t share with personal apps"</string>
+    <string name="resolver_cant_share_cross_profile_explanation" msgid="3536237105241882679">"Your IT admin blocked sharing between personal and work apps"</string>
+    <string name="resolver_turn_on_work_apps" msgid="8987359079870455469">"Turn on work apps"</string>
+    <string name="resolver_turn_on_work_apps_explanation" msgid="6322467455509618928">"Turn on work apps to access work apps and contacts"</string>
+    <string name="resolver_no_apps_available" msgid="7710339903040989654">"No apps available"</string>
+    <string name="resolver_no_apps_available_explanation" msgid="4662694431121196560">"We couldn’t find any apps"</string>
+    <string name="resolver_switch_on_work" msgid="8294542702883688533">"Switch on work"</string>
 </resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index d15fc5a..7ee9846 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Admin relinquished device for personal use"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Device is managed"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Your organisation manages this device and may monitor network traffic. Tap for details."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Location settings changed by your admin"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Tap to see your location settings."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Your device will be erased"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"The admin app can\'t be used. Your device will now be erased.\n\nIf you have questions, contact your organisation\'s admin."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Printing disabled by <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"This privileged | system app can take pictures and record videos using a system camera at any time. Requires the android.permission.CAMERA permission to be held by the app as well"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"control vibration"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Allows the app to control the vibrator."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Allows the app to access the vibrator state."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"directly call phone numbers"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Allows the app to call phone numbers without your intervention. This may result in unexpected charges or calls. Note that this doesn\'t allow the app to call emergency numbers. Malicious apps may cost you money by making calls without your confirmation."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"access IMS call service"</string>
@@ -543,6 +546,7 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Try again."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
+    <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +590,7 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Can’t verify face. Try again."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"You haven’t set up face unlock."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Face unlock is not supported on this device."</string>
+    <string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor temporarily disabled."</string>
     <string name="face_name_template" msgid="3877037340223318119">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1619,7 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"The background started foreground service from <xliff:g id="PACKAGENAME">%1$s</xliff:g> will not have while-in-use permission in future R builds. Please see go/r-bg-fgs-restriction and file a bug report."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Raise volume above recommended level?\n\nListening at high volume for long periods may damage your hearing."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Use Accessibility Shortcut?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"When the shortcut is on, pressing both volume buttons for 3 seconds will start an accessibility feature.\n\n Current accessibility feature:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n You can change the feature in Settings &gt; Accessibility."</string>
+    <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"When the shortcut is on, pressing both volume buttons for three seconds will start an accessibility feature."</string>
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Edit shortcuts"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Cancel"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Turn off Shortcut"</string>
@@ -2010,4 +2015,12 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> has been put into the RESTRICTED bucket"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Personal"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Work"</string>
+    <string name="resolver_cant_share_with_work_apps" msgid="7539495559434146897">"Can’t share with work apps"</string>
+    <string name="resolver_cant_share_with_personal_apps" msgid="8020581735267157241">"Can’t share with personal apps"</string>
+    <string name="resolver_cant_share_cross_profile_explanation" msgid="3536237105241882679">"Your IT admin blocked sharing between personal and work apps"</string>
+    <string name="resolver_turn_on_work_apps" msgid="8987359079870455469">"Turn on work apps"</string>
+    <string name="resolver_turn_on_work_apps_explanation" msgid="6322467455509618928">"Turn on work apps to access work apps and contacts"</string>
+    <string name="resolver_no_apps_available" msgid="7710339903040989654">"No apps available"</string>
+    <string name="resolver_no_apps_available_explanation" msgid="4662694431121196560">"We couldn’t find any apps"</string>
+    <string name="resolver_switch_on_work" msgid="8294542702883688533">"Switch on work"</string>
 </resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index d15fc5a..7ee9846 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Admin relinquished device for personal use"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Device is managed"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Your organisation manages this device and may monitor network traffic. Tap for details."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Location settings changed by your admin"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Tap to see your location settings."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Your device will be erased"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"The admin app can\'t be used. Your device will now be erased.\n\nIf you have questions, contact your organisation\'s admin."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Printing disabled by <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"This privileged | system app can take pictures and record videos using a system camera at any time. Requires the android.permission.CAMERA permission to be held by the app as well"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"control vibration"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Allows the app to control the vibrator."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Allows the app to access the vibrator state."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"directly call phone numbers"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Allows the app to call phone numbers without your intervention. This may result in unexpected charges or calls. Note that this doesn\'t allow the app to call emergency numbers. Malicious apps may cost you money by making calls without your confirmation."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"access IMS call service"</string>
@@ -543,6 +546,7 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Try again."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No fingerprints enrolled."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
+    <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +590,7 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Can’t verify face. Try again."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"You haven’t set up face unlock."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Face unlock is not supported on this device."</string>
+    <string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor temporarily disabled."</string>
     <string name="face_name_template" msgid="3877037340223318119">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1619,7 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"The background started foreground service from <xliff:g id="PACKAGENAME">%1$s</xliff:g> will not have while-in-use permission in future R builds. Please see go/r-bg-fgs-restriction and file a bug report."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Raise volume above recommended level?\n\nListening at high volume for long periods may damage your hearing."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Use Accessibility Shortcut?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"When the shortcut is on, pressing both volume buttons for 3 seconds will start an accessibility feature.\n\n Current accessibility feature:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n You can change the feature in Settings &gt; Accessibility."</string>
+    <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"When the shortcut is on, pressing both volume buttons for three seconds will start an accessibility feature."</string>
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Edit shortcuts"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Cancel"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Turn off Shortcut"</string>
@@ -2010,4 +2015,12 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> has been put into the RESTRICTED bucket"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Personal"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Work"</string>
+    <string name="resolver_cant_share_with_work_apps" msgid="7539495559434146897">"Can’t share with work apps"</string>
+    <string name="resolver_cant_share_with_personal_apps" msgid="8020581735267157241">"Can’t share with personal apps"</string>
+    <string name="resolver_cant_share_cross_profile_explanation" msgid="3536237105241882679">"Your IT admin blocked sharing between personal and work apps"</string>
+    <string name="resolver_turn_on_work_apps" msgid="8987359079870455469">"Turn on work apps"</string>
+    <string name="resolver_turn_on_work_apps_explanation" msgid="6322467455509618928">"Turn on work apps to access work apps and contacts"</string>
+    <string name="resolver_no_apps_available" msgid="7710339903040989654">"No apps available"</string>
+    <string name="resolver_no_apps_available_explanation" msgid="4662694431121196560">"We couldn’t find any apps"</string>
+    <string name="resolver_switch_on_work" msgid="8294542702883688533">"Switch on work"</string>
 </resources>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 42ec932..bef3442 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‎‎‏‎‎‎‏‏‏‎‎‏‎‎‎‏‏‎‎‏‎‎‎‏‎‎‎‏‏‎‎‏‎‏‏‏‎‏‏‏‏‎‎‎‎‏‎‎‏‏‎‎‎Admin relinquished device for personal use‎‏‎‎‏‎"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‏‎‎‏‎‎‏‎‎‎‏‎‎‏‏‎‎‎‏‏‎‎‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‎Device is managed‎‏‎‎‏‎"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‎‏‎‏‏‏‏‎‎‎‏‏‎‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‏‎‏‎‎‎‏‏‎‏‎‎‏‎‏‎‎‎‏‎‏‎‎‎‎‎Your organization manages this device and may monitor network traffic. Tap for details.‎‏‎‎‏‎"</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎‎‎‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‏‏‎‎‏‏‏‎‎‎‏‏‏‏‎‏‏‏‎‎Location settings changed by your admin‎‏‎‎‏‎"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‏‎‏‎‏‎‏‎‎‏‎‎‎‏‏‎‏‏‎‏‎‎‏‎‎‏‎‏‏‏‎‏‎‏‏‏‏‎‎‎‎‏‎‎‏‎‏‏‏‏‎Tap to see your location settings.‎‏‎‎‏‎"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‏‏‏‎‎‎‎‎‏‎‎‎‏‎‏‎‏‏‎‏‎‏‎‏‎‏‏‎‏‏‎‏‎‎‏‎‎‏‎‎‏‎‎‎‏‎‎‎‎‎‏‎Your device will be erased‎‏‎‎‏‎"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‎‏‎‏‏‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‏‎‏‎‏‎The admin app can\'t be used. Your device will now be erased.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎If you have questions, contact your organization\'s admin.‎‏‎‎‏‎"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‏‎‎‎‎‏‎‏‎‏‎‏‏‎‏‏‏‎‎‎‎‎‎‎‎‎‎‎‏‏‎‏‎‏‎‎‎‏‎‎‎‎‎‎‏‎‏‏‏‏‎‎‏‎Printing disabled by ‎‏‎‎‏‏‎<xliff:g id="OWNER_APP">%s</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‎"</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‏‏‎‏‎‎‎‏‎‏‏‎‎‎‏‎‏‏‏‎‎‎‎‎‏‏‎‏‎‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‎‎‎‏‎‎This privileged | system app can take pictures and record videos using a system camera at any time. Requires the android.permission.CAMERA permission to be held by the app as well‎‏‎‎‏‎"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‏‏‎‎‎‎‎‎‏‎‏‎‏‏‎‏‏‎‎‏‎‎‏‏‏‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎control vibration‎‏‎‎‏‎"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‎‏‎‎‎‏‎‏‏‎‎‏‏‎‏‎‎‎‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‎‎‎‏‎‎‎‏‎‎‏‎Allows the app to control the vibrator.‎‏‎‎‏‎"</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‏‏‎‏‎‏‏‏‎‎‎‎‏‎‏‏‎‎‎‎‏‏‎‏‎‏‏‎‏‏‎‏‏‏‏‎‎‏‎‏‎‏‏‎‏‏‎‎‏‎‎‎Allows the app to access the vibrator state.‎‏‎‎‏‎"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‎‎‏‎‎‏‏‎‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‏‏‎‎‎‎directly call phone numbers‎‏‎‎‏‎"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‎‎‎‏‎‏‎‏‎Allows the app to call phone numbers without your intervention. This may result in unexpected charges or calls. Note that this doesn\'t allow the app to call emergency numbers. Malicious apps may cost you money by making calls without your confirmation.‎‏‎‎‏‎"</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‏‎‎‏‏‎‏‏‏‎‎‏‎‎‏‎‏‎‎‏‏‎‎access IMS call service‎‏‎‎‏‎"</string>
@@ -543,6 +546,7 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‏‏‎‎‎‏‎‏‏‎‎‎‎‏‎‎‏‏‏‎‏‎‏‎‏‏‏‎‎‏‏‎‎Try again.‎‏‎‎‏‎"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‎‎‏‏‏‎‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‎‏‏‏‎‎‎‎‏‎‏‏‎‎‏‏‎‏‏‎No fingerprints enrolled.‎‏‎‎‏‎"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‎‏‏‏‏‎‎‎‏‎‎‎‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‎‎‎‎‎‎‎‎‏‏‎‎‏‎‏‏‎‎This device does not have a fingerprint sensor.‎‏‎‎‏‎"</string>
+    <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‏‏‏‎‎‎‏‏‎‎‏‎‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎‏‏‎‎‎‏‎‎‎‏‏‏‎‎‎‎‏‎‏‏‏‎‎‎‏‎Sensor temporarily disabled.‎‏‎‎‏‎"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‎‎‏‎‏‎‏‎‎‏‎‎‏‎‏‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‎‏‎‎Finger ‎‏‎‎‏‏‎<xliff:g id="FINGERID">%d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +590,7 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‎‎‏‏‏‎‎‎‎‏‏‎‎‎‏‎‏‎‎‎‏‏‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‏‎‎‏‎‏‏‎‎Can’t verify face. Try again.‎‏‎‎‏‎"</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‎‏‏‏‎‎‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‎‏‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‏‎‏‏‎You haven’t set up face unlock.‎‏‎‎‏‎"</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‎‏‏‎‏‎‏‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‏‏‎‎‎‎Face unlock is not supported on this device.‎‏‎‎‏‎"</string>
+    <string name="face_error_security_update_required" msgid="5076017208528750161">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‏‏‎‎‎‏‏‎‏‎‎‎‏‎‏‏‎‎‎‎‎‏‏‏‎‏‏‏‎‎‎‎‏‎‎‎‎‎‎‏‎‎‎‏‏‎‎‏‎‏‎‎‎‏‎Sensor temporarily disabled.‎‏‎‎‏‎"</string>
     <string name="face_name_template" msgid="3877037340223318119">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‎‏‏‏‎‎‎‎‎‎‎‎‎‏‏‏‎‏‎‏‏‎‏‏‎‎‏‎‎‏‏‏‎‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‎‏‏‏‎Face ‎‏‎‎‏‏‎<xliff:g id="FACEID">%d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1619,7 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‎‏‎‏‎‏‏‏‎‎‎‏‎‏‎‏‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎The background started foreground service from ‎‏‎‎‏‏‎<xliff:g id="PACKAGENAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ will not have while-in-use permission in future R builds. Please see go/r-bg-fgs-restriction and file a bugreport.‎‏‎‎‏‎"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‎‎‎‏‎‏‎‎‎‏‎‎‎‏‏‎‎‎‏‏‏‎‎‏‏‏‏‏‏‎‎‏‏‎‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‏‎‎Raise volume above recommended level?‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Listening at high volume for long periods may damage your hearing.‎‏‎‎‏‎"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‏‎‏‎‏‎‏‎‏‎‏‎‏‏‏‎‎‎‎‏‎‏‎‏‎‏‎Use Accessibility Shortcut?‎‏‎‎‏‎"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‎‏‎‏‏‎‏‏‎‎‎‎‏‏‎‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‎‎‎‎‏‏‏‎‎‏‎‏‎‏‎‎‏‎‏‏‎‎‎When the shortcut is on, pressing both volume buttons for 3 seconds will start an accessibility feature.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎ Current accessibility feature:‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎ ‎‏‎‎‏‏‎<xliff:g id="SERVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎ You can change the feature in Settings &gt; Accessibility.‎‏‎‎‏‎"</string>
+    <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‎‎‎‎‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‎‎‎‏‎‏‏‏‎‎‏‎‎‏‏‏‎‎‏‏‎‎‎‎‏‎‏‎‎‎‏‎‎‎‎When the shortcut is on, pressing both volume buttons for 3 seconds will start an accessibility feature.‎‏‎‎‏‎"</string>
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‏‎‎‎‏‎‎‏‎‎‎‎‏‎‎‏‏‎‎‎‎‎‏‎‎‎‏‎‏‏‏‎‎‏‎‏‎‎‎‎‏‎‎‎‎‏‏‏‎Edit shortcuts‎‏‎‎‏‎"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‎‎‏‏‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‏‏‏‎‏‏‏‏‎‎‎‎‎‎‏‎‏‏‎‏‎‎‏‏‏‎‏‎‎Cancel‎‏‎‎‏‎"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‎‏‏‎‏‏‎‎‎‎‏‎‏‎‏‏‎‎‎‏‏‎‏‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎Turn off Shortcut‎‏‎‎‏‎"</string>
@@ -2010,4 +2015,12 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‎‎‏‎‎‏‎‏‏‎‎‏‎‏‎‎‎‎‎‎‎‏‎‎‎‎‎‎‏‏‏‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ has been put into the RESTRICTED bucket‎‏‎‎‏‎"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‏‎‎‎‏‎‏‎‏‎‎‎‏‏‏‏‎‏‏‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‎‎‏‏‏‎‎‏‎‏‏‎‎‏‎Personal‎‏‎‎‏‎"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‎‏‎‏‎‎‏‏‎‏‏‏‏‎‎‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‎‏‏‎Work‎‏‎‎‏‎"</string>
+    <string name="resolver_cant_share_with_work_apps" msgid="7539495559434146897">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‎‎‎‏‏‎‏‎‏‎‏‏‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‏‎‏‎‎‎‏‎‏‎‎‎‏‎‏‎‎‎‏‎Can’t share with work apps‎‏‎‎‏‎"</string>
+    <string name="resolver_cant_share_with_personal_apps" msgid="8020581735267157241">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‏‎‎‏‏‎‏‎‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‏‏‎‎‏‎Can’t share with personal apps‎‏‎‎‏‎"</string>
+    <string name="resolver_cant_share_cross_profile_explanation" msgid="3536237105241882679">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‏‎‎‏‏‎‎‏‏‏‏‎‎‏‏‏‎‏‎‎‏‎‏‎‏‎‎‏‏‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‎‏‏‎‏‏‏‎Your IT admin blocked sharing between personal and work apps‎‏‎‎‏‎"</string>
+    <string name="resolver_turn_on_work_apps" msgid="8987359079870455469">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‏‏‎‎‎‎‎‏‏‎‏‏‏‎‏‏‏‎‏‎‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‎‏‎‏‎‏‏‎‏‎Turn on work apps‎‏‎‎‏‎"</string>
+    <string name="resolver_turn_on_work_apps_explanation" msgid="6322467455509618928">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‎‏‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎‏‏‏‏‎‎‏‏‎‎‎‎‎‏‏‏‏‎‎‎‎‎Turn on work apps to access work apps &amp; contacts‎‏‎‎‏‎"</string>
+    <string name="resolver_no_apps_available" msgid="7710339903040989654">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‎‎‎‎‏‎‏‎‎‎‎‏‎‏‎‎‏‎‏‎‎‏‏‎‏‎‏‎‎‏‎‎‎‏‏‏‎‎‏‎‏‎‎‏‏‏‎‏‎‏‏‎‎No apps available‎‏‎‎‏‎"</string>
+    <string name="resolver_no_apps_available_explanation" msgid="4662694431121196560">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‏‏‎‏‎‏‎‎‏‏‎‏‏‏‏‏‏‎‎‎‎‏‏‎‎‎‏‏‏‏‎‎‏‎‏‎‏‏‏‏‎‎‎‏‏‎‎‎‎‏‎‎‎‎‎We couldn’t find any apps‎‏‎‎‏‎"</string>
+    <string name="resolver_switch_on_work" msgid="8294542702883688533">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‏‏‎‏‏‎‎‎‎‏‏‎‏‎‎‎‎‎‏‎‏‎‏‎‏‎Switch on work‎‏‎‎‏‎"</string>
 </resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index ac555d5..29318bd 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"El administrador no permite hacer un uso personal del dispositivo"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Dispositivo administrado"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Tu organización administra este dispositivo y es posible que controle el tráfico de red. Presiona para obtener más información."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Tu administrador cambió la configuración de la ubicación"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Presiona para ver la configuración de la ubicación."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Se borrarán los datos del dispositivo"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"No se puede usar la app de administrador. Ahora se borrará tu dispositivo.\n\nSi tienes preguntas, comunícate con el administrador de tu organización."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> inhabilitó la impresión."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Esta privilegiada | app del sistema puede tomar fotos y grabar videos con una cámara del sistema en cualquier momento. También se requiere que la app posea el permiso android.permission.CAMERA."</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"controlar la vibración"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Permite que la aplicación controle la vibración."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permite que la app acceda al estado del vibrador."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"llamar directamente a números de teléfono"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Permite que la aplicación haga llamadas a números de teléfono sin intervención del usuario, lo que puede dar lugar a llamadas o cargos inesperados. Ten en cuenta que las aplicaciones no pueden usar este servicio para realizar llamadas a números de emergencia, pero las aplicaciones malintencionadas pueden causarte gastos imprevistos al realizar llamadas sin tu confirmación."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"acceder al servicio IMS para realizar llamadas"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Vuelve a intentarlo."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No se registraron huellas digitales."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo no tiene sensor de huellas digitales."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"No se pudo verificar la cara. Vuelve a intentarlo."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"No configuraste el Desbloqueo facial."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"No se admite el Desbloqueo facial en este dispositivo."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Rostro <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1217,7 +1224,7 @@
     <string name="dump_heap_ready_text" msgid="5849618132123045516">"Tienes un volcado del montón del proceso de <xliff:g id="PROC">%1$s</xliff:g> disponible para compartir. Ten cuidado: Es posible que este volcado contenga información personal sensible (incluido el contenido que hayas escrito) a la que puede acceder el proceso."</string>
     <string name="sendText" msgid="493003724401350724">"Seleccionar una acción para el texto"</string>
     <string name="volume_ringtone" msgid="134784084629229029">"Volumen del timbre"</string>
-    <string name="volume_music" msgid="7727274216734955095">"Volumen de los medios"</string>
+    <string name="volume_music" msgid="7727274216734955095">"Volumen multimedia"</string>
     <string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Reproduciendo a través de Bluetooth"</string>
     <string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Tono de silencio establecido"</string>
     <string name="volume_call" msgid="7625321655265747433">"Volumen de llamadas entrantes"</string>
@@ -1228,7 +1235,7 @@
     <string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Volumen de Bluetooth"</string>
     <string name="volume_icon_description_ringer" msgid="2187800636867423459">"Volumen del tono de llamada"</string>
     <string name="volume_icon_description_incall" msgid="4491255105381227919">"Volumen de la llamada"</string>
-    <string name="volume_icon_description_media" msgid="4997633254078171233">"Volumen de los medios"</string>
+    <string name="volume_icon_description_media" msgid="4997633254078171233">"Volumen multimedia"</string>
     <string name="volume_icon_description_notification" msgid="579091344110747279">"Volumen de notificación"</string>
     <string name="ringtone_default" msgid="9118299121288174597">"Tono predeterminado"</string>
     <string name="ringtone_default_with_actual" msgid="2709686194556159773">"Predeterminado (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"El servicio que pasó del segundo al primer plano de <xliff:g id="PACKAGENAME">%1$s</xliff:g> no tendrá permiso durante el uso en las próximas compilaciones de R. Ve a go/r-bg-fgs-restriction y envía un informe de errores."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"¿Quieres subir el volumen por encima del nivel recomendado?\n\nEscuchar a un alto volumen durante largos períodos puede dañar tu audición."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"¿Usar acceso directo de accesibilidad?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Cuando el acceso directo está activado, puedes presionar los botones de volumen durante 3 segundos para iniciar una función de accesibilidad.\n\n Función de accesibilidad actual:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Puedes cambiar la función en Configuración &gt; Accesibilidad."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editar accesos directos"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Cancelar"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desactivar acceso directo"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Se colocó <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> en el depósito RESTRICTED"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Personal"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Trabajo"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 190664b..5db4f42 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"El administrador no permite hacer un uso personal del dispositivo"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"El dispositivo está administrado"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Tu organización administra este dispositivo y puede supervisar el tráfico de red. Toca la notificación para obtener más información."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Tu administrador ha cambiado los ajustes de ubicación-"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Toca para ver tus ajustes de ubicación."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Tu dispositivo se borrará"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"No se puede utilizar la aplicación de administración. Se borrarán todos los datos del dispositivo.\n\nSi tienes alguna pregunta, ponte en contacto con el administrador de tu organización."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ha inhabilitado la impresión."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Esta aplicación del sistema tiene permiso para hacer fotos y grabar vídeos en cualquier momento con una cámara del sistema, aunque debe tener también el permiso android.permission.CAMERA para hacerlo"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"controlar la vibración"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Permite que la aplicación controle la función de vibración."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permite que la aplicación acceda al ajuste de vibración."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"llamar directamente a números de teléfono"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Permite que la aplicación haga llamadas sin intervención del usuario, lo que puede dar lugar a llamadas o cargos inesperados. Ten en cuenta que las aplicaciones no pueden usar este servicio para realizar llamadas a números de emergencia, pero las aplicaciones malintencionadas pueden causarte gastos imprevistos al realizar llamadas sin tu confirmación."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"acceder al servicio de llamadas IMS"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Vuelve a intentarlo."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"No se ha registrado ninguna huella digital."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo no tiene sensor de huellas digitales."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"No se ha verificado tu cara. Vuelve a intentarlo."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"No has configurado el desbloqueo facial."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"El desbloqueo facial no está disponible en este dispositivo."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Cara <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"El servicio en primer plano que se inició en segundo plano en <xliff:g id="PACKAGENAME">%1$s</xliff:g> no tendrá permisos en compilaciones R futuras mientras se estén usando. Ve a go/r-bg-fgs-restriction y envía un informe de errores."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"¿Quieres subir el volumen por encima del nivel recomendado?\n\nEscuchar sonidos fuertes durante mucho tiempo puede dañar los oídos."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"¿Utilizar acceso directo de accesibilidad?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Si el acceso directo está activado, pulsa los dos botones de volumen durante tres segundos para iniciar una función de accesibilidad.\n\n Función de accesibilidad actual:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Puedes cambiar la función en Ajustes &gt; Accesibilidad."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editar accesos directos"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Cancelar"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desactivar acceso directo"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> se ha incluido en el grupo de restringidos"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Personal"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Trabajo"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 0c302ee..2c98716 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administraator keelas seadme isikliku kasutamise"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Seade on hallatud"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Teie organisatsioon haldab seda seadet ja võib jälgida võrguliiklust. Puudutage üksikasjade vaatamiseks."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Administraator muutis teie asukohaseadeid"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Puudutage oma asukohaseadete nägemiseks."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Seade kustutatakse"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Administraatori rakendust ei saa kasutada. Teie seade tühjendatakse nüüd.\n\nKui teil on küsimusi, võtke ühendust organisatsiooni administraatoriga."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Rakendus <xliff:g id="OWNER_APP">%s</xliff:g> on printimise keelanud."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"See privileegidega | süsteemirakendus saab süsteemi kaameraga alati pilte ja videoid jäädvustada. Rakendusel peab olema ka luba android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"juhtige vibreerimist"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Võimaldab rakendusel juhtida vibreerimist."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Võimaldab rakendusel juurde pääseda vibreerimise olekule."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"helista otse telefoninumbritele"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Võimaldab rakendusel teie sekkumiseta telefoninumbritele helistada. See võib põhjustada ootamatuid tasusid või telefonikõnesid. Pange tähele, et see ei luba rakendusel helistada hädaabinumbritele. Pahatahtlikud rakendused võivad teile kulusid tekitada, tehes telefonikõnesid teie kinnituseta."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"juurdepääs IMS-kõneteenusele"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Proovige uuesti."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ühtegi sõrmejälge pole registreeritud."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Selles seadmes pole sõrmejäljeandurit."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Sõrm <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Nägu ei saa kinnitada. Proovige uuesti."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Face Unlocki ei ole seadistatud."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Seade ei toeta Face Unlocki."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Nägu <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Taustal käitatud esiplaanil oleval teenusel paketist <xliff:g id="PACKAGENAME">%1$s</xliff:g> ei ole tulevastes R-järkudes luba „kui kasutuses”. Vaadake saiti go/r-bg-fgs-restriction ja esitage veaaruanne."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Kas suurendada helitugevuse taset üle soovitatud taseme?\n\nPikaajaline valju helitugevusega kuulamine võib kuulmist kahjustada."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Kas kasutada juurdepääsetavuse otseteed?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Kui otsetee on sisse lülitatud, käivitab mõlema helitugevuse nupu kolm sekundit all hoidmine juurdepääsetavuse funktsiooni.\n\n Praegune juurdepääsetavuse funktsioon:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Saate seda funktsiooni muuta valikutega Seaded &gt; Juurdepääsetavus."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Muuda otseteid"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Tühista"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Lülita otsetee välja"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> on lisatud salve PIIRANGUTEGA"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Isiklik"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Töö"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index e7aedd5..8e247fc 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -191,6 +191,10 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Erabilera pertsonalerako utzi du gailua administratzaileak"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Jabeak kudeatzen du gailua"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Erakundeak kudeatzen du gailua eta baliteke sareko trafikoa gainbegiratzea. Sakatu hau xehetasunak ikusteko."</string>
+    <!-- no translation found for location_changed_notification_title (4119726617105166830) -->
+    <skip />
+    <!-- no translation found for location_changed_notification_text (198907268219396399) -->
+    <skip />
     <string name="factory_reset_warning" msgid="6858705527798047809">"Gailuko datuak ezabatu egingo dira"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Ezin da erabili administratzeko aplikazioa. Ezabatu egingo da gailuko eduki guztia.\n\nZalantzarik baduzu, jarri erakundeko administratzailearekin harremanetan."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> aplikazioak desgaitu egin du inprimatzeko aukera."</string>
@@ -429,6 +433,8 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Pribilegioa duen sistema-aplikazio honek edonoiz erabil dezake kamera argazkiak ateratzeko eta bideoak grabatzeko. Halaber, android.permission.CAMERA baimena izan behar du aplikazioak."</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"kontrolatu dardara"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Bibragailua kontrolatzeko aukera ematen die aplikazioei."</string>
+    <!-- no translation found for permdesc_vibrator_state (7050024956594170724) -->
+    <skip />
     <string name="permlab_callPhone" msgid="1798582257194643320">"deitu zuzenean telefono-zenbakietara"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Telefono-zenbakietara zuk esku hartu gabe deitzeko baimena ematen die aplikazioei. Horrela, ustekabeko gastuak edo deiak eragin daitezke. Aplikazio gaiztoek erabil dezakete zuk berretsi gabeko deiak eginda gastuak eragiteko."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"atzitu IMS dei-zerbitzua"</string>
@@ -543,6 +549,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Saiatu berriro."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ez da erregistratu hatz-markarik."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Gailu honek ez du hatz-marken sentsorerik."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> hatza"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +594,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Ezin da egiaztatu aurpegia. Saiatu berriro."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Ez duzu konfiguratu aurpegiaren bidez desblokeatzeko aukera."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Gailu honek ez du onartzen aurpegiaren bidez desblokeatzea."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"<xliff:g id="FACEID">%d</xliff:g> aurpegia"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1624,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> webgunearen atzeko planoak hasitako aurreko planoko zerbitzuak ez du izango erabili bitarteko baimenik etorkizuneko R konpilazioetan. Joan go/r-bg-fgs-restriction atalera eta egin akatsaren txostena."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Bolumena gomendatutako mailatik gora igo nahi duzu?\n\nMusika bolumen handian eta denbora luzez entzuteak entzumena kalte diezazuke."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Erabilerraztasun-lasterbidea erabili nahi duzu?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Lasterbidea aktibatuta dagoenean, bi bolumen-botoiak hiru segundoz sakatuta abiaraziko da erabilerraztasun-eginbidea.\n\n Uneko erabilerraztasun-eginbidea:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Eginbidea aldatzeko, joan Ezarpenak &gt; Erabilerraztasuna atalera."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editatu lasterbideak"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Utzi"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desaktibatu lasterbidea"</string>
@@ -2010,4 +2021,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Murriztuen edukiontzian ezarri da <xliff:g id="PACKAGE_NAME">%1$s</xliff:g>"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Pertsonala"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Lanekoa"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 9d9a13c..c603da3 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"سرپرست از این دستگاه برای استفاده شخصی چشم‌پوشی کرد"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"دستگاه مدیریت می‌شود"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"سازمانتان این دستگاه را مدیریت می‌کند و ممکن است ترافیک شبکه را پایش کند. برای اطلاع از جزئیات، ضربه بزنید."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"سرپرست شما تنظیمات مکان را تغییر داده است"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"برای مشاهده تنظیمات مکان ضربه بزنید."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"دستگاهتان پاک خواهد شد"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"برنامه سرپرست سیستم را نمی‌توان استفاده کرد. دستگاه شما در این لحظه پاک می‌شود.\n\nاگر سؤالی دارید، با سرپرست سیستم سازمانتان تماس بگیرید."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> چاپ کردن را غیرفعال کرده است."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"‏این برنامه سیستم که دارای امتیاز دسترسی است می‌تواند با استفاده از دوربین سیستم در هر زمانی عکس‌برداری و فیلم‌برداری کند. برنامه به مجوز android.permission.CAMERA هم نیاز دارد."</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"کنترل لرزش"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"‏به برنامه اجازه می‎دهد تا لرزاننده را کنترل کند."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"به برنامه اجازه می‌دهد تا به وضعیت لرزاننده دسترسی داشته باشد."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"تماس مستقیم با شماره تلفن‌ها"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"به برنامه اجازه می‌دهد بدون دخالت شما با شماره‌های تلفن تماس بگیرد. این ممکن است باعث ایجاد هزینه یا تماس‌های پیش‌بینی نشده شود. توجه داشته باشید که این به برنامه اجازه نمی‌دهد به برقراری تماس‌های اضطراری بپردازد. برنامه‌های مخرب ممکن است با برقراری تماس بدون تأیید شما هزینه‌هایی را برای شما ایجاد کنند."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"‏دسترسی به سرویس تماس IMS"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"دوباره امتحان کنید."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"اثر انگشتی ثبت نشده است."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"این دستگاه حسگر اثر انگشت ندارد."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"انگشت <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"چهره تأیید نشد. دوباره امتحان کنید."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"«بازگشایی با چهره» را راه‌اندازی نکرده‌اید."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"«بازگشایی با چهره» در این دستگاه پشتیبانی نمی‌شود."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"چهره <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"‏سرویس پیش‌نمای <xliff:g id="PACKAGENAME">%1$s</xliff:g>، که در پس‌زمینه شروع شده، در ساخت‌های آتی R اجازهٔ حین استفاده نخواهد داشت. لطفاً به go/r-bg-fgs-restriction بروید و گزارش اشکال ارسال کنید."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"میزان صدا را به بالاتر از حد توصیه شده افزایش می‌دهید؟\n\nگوش دادن به صداهای بلند برای مدت طولانی می‌تواند به شنوایی‌تان آسیب وارد کند."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"از میان‌بر دسترس‌پذیری استفاده شود؟"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"وقتی میان‌بر روشن است،‌ اگر هر دو دکمه صدا را ۳ ثانیه فشار دهید یکی از قابلیت‌های دسترس‌پذیری شروع می‌شود.\n\n قابلیت دسترس‌پذیری کنونی:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n می‌توانید در «تنظیمات &gt; دسترس‌پذیری»، قابلیت را تغییر دهید."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"ویرایش میان‌برها"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"لغو"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"خاموش کردن میان‌بر"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> در سطل «محدودشده» قرار گرفت"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"شخصی"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"کاری"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 35cc8b9..5ee67d95 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Järjestelmänvalvoja luovutti laitteen henkilökohtaiseen käyttöön"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Hallinnoitu laite"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Organisaatiosi hallinnoi tätä laitetta ja voi tarkkailla verkkoliikennettä. Katso lisätietoja napauttamalla."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Järjestelmänvalvoja muutti sijaintiasetuksia"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Katso sijaintiasetukset napauttamalla."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Laitteen tiedot poistetaan"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Hallintasovellusta ei voi käyttää. Laitteen tiedot pyyhitään.\n\nPyydä ohjeita järjestelmänvalvojaltasi."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> on poistanut tulostuksen käytöstä."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Tämä käyttöoikeuden saanut | järjestelmäsovellus voi ottaa järjestelmän kameralla kuvia ja videoita koska tahansa. Sovelluksella on oltava myös android.permission.CAMERA-käyttöoikeus"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"hallita värinää"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Antaa sovelluksen hallita värinää."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Sallii sovelluksen käyttää värinätilaa."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"soittaa puhelinnumeroihin suoraan"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Antaa sovelluksen soittaa puhelinnumeroihin kysymättä sinulta. Tämä voi aiheuttaa odottamattomia kuluja tai puheluita. Huomaa, että tämä ei anna sovellukselle lupaa soittaa hätänumeroihin. Haitalliset sovellukset voivat aiheuttaa sinulle kuluja soittamalla puheluita ilman lupaa."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"pikaviestipalvelun puhelukäyttöoikeus"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Yritä uudelleen."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Sormenjälkiä ei ole otettu käyttöön."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Laitteessa ei ole sormenjälkitunnistinta."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Sormi <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Kasvoja ei voi vahvistaa. Yritä uudelleen."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Et ole määrittänyt Face Unlockia."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Tämä laite ei tue Face Unlockia."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Kasvot <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Taustalla aloitettu etualan palvelu (<xliff:g id="PACKAGENAME">%1$s</xliff:g>) ei ole käytön aikana sallittu R:n tulevissa versioissa. Lue go/r-bg-fgs-restriction ja lähetä virheraportti."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Nostetaanko äänenvoimakkuus suositellun tason yläpuolelle?\n\nPitkäkestoinen kova äänenvoimakkuus saattaa heikentää kuuloa."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Käytetäänkö esteettömyyden pikanäppäintä?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Kun pikanäppäin on käytössä, voit käynnistää esteettömyystoiminnon pitämällä molempia äänenvoimakkuuspainikkeita painettuna kolmen sekunnin ajan.\n\n Tällä hetkellä valittu esteettömyystoiminto:\n<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Voit vaihtaa toimintoa valitsemalla Asetukset &gt; Esteettömyys."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Muokkaa pikakuvakkeita"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Peruuta"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Poista pikanäppäin käytöstä"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> on nyt rajoitettujen ryhmässä"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Henkilökohtainen"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Työ"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index caec9fa..7c4dd03 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -191,6 +191,10 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"L\'administrateur a libéré l\'appareil pour un usage personnel"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"L\'appareil est géré"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Votre organisation gère cet appareil et peut surveiller le trafic réseau. Touchez ici pour obtenir plus d\'information."</string>
+    <!-- no translation found for location_changed_notification_title (4119726617105166830) -->
+    <skip />
+    <!-- no translation found for location_changed_notification_text (198907268219396399) -->
+    <skip />
     <string name="factory_reset_warning" msgid="6858705527798047809">"Le contenu de votre appareil sera effacé"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Impossible d\'utiliser l\'application d\'administration. Les données de votre appareil vont maintenant être effacées.\n\nSi vous avez des questions, communiquez avec l\'administrateur de votre organisation."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Impression désactivée par <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -429,6 +433,8 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Cette application privilégiée | système peut prendre des photos ou filmer des vidéos à l\'aide d\'un appareil photo système en tout temps. L\'application doit également posséder l\'autorisation android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"gérer le vibreur"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Permet à l\'application de gérer le vibreur de l\'appareil."</string>
+    <!-- no translation found for permdesc_vibrator_state (7050024956594170724) -->
+    <skip />
     <string name="permlab_callPhone" msgid="1798582257194643320">"appeler directement des numéros de téléphone"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Permet à l\'application d\'appeler des numéros de téléphone sans votre intervention. Cette autorisation peut entraîner des frais ou des appels imprévus et ne permet pas à l\'application d\'appeler des numéros d\'urgence. Des applications malveillantes peuvent générer des frais en passant des appels sans votre consentement."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"accéder au service d\'appel IMS"</string>
@@ -543,6 +549,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Réessayer."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Aucune empreinte digitale enregistrée."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Cet appareil ne possède pas de capteur d\'empreintes digitales."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +594,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Impossible de vérifier le visage. Réessayez."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Vous n\'avez pas config. le déverr. par reconn. faciale."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Cet appar. ne prend pas en charge le déverr. par reconn. faciale."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Visage <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1624,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Le service de premier plan qui a démarré en arrière-plan provenant de <xliff:g id="PACKAGENAME">%1$s</xliff:g> ne disposera pas de l\'autorisation pendant l\'utilisation dans les futures versions R. Veuillez accéder à go/r-bg-fgs-restriction et envoyer un rapport de bogue."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Augmenter le volume au-dessus du niveau recommandé?\n\nL\'écoute prolongée à un volume élevé peut endommager vos facultés auditives."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Utiliser le raccourci d\'accessibilité?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Quand le raccourci est activé, appuyez sur les deux boutons de volume pendant trois secondes pour lancer une fonctionnalité d\'accessibilité.\n\n Fonctionnalité d\'accessibilité utilisée actuellement :\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Vous pouvez changer de fonctionnalité sous Paramètres &gt; Accessibilité."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Modifier les raccourcis"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Annuler"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Désactiver le raccourci"</string>
@@ -2010,4 +2021,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> a été placé dans le compartiment RESTREINT"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Personnel"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Bureau"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 601fe43..9d2e267 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"L\'administrateur a mis l\'appareil à disposition pour un usage personnel"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"L\'appareil est géré"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Votre organisation gère cet appareil et peut surveiller le trafic réseau. Appuyez ici pour obtenir plus d\'informations."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Paramètres de localisation modifiés par l\'administrateur"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Appuyez pour afficher les paramètres de localisation."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Les données de votre appareil vont être effacées"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Impossible d\'utiliser l\'application d\'administration. Les données de votre appareil vont maintenant être effacées.\n\nSi vous avez des questions, contactez l\'administrateur de votre organisation."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Impression désactivée par <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Cette application privilégiée ou système peut utiliser une caméra photo système pour prendre des photos et enregistrer des vidéos à tout moment. Pour cela, l\'application doit également disposer de l\'autorisation android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"contrôler le vibreur"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Permet à l\'application de contrôler le vibreur."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permet à l\'application d\'accéder à l\'état du vibreur."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"appeler directement les numéros de téléphone"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Permet à l\'application d\'appeler des numéros de téléphone sans votre intervention. Cette autorisation peut entraîner des frais ou des appels imprévus et ne permet pas à l\'application d\'appeler des numéros d\'urgence. Les applications malveillantes peuvent générer des frais en passant des appels sans votre consentement."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"accéder au service d\'appel IMS"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Veuillez réessayer."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Aucune empreinte digitale enregistrée."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aucun lecteur d\'empreinte digitale n\'est installé sur cet appareil."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Impossible de valider votre visage. Réessayez."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Face Unlock n\'est pas configuré."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Face Unlock n\'est pas compatible avec cet appareil."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Visage <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Le service de premier plan qui a démarré en arrière-plan et provenant de <xliff:g id="PACKAGENAME">%1$s</xliff:g> ne disposera pas de l\'autorisation \"pendant l\'utilisation\" dans les futurs builds R. Veuillez accéder à go/r-bg-fgs-restriction et envoyer un rapport de bug."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Augmenter le volume au dessus du niveau recommandé ?\n\nL\'écoute prolongée à un volume élevé peut endommager vos facultés auditives."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Utiliser le raccourci d\'accessibilité ?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Quand le raccourci est activé, appuyez sur les deux boutons de volume pendant trois secondes pour lancer une fonctionnalité d\'accessibilité.\n\n Fonctionnalité d\'accessibilité utilisée actuellement :\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Vous pouvez changer de fonctionnalité dans Paramètres &gt; Accessibilité."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Modifier les raccourcis"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Annuler"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Désactiver le raccourci"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> a été placé dans le bucket RESTRICTED"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Personnel"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Professionnel"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 0aa6277..0170f16 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"O administrador renunciou ao dispositivo para uso persoal"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"O dispositivo está xestionado"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"A túa organización xestiona este dispositivo e pode controlar o tráfico de rede. Toca para obter máis detalles."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"O administrador cambiou a configuración de localización"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Toca para ver a configuración de localización."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Borrarase o teu dispositivo"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Non se pode utilizar a aplicación de administración. Borrarase o teu dispositivo.\n\nSe tes preguntas, contacta co administrador da organización."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> desactivou a impresión."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Esta aplicación do sistema con privilexios pode utilizar unha cámara do sistema en calquera momento para sacar fotos e gravar vídeos. Require que a aplicación tamén teña o permiso android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"controlar a vibración"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Permite á aplicación controlar o vibrador."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permite que a aplicación acceda ao estado de vibrador"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"chamar directamente aos números de teléfono"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Permite á aplicación chamar a números de teléfono sen a túa intervención. Esta acción pode implicar chamadas ou custos inesperados. Ten en conta que isto non permite á aplicación chamar a números de emerxencia. É posible que aplicacións maliciosas che custen diñeiro debido á realización de chamadas sen a túa confirmación."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"acceso ao servizo de chamadas de IMS"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Téntao de novo."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Non se rexistraron impresións dixitais."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo non ten sensor de impresión dixital."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Non se puido verificar a cara. Téntao de novo."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Non configuraches o desbloqueo facial."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Este dispositivo non admite o desbloqueo facial."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Cara <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Nas futuras compilacións R, o servizo en primeiro plano iniciado en segundo plano desde <xliff:g id="PACKAGENAME">%1$s</xliff:g> non terá permiso mentres estea en uso. Consulta go/r-bg-fgs-restriction e presenta un informe de erros."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Queres subir o volume máis do nivel recomendado?\n\nA reprodución de son a un volume elevado durante moito tempo pode provocar danos nos oídos."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Queres utilizar o atallo de accesibilidade?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Cando o atallo está activado, podes premer os dous botóns de volume durante 3 segundos para iniciar unha función de accesibilidade.\n\n Función de accesibilidade actual:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Podes cambiar a función en Configuración &gt; Accesibilidade."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editar atallos"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Cancelar"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desactivar atallo"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> incluíuse no grupo RESTRINXIDO"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Persoal"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Traballo"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 85bf30e..8b0b374 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -191,6 +191,10 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"વ્યવસ્થાપકે ડિવાઇસ વ્યક્તિગત ઉપયોગ માટે આપી દીધું છે"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"ઉપકરણ સંચાલિત છે"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"તમારી સંસ્થા આ ઉપકરણનું સંચાલન કરે છે અને નેટવર્ક ટ્રાફિફનું નિયમન કરી શકે છે. વિગતો માટે ટૅપ કરો."</string>
+    <!-- no translation found for location_changed_notification_title (4119726617105166830) -->
+    <skip />
+    <!-- no translation found for location_changed_notification_text (198907268219396399) -->
+    <skip />
     <string name="factory_reset_warning" msgid="6858705527798047809">"તમારું ઉપકરણ કાઢી નાખવામાં આવશે"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"વ્યવસ્થાપક ઍપનો ઉપયોગ કરી શકાશે નહીં. તમારું ઉપકરણ હવે કાઢી નાખવામાં આવશે.\n\nજો તમને પ્રશ્નો હોય, તો તમારી સંસ્થાના વ્યવસ્થાપકનો સંપર્ક કરો."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> દ્વારા પ્રિન્ટ કરવાનું બંધ કરાયું છે."</string>
@@ -429,6 +433,8 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"આ વિશેષાધિકૃત | સિસ્ટમ ઍપ કોઈપણ સમયે સિસ્ટમ કૅમેરાનો ઉપયોગ કરીને ફોટા લઈ અને વીડિયો રેકોર્ડ કરી શકે છે. ઍપ દ્વારા આયોજિત કરવા માટે android.permission.CAMERAની પરવાનગી પણ જરૂરી છે"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"વાઇબ્રેશન નિયંત્રિત કરો"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"એપ્લિકેશનને વાઇબ્રેટરને નિયંત્રિત કરવાની મંજૂરી આપે છે."</string>
+    <!-- no translation found for permdesc_vibrator_state (7050024956594170724) -->
+    <skip />
     <string name="permlab_callPhone" msgid="1798582257194643320">"સીધા જ ફોન નંબર્સ પર કૉલ કરો"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"એપ્લિકેશનને તમારા હસ્તક્ષેપ વિના ફોન નંબર્સ પર કૉલ કરવાની મંજૂરી આપે છે. આ અનપેક્ષિત શુલ્ક અથવા કૉલ્સમાં પરિણમી શકે છે. નોંધો કે આ એપ્લિકેશનને કટોકટીના નંબર્સ પર કૉલ કરવાની મંજૂરી આપતું નથી. દુર્ભાવનાપૂર્ણ ઍપ્લિકેશનો તમારી પુષ્ટિ વિના કૉલ્સ કરીને તમારા પૈસા ખર્ચ કરી શકે છે."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS કૉલ સેવા ઍક્સેસ કરો"</string>
@@ -543,6 +549,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"ફરી પ્રયાસ કરો."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"કોઈ ફિંગરપ્રિન્ટની નોંધણી કરવામાં આવી નથી."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"આ ડિવાઇસમાં કોઈ ફિંગરપ્રિન્ટ સેન્સર નથી."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"આંગળી <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +594,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"ચહેરો ચકાસી શકાતો નથી. ફરી પ્રયાસ કરો."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"તમે ફેસ અનલૉકનું સેટઅપ કર્યું નથી."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"આ ડિવાઇસ પર ફેસ અનલૉક કરવાની સુવિધા નથી."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"ચહેરાનું <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1624,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"બૅકગ્રાઉન્ડમાં શરૂ થયેલી <xliff:g id="PACKAGENAME">%1$s</xliff:g>ની ફોરગ્રાઉન્ડ સેવા પાસે ભવિષ્યની R બિલ્ડમાં ઉપયોગમાં હોય તે સમયની પરવાનગી હશે નહીં. કૃપા કરીને go/r-bg-fgs-restriction જુઓ અને ભૂલનો અહેવાલ દાખલ કરો."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ભલામણ કરેલ સ્તરની ઉપર વૉલ્યૂમ વધાર્યો?\n\nલાંબા સમય સુધી ઊંચા અવાજે સાંભળવું તમારી શ્રવણક્ષમતાને નુકસાન પહોંચાડી શકે છે."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ઍક્સેસિબિલિટી શૉર્ટકટનો ઉપયોગ કરીએ?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"જ્યારે શૉર્ટકટ ચાલુ હોય, ત્યારે બન્ને વૉલ્યૂમ બટનને 3 સેકન્ડ સુધી દબાવી રાખવાથી ઍક્સેસિબિલિટી સુવિધા શરૂ થઈ જશે.\n\n વર્તમાન ઍક્સેસિબિલિટી સુવિધા:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n તમે સેટિંગ્સ &gt; ઍક્સેસિબિલિટીમાં જઈને આ સુવિધા બદલી શકો છો."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"શૉર્ટકટમાં ફેરફાર કરો"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"રદ કરો"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"શૉર્ટકટ બંધ કરો"</string>
@@ -2010,4 +2021,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>ને પ્રતિબંધિત સમૂહમાં મૂકવામાં આવ્યું છે"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"વ્યક્તિગત"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"કાર્યાલય"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 19e154e..989cb15 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -191,6 +191,10 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"एडमिन ने निजी इस्तेमाल के लिए डिवाइस दे दिया है"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"डिवाइस प्रबंधित है"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"आपका संगठन इस डिवाइस का प्रबंधन करता है और वह नेटवर्क ट्रैफ़िक की निगरानी भी कर सकता है. विवरण के लिए टैप करें."</string>
+    <!-- no translation found for location_changed_notification_title (4119726617105166830) -->
+    <skip />
+    <!-- no translation found for location_changed_notification_text (198907268219396399) -->
+    <skip />
     <string name="factory_reset_warning" msgid="6858705527798047809">"आपके डिवाइस को मिटा दिया जाएगा"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"एडमिन ऐप्लिकेशन का इस्तेमाल नहीं किया जा सकता. आपके डिवाइस पर मौजूद डेटा अब मिटा दिया जाएगा.\n\nअगर आप कुछ पूछना चाहते हैं तो, अपने संगठन के एडमिन से संपर्क करें."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ने प्रिंटिंग सुविधा बंद कर दी है."</string>
@@ -429,6 +433,8 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"यह सिस्टम ऐप्लिकेशन तस्वीरें लेने और वीडियो रिकॉर्ड करने के लिए जब चाहे, सिस्टम के कैमरे का इस्तेमाल कर सकता है. ऐप्लिकेशन को android.permission.CAMERA की अनुमति देना भी ज़रूरी है"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"कंपन (वाइब्रेशन) को नियंत्रित करें"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"ऐप्स को कंपनकर्ता नियंत्रित करने देता है."</string>
+    <!-- no translation found for permdesc_vibrator_state (7050024956594170724) -->
+    <skip />
     <string name="permlab_callPhone" msgid="1798582257194643320">"फ़ोन नंबर पर सीधे कॉल करें"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"ऐप्लिकेशन को आपके हस्‍तक्षेप के बिना फ़ोन नंबर पर कॉल करने देता है. इसके परिणाम अनचाहे शुल्‍क या कॉल हो सकते हैं. ध्यान दें कि यह ऐप्लिकेशन को आपातकालीन नंबर पर कॉल नहीं करने देता. नुकसान पहुंचाने वाला ऐप्लिकेशन आपकी पुष्टि के बिना कॉल करके आपके पैसे खर्च करवा सकते हैं."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS कॉल सेवा ऐक्‍सेस करें"</string>
@@ -543,6 +549,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"फिर से प्रयास करें."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"कोई फ़िंगरप्रिंट रजिस्टर नहीं किया गया है."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"इस डिवाइस में फ़िंगरप्रिंट सेंसर नहीं है."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"फ़िंगरप्रिंट <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +594,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"चेहरा नहीं पहचान पा रहे. फिर से कोशिश करें."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"आपने \'मालिक का चेहरा पहचानकर अनलॉक\' सेट नहीं की है."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"इस डिवाइस पर \'मालिक का चेहरा पहचानकर अनलॉक\' काम नहीं करती है."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"चेहरा <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1624,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>से बैकग्राउंड में शुरू की गई फ़ॉरग्राउंड सेवा के लिए, भविष्य के R बिल्ड में \'इस्तेमाल के समय अनुमति दें\' की सुविधा नहीं होगी. कृपया go/r-bg-fgs-restriction देखें और गड़बड़ी की शिकायत करें."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"वॉल्यूम को सुझाए गए स्तर से ऊपर बढ़ाएं?\n\nअत्यधिक वॉल्यूम पर ज़्यादा समय तक सुनने से आपकी सुनने की क्षमता को नुकसान हो सकता है."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"सुलभता शॉर्टकट का इस्तेमाल करना चाहते हैं?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"इस शॉर्टकट के चालू होने पर, दोनों वॉल्यूम बटनों को 3 सेकंड तक दबाने से सुलभता सुविधा शुरू हो जाएगी.\n\n मौजूदा सुलभता सुविधा:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n आप इस सुविधा को सेटिंग &gt; सुलभता पर जाकर बदल सकते हैं."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"शॉर्टकट में बदलाव करें"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"अभी नहीं"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"शॉर्टकट बंद करें"</string>
@@ -2010,4 +2021,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> को प्रतिबंधित बकेट में रखा गया है"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"निजी प्रोफ़ाइल"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"वर्क प्रोफ़ाइल"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 9a9357f..cd8eae5 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -193,6 +193,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrator je ustupio uređaj za osobnu upotrebu"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Uređaj je upravljan"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Vaša organizacija upravlja ovim uređajem i može nadzirati mrežni promet. Dodirnite za pojedinosti."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Postavke lokacije koje je promijenio administrator"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Dodirnite da biste vidjeli svoje postavke lokacije."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Uređaj će se izbrisati"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Administratorska aplikacija ne može se upotrebljavati. Uređaj će se izbrisati.\n\nAko imate pitanja, obratite se administratoru organizacije."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Ispis je onemogućila aplikacija <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -432,6 +434,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Ova povlaštena aplikacija sustava | u svakom trenutku može snimati fotografije i videozapise kamerom sustava. Aplikacija mora imati i dopuštenje android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"upravljanje vibracijom"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Aplikaciji omogućuje nadzor nad vibratorom."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Aplikaciji omogućuje da pristupi stanju vibracije."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"izravno pozivanje telefonskog broja"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Aplikaciji omogućuje pozivanje telefonskih brojeva bez vašeg sudjelovanja. To može dovesti do neočekivanih troškova ili poziva. Uzmite u obzir da se aplikaciji time ne omogućuje pozivanje brojeva u nuždi. Zlonamjerne aplikacije mogu vam uzrokovati dodatne troškove postavljanjem poziva bez vašeg odobrenja."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"pristupiti usluzi poziva izravnih poruka"</string>
@@ -546,6 +549,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Pokušajte ponovo."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nije registriran nijedan otisak prsta."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor otiska prsta."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -589,6 +594,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Lice nije potvrđeno. Pokušajte ponovo."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Niste postavili otključavanje licem"</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Otključavanje licem nije podržano na ovom uređaju."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Lice <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1636,7 +1643,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Usluga u prednjem planu s <xliff:g id="PACKAGENAME">%1$s</xliff:g> pokrenuta u pozadini neće imati dopuštenje tijekom upotrebe u budućim R kompilacijama. Pogledajte go/r-bg-fgs-restriction i pošaljite izvješće o programskoj pogrešci."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Želite li pojačati zvuk iznad preporučene razine?\n\nDugotrajno slušanje glasne glazbe može vam oštetiti sluh."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Želite li upotrebljavati prečac za pristupačnost?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Kada je taj prečac uključen, pritiskom na obje tipke za glasnoću na 3 sekunde pokrenut će se značajka pristupačnosti.\n\n Trenutačna značajka pristupačnosti:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Značajku možete promijeniti u Postavkama &gt; Pristupačnost."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Uredi prečace"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Otkaži"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Isključi prečac"</string>
@@ -2044,4 +2052,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Paket <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> premješten je u spremnik OGRANIČENO"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Osobno"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Posao"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index d4ac7e2..bb1ad32 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Az adminisztrátor átadta az eszközt személyes használatra"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Felügyelt eszköz"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Ezt az eszközt szervezete kezeli, és lehetséges, hogy a hálózati forgalmat is figyelik. További részletekért koppintson."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"A helybeállításokat módosította a adminisztrátora"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Koppintson a helybeállítások megtekintéséhez."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"A rendszer törölni fogja eszközét"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"A rendszergazdai alkalmazás nem használható. A rendszer most törli az eszközt.\n\nKérdéseivel forduljon szervezete rendszergazdájához."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"A(z) <xliff:g id="OWNER_APP">%s</xliff:g> letiltotta a nyomtatást."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"A rendszerkamera használatával ez az előnyben részesített vagy rendszeralkalmazás bármikor készíthet fényképeket és videókat. Az alkalmazásnak az „android.permission.CAMERA” engedéllyel is rendelkeznie kell."</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"rezgés szabályozása"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Lehetővé teszi az alkalmazás számára a rezgés vezérlését."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Lehetővé teszi az alkalmazás számára a rezgés állapotához való hozzáférést."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"telefonszámok közvetlen hívása"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Lehetővé teszi az alkalmazás számára, hogy az Ön jóváhagyása nélkül hívjon fel telefonszámokat. Ennek eredményeként váratlan terhelésekkel vagy telefonhívásokkal találkozhat. Vegye figyelembe, hogy ez nem teszi lehetővé segélyhívó számok hívását az alkalmazás számára. A rosszindulatú alkalmazások az Ön jóváhagyása nélkül kezdeményezhetnek hívásokat, így költségek merülhetnek fel."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"hozzáférés az IMS-hívásszolgáltatáshoz"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Próbálkozzon újra."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nincsenek regisztrált ujjlenyomatok."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ez az eszköz nem rendelkezik ujjlenyomat-érzékelővel."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. ujj"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Nem sikerült ellenőrizni az arcát. Próbálja újra."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Nem állította be az arcalapú feloldást."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Az eszköz nem támogatja az arcalapú feloldást"</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"<xliff:g id="FACEID">%d</xliff:g> arc"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"A háttér által indított előtérben futó szolgáltatás (innen: <xliff:g id="PACKAGENAME">%1$s</xliff:g>) nem tartalmaz majd használat közbeni engedélyt a jövőbeli R buildekben. Kérjük, keresse fel a go/r-bg-fgs-restriction webhelyet, és jelentse a hibát."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Az ajánlott szint fölé szeretné emelni a hangerőt?\n\nHa hosszú időn át teszi ki magát nagy hangerőnek, azzal károsíthatja a hallását."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Szeretné használni a Kisegítő lehetőségek billentyűparancsot?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Ha be van kapcsolva a billentyűparancs, a két hangerőgomb 3 másodpercig tartó lenyomásával elindíthatja a kisegítő lehetőségek egyik funkcióját.\n\n A kisegítő lehetőségek jelenleg beállított funkciója:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n A funkciót a Beállítások &gt; Kisegítő lehetőségek menüpontban módosíthatja."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Gyorsparancsszerkesztés"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Mégse"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Billentyűparancs kikapcsolása"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"A következő csomag a KORLÁTOZOTT csoportba került: <xliff:g id="PACKAGE_NAME">%1$s</xliff:g>"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Személyes"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Munka"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 5cd8e8e..aabfc80 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Ադմինիստրատորը տրամադրել է սարքը անձնական օգտագործման համար"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Սարքը կառավարվում է"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Ձեր կազմակերպությունը կառավարում է այս սարքը և կարող է վերահսկել ցանցի թրաֆիկը: Հպեք՝ մանրամասները դիտելու համար:"</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Տեղադրության կարգավորումները փոփոխվել են ձեր ադմինիստրատորի կողմից։"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Հպեք՝ ձեր տեղադրության կարգավորումները տեսնելու համար։"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Ձեր սարքը ջնջվելու է"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Հնարավոր չէ օգտագործել ադմինիստրատորի հավելվածը։ Ձեր սարքից բոլոր տվյալները կջնջվեն։\n\nՀարցեր ունենալու դեպքում դիմեք ձեր կազմակերպության ադմինիստրատորին։"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Տպումն անջատված է <xliff:g id="OWNER_APP">%s</xliff:g> հավելվածի կողմից։"</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Այս արտոնյալ | համակարգային հավելվածը կարող է ցանկացած պահի լուսանկարել և տեսագրել՝ օգտագործելով համակարգի տեսախցիկները: Հավելվածին նաև անհրաժեշտ է android.permission.CAMERA թույլտվությունը:"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"կառավարել թրթռումը"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Թույլ է տալիս հավելվածին կառավարել թրթռոցը:"</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Հավելվածին թույլ է տալիս օգտագործել սարքի թրթռալու ռեժիմը։"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ուղղակիորեն զանգել հեռախոսահամարներին"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Թույլ է տալիս հավելվածին զանգել հեռախոսահամարներին առանց ձեր միջամտության: Սա կարող է հանգեցնել անկանխատեսելի գանձումների կամ զանգերի: Նկատի ունեցեք, որ սա թույլ չի տալիս հավելվածին զանգել արտակարգ իրավիճակների համարներին: Վնասարար հավելվածները կարող են ձեր հաշվից զանգեր կատարել` առանց ձեր հաստատման:"</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"օգտվել IMS զանգերի ծառայությունից"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Փորձեք նորից:"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Գրանցված մատնահետք չկա:"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Այս սարքը չունի մատնահետքերի սկաներ։"</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Մատնահետք <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Չհաջողվեց հաստատել դեմքը։ Նորից փորձեք։"</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Դուք չեք կարգավորել դեմքով ապակողպումը:"</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Դեմքով ապակողպումն այս սարքում չի աջակցվում"</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Դեմք <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Ֆոնային ռեժիմում <xliff:g id="PACKAGENAME">%1$s</xliff:g>-ից գործարկված առաջին պլանի ծառայությունը հետագա R կառուցումներում թույլտվություն չի ունենա օգտագործման ընթացքում։ Անցեք go/r-bg-fgs-restriction էջ և հաղորդեք վրիպակի մասին։"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Ձայնը բարձրացնե՞լ խորհուրդ տրվող մակարդակից ավել:\n\nԵրկարատև բարձրաձայն լսելը կարող է վնասել ձեր լսողությունը:"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Օգտագործե՞լ Մատչելիության դյուրանցումը։"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Հատուկ գործառույթն օգտագործելու համար սեղմեք և 3 վայրկյան սեղմած պահեք ձայնի ուժգնության երկու կոճակները, երբ գործառույթը միացված է։\n\n Մատչելիության ակտիվ գործառույթը՝\n<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Գործառույթը կարող եք փոփոխել՝ անցնելով Կարգավորումներ &gt; Հատուկ գործառույթներ։"</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Փոփոխել դյուրանցումները"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Չեղարկել"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Անջատել դյուրանցումը"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> փաթեթը գցվեց ՍԱՀՄԱՆԱՓԱԿՎԱԾ զամբյուղի մեջ"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Անձնական"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Աշխատանքային"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 3a1571d..7963ba7 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Admin melepaskan perangkat untuk penggunaan pribadi"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Perangkat ini ada yang mengelola"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Organisasi mengelola perangkat ini dan mungkin memantau traffic jaringan. Ketuk untuk melihat detailnya."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Setelan lokasi diubah oleh admin Anda"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Ketuk untuk melihat setelan lokasi Anda."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Perangkat akan dihapus"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Aplikasi admin tidak dapat digunakan. Perangkat Anda kini akan dihapus.\n\nJika ada pertanyaan, hubungi admin organisasi."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Fitur pencetakan dinonaktifkan oleh <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Hak istimewa ini | aplikasi sistem dapat mengambil gambar dan merekam video menggunakan kamera sistem kapan saja. Mewajibkan aplikasi juga memegang izin android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"kontrol getaran"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Mengizinkan aplikasi untuk mengendalikan vibrator."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Mengizinkan aplikasi untuk mengakses status vibrator."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"panggil nomor telepon secara langsung"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Memungkinkan aplikasi menghubungi nomor telepon tanpa campur tangan Anda. Izin ini dapat mengakibatkan biaya atau panggilan tak terduga. Perhatikan bahwa izin ini tidak memungkinkan aplikasi menghubungi nomor darurat. Aplikasi berbahaya dapat menyebabkan Anda dikenakan biaya dengan melakukan panggilan tanpa konfirmasi Anda."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"akses layanan panggilan IMS"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Coba lagi."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Tidak ada sidik jari yang terdaftar."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Perangkat ini tidak memiliki sensor sidik jari."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Tidak dapat memverifikasi wajah. Coba lagi."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Anda belum menyiapkan face unlock."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Face unlock tidak didukung di perangkat ini."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"<xliff:g id="FACEID">%d</xliff:g> wajah"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Layanan latar depan yang dimulai oleh latar belakang dari <xliff:g id="PACKAGENAME">%1$s</xliff:g> tidak akan memiliki izin saat-sedang-digunakan pada build R masa mendatang Lihat go/r-bg-fgs-restriction dan kirim laporan bug."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Mengeraskan volume di atas tingkat yang disarankan?\n\nMendengarkan dengan volume keras dalam waktu yang lama dapat merusak pendengaran Anda."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Gunakan Pintasan Aksesibilitas?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Saat pintasan aktif, menekan kedua tombol volume selama 3 detik akan memulai fitur aksesibilitas.\n\n Fitur aksesibilitas saat ini:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Anda dapat mengubah fitur di Setelan &gt; Aksesibilitas."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Edit pintasan"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Batal"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Nonaktifkan Pintasan"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> telah dimasukkan ke dalam bucket DIBATASI"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Pribadi"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Kerja"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index eddb214..b128e53 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Kerfisstjóri lét af hendi tæki til einkanota"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Tækinu er stjórnað"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Fyrirtækið þitt stjórnar þessu tæki og kann að fylgjast með netnotkun. Ýttu hér til að fá upplýsingar."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Stjórnandi breytti staðsetningarstillingum"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Ýttu til að sjá staðsetningarstillingar."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Tækið verður hreinsað"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Ekki er hægt að nota stjórnunarforritið. Tækinu verður eytt.\n\nEf spurningar vakna skaltu hafa samband við kerfisstjóra fyrirtækisins."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> lokaði á prentun."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Þetta kerfisforrit hefur heimild til að taka myndir og taka upp myndskeið með myndavél kerfisins hvenær sem er. Forritið þarf einnig að vera með heimildina android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"stjórna titringi"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Leyfir forriti að stjórna titraranum."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Veitir forritinu aðgang að stöðu titrings."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"hringja beint í símanúmer"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Leyfir forriti að hringja í símanúmer án íhlutunar notanda. Þetta getur haft í för með sér óumbeðin gjöld og símtöl. Athugaðu að þetta leyfir forritinu ekki að hringja í neyðarnúmer. Spilliforrit geta stofnað til kostnaðar fyrir þig með því að hringja símtöl án þinnar heimildar."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"fá aðgang að IMS-símtalsþjónustu"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Reyndu aftur."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Engin fingraför hafa verið skráð."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Þetta tæki er ekki með fingrafaralesara."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Fingur <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Ekki tókst að staðfesta andlit. Reyndu aftur."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Þú hefur ekki sett upp andlitsopnun."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Andlitsopnun er ekki studd í þessu tæki."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Andlit <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Forgrunnsþjónusta frá <xliff:g id="PACKAGENAME">%1$s</xliff:g> sem er ræst úr bakgrunni mun ekki hafa heimild við notkun í framtíðarútgáfum R. Farðu á go/r-bg-fgs-restriction og gefðu villuskýrslu."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Hækka hljóðstyrk umfram ráðlagðan styrk?\n\nEf hlustað er á háum hljóðstyrk í langan tíma kann það að skaða heyrnina."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Viltu nota aðgengisflýtileið?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Þegar flýtileiðin er virk er kveikt á aðgengiseiginleikanum með því að halda báðum hljóðstyrkshnöppunum inni í þrjár sekúndur.\n\n Virkur aðgengiseiginleiki:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Hægt er að skipta um eiginleika í Stillingar &gt; Aðgengi."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Breyta flýtileiðum"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Hætta við"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Slökkva á flýtileið"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> var sett í flokkinn TAKMARKAÐ"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Persónulegt"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Vinna"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 135a226..b8515df 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"L\'amministratore ha abbandonato il dispositivo per uso personale"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Il dispositivo è gestito"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Questo dispositivo è gestito dalla tua organizzazione, che potrebbe monitorare il traffico di rete. Tocca per i dettagli."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Impostazioni di geolocalizzazione modificate dal tuo amministratore"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Tocca per vedere le tue impostazioni di geolocalizzazione."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Il dispositivo verrà resettato"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Impossibile usare l\'app di amministrazione. Il dispositivo verrà resettato.\n\nPer eventuali domande, contatta l\'amministratore della tua organizzazione."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Stampa disattivata da <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Questa app di sistema | privilegiata può fare foto e video tramite una videocamera del sistema in qualsiasi momento. Richiede che l\'autorizzazione android.permission.CAMERA sia concessa anche all\'app"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"controllo vibrazione"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Consente all\'applicazione di controllare la vibrazione."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Consente all\'app di accedere allo stato di vibrazione."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"chiamata diretta n. telefono"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Consente all\'applicazione di chiamare numeri di telefono senza il tuo intervento. Ciò può comportare chiamate o addebiti imprevisti. Tieni presente che ciò non consente all\'applicazione di chiamare numeri di emergenza. Applicazioni dannose potrebbero generare dei costi effettuando chiamate senza la tua conferma."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"accesso al servizio di chiamata IMS"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Riprova."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nessuna impronta digitale registrata."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Questo dispositivo non dispone di sensore di impronte."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dito <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Impossibile verificare il volto. Riprova."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Non hai configurato Sblocco con il volto."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Sblocco con il volto non supportato su questo dispositivo."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Volto <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1184,7 +1191,7 @@
     <string name="unsupported_display_size_show" msgid="980129850974919375">"Mostra sempre"</string>
     <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"L\'app <xliff:g id="APP_NAME">%1$s</xliff:g> è stata realizzata per una versione non compatibile del sistema operativo Android e potrebbe avere un comportamento imprevisto. Potrebbe essere disponibile una versione aggiornata dell\'app."</string>
     <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Mostra sempre"</string>
-    <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Verifica la presenza di aggiornamenti"</string>
+    <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Cerca aggiornamenti"</string>
     <string name="smv_application" msgid="3775183542777792638">"L\'applicazione <xliff:g id="APPLICATION">%1$s</xliff:g> (processo <xliff:g id="PROCESS">%2$s</xliff:g>) ha violato la norma StrictMode autoimposta."</string>
     <string name="smv_process" msgid="1398801497130695446">"Il processo <xliff:g id="PROCESS">%1$s</xliff:g> ha violato la norma StrictMode autoimposta."</string>
     <string name="android_upgrading_title" product="default" msgid="7279077384220829683">"Aggiornamento del telefono…"</string>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Il servizio in primo piano avviato in background da <xliff:g id="PACKAGENAME">%1$s</xliff:g> non avrà l\'autorizzazione \"durante l\'uso\" nelle future build R. Visita la pagina go/r-bg-fgs-restriction e invia una segnalazione di bug."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vuoi aumentare il volume oltre il livello consigliato?\n\nL\'ascolto ad alto volume per lunghi periodi di tempo potrebbe danneggiare l\'udito."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Usare la scorciatoia Accessibilità?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Quando la scorciatoia è attiva, puoi premere entrambi i pulsanti del volume per tre secondi per avviare una funzione di accessibilità.\n\n Funzione di accessibilità corrente:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Puoi cambiare la funzione in Impostazioni &gt; Accessibilità."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Modifica scorciatoie"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Annulla"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Disattiva scorciatoia"</string>
@@ -1856,7 +1864,7 @@
     <string name="app_blocked_title" msgid="7353262160455028160">"L\'app non è disponibile"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"L\'app <xliff:g id="APP_NAME">%1$s</xliff:g> non è al momento disponibile."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Questa app è stata realizzata per una versione precedente di Android e potrebbe non funzionare correttamente. Prova a verificare la disponibilità di aggiornamenti o contatta lo sviluppatore."</string>
-    <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Verifica la presenza di aggiornamenti"</string>
+    <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Cerca aggiornamenti"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Hai nuovi messaggi"</string>
     <string name="new_sms_notification_content" msgid="3197949934153460639">"Apri l\'app SMS per la visualizzazione"</string>
     <string name="profile_encrypted_title" msgid="9001208667521266472">"Alcune funzionalità sono limitate"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> è stato inserito nel bucket RESTRICTED"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Personale"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Lavoro"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 65b7384..4886b4a 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -195,6 +195,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"מנהל המערכת ביטל את המכשיר לצורכי שימוש אישי"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"המכשיר מנוהל"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"הארגון שלך מנהל מכשיר זה ועשוי לנטר את התנועה ברשת. הקש לקבלת פרטים."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"מנהל המערכת שינה את הגדרות המיקום"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"יש להקיש כדי לראות את הגדרות המיקום שלך."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"תתבצע מחיקה של המכשיר"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"לא ניתן להשתמש באפליקציה של מנהל המערכת.\n\nאם יש לך שאלות, יש ליצור קשר עם מנהל המערכת של הארגון."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"ההדפסה הושבתה על ידי <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -435,6 +437,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"‏לאפליקציית המערכת | הזו יש הרשאות מיוחדות והיא יכולה לצלם תמונות ולהקליט סרטונים באמצעות מצלמת מערכת בכל זמן. בנוסף, לאפליקציה נדרשת ההרשאה android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"שליטה ברטט"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"מאפשר לאפליקציה לשלוט ברטט."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"מאפשרת לאפליקציה לקבל גישה למצב הרטט."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"התקשר ישירות למספרי טלפון"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"מאפשר לאפליקציה להתקשר למספרי טלפון ללא התערבותך. פעולה זו עשויה לגרום לשיחות או לחיובים לא צפויים. שים לב שהדבר לא מאפשר לאפליקציה להתקשר למספרי חירום. אפליקציות זדוניות עשויות לגרום לעלויות על ידי ביצוע שיחות ללא התערבותך."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"‏גישה אל שירות שיחות IMS"</string>
@@ -549,6 +552,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"כדאי לנסות שוב."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"לא נרשמו טביעות אצבע."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"במכשיר זה אין חיישן טביעות אצבע."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"אצבע <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -592,6 +597,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"לא ניתן לאמת את הפנים. יש לנסות שוב."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"לא הגדרת שחרור נעילה על ידי זיהוי פנים."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"המכשיר הזה לא תומך בשחרור נעילה על ידי זיהוי פנים."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"פנים <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1658,7 +1665,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"‏לשירות שפועל בחזית מ-<xliff:g id="PACKAGENAME">%1$s</xliff:g> שהחל ברקע לא תהיה הרשאת while-in-use בגרסאות R build בעתיד. יש לעיין בכתובת go/r-bg-fgs-restriction ולהגיש דוח על באג."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"האם להעלות את עוצמת הקול מעל לרמה המומלצת?\n\nהאזנה בעוצמת קול גבוהה למשכי זמן ממושכים עלולה לפגוע בשמיעה."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"להשתמש בקיצור הדרך לתכונת הנגישות?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"כשקיצור הדרך מופעל, לחיצה על שני לחצני עוצמת השמע למשך שלוש שניות מפעילה את תכונת הנגישות.\n\n תכונת הנגישות המוגדרת כרגע:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n אפשר לשנות את התכונה בקטע \'הגדרות ונגישות\'."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"עריכת קיצורי הדרך"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"ביטול"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"כבה את קיצור הדרך"</string>
@@ -2078,4 +2086,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> התווספה לקטגוריה \'מוגבל\'"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"אישי"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"עבודה"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index bda2064..9de1672 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"管理者により、デバイスの個人使用が許可されました"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"管理対象のデバイス"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"このデバイスは組織によって管理され、ネットワーク トラフィックが監視される場合があります。詳しくはタップしてください。"</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"位置情報の設定が管理者によって変更されました"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"タップすると位置情報の設定が表示されます。"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"デバイスのデータが消去されます"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"管理アプリを使用できません。デバイスのデータはこれから消去されます。\n\nご不明な点がある場合は、組織の管理者にお問い合わせください。"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"「<xliff:g id="OWNER_APP">%s</xliff:g>」により印刷は無効にされています。"</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"権限を付与されたこのシステムアプリは、いつでもシステムカメラを使用して写真と動画を撮影できます。アプリには android.permission.CAMERA 権限も必要です"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"バイブレーションの制御"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"バイブレーションの制御をアプリに許可します。"</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"バイブレーションの状態へのアクセスをアプリに許可します。"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"電話番号発信"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"電話番号への自動発信をアプリに許可します。これにより、予期せぬ発信や料金が発生する可能性があります。なお、緊急通報番号への発信は許可されません。悪意のあるアプリが確認なしで発信し、料金が発生する恐れがあります。"</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS通話サービスへのアクセス"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"もう一度お試しください。"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"指紋が登録されていません。"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"このデバイスには指紋認証センサーがありません。"</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"指紋 <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"顔を確認できません。もう一度お試しください。"</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"顔認証を設定していません。"</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"このデバイスでは、顔認証はご利用いただけません。"</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"顔 <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"今後の R ビルドでは、<xliff:g id="PACKAGENAME">%1$s</xliff:g> からバックグラウンドで開始されるフォアグラウンド サービスに「使用中のみ許可」の権限がありません。go/r-bg-fgs-restriction を確認し、バグレポートを提出してください。"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"推奨レベルを超えるまで音量を上げますか?\n\n大音量で長時間聞き続けると、聴力を損なう恐れがあります。"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ユーザー補助機能のショートカットの使用"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"ショートカットが ON の場合、両方の音量ボタンを 3 秒間押し続けるとユーザー補助機能が起動します。\n\n現在のユーザー補助機能:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\nユーザー補助機能は [設定] &gt; [ユーザー補助] で変更できます。"</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"ショートカットの編集"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"キャンセル"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ショートカットを OFF にする"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> は RESTRICTED バケットに移動しました。"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"個人用"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"仕事用"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index c47b710..2d15c16 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"ადმინისტრატორმა გაათავისუფლა მოწყობილობა პირადი გამოყენებისთვის"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"მოწყობილობა მართულია"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"ამ მოწყობილობას თქვენი ორგანიზაცია მართავს და მას ქსელის ტრაფიკის მონიტორინგი შეუძლია. შეეხეთ დამატებითი დეტალებისთვის."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"მდებარეობის პარამეტრები თქვენმა ადმინისტრატორმა შეცვალა"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"შეეხეთ თქვენი მდებარეობის პარამეტრების სანახავად."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"თქვენი მოწყობილობა წაიშლება"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"ადმინისტრატორის აპის გამოყენება ვერ მოხერხდება. თქვენი მოწყობილობა ახლა ამოიშლება.\n\nთუ შეკითხვები გაქვთ, დაუკავშირდით თქვენი ორგანიზაციის ადმინისტრატორს."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"ბეჭდვა გათიშულია <xliff:g id="OWNER_APP">%s</xliff:g>-ის მიერ."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"ამ პრივილეგირებულ | სისტემის აპს შეუძლია ფოტოების გადაღება და ვიდეოების ჩაწერა ნებისმიერ დროს სისტემის კამერის გამოყენებით. საჭიროა, რომ აპს ჰქოდეს android.permission.CAMERA ნებართვაც"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"ვიბრაციის კონტროლი"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"აპს შეეძლება, მართოს ვიბრირება."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"ნებას რთავს აპს, ჰქონდეს წვდომა ვიბრაციის მდგომარეობაზე."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"პირდაპირი დარეკვა ტელეფონის ნომრებზე"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"აპს შეეძლება დარეკოს ტელეფონის ნომრებზე თქვენი ჩარევის გარეშე. ამან შესაძლოა გამოიწვიოს თქვენს სატელეფონი ქვითარზე მოულოდნელი ხარჯებისა და ზარების გაჩენა. გაითვალისწინეთ, რომ აპს გადაუდებელი დახმარების ნომრებზე დარეკვა არ შეუძლია. მავნე აპებს შეეძლება თქვენი დადასტურების გარეშე ზარების განხორციელება და შესაბამისი საფასურის გადახდაც მოგიწევთ."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS ზარების სერვისზე წვდომა"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"ხელახლა სცადეთ"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"თითის ანაბეჭდები რეგისტრირებული არ არის."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ამ მოწყობილობას არ აქვს თითის ანაბეჭდის სენსორი."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"თითი <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"სახის დადასტურება ვერ ხერხდება. ცადეთ ხელახლა."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"თქვენ არ დაგიყენებიათ სახით განბლოკვა."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"განბლოკვა სახით ამ მოწყობილობაზე მხარდაჭერილი არ არის."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"სახე <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>-ის ფონურად დაწყებულ წინა პლანის სერვისს მომავალ R build-ებში გამოყენების პროცესში წვდომის ნებართვა არ ექნება. გთხოვთ, იხილოთ go/r-bg-fgs-restriction და გამოგზავნოთ ხარვეზის ანგარიში."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"გსურთ ხმის რეკომენდებულ დონეზე მაღლა აწევა?\n\nხანგრძლივად ხმამაღლა მოსმენით შესაძლოა სმენადობა დაიზიანოთ."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"გსურთ მარტივი წვდომის მალსახმობის გამოყენება?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"მალსახმობის ჩართვის შემთხვევაში, ხმის ორივე ღილაკზე 3 წამის განმავლობაში დაჭერით მარტივი წვდომის ფუნქცია ჩაირთვება.\n\n მარტივი წვდომის ამჟამინდელი ფუნქციაა:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n ამ ფუნქციის შეცვლა შეგიძლიათ აქ: პარამეტრები &gt; მარტივი წვდომა."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"მალსახმობების რედაქტირება"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"გაუქმება"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"მალსახმობის გამორთვა"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> მოთავსდა კალათაში „შეზღუდული“"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"პირადი"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"სამსახური"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 241cf08..1406a8b 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -191,6 +191,10 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Әкімші құрылғыны жеке пайдалануға ұсынды."</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Құрылғы басқарылады"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Ұйымыңыз осы құрылғыны басқарады және желі трафигін бақылауы мүмкін. Мәліметтер алу үшін түртіңіз."</string>
+    <!-- no translation found for location_changed_notification_title (4119726617105166830) -->
+    <skip />
+    <!-- no translation found for location_changed_notification_text (198907268219396399) -->
+    <skip />
     <string name="factory_reset_warning" msgid="6858705527798047809">"Құрылғыңыздағы деректер өшіріледі"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Әкімші қолданбасын пайдалану мүмкін емес. Қазір құрылғыдағы деректер өшіріледі\n\nСұрақтарыңыз болса, ұйым әкімшісіне хабарласыңыз."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Басып шығаруды <xliff:g id="OWNER_APP">%s</xliff:g> өшірді."</string>
@@ -429,6 +433,8 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Осы айрықша | жүйе қолданбасы кез келген уақытта жүйелік камера арқылы суретке не бейнеге түсіре алады. Қолданбаға android.permission.CAMERA рұқсаты қажет болады."</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"тербелісті басқару"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Қолданбаға вибраторды басқаруға рұқсат береді."</string>
+    <!-- no translation found for permdesc_vibrator_state (7050024956594170724) -->
+    <skip />
     <string name="permlab_callPhone" msgid="1798582257194643320">"нөмірлерге тікелей телефон шалу"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Қолданбаға сіздің қатысуыңызсыз қоңырау шалу мүмкіндігін береді. Нәтижесінде қосымша төлем немесе күтпеген қоңырау алуыңыз мүмкін. Есіңізде болсын, қолданба төтенше байланыстарға қоңырау шала алмайды. Залалды қолданбалар сіздің рұқсатыңызсыз қоңыраулар шалып, күтпеген төлемдерге себеп болуы мүмкін."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS қоңырау қызметін пайдалану"</string>
@@ -543,6 +549,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Әрекетті қайталаңыз."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Саусақ іздері тіркелмеген."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бұл құрылғыда саусақ ізін оқу сканері жоқ."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> саусағы"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +594,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Бетті тану мүмкін емес. Әрекетті қайталаңыз."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Face Unlock реттелмеді."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Бұл құрылғыда Face Unlock функциясы істемейді."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"<xliff:g id="FACEID">%d</xliff:g> беті"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1624,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Фондық режимде іске қосылған <xliff:g id="PACKAGENAME">%1$s</xliff:g> белсенді пакетінің алдағы R құрамаларында \"Пайдаланғанда ғана рұқсат ету\" рұқсаты болмайды. go/r-bg-fgs-restriction бетіне өтіп, қате туралы есеп жіберіңіз."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Дыбыс деңгейін ұсынылған деңгейден көтеру керек пе?\n\nЖоғары дыбыс деңгейінде ұзақ кезеңдер бойы тыңдау есту қабілетіңізге зиян тигізуі мүмкін."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Арнайы мүмкіндік төте жолын пайдалану керек пе?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Бұл төте жол қосулы кезде дыбыс деңгейі түймелерінің екеуін де 3 секунд бойы басқанда арнайы мүмкіндік іске қосылады.\n\n Ағымдағы арнайы мүмкіндік:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Бұл мүмкіндікті \"Параметрлер\" &gt; \"Арнайы мүмкіндіктер\" тармағында өзгертуге болады."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Таңбашаларды өзгерту"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Бас тарту"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Төте жолды өшіру"</string>
@@ -2010,4 +2021,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ШЕКТЕЛГЕН себетке салынды."</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Жеке"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Жұмыс"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 483e236..50e2e15 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"អ្នកគ្រប់គ្រង​បានបោះបង់​ឧបករណ៍​ចោល​ដោយសារ​ការប្រើប្រាស់​ផ្ទាល់ខ្លួន"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"ឧបករណ៍ស្ថិតក្រោមការគ្រប់គ្រង"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"ស្ថាប័នរបស់អ្នកគ្រប់គ្រងឧបករណ៍នេះ ហើយអាចនឹងតាមដានចរាចរណ៍បណ្តាញ។ ចុចដើម្បីទទួលបានព័ត៌មានលម្អិត។"</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"ការកំណត់​ទីតាំង​ត្រូវបានប្ដូរដោយ​អ្នកគ្រប់គ្រង​របស់អ្នក"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"ចុច​ដើម្បី​មើល​ការកំណត់​ទីតាំង​របស់អ្នក។"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"ឧបករណ៍របស់អ្នកនឹងត្រូវបានលុប"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"មិនអាច​ប្រើ​កម្មវិធី​អ្នកគ្រប់គ្រង​បានទេ។ ឧបករណ៍​របស់អ្នក​នឹងលុប​ឥឡូវនេះ។\n\nប្រសិនបើ​អ្នកមាន​សំណួរផ្សេងៗ​ សូមទាក់ទង​ទៅអ្នក​គ្រប់គ្រង​ស្ថាប័ន​របស់​អ្នក។"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"ការបោះពុម្ព​ត្រូវបាន​បិទ​ដោយ <xliff:g id="OWNER_APP">%s</xliff:g> ។"</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"កម្មវិធីប្រព័ន្ធ​ដែលមានសិទ្ធិអនុញ្ញាត​នេះអាចថត​រូប និង​ថតវីដេអូ​ ដោយប្រើកាមេរ៉ា​ប្រព័ន្ធបាន​គ្រប់ពេល។ តម្រូវឱ្យមាន​ការអនុញ្ញាត android.permission.CAMERA ដើម្បីឱ្យ​កម្មវិធីអាចធ្វើ​សកម្មភាព​បានផងដែរ"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"ពិនិត្យ​ការ​ញ័រ"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"ឲ្យ​កម្មវិធី​គ្រប់គ្រង​កម្មវិធី​ញ័រ។"</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"អនុញ្ញាតឱ្យ​កម្មវិធី​ចូលប្រើ​ស្ថានភាពកម្មវិធី​ញ័រ។"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ហៅ​លេខ​ទូរស័ព្ទ​ដោយ​ផ្ទាល់"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"ឲ្យ​កម្មវិធី​ហៅ​លេខ​ទូរស័ព្ទ​ដោយ​គ្មាន​សកម្មភាព​របស់​អ្នក។​ វា​អាច​កាត់​លុយ​ ឬ​ហៅ​ដោយ​មិន​រំពឹង​ទុក។ ចំណាំ​ថា​ វា​មិន​អនុញ្ញាត​ឲ្យ​កម្មវិធី​ហៅ​លេខ​ពេល​អាសន្ន​ទេ។ កម្មវិធី​ព្យាបាទ​អាច​កាត់​លុយ​របស់​អ្នក​ ដោយ​ធ្វើការ​ហៅ​ដោយ​គ្មាន​ការ​បញ្ជាក់​របស់​អ្នក។"</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"ចូលដំណើរការសេវាកម្មការហៅតាម IMS"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"ព្យាយាមម្ដងទៀត។"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"មិន​មាន​ការ​ចុះឈ្មោះស្នាម​ម្រាមដៃទេ។"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ឧបករណ៍នេះ​មិនមាន​ឧបករណ៍ចាប់​ស្នាមម្រាមដៃទេ។"</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ម្រាមដៃ <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"មិន​អាច​ផ្ទៀងផ្ទាត់​មុខ​បាន​ទេ។ សូមព្យាយាមម្ដងទៀត។"</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"អ្នក​មិនទាន់​រៀបចំ​ការដោះសោតាមទម្រង់មុខ​នៅឡើយទេ។"</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"មិនអាចប្រើ​ការដោះសោតាមទម្រង់មុខ​នៅលើ​ឧបករណ៍​នេះ​បានទេ។"</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"ផ្ទៃមុខទី <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1616,7 +1623,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"សេវាកម្ម​ផ្ទៃខាងមុខ​ដែលចាប់ផ្ដើមដោយ​ផ្ទៃខាងក្រោយ​ពី <xliff:g id="PACKAGENAME">%1$s</xliff:g> នឹង​មិនមាន​ការអនុញ្ញាត​ខណៈពេល​កំពុង​ប្រើប្រាស់​ទេ នៅក្នុង​កំណែបង្កើត R នៅពេល​អនាគត​។ សូម​មើល go/r-bg-fgs-restriction និង​ផ្ញើ​របាយការណ៍​អំពី​បញ្ហា​។"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"បង្កើន​កម្រិត​សំឡេង​លើស​ពី​កម្រិត​បាន​ផ្ដល់​យោបល់?\n\nការ​ស្ដាប់​នៅ​កម្រិត​សំឡេង​ខ្លាំង​យូរ​អាច​ធ្វើឲ្យ​ខូច​ត្រចៀក។"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ប្រើប្រាស់​ផ្លូវកាត់​ភាព​ងាយស្រួល?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"នៅពេល​ផ្លូវកាត់​នេះបើក ការ​ចុច​ប៊ូតុង​កម្រិត​សំឡេង​ទាំង​ពីរ​ឲ្យ​ជាប់​រយៈពេល​ 3 វិនាទីនឹង​ចាប់ផ្តើម​មុខងារ​ភាពងាយស្រួល។\n\n មុខងារ​ភាពងាយស្រួល​បច្ចុប្បន្ន៖\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n អ្នក​អាច​ផ្លាស់​ប្តូរ​មុខងារ​នេះ​បាន​នៅក្នុង​ការ កំណត់ &gt; ភាព​ងាយស្រួល។"</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"កែ​ផ្លូវកាត់"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"បោះបង់"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"បិទ​ផ្លូវកាត់"</string>
@@ -2012,4 +2020,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ត្រូវបានដាក់​ទៅក្នុងធុង​ដែលបានដាក់កំហិត"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"ផ្ទាល់ខ្លួន"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"ការងារ"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 7133e89..4099d30 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"ವೈಯಕ್ತಿಕ ಬಳಕೆಗಾಗಿ ನಿರ್ವಾಹಕರು ತೊರೆದ ಸಾಧನ"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"ಸಾಧನವನ್ನು ನಿರ್ವಹಿಸಲಾಗುತ್ತಿದೆ"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಈ ಸಾಧನವನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ ಮತ್ತು ಅದು ನೆಟ್‌ವರ್ಕ್ ಟ್ರಾಫಿಕ್ ಮೇಲೆ ಗಮನವಿರಿಸಬಹುದು. ವಿವರಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರಿಂದ ಸ್ಥಳ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಲಾಗಿದೆ"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"ನಿಮ್ಮ ಸ್ಥಳ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ನೋಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"ನಿರ್ವಹಣೆ ಅಪ್ಲಿಕೇಶನ್ ಬಳಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ನಿಮ್ಮ ಸಾಧನವನ್ನು ಇದೀಗ ಅಳಿಸಲಾಗುತ್ತದೆ.\n\nನಿಮ್ಮಲ್ಲಿ ಪ್ರಶ್ನೆಗಳಿದ್ದರೆ, ನಿಮ್ಮ ಸಂಸ್ಥೆಯ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ಮೂಲಕ ಪ್ರಿಂಟಿಂಗ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"ಈ ವಿಶೇಷ | ಸಿಸ್ಟಂ ಆ್ಯಪ್ ಯಾವುದೇ ಸಮಯದಲ್ಲಾದರೂ ಸಿಸ್ಟಂ ಕ್ಯಾಮರಾವನ್ನು ಬಳಸಿಕೊಂಡು ಫೋಟೋಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳಬಹುದು ಮತ್ತು ವೀಡಿಯೋಗಳನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಬಹುದು. ಆ್ಯಪ್‌ಗೆ android.permission.CAMERA ಅನುಮತಿಯ ಅಗತ್ಯವಿರುತ್ತದೆ"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"ವೈಬ್ರೇಷನ್‌‌ ನಿಯಂತ್ರಿಸಿ"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"ವೈಬ್ರೇಟರ್‌ ನಿಯಂತ್ರಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"ವೈಬ್ರೇಟರ್ ಸ್ಥಿತಿಯನ್ನು ಪ್ರವೇಶಿಸಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ಫೋನ್ ಸಂಖ್ಯೆಗಳಿಗೆ ನೇರವಾಗಿ ಕರೆ ಮಾಡಿ"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"ನಿಮ್ಮ ಹಸ್ತಕ್ಷೇಪ ಇಲ್ಲದೆಯೇ ಫೋನ್‍ ಸಂಖ್ಯೆಗಳಿಗೆ ಕರೆ ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್‍‍ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಇದು ಅನಿರೀಕ್ಷಿತ ಶುಲ್ಕಗಳು ಅಥವಾ ಕರೆಗಳಿಗೆ ಕಾರಣವಾಗಬಹುದು. ತುರ್ತು ಸಂಖ್ಯೆಗಳಿಗೆ ಕರೆಮಾಡಲು ಈ ಅಪ್ಲಿಕೇಶನ್‍ ಅನುಮತಿಸುವುದಿಲ್ಲ ಎಂಬುದು ಗಮನದಲ್ಲಿರಲಿ. ದುರುದ್ದೇಶಪೂರಿತ ಅಪ್ಲಿಕೇಶನ್‍‍ಗಳು ನಿಮ್ಮ ಖಾತರಿ ಇಲ್ಲದೆಯೇ ಕರೆಗಳನ್ನು ಮಾಡುವುದರ ಮೂಲಕ ನಿಮ್ಮ ಹಣ ಖರ್ಚಾಗಬಹುದು."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS ಕರೆ ಸೇವೆಯನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ಯಾವುದೇ ಫಿಂಗರ್‌ಪ್ರಿಂಟ್‌ ಅನ್ನು ನೋಂದಣಿ ಮಾಡಿಲ್ಲ."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ಈ ಸಾಧನವು ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್‌‌ ಅನ್ನು ಹೊಂದಿಲ್ಲ."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ಫಿಂಗರ್ <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"ಮುಖವನ್ನು ದೃಢೀಕರಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"ನೀವು ಫೇಸ್ ಅನ್‌ಲಾಕ್ ಅನ್ನು ಸೆಟಪ್ ಮಾಡಿಲ್ಲ."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"ಈ ಸಾಧನದಲ್ಲಿ ಫೇಸ್ ಅನ್‌ಲಾಕ್ ವೈಶಿಷ್ಟ್ಯವು ಬೆಂಬಲಿತವಾಗಿಲ್ಲ."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"ಮುಖದ <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> ನಿಂದ ಹಿನ್ನೆಲೆಯಲ್ಲಿ ಪ್ರಾರಂಭಿಸಲಾದ ಮುನ್ನೆಲೆ ಸೇವೆ ಭವಿಷ್ಯದ R ಬಿಲ್ಡ್‌ಗಳಿಂದ ಬಳಕೆಯಲ್ಲಿರುವಾಗ ಅನುಮತಿಯನ್ನು ಪಡೆಯುವುದಿಲ್ಲ. go/r-bg-fgs-restriction ಅನ್ನು ನೋಡಿ ಮತ್ತು ದೋಷವರದಿಯನ್ನು ಫೈಲ್‌ ಮಾಡಿ."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ವಾಲ್ಯೂಮ್‌ ಅನ್ನು ಶಿಫಾರಸು ಮಾಡಲಾದ ಮಟ್ಟಕ್ಕಿಂತಲೂ ಹೆಚ್ಚು ಮಾಡುವುದೇ?\n\nದೀರ್ಘ ಅವಧಿಯವರೆಗೆ ಹೆಚ್ಚಿನ ವಾಲ್ಯೂಮ್‌ನಲ್ಲಿ ಆಲಿಸುವುದರಿಂದ ನಿಮ್ಮ ಆಲಿಸುವಿಕೆ ಸಾಮರ್ಥ್ಯಕ್ಕೆ ಹಾನಿಯುಂಟು ಮಾಡಬಹುದು."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ಪ್ರವೇಶಿಸುವಿಕೆ ಶಾರ್ಟ್‌ಕಟ್ ಬಳಸುವುದೇ?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"ಶಾರ್ಟ್‌ಕಟ್ ಆನ್ ಆಗಿರುವಾಗ ಪ್ರವೇಶಿಸುವಿಕೆ ವೈಶಿಷ್ಟ್ಯ ಆನ್ ಮಾಡಲು, ಎರಡೂ ವಾಲ್ಯೂಮ್ ಬಟನ್‌ಗಳನ್ನು ನೀವು 3 ಸೆಕೆಂಡುಗಳ ಕಾಲ ಒತ್ತಬೇಕು.\n\nಪ್ರಸ್ತುತ ಪ್ರವೇಶಿಸುವಿಕೆ ವೈಶಿಷ್ಟ್ಯ: \n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಪ್ರವೇಶಿಸುವಿಕೆಯಲ್ಲಿ ನೀವು ವೈಶಿಷ್ಟ್ಯವನ್ನು ಬದಲಾಯಿಸಬಹುದು."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"ಶಾರ್ಟ್‌ಕಟ್‌‍ಗಳನ್ನು ಎಡಿಟ್ ಮಾಡಿ"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"ರದ್ದುಗೊಳಿಸಿ"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ಶಾರ್ಟ್‌ಕಟ್‌ ಆಫ್ ಮಾಡಿ"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ಅನ್ನು ನಿರ್ಬಂಧಿತ ಬಕೆಟ್‌ಗೆ ಹಾಕಲಾಗಿದೆ"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"ವೈಯಕ್ತಿಕ"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"ಕೆಲಸ"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 12c05ba..bae739c 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"관리자가 기기를 개인용으로 전환했습니다."</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"관리되는 기기"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"조직에서 이 기기를 관리하며 네트워크 트래픽을 모니터링할 수도 있습니다. 자세한 내용을 보려면 탭하세요."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"관리자가 위치 설정을 변경함"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"위치 설정을 보려면 탭하세요."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"기기가 삭제됩니다."</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"관리자 앱을 사용할 수 없습니다. 곧 기기가 삭제됩니다.\n\n궁금한 점이 있으면 조직의 관리자에게 문의하세요."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g>에 의해 사용 중지되었습니다."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"이 권한을 가진 시스템 앱은 언제든지 시스템 카메라를 사용하여 사진을 촬영하고 동영상을 녹화할 수 있습니다. 또한 앱에 android.permission.CAMERA 권한이 필요합니다."</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"진동 제어"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"앱이 진동을 제어할 수 있도록 허용합니다."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"앱이 진동 상태에 액세스하도록 허용합니다."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"전화번호 자동 연결"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"앱이 사용자의 조작 없이 전화번호로 전화를 걸 수 있도록 허용합니다. 이 경우 예상치 못한 통화 요금이 부과될 수 있습니다. 앱이 비상 전화를 걸도록 하는 권한은 주어지지 않습니다. 악성 앱이 사용자의 확인 없이 전화를 걸어 요금이 부과될 수 있습니다."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS 통화 서비스에 접근"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"다시 시도해 보세요."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"등록된 지문이 없습니다."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"기기에 지문 센서가 없습니다."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"손가락 <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"얼굴을 확인할 수 없습니다. 다시 시도하세요."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"얼굴인식 잠금해제를 설정하지 않았습니다."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"이 기기에서는 얼굴인식 잠금해제가 지원되지 않습니다."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"얼굴 <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"향후 R 빌드에서는 백그라운드에서 시작된 <xliff:g id="PACKAGENAME">%1$s</xliff:g>의 포그라운드 서비스에 더 이상 사용 중인 상태에서 필요한 권한이 부여되지 않습니다. go/r-bg-fgs-restriction 페이지에서 버그 신고를 제출하세요."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"권장 수준 이상으로 볼륨을 높이시겠습니까?\n\n높은 볼륨으로 장시간 청취하면 청력에 손상이 올 수 있습니다."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"접근성 단축키를 사용하시겠습니까?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"단축키가 사용 설정된 경우 두 개의 볼륨 버튼을 3초간 누르면 접근성 기능이 시작됩니다.\n\n 현재 접근성 기능:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n \'설정 &gt; 접근성\'에서 기능을 변경할 수 있습니다."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"단축키 수정"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"취소"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"단축키 사용 중지"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> 항목이 RESTRICTED 버킷으로 이동함"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"개인"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"직장"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index ccbf845..e9177ab 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -184,13 +184,17 @@
     <string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"Аныкталбаган үчүнчү тараптардан"</string>
     <string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"Жумуш профилиңиздин администратору тарабынан"</string>
     <string name="ssl_ca_cert_noti_managed" msgid="217337232273211674">"<xliff:g id="MANAGING_DOMAIN">%s</xliff:g> тарабынан"</string>
-    <string name="work_profile_deleted" msgid="5891181538182009328">"Жумуш профили жок кылынды"</string>
-    <string name="work_profile_deleted_details" msgid="3773706828364418016">"Жумуш профилинин башкаруучу колдонмосу жок же бузулгандыктан, жумуш профилиңиз жана ага байланыштуу дайындар жок кылынды. Жардам алуу үчүн администраторуңузга кайрылыңыз."</string>
-    <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Жумуш профилиңиз бул түзмөктөн жок кылынды"</string>
+    <string name="work_profile_deleted" msgid="5891181538182009328">"Жумуш профили өчүрүлдү"</string>
+    <string name="work_profile_deleted_details" msgid="3773706828364418016">"Жумуш профилинин башкаруучу колдонмосу жок же бузулгандыктан, жумуш профилиңиз жана ага байланыштуу дайындар өчүрүлдү. Жардам алуу үчүн администраторуңузга кайрылыңыз."</string>
+    <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Жумуш профилиңиз бул түзмөктөн өчүрүлдү"</string>
     <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Өтө көп жолу сырсөздү киргизүү аракети жасалды"</string>
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Админ түзмөктөн жеке колдонуу үчүн баш тартты"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Түзмөктү ишкана башкарат"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Ишканаңыз бул түзмөктү башкарат жана тармак трафигин көзөмөлдөшү мүмкүн. Чоо-жайын билгиңиз келсе, таптап коюңуз."</string>
+    <!-- no translation found for location_changed_notification_title (4119726617105166830) -->
+    <skip />
+    <!-- no translation found for location_changed_notification_text (198907268219396399) -->
+    <skip />
     <string name="factory_reset_warning" msgid="6858705527798047809">"Түзмөгүңүз тазаланат"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Түзмөктү башкаруучу колдонмо жараксыз. Түзмөгүңүз азыр тазаланат.\n\nСуроолоруңуз болсо, ишканаңыздын администраторуна кайрылыңыз."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Басып чыгаруу <xliff:g id="OWNER_APP">%s</xliff:g> тарабынан өчүрүлдү."</string>
@@ -429,6 +433,8 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Бул артыкчылыктуу | тутум колдонмосу тутумдун камерасын каалаган убакта колдонуп, сүрөткө тартып, видео жаздыра алат. Ошондой эле колдонмого android.permission.CAMERA уруксатын берүү керек."</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"титирөөнү башкаруу"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Колдонмого дирилдегичти көзөмөлдөө мүмкүнчүлүгүн берет."</string>
+    <!-- no translation found for permdesc_vibrator_state (7050024956594170724) -->
+    <skip />
     <string name="permlab_callPhone" msgid="1798582257194643320">"телефон номерлерине түз чалуу"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Колдонмого сиздин катышууңузсуз телефон номурларга чалуу уруксатын берет. Бул сиз күтпөгөн чыгымдарга же чалууларга алып келиши мүмкүн. Бул куткаруучулардын номурларына чалууга уруксат бербей тургандыгын эске алыңыз. Зыяндуу колдонмолор, сиздин ырастооңузсуз чалууларды аткарып, көп чыгымдарга себепкер болушу мүмкүн."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS чалуу кызматына мүмкүнчүлүк алуу"</string>
@@ -523,11 +529,11 @@
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Таанылган жок"</string>
     <string name="biometric_error_canceled" msgid="8266582404844179778">"Аныктыгын текшерүү жокко чыгарылды"</string>
     <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"PIN код, графикалык ачкыч же сырсөз коюлган жок"</string>
-    <string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Манжа изи жарым-жартылай аныкталды. Кайра аракет кылыңыз."</string>
-    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Манжа изи иштелбей койду. Кайра аракет кылыңыз."</string>
-    <string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Манжа изинин сенсору кирдеп калган. Тазалап, кайра аракет кылыңыз."</string>
-    <string name="fingerprint_acquired_too_fast" msgid="5151661932298844352">"Манжа өтө тез жылдырылды. Кайра аракет кылыңыз."</string>
-    <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Манжа өтө жай жылды. Кайра аракет кылыңыз."</string>
+    <string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Манжа изи жарым-жартылай аныкталды. Кайталап көрүңүз."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Манжа изи иштелбей койду. Кайталап көрүңүз."</string>
+    <string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Манжа изинин сенсору кирдеп калган. Тазалап, кайталап көрүңүз."</string>
+    <string name="fingerprint_acquired_too_fast" msgid="5151661932298844352">"Манжа өтө тез жылдырылды. Кайталап көрүңүз."</string>
+    <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Манжа өтө жай жылды. Кайталап көрүңүз."</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Манжа изи текшерилди"</string>
@@ -535,7 +541,7 @@
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Жүздүн аныктыгы текшерилди, эми \"Ырастоону\" басыңыз"</string>
     <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Манжа изинин аппараттык камсыздоосу жеткиликтүү эмес."</string>
     <string name="fingerprint_error_no_space" msgid="6126456006769817485">"Манжа изин сактоо мүмкүн эмес. Учурдагы манжа изин алып салыңыз."</string>
-    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Манжа изин күтүү мөөнөтү бүттү. Кайра аракет кылыңыз."</string>
+    <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Манжа изин күтүү мөөнөтү бүттү. Кайталап көрүңүз."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Манжа изи иш-аракети жокко чыгарылды."</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Манжа изи операциясын колдонуучу жокко чыгарды."</string>
     <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Аракеттер өтө көп болду. Бир аздан кийин кайталап көрүңүз."</string>
@@ -543,6 +549,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Кайра бир аракеттениңиз."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Бир да манжа изи катталган эмес."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бул түзмөктө манжа изинин сенсору жок."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>-манжа"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -554,7 +562,7 @@
     <string name="face_recalibrate_notification_name" msgid="6006095897989257026">"Жүзүнөн таануу"</string>
     <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Жүзүңүздү кайра таанытыңыз."</string>
     <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Мыкты таануу үчүн, жүзүңүздү кайра таанытыңыз"</string>
-    <string name="face_acquired_insufficient" msgid="2150805835949162453">"Жүзүңүз жакшы тартылган жок. Кайра аракет кылыңыз."</string>
+    <string name="face_acquired_insufficient" msgid="2150805835949162453">"Жүзүңүз жакшы тартылган жок. Кайталап көрүңүз."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Өтө жарык. Жарыктыкты азайтып көрүңүз."</string>
     <string name="face_acquired_too_dark" msgid="252573548464426546">"Өтө караңгы. Жарыгыраак жерден тартып көрүңүз."</string>
     <string name="face_acquired_too_close" msgid="1628767882971469833">"Телефонду алысыраак жылдырыңыз."</string>
@@ -567,7 +575,7 @@
     <string name="face_acquired_not_detected" msgid="2945945257956443257">"Телефонду жүзүңүздүн маңдайында кармаңыз."</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Кыймылдап жибердиңиз. Телефонду түз кармаңыз."</string>
     <string name="face_acquired_recalibrate" msgid="8724013080976469746">"Жүзүңүздү кайра таанытыңыз."</string>
-    <string name="face_acquired_too_different" msgid="4699657338753282542">"Жүз таанылган жок. Кайра аракет кылыңыз."</string>
+    <string name="face_acquired_too_different" msgid="4699657338753282542">"Жүз таанылган жок. Кайталап көрүңүз."</string>
     <string name="face_acquired_too_similar" msgid="7684650785108399370">"Мурункуга окшош болуп калды, башкача туруңуз."</string>
     <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Башыңызды бир аз гана эңкейтиңиз."</string>
     <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Башыңызды бир аз гана эңкейтиңиз."</string>
@@ -583,9 +591,11 @@
     <string name="face_error_user_canceled" msgid="8553045452825849843">"Жүзүнөн таануу функциясын колдонуучу өчүрүп салды."</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Өтө көп жолу аракет жасадыңыз. Бир аздан кийин кайталап көрүңүз."</string>
     <string name="face_error_lockout_permanent" msgid="8277853602168960343">"Өтө көп жолу аракет кылдыңыз. Жүзүнөн таануу функциясы өчүрүлдү."</string>
-    <string name="face_error_unable_to_process" msgid="5723292697366130070">"Жүз ырасталбай жатат. Кайра аракет кылыңыз."</string>
+    <string name="face_error_unable_to_process" msgid="5723292697366130070">"Жүз ырасталбай жатат. Кайталап көрүңүз."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Жүзүнөн таануу функциясын жөндөй элексиз."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Жүзүнөн таануу функциясы бул түзмөктө иштебейт."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Жүз <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -652,7 +662,7 @@
     <string name="policydesc_limitPassword" msgid="4105491021115793793">"Экран кулпусунун сырсөздөрү менен PIN\'дерине уруксат берилген узундук менен белгилерди көзөмөлдөө."</string>
     <string name="policylab_watchLogin" msgid="7599669460083719504">"Экран кулпусун ачуу аракеттерин көзөмөлдөө"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Экрандын кулпусу ачылып жатканда туура эмес терилген сырсөздөрдүн санын текшерип, эгер алардын саны өтө эле көп болсо, планшетти кулпулаңыз же планшеттеги бардык дайындарды тазалап салыңыз."</string>
-    <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Экрандын кулпусун ачуу учурунда сырсөздөр канча жолу туура эмес терилгенин тескөө жана сырсөз өтө көп жолу туура эмес терилген болсо, Android TV түзмөгүңүздү кулпулап же Android TV түзмөгүңүздөгү бардык дайындарыңызды тазалап салуу."</string>
+    <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Экрандын кулпусун ачуу учурунда сырсөздөр канча жолу туура эмес терилгенин тескөө жана сырсөз өтө көп жолу туура эмес терилген болсо, Android TV түзмөгүңүздү кулпулап же Android TV түзмөгүңүздөгү бардык дайын-даректериңизди тазалап салуу."</string>
     <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Экрандын кулпусу ачылып жатканда туура эмес терилген сырсөздөрдүн санын текшерип, эгер алардын саны өтө эле көп болсо, телефонду кулпулаңыз же телефондогу бардык дайындарды тазалап салыңыз."</string>
     <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Экрандын кулпусун ачуу учурунда туура эмес терилген сырсөздөрдү тескөө жана сырсөз өтө көп жолу туура эмес терилген болсо, планшетти кулпулап же бул колдонуучунун бардык дайындарын тазалап салуу."</string>
     <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Экрандын кулпусун ачуу учурунда сырсөздөр канча жолу туура эмес терилгенин тескөө жана сырсөз өтө көп жолу туура эмес терилген болсо, Android TV түзмөгүңүздү кулпулап же колдонуучунун бардык дайындарын тазалап салуу."</string>
@@ -840,7 +850,7 @@
     <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"Сырсөзүңүздү <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
     <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"PIN-кодуңузду <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"Кулпуну ачуу үлгүсүн <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу туура эмес тартсаңыз, планшетиңиздин кулпусун Google\'га кирип ачууга туура келет.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"Графикалык ачкычыңызды <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес чийдиңиз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> ийгиликсиз аракеттен кийин, Android TV түзмөгүңүздүн кулпусун Google аккаунтуңузга кирип ачышыңыз керек болот.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секунддан кийин кайра аракет кылыңыз."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"Графикалык ачкычыңызды <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес чийдиңиз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> ийгиликсиз аракеттен кийин, Android TV түзмөгүңүздүн кулпусун Google аккаунтуңузга кирип ачышыңыз керек болот.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секунддан кийин кайталап көрүңүз."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"Кулпуну ачуу үлгүсүн <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу туура эмес тартсаңыз, телефонуңуздун кулпусун Google\'га кирип ачууга туура келет.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"Сиз планшетиңизди бөгөттөн чыгарууга <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес аракет кылдыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> аракеттен кийин, планшет баштапкы абалына келтирилет жана бардык маалыматтар өчүрүлөт."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"Android TV түзмөгүңүздүн кулпусун <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес ачууга аракет жасадыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> ийгиликсиз аракеттен кийин, Android TV түзмөгүңүз демейки жөндөөлөргө кайтарылып, бардык колдонуучу дайындары жоголот."</string>
@@ -880,7 +890,7 @@
     <string name="keygaurd_accessibility_media_controls" msgid="2267379779900620614">"Медиа башкаруу"</string>
     <string name="keyguard_accessibility_widget_reorder_start" msgid="7066213328912939191">"Виджет иреттөө башталды."</string>
     <string name="keyguard_accessibility_widget_reorder_end" msgid="1083806817600593490">"Виджет иреттөө аяктады."</string>
-    <string name="keyguard_accessibility_widget_deleted" msgid="1509738950119878705">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> виждети жок кылынды."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="1509738950119878705">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> виждети өчүрүлдү."</string>
     <string name="keyguard_accessibility_expand_lock_area" msgid="4215280881346033434">"Бөгөттөн чыгаруу аймагын кеңейтүү."</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2968195219692413046">"Жылмыштырып ачуу."</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"Үлгү менен ачуу."</string>
@@ -1276,7 +1286,7 @@
     <string name="sms_short_code_remember_undo_instruction" msgid="2620984439143080410">"Муну кийин Тууралоолор &gt; Колдонмолордон өзгөртө аласыз"</string>
     <string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"Дайыма уруксат берүү"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="2688828813521652079">"Эч качан уруксат берилбесин"</string>
-    <string name="sim_removed_title" msgid="5387212933992546283">"SIM-карта алынып салынды"</string>
+    <string name="sim_removed_title" msgid="5387212933992546283">"SIM-карта өчүрүлдү"</string>
     <string name="sim_removed_message" msgid="9051174064474904617">"Сиз жарактуу SIM салып, кайра иштетмейинче, мобилдик тармак жеткиликсиз болот."</string>
     <string name="sim_done_button" msgid="6464250841528410598">"Даяр"</string>
     <string name="sim_added_title" msgid="7930779986759414595">"SIM-карта кошулду"</string>
@@ -1348,7 +1358,7 @@
     <string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> колдоого алынбайт"</string>
     <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Бул түзмөктө <xliff:g id="NAME">%s</xliff:g> колдоого алынбайт. Колдоого алынуучу форматта орнотуу үчүн таптап коюңуз."</string>
     <string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Бул түзмөктө <xliff:g id="NAME">%s</xliff:g> колдоого алынбайт. Колдоого алынуучу форматта орнотуу үчүн тандаңыз."</string>
-    <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> күтүүсүздөн алынып салынды"</string>
+    <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> күтүүсүздөн өчүрүлдү"</string>
     <string name="ext_media_badremoval_notification_message" msgid="1986514704499809244">"Мазмунду жоготуп албаш үчүн алып салуудан мурда медианы өчүрүңүз"</string>
     <string name="ext_media_nomedia_notification_title" msgid="742671636376975890">"<xliff:g id="NAME">%s</xliff:g> чыгарылды"</string>
     <string name="ext_media_nomedia_notification_message" msgid="2832724384636625852">"Айрым функциялар талаптагыдай иштебей калышы мүмкүн. Жаңы сактагычты салыңыз."</string>
@@ -1607,14 +1617,15 @@
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"Android TV түзмөгүңүздүн кулпусун <xliff:g id="NUMBER">%d</xliff:g> жолу туура эмес ачууга аракет жасадыңыз. Android TV түзмөгүңүз эми демейки жөндөөлөргө кайтарылат."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"Сиз телефонуңузду <xliff:g id="NUMBER">%d</xliff:g> жолу ийгиликсиз бөгөттөн чыгаруу аракетин кылдыңыз. Телефон баштапкы абалына кайтарылат."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"Графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес көрсөттүңүз. <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу туура эмес көрсөтүлгөндөн кийин, планшетиңиздин кулпусун ачуу үчүн Google аккаунтуңузга кирүүгө туура келет.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> секундадан кийин кайталап көрсөңүз болот."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"Графикалык ачкычыңызды <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес чийдиңиз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> ийгиликсиз аракеттен кийин, Android TV түзмөгүңүздүн кулпусун электрондук почта аккаунтуңуз менен ачышыңыз керек болот.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секунддан кийин кайра аракет кылыңыз."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"Графикалык ачкычыңызды <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес чийдиңиз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> ийгиликсиз аракеттен кийин, Android TV түзмөгүңүздүн кулпусун электрондук почта аккаунтуңуз менен ачышыңыз керек болот.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секунддан кийин кайталап көрүңүз."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес көрсөттүңүз. <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу туура эмес көрсөтүлгөндөн кийин, телефондун кулпусун ачуу үчүн Google аккаунтуңузга кирүүгө туура келет.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> секундадан кийин кайталап көрсөңүз болот."</string>
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Алып салуу"</string>
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Фондогу <xliff:g id="PACKAGENAME">%1$s</xliff:g> кызматы активдүү режимде иштеп баштап, кийинки R курамаларында колдонуу учурунда уруксаты болбойт. Төмөнкү бөлүмгө өтүп, мүчүлүштүк тууралуу кабарды тапшырыңыз: go/r-bg-fgs-restriction."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Сунушталган деңгээлден да катуулатып уккуңуз келеби?\n\nМузыканы узакка чейин катуу уксаңыз, угууңуз начарлап кетиши мүмкүн."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Ыкчам иштетесизби?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Атайын мүмкүнчүлүктөр функциясын пайдалануу үчүн, ал күйгүзүлгөндө, үндү катуулатып/акырындаткан эки баскычты тең үч секунддай кое бербей басып туруңуз.\n\n Учурдагы атайын мүмкүнчүлүктөрдүн жөндөөлөрү:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\nЖөндөөлөр &gt; Атайын мүмкүнчүлүктөр бөлүмүнөн өзгөртө аласыз."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Кыска жолдорду түзөтүү"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Жокко чыгаруу"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Кыска жолду өчүрүү"</string>
@@ -1735,7 +1746,7 @@
       <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> секунддан кийин кайталаңыз</item>
       <item quantity="one">1 секунддан кийин кайталаңыз</item>
     </plurals>
-    <string name="restr_pin_try_later" msgid="5897719962541636727">"Кийинчерээк кайталаңыз"</string>
+    <string name="restr_pin_try_later" msgid="5897719962541636727">"Бир аздан кийин кайталап көрүңүз"</string>
     <string name="immersive_cling_title" msgid="2307034298721541791">"Толук экран режими"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Чыгуу үчүн экранды ылдый сүрүп коюңуз."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Түшүндүм"</string>
@@ -1948,11 +1959,11 @@
     <string name="harmful_app_warning_title" msgid="8794823880881113856">"Зыянкеч колдонмо аныкталды"</string>
     <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> колдонмосу <xliff:g id="APP_2">%2$s</xliff:g> үлгүлөрүн көрсөткөнү жатат"</string>
     <string name="screenshot_edit" msgid="7408934887203689207">"Түзөтүү"</string>
-    <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Чалуулар менен эскертмелер дирилдөө режиминде иштейт"</string>
+    <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Чалуулар менен билдирмелер дирилдөө режиминде иштейт"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Чалуулар менен эскертмелердин үнү өчүрүлөт"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Тутум өзгөрүүлөрү"</string>
     <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Тынчымды алба"</string>
-    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Жаңы: \"Тынчымды алба\" режими эскертмелерди жашырууда"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Жаңы: \"Тынчымды алба\" режими билдирмелерди жашырууда"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Көбүрөөк маалымат алып, өзгөртүү үчүн таптаңыз."</string>
     <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\"Тынчымды алба\" режими өзгөрдү"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Бөгөттөлгөн нерселерди көрүү үчүн таптаңыз."</string>
@@ -2010,4 +2021,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ЧЕКТЕЛГЕН чакага коюлган"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Жеке"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Жумуш"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index e8bda53..ce17258 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"ອຸປະກອນທີ່ຍົກເລີກແລ້ວສຳລັບການໃຊ້ສ່ວນບຸກຄົນ"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"ອຸປະກອນມີການຈັດການ"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"ອົງກອນຂອງທ່ານຈັດການອຸປະກອນນີ້ ແລະ ອາດກວດສອບທຣາບຟິກເຄືອຂ່າຍນຳ. ແຕະເພື່ອເບິ່ງລາຍລະອຽດ."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"ຜູ້ເບິ່ງແຍງຂອງທ່ານປ່ຽນການຕັ້ງຄ່າສະຖານທີ່ແລ້ວ"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"ແຕະເພື່ອເບິ່ງການຕັ້ງຄ່າສະຖານທີ່ຂອງທ່ານ."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"ອຸ​ປະ​ກອນ​ຂອງ​ທ່ານ​ຈະ​ຖືກ​ລຶບ"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"ບໍ່ສາມາດໃຊ້ແອັບຜູ້ເບິ່ງແຍງລະບົບໄດ້. ອຸປະກອນຂອງທ່ານຈະຖືກລຶບຂໍ້ມູນໃນຕອນນີ້.\n\nຫາກທ່ານມີຄຳຖາມ, ໃຫ້ຕິດຕໍ່ຜູ້ເບິ່ງແຍງລະບົບອົງກອນຂອງທ່ານ."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"ການພິມຖືກປິດໄວ້ໂດຍ <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"ສິດນີ້ | ແອັບລະບົບສາມາດຖ່າຍຮູບ ແລະ ບັນທຶກວິດີໂອໄດ້ໂດຍໃຊ້ກ້ອງຂອງລະບົບຕອນໃດກໍໄດ້. ຕ້ອງໃຊ້ສິດອະນຸຍາດ android.permission.CAMERA ໃຫ້ແອັບຖືນຳ"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"ຄວບຄຸມການສັ່ນ"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"ອະນຸຍາດໃຫ້ແອັບຯຄວບຄຸມໂຕສັ່ນ."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"ອະນຸຍາດໃຫ້ແອັບເຂົ້າເຖິງສະຖານະການສັ່ນໄດ້."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ໂທຫາເບີໂທລະສັບໂດຍກົງ"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"ອະນຸຍາດໃຫ້ແອັບຯໂທຫາເບີໂທລະສັບໄດ້ ໂດຍບໍ່ຕ້ອງຖ້າການດຳເນີນການໃດໆຈາກທ່ານ. ຄຸນສົມບັດນີ້ອາດກໍ່ໃຫ້ເກີດຄ່າໃຊ້ຈ່າຍໃນການໂທທີ່ບໍ່ຄາດຄິດໄດ້. ໝາຍເຫດ: ຄຸນສົມບັດນີ້ບໍ່ໄດ້ເປັນການອະນຸຍາດໃຫ້ແອັບຯ ສາມາດໂທຫາເບີສຸກເສີນ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດເຮັດໃຫ້ທ່ານ ຕ້ອງເສຍຄ່າໂທໂດຍທີ່ບໍ່ໄດ້ຄາດຄິດ."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"ເຂົ້າ​ຫາ​ການ​ບໍ​ລິ​ການ​ໂທ IMS"</string>
@@ -543,6 +546,7 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"ລອງໃໝ່ອີກຄັ້ງ."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ບໍ່ມີການລົງທະບຽນລາຍນິ້ວມື."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ອຸປະກອນນີ້ບໍ່ມີເຊັນເຊີລາຍນິ້ວມື."</string>
+    <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ປິດການເຮັດວຽກຂອງເຊັນເຊີໄວ້ຊົ່ວຄາວແລ້ວ."</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ນີ້ວ​ມື <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +590,7 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"ບໍ່ສາມາດຢັ້ງຢືນໃບໜ້າໄດ້. ກະລຸນາລອງໃໝ່."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"ທ່ານຍັງບໍ່ໄດ້ຕັ້ງການປົດລັອກດ້ວຍໜ້າເທື່ອ."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"ບໍ່ຮອງຮັບການປົດລັອກດ້ວຍໜ້າຢູ່ອຸປະກອນນີ້."</string>
+    <string name="face_error_security_update_required" msgid="5076017208528750161">"ປິດການເຮັດວຽກຂອງເຊັນເຊີໄວ້ຊົ່ວຄາວແລ້ວ."</string>
     <string name="face_name_template" msgid="3877037340223318119">"ໃບໜ້າ <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1619,7 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"ບໍລິການພື້ນໜ້າທີ່ເລີ່ມຕົ້ນຈາກພື້ນຫຼັງຈາກ <xliff:g id="PACKAGENAME">%1$s</xliff:g> ຈະບໍ່ມີສິດອະນຸຍາດໃນຂະນະທີ່ໃຊ້ໃນ R builds ໃນອະນາຄົດ. ກະລຸນາອ່ານ go/r-bg-fgs-restriction ແລະ ລາຍງານຂໍ້ຜິດພາດ."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ເພີ່ມ​ລະ​ດັບ​ສຽງ​ໃຫ້​ເກີນກວ່າ​ລະ​ດັບ​ທີ່​ແນະ​ນຳ​ບໍ?\n\n​ການ​ຮັບ​ຟັງ​ສຽງ​ໃນ​ລະ​ດັບ​ທີ່​ສູງ​ເປັນ​ໄລ​ຍະ​ເວ​ລາ​ດົນ​​ອາດ​ເຮັດ​ໃຫ້​ການ​ຟັງ​ຂອງ​ທ່ານ​ມີ​ບັນ​ຫາ​ໄດ້."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ໃຊ້ປຸ່ມລັດການຊ່ວຍເຂົ້າເຖິງບໍ?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"ເມື່ອເປີດໃຊ້ປຸ່ມລັດແລ້ວ, ໃຫ້ກົດປຸ່ມສຽງທັງສອງຄ້າງໄວ້ 3 ວິນາທີເພື່ອເລີ່ມຄຸນສົມບັດການຊ່ວຍເຂົ້າເຖິງ.\n\n ຄຸນສົມບັດການຊ່ວຍເຂົ້າເຖິງປັດຈຸບັນ:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n ທ່ານສາມາດປ່ຽນຄຸນສົມບັດໄດ້ໃນການຕັ້ງຄ່າ &gt; ການຊ່ວຍເຂົ້າເຖິງ."</string>
+    <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"ເມື່ອເປີດໃຊ້ທາງລັດແລ້ວ, ການກົດປຸ່ມລະດັບສຽງທັງສອງຄ້າງໄວ້ 3 ວິນາທີຈະເປັນການເລີ່ມຄຸນສົມບັດການຊ່ວຍເຂົ້າເຖິງ."</string>
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"ແກ້ໄຂທາງລັດ"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"ຍົກເລີກ"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ປິດປຸ່ມລັດ"</string>
@@ -2010,4 +2015,12 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ຖືກວາງໄວ້ໃນກະຕ່າ \"ຈຳກັດ\" ແລ້ວ"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"ສ່ວນຕົວ"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"ວຽກ"</string>
+    <string name="resolver_cant_share_with_work_apps" msgid="7539495559434146897">"ບໍ່ສາມາດແບ່ງປັນກັບແອັບວຽກໄດ້"</string>
+    <string name="resolver_cant_share_with_personal_apps" msgid="8020581735267157241">"ບໍ່ສາມາດແບ່ງປັນກັບແອັບສ່ວນຕົວໄດ້"</string>
+    <string name="resolver_cant_share_cross_profile_explanation" msgid="3536237105241882679">"ຜູ້ເບິ່ງແຍງໄອທີຂອງທ່ານບລັອກການແບ່ງປັນລະຫວ່າງແອັບສ່ວນຕົວ ແລະ ແອັບວຽກໄວ້"</string>
+    <string name="resolver_turn_on_work_apps" msgid="8987359079870455469">"ປຸ່ມເປີດຢູ່ແອັບວຽກ"</string>
+    <string name="resolver_turn_on_work_apps_explanation" msgid="6322467455509618928">"ເປີດໃຊ້ແອັບວຽກເພື່ອເຂົ້າເຖິງແອັບ ແລະ ລາຍຊື່ຜູ້ຕິດຕໍ່ວຽກ"</string>
+    <string name="resolver_no_apps_available" msgid="7710339903040989654">"ບໍ່ມີແອັບທີ່ສາມາດໃຊ້ໄດ້"</string>
+    <string name="resolver_no_apps_available_explanation" msgid="4662694431121196560">"ພວກເຮົາບໍ່ພົບແອັບໃດໆເລີຍ"</string>
+    <string name="resolver_switch_on_work" msgid="8294542702883688533">"ປຸ່ມເປີດຢູ່ວຽກ"</string>
 </resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index ad90ab3..2c7e96b 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -195,6 +195,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administratorius atmetė prašymą įrenginį naudoti asmeniniais tikslais"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Įrenginys yra tvarkomas"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Šį įrenginį tvarko organizacija ir gali stebėti tinklo srautą. Palieskite, kad gautumėte daugiau informacijos."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Vietovės nustatymus pakeitė administratorius"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Palieskite, kad peržiūrėtumėte vietovės nustatymus."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Įrenginys bus ištrintas"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Administratoriaus programos negalima naudoti. Dabar įrenginio duomenys bus ištrinti.\n\nJei turite klausimų, susisiekite su organizacijos administratoriumi."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Neleidžiama spausdinti (<xliff:g id="OWNER_APP">%s</xliff:g>)."</string>
@@ -435,6 +437,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Ši privilegijuota | sistemos programa gali daryti nuotraukas ir įrašyti vaizdo įrašus naudodama sistemos fotoaparatą bet kuriuo metu. Programai taip pat būtinas leidimas „android.permission.CAMERA“"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"valdyti vibraciją"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Leidžiama programai valdyti vibravimą."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Programai leidžiama pasiekti vibratoriaus būseną."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"skambinti tiesiogiai telefono numeriais"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Leidžiama programai skambinti telefonų numeriais be jūsų įsikišimo. Dėl to gali atsirasti nenumatytų apmokestinimų ar skambučių. Atminkite, kad programai neleidžiama skambinti pagalbos telefonų numeriais. Kenkėjiškos programos gali skambinti be jūsų patvirtinimo, o dėl to jums gali būti taikomi mokesčiai."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"pasiekti IMS skambučių paslaugą"</string>
@@ -549,6 +552,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Bandykite dar kartą."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Neužregistruota jokių kontrolinių kodų."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Šiame įrenginyje nėra kontrolinio kodo jutiklio."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> pirštas"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -592,6 +597,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Nepavyko patvirtinti veido. Bandykite dar kartą."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Nenustatėte Atrakinimo pagal veidą."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Atrakinimas pagal veidą šiame įrenginyje nepalaikomas."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"<xliff:g id="FACEID">%d</xliff:g> veidas"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1658,7 +1665,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Fone pradėtai priekinio plano paslaugai iš „<xliff:g id="PACKAGENAME">%1$s</xliff:g>“ nebus suteiktas leidimas naudojimo metu būsimose R versijose. Apsilankykite go/r-bg-fgs-restriction ir pateikite pranešimą apie riktą."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Padidinti garsą daugiau nei rekomenduojamas lygis?\n\nIlgai klausydami dideliu garsu galite pažeisti klausą."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Naudoti spartųjį pritaikymo neįgaliesiems klavišą?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Kai spartusis klavišas įjungtas, spaudžiant abu garsumo mygtukus 3 sekundes bus paleista pritaikymo neįgaliesiems funkcija.\n\n Dabartinė pritaikymo neįgaliesiems funkcija:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>„\n“\n Funkciją galite pakeisti skiltyje „Nustatymai“ &gt; „Pritaikymas neįgaliesiems“."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Redaguoti sparčiuosius klavišus"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Atšaukti"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Išjungti spartųjį klavišą"</string>
@@ -2078,4 +2086,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"„<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>“ įkeltas į grupę APRIBOTA"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Asmeninė"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Darbo"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 6ffe39a..8614214 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -193,6 +193,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrators atteicās no tādas ierīces pārvaldības, ko var izmantot personiskām vajadzībām"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Ierīce tiek pārvaldīta"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Jūsu organizācija pārvalda šo ierīci un var uzraudzīt tīkla datplūsmu. Pieskarieties, lai saņemtu detalizētu informāciju."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Atrašanās vietas iestatījumus nomainīja administrators"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Pieskarieties, lai skatītu atrašanās vietas iestatījumus."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Jūsu ierīces dati tiks dzēsti"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Administratora lietotni nevar izmantot. Ierīcē saglabātie dati tiks dzēsti.\n\nJa jums ir kādi jautājumi, sazinieties ar savas organizācijas administratoru."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Drukāšanu atspējoja <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -432,6 +434,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Šī privileģētā/sistēmas lietotne var jebkurā brīdī uzņemt attēlus un ierakstīt videoklipus, izmantojot sistēmas kamerus. Lietotnei nepieciešama arī atļauja android.permission.CAMERA."</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"kontrolēt vibrosignālu"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Ļauj lietotnei kontrolēt vibrosignālu."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Ļauj lietotnei piekļūt vibrosignāla statusam."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"tieši zvanīt uz tālruņa numuriem"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Ļauj lietotnei zvanīt uz tālruņa numuriem bez jūsu iejaukšanās. Tas var radīt neparedzētas izmaksas vai zvanus. Ņemiet vērā, ka lietotnei nav atļauts zvanīt uz tālruņa numuriem ārkārtas situācijām. Ļaunprātīgas lietotnes var radīt jums izmaksas, veicot zvanus bez jūsu apstiprinājuma."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"piekļūt tūlītējās ziņojumapmaiņas pakalpojumam, lai veiktu zvanus"</string>
@@ -546,6 +549,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Mēģiniet vēlreiz."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nav reģistrēts neviens pirksta nospiedums."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Šajā ierīcē nav pirksta nospieduma sensora."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. pirksts"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -589,6 +594,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Nevar verificēt seju. Mēģiniet vēlreiz."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Autorizācija pēc sejas nav iestatīta."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Autorizācija pēc sejas šajā ierīcē netiek atbalstīta"</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Seja <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1636,7 +1643,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Fonā sāktam priekšplāna pakalpojumam no pakotnes <xliff:g id="PACKAGENAME">%1$s</xliff:g> nebūs atļaujas “while-in-use” turpmākajās R versijās. Lūdzu, skatiet vietni go/r-bg-fgs-restriction un iesniedziet kļūdas pārskatu."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vai palielināt skaļumu virs ieteicamā līmeņa?\n\nIlgstoši klausoties skaņu lielā skaļumā, var tikt bojāta dzirde."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Vai izmantot pieejamības saīsni?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Ja saīsne ir iespējota, vienlaikus nospiežot abas skaļuma regulēšanas pogas un trīs sekundes turot tās, tiks palaista pieejamības funkcija.\n\n Pašreiz iestatītā pieejamības funkcija:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Šo funkciju var mainīt sadaļā Iestatījumi &gt; Pieejamība."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Rediģēt īsinājumtaustiņus"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Atcelt"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Izslēgt saīsni"</string>
@@ -2044,4 +2052,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Pakotne “<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>” ir ievietota ierobežotā kopā."</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Privātais profils"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Darba profils"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index bb1d9c6..a80779c 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Уред откажан од администраторот за лична употреба"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Некој управува со уредот"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Вашата организација управува со уредов и можно е да го следи сообраќајот на мрежата. Допрете за детали."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Администраторот ги променил поставките за локација"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Допрете за да ги видите поставките за локација."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Уредот ќе се избрише"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Апликацијата на администраторот не може да се користи. Уредот ќе се избрише сега.\n\nАко имате прашања, контактирајте со администраторот на организацијата."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Печатењето е оневозможено од <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Оваа привилегирана | системска апликација може да фотографира и да снима видеа со системската камера во секое време. Потребно е апликацијата да ја има и дозволата android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"контролирај вибрации"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Дозволува апликацијата да ги контролира вибрациите."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Ѝ дозволува на апликацијата да пристапи до состојбата на вибрации."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"директно избирај телефонски броеви"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Овозможува апликацијата да повикува телефонски броеви без ваша интервенција. Ова може да предизвика неочекувани трошоци или повици. Имајте на ум дека ова не дозволува апликацијата да повикува броеви на служби за итна помош. Злонамерните апликации може да ве чинат пари поради повици без ваша потврда."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"пристапи до услугата за повици IMS"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Обидете се повторно."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Не се запишани отпечатоци."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Уредов нема сензор за отпечатоци."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Ликот не може да се потврди. Обидете се повторно."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Не сте поставиле „Отклучување со лик“."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"„Отклучувањето со лик“ не е поддржано на уредов."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Лице <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1616,7 +1623,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Услугата од преден план започната во заднина од <xliff:g id="PACKAGENAME">%1$s</xliff:g> нема да има дозола за „додека се користи“ во идните R-верзии. Погледнете на go/r-bg-fgs-restriction и испратете извештај за грешка."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Да го зголемиме звукот над препорачаното ниво?\n\nСлушањето звуци со голема јачина подолги периоди може да ви го оштети сетилото за слух."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Да се користи кратенка за „Пристапност“?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Кога е вклучена кратенката, ако ги притиснете двете копчиња за јачина на звук во времетраење од 3 секунди, ќе се стартува функција на пристапност.\n\n Тековна функција на пристапност:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Функцијата може да ја промените во „Поставки“ &gt; „Пристапност“."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Изменете ги кратенките"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Откажи"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Исклучи ја кратенката"</string>
@@ -2012,4 +2020,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> е ставен во корпата ОГРАНИЧЕНИ"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Лични"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Службени"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 31edd8c..ccc6b31 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -191,6 +191,10 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"വ്യക്തിപരമായ ഉപയോഗത്തിനായി, ഉപകരണത്തിന്റെ ഔദ്യോഗിക ഉപയോഗം അഡ്‌മിൻ അവസാനിപ്പിച്ചു"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"ഉപകരണം മാനേജുചെയ്യുന്നുണ്ട്"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"നിങ്ങളുടെ സ്ഥാപനമാണ് ഈ ഉപകരണം മാനേജുചെയ്യുന്നത്, നെറ്റ്‌വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിക്കുകയും ചെയ്തേക്കാം, വിശദാംശങ്ങൾ അറിയാൻ ടാപ്പുചെയ്യുക."</string>
+    <!-- no translation found for location_changed_notification_title (4119726617105166830) -->
+    <skip />
+    <!-- no translation found for location_changed_notification_text (198907268219396399) -->
+    <skip />
     <string name="factory_reset_warning" msgid="6858705527798047809">"നിങ്ങളുടെ ഉപകരണം മായ്‌ക്കും"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"അഡ്‌മിൻ ആപ്പ് ഉപയോഗിക്കാനാകില്ല. നിങ്ങളുടെ ഉപകരണം ഇപ്പോൾ മായ്ക്കപ്പെടും.\n\nനിങ്ങൾക്ക് ചോദ്യങ്ങൾ ഉണ്ടെങ്കിൽ, നിങ്ങളുടെ സ്ഥാപനത്തിന്റെ അഡ്‌മിനെ ബന്ധപ്പെടുക."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> പ്രിന്റിംഗ് പ്രവർത്തനരഹിതമാക്കി."</string>
@@ -429,6 +433,8 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"സിസ്‌റ്റം ക്യാമറ ഉപയോഗിച്ച് ഏത് സമയത്തും ചിത്രങ്ങളെടുക്കാനും വീഡിയോകൾ റെക്കോർഡ് ചെയ്യാനും ഈ വിശേഷാധികാര | സിസ്‌റ്റം ആപ്പിന് കഴിയും. ആപ്പിലും android.permission.CAMERA അനുമതി ഉണ്ടായിരിക്കണം"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"വൈബ്രേറ്റുചെയ്യൽ നിയന്ത്രിക്കുക"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"വൈബ്രേറ്റർ നിയന്ത്രിക്കുന്നതിന് അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
+    <!-- no translation found for permdesc_vibrator_state (7050024956594170724) -->
+    <skip />
     <string name="permlab_callPhone" msgid="1798582257194643320">"ഫോൺ നമ്പറുകളിലേക്ക് നേരിട്ട് വിളിക്കുക"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"നിങ്ങളുടെ ഇടപെടൽ ഇല്ലാതെ ഫോൺ നമ്പറുകളിലേക്ക് കോൾ ചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഇത് അപ്രതീക്ഷിത നിരക്കുകൾക്കോ കോളുകൾക്കോ ഇടയാക്കാം. ഇത് അടിയന്തര നമ്പറുകളിലേക്ക് വിളിക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കില്ലെന്ന കാര്യം ശ്രദ്ധിക്കുക. ക്ഷുദ്രകരമായ അപ്ലിക്കേഷനുകൾ നിങ്ങളുടെ സ്ഥിരീകരണമില്ലാതെ കോളുകൾ ചെയ്യുന്നത് പണച്ചെലവിനിടയാക്കാം."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS കോൾ സേവനം ആക്സസ് ചെയ്യുക"</string>
@@ -543,6 +549,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"വീണ്ടും ശ്രമിക്കൂ."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"വിരലടയാളങ്ങൾ എൻറോൾ ചെയ്തിട്ടില്ല."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ഈ ഉപകരണത്തിൽ ഫിംഗർപ്രിന്റ് സെൻസറില്ല."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"കൈവിരൽ <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +594,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"മുഖം പരിശോധിക്കാൻ കഴിയില്ല. വീണ്ടും ശ്രമിക്കൂ."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"മുഖം തിരിച്ചറിഞ്ഞുള്ള അൺലോക്ക് സജ്ജീകരിച്ചില്ല."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"മുഖം തിരിച്ചറിഞ്ഞുള്ള അൺലോക്ക് ഈ ഉപകരണം പിന്തുണയ്ക്കുന്നില്ല."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"മുഖം <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1624,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> എന്നതിൽ നിന്നുള്ള പശ്ചാത്തലത്തിൽ ആരംഭിച്ച് ഫോർഗ്രൗണ്ടിൽ വരുന്ന സേവനത്തിന് ഭാവി R ബിൽഡുകളിൽ, \'ഉപയോഗിക്കുമ്പോൾ മാത്രമുള്ള അനുമതി\' ഉണ്ടായിരിക്കില്ല. go/r-bg-fgs-restriction കണ്ട് ബഗ് റിപ്പോർട്ട് ഫയൽ ചെയ്യുക."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"മുകളിൽക്കൊടുത്തിരിക്കുന്ന ശുപാർശചെയ്‌ത ലെവലിലേക്ക് വോളിയം വർദ്ധിപ്പിക്കണോ?\n\nഉയർന്ന വോളിയത്തിൽ ദീർഘനേരം കേൾക്കുന്നത് നിങ്ങളുടെ ശ്രവണ ശേഷിയെ ദോഷകരമായി ബാധിക്കാം."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ഉപയോഗസഹായി കുറുക്കുവഴി ഉപയോഗിക്കണോ?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"കുറുക്കുവഴി ഓണാണെങ്കിൽ, രണ്ട് വോളിയം ബട്ടണുകളും 3 സെക്കൻഡ് നേരത്തേക്ക് അമർത്തുന്നത് ഉപയോഗസഹായി ഫീച്ചർ ആരംഭിക്കും.\n\n നിലവിലെ  ഉപയോഗസഹായി ഫീച്ചർ:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n ക്രമീകരണം &gt; ഉപയോഗസഹായി എന്നതിൽ ഏത് സമയത്തും നിങ്ങൾക്ക് ഫീച്ചർ മാറ്റാവുന്നതാണ്."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"കുറുക്കുവഴികൾ തിരുത്തുക"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"റദ്ദാക്കുക"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"കുറുക്കുവഴി ‌ഓഫാക്കുക"</string>
@@ -2010,4 +2021,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> നിയന്ത്രിത ബക്കറ്റിലേക്ക് നീക്കി"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"വ്യക്തിപരമായത്"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"ജോലിസ്ഥലം"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index eb61a46..a21f6ec 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Админ хувийн хэрэглээнд зориулж төхөөрөмжийн эрхийг хассан"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Төхөөрөмжийг удирдсан"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Таны байгууллага энэ төхөөрөмжийг удирдаж, сүлжээний ачааллыг хянадаг. Дэлгэрэнгүй мэдээлэл авах бол товшино уу."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Таны админ байршлын тохиргоог өөрчилсөн байна"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Байршлын тохиргоогоо харахын тулд товшино уу."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Таны төхөөрөмж устах болно."</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Админ аппыг ашиглах боломжгүй. Таны төхөөрөмжийг одоо устгана.\n\nХэрэв танд асуулт байгаа бол байгууллагынхаа админтай холбогдоно уу."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> хэвлэх үйлдлийг идэвхгүй болгосон."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Энэ хамгаалагдсан | системийн апп нь системийн камер ашиглан ямар ч үед зураг авж, видео бичих боломжтой. Аппыг ашиглахын тулд android.permission.CAMERA-н зөвшөөрөл мөн шаардлагатай"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"чичиргээг удирдах"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Апп нь чичиргээг удирдах боломжтой."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Аппыг чичиргээний төлөвт хандахыг зөвшөөрдөг."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"утасны дугаарт шууд дуудлага хийх"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Апп нь таны оролцоогүйгээр дуудлага хийх боломжтой. Энэ нь төлөвлөгдөөгүй төлбөрт оруулах эсвэл дуудлага хийнэ. Энэ нь апп-г яаралтай дугаарт дуудлага хийхйг зөвшөөрөхгүй. Хортой апп нь таны зөвшөөрөлгүйгээр дуудлага хийж таныг төлбөрт оруулж болзошгүй"</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS дуудлагын үйлчилгээнд хандах"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Дахин оролдно уу."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Бүртгүүлсэн хурууны хээ алга."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Энэ төхөөрөмжид хурууны хээ мэдрэгч алга."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Хурууны хээ <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Царайг бататгаж чадсангүй. Дахин оролдоно уу."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Та царайгаар тайлахыг тохируулаагүй байна."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Царайгаар тайлахыг энэ төхөөрөмж дээр дэмждэггүй."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Царай <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>-н дэлгэц дээрх үйлчилгээг эхлүүлдэг дэвсгэр нь цаашид R хийцийн ашиглах үеийн зөвшөөрөлгүй болно. go/r-bg-fgs-restriction-г үзэж, алдааны мэдээ илгээнэ үү."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Дууг санал болгосноос чанга болгож өсгөх үү?\n\nУрт хугацаанд чанга хөгжим сонсох нь таны сонсголыг муутгаж болно."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Хүртээмжийн товчлолыг ашиглах уу?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Товчлолыг асаасан үед дуун товчлуурыг 3 секунд дарснаар хүртээмжийн онцлогийг эхлүүлнэ.\n\n Одоогийн хүртээмжийн онцлог:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Онцлогийг Тохиргоо &gt; Хүртээмж хэсэгт өөрчлөх боломжтой."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Товчлолуудыг засах"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Болих"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Товчлолыг унтраах"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>-г ХЯЗГААРЛАСАН сагс руу орууллаа"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Хувийн"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Ажил"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 0a8f4af..5f392af 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"वैयक्तिक वापरासाठी ॲडमिनने नियंत्रण सोडलेले डिव्हाइस"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"डिव्हाइस व्यवस्थापित केले आहे"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"तुमची संस्था हे डिव्हाइस व्यवस्थापित करते आणि नेटवर्क रहदारीचे निरीक्षण करू शकते. तपशीलांसाठी टॅप करा."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"तुमच्या ॲडमिनने स्थान सेटिंग्ज बदलल्या आहेत"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"तुमची स्थान सेटिंग्ज पाहण्यासाठी टॅप करा."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"तुमचे डिव्हाइस मिटविले जाईल"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"प्रशासक अ‍ॅप वापरता येणार नाही. तुमचे डिव्हाइस आता साफ केले जाईल.\n\nतुम्हाला कुठलेही प्रश्न असल्यास, तुमच्या संस्थेच्या प्रशासकाशी संपर्क साधा."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> नी प्रिंट करणे बंद केले आहे."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"हे विशेषाधिकृत आहे | सिस्टम ॲप कधीही सिस्टम कॅमेरा वापरून फोटो आणि व्हिडिओ रेकॉर्ड करू शकते. ॲपला android.permission.CAMERA परवानगी देण्याचीदेखील आवश्यकता आहे"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"व्हायब्रेट नियंत्रित करा"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"अ‍ॅप ला व्हायब्रेटर नियंत्रित करण्यासाठी अनुमती देते."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"अ‍ॅपला व्हायब्रेटर स्थितीचा अ‍ॅक्सेस करण्याची अनुमती देते."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"फोन नंबरवर प्रत्यक्ष कॉल करा"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"आपल्या हस्तक्षेपाशिवाय फोन नंबरवर कॉल करण्यासाठी अ‍ॅप ला अनुमती देते. यामुळे अनपेक्षित शुल्क किंवा कॉल लागू शकतात. लक्षात ठेवा की हे आणीबाणीच्या नंबरवर कॉल करण्यासाठी अ‍ॅप ला अनुमती देत नाही. दुर्भावनापूर्ण अ‍ॅप्स नी आपल्या पुष्टिकरणाशिवाय कॉल केल्यामुळे तुमचे पैसे खर्च होऊ शकतात."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS कॉल सेवा अ‍ॅक्सेस करा"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"पुन्हा प्रयत्न करा."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"कोणत्याही फिंगरप्रिंटची नोंद झाली नाही"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"या डिव्हाइसमध्ये फिंगरप्रिंट सेन्सर नाही."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> बोट"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"चेहरा पडताळणी करू शकत नाही. पुन्हा प्रयत्न करा."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"तुम्ही फेस अनलॉक सेट केले नाही."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"या डिव्हाइसवर फेस अनलॉकला सपोर्ट नाही."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"चेहरा <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> कडून बॅकग्राउंडने फोरग्राउंडमध्ये सुरू केलेल्या सेवेला भविष्यातील आर बिल्डमध्ये वापर करते वेळची परवानगी नसेल. कृपया go/r-bg-fgs-restriction पहा आणि बगची तक्रार नोंदवा."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"शिफारस केलेल्‍या पातळीच्या वर आवाज वाढवायचा?\n\nउच्च आवाजात दीर्घ काळ ऐकण्‍याने आपल्‍या श्रवणशक्तीची हानी होऊ शकते."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"प्रवेशयोग्यता शॉर्टकट वापरायचा?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"शॉर्टकट चालू असताना, दोन्ही आवाज बटणे 3 सेकंद दाबल्याने प्रवेशयोग्यता वैशिष्ट्य सुरू होईल.\n\n वर्तमान प्रवेशयोग्यता वैशिष्ट्य:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n तुम्ही सेटिंग्ज &gt; प्रवेशयोग्यता मध्ये वैशिष्ट्य बदलू शकता."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"शॉर्टकट संपादित करा"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"रद्द करा"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"शॉर्टकट बंद करा"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> हे प्रतिबंधित बादलीमध्ये ठेवण्यात आले आहे"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"वैयक्तिक"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"ऑफिस"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 59c7d65..848ebf4 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Pentadbir melepaskan peranti untuk kegunaan peribadi"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Peranti ini diurus"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Organisasi anda mengurus peranti ini dan mungkin memantau trafik rangkaian. Ketik untuk mendapatkan butiran."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Tetapan lokasi diubah oleh pentadbir anda"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Ketik untuk melihat tetapan lokasi anda."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Peranti anda akan dipadam"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Apl pentadbir tidak dapat digunakan. Peranti anda akan dipadamkan sekarang.\n\nJika anda ingin mengemukakan soalan, hubungi pentadbir organisasi anda."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Pencetakan dilumpuhkan oleh <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Apl sistem | terlindung ini boleh mengambil gambar dan merakam video menggunakan kamera sistem pada bila-bila masa. Apl juga perlu mempunyai kebenaran android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"kawal getaran"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Membenarkan apl mengawal penggetar."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Membenarkan apl mengakses keadaan penggetar."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"panggil terus nombor telefon"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Membenarkan apl memanggil nombor telefon tanpa campur tangan anda. Ini mungkin menyebabkan caj atau panggilan yang di luar jangkaan. Apl hasad boleh menyebabkan anda kerugian wang dengan membuat panggilan tanpa pengesahan anda."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"akses perkhidmatan panggilan IMS"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Cuba lagi."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Tiada cap jari didaftarkan."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Peranti ini tiada penderia cap jari."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Tidak dapat mengesahkan wajah. Cuba lagi."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Anda belum menyediakan wajah buka kunci."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Wajah buka kunci tidak disokong pada peranti ini."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Wajah <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Perkhidmatan latar depan dimulakan latar belakang daripada <xliff:g id="PACKAGENAME">%1$s</xliff:g> tidak akan mempunyai kebenaran semasa-dalam-penggunaan dalam binaan R akan datang. Sila lihat go/r-bg-fgs-restriction dan failkan laporan pepijat."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Naikkan kelantangan melebihi paras yang disyokorkan?\n\nMendengar pada kelantangan yang tinggi untuk tempoh yang lama boleh merosakkan pendengaran anda."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Gunakan Pintasan Kebolehaksesan?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Apabila pintasan dihidupkan, tindakan menekan kedua-dua butang kelantangan selama 3 saat akan memulakan ciri kebolehaksesan.\n\n Ciri kebolehaksesan semasa:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Anda boleh menukar ciri itu dalam Tetapan &gt; Kebolehaksesan."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Edit pintasan"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Batal"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Matikan pintasan"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> telah diletakkan dalam baldi TERHAD"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Peribadi"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Kerja"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index b3efcb1..95a41f2 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"ပုဂ္ဂိုလ်ရေးအသုံးပြုရန်အတွက် စီမံခန့်ခွဲသူက စက်ပစ္စည်းထိန်းချုပ်မှုကို ရပ်တန့်လိုက်သည်"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"စက်ပစ္စည်းကို စီမံခန့်ခွဲထားပါသည်"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"ဤစက်ပစ္စည်းကို သင်၏ အဖွဲ့အစည်းက စီမံပြီး ကွန်ရက်အသွားအလာကို စောင့်ကြည့်နိုင်ပါသည်။ ထပ်မံလေ့လာရန် တို့ပါ။"</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"သင့်စီမံခန့်ခွဲသူက တည်နေရာပြ ဆက်တင်များကို ပြောင်းထားသည်"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"သင့်တည်နေရာပြ ဆက်တင်များကို ကြည့်ရန် တို့ပါ။"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"သင့်ကိရိယာအား ပယ်ဖျက်လိမ့်မည်"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"စီမံခန့်ခွဲမှု အက်ပ်ကို သုံး၍မရပါ။ သင်၏ စက်ပစ္စည်းအတွင်းရှိ အရာများကို ဖျက်လိုက်ပါမည်\n\nမေးစရာများရှိပါက သင့်အဖွဲ့အစည်း၏ စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ။"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> က ပုံနှိပ်ထုတ်ယူခြင်းကို ပိတ်ထားသည်။"</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"ခွင့်ပြုချက်ရှိသည့် | ဤစနစ်အက်ပ်သည် စနစ်ကင်မရာကို အသုံးပြု၍ ဓာတ်ပုံနှင့် ဗီဒီယိုများကို အချိန်မရွေး ရိုက်ကူးနိုင်သည်။ အက်ပ်ကလည်း android.permission.CAMERA ခွင့်ပြုချက် ရှိရပါမည်"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"တုန်ခုန်မှုအား ထိန်းချုပ်ခြင်း"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"အက်ပ်အား တုန်ခါစက်ကို ထိန်းချုပ်ခွင့် ပြုသည်။"</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"အက်ပ်ကို တုန်ခါမှုအခြေအနေအား သုံးခွင့်ပေးပါ။"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ဖုန်းနံပါတ်များကိုတိုက်ရိုက်ခေါ်ဆိုခြင်း"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"အပလီကေးရှင်းအား အလိုအလျောက် ဖုန်းခေါ်ခွင့် ပြုပါ။ မလိုအပ်သော ဖုန်းခ များ ဖြစ်ပေါ်နိုင်ပါသည်။ ဒီခွင့်ပြုခြင်းမှာ အရေးပေါ်ဖုန်းခေါ်ခြင်း မပါဝင်ပါ။ သံသယဖြစ်စရာ အပလီကေးရှင်းများက သင့်မသိပဲ ဖုန်းခေါ်ခြင်းဖြင့် ဖုန်းခ ပိုမိုကျနိုင်ပါသည်။"</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS ဖုန်းခေါ်ဆိုမှု ဝန်ဆောင်ဌာန ဝင်ကြည့်ပါ"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"ပြန်ကြိုးစားပါ"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"မည်သည့် လက်ဗွေကိုမျှ ထည့်သွင်းမထားပါ။"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ဤစက်တွင် လက်ဗွေအာရုံခံကိရိယာ မရှိပါ။"</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"လက်ချောင်း <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"မျက်နှာကို အတည်ပြု၍ မရပါ။ ထပ်စမ်းကြည့်ပါ။"</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"မျက်နှာမှတ် သော့ဖွင့်ခြင်းကို ထည့်သွင်းမထားပါ"</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"ဤစက်ပစ္စည်းတွင် မျက်နှာမှတ် သော့ဖွင့်ခြင်းကို သုံး၍မရပါ။"</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"မျက်နှာ <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> တွင် မှ စတင်သည့် foreground ဝန်ဆောင်မှုသည် နောက်ထွက်ရှိမည့် R စုပေါင်းစပ်ပေါင်း ပရိုဂရမ်များတွင် အသုံးပြုစဉ်အတွင်း ခွင့်ပြုချက် ရရှိမည်မဟုတ်ပါ။ go/r-bg-fgs-ကန့်သတ်ချက်များကို ကြည့်ပြီး အမှားသတင်းပို့ချက်တစ်ခု တင်သွင်းပါ။"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"အသံကို အကြံပြုထားသည့် ပမာဏထက် မြှင့်ပေးရမလား?\n\nအသံကို မြင့်သည့် အဆင့်မှာ ကြာရှည်စွာ နားထောင်ခြင်းက သင်၏ နားကို ထိခိုက်စေနိုင်သည်။"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"အများသုံးစွဲနိုင်မှု ဖြတ်လမ်းလင့်ခ်ကို အသုံးပြုလိုပါသလား။"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"ဖြတ်လမ်းလင့်ခ်ကို ဖွင့်ထားစဉ် အသံအတိုးအလျှော့ခလုတ် နှစ်ခုစလုံးကို ၃ စက္ကန့်ခန့် ဖိထားခြင်းဖြင့် အများသုံးစွဲနိုင်မှုဆိုင်ရာ ဝန်ဆောင်မှုကို ဖွင့်နိုင်သည်။\n\n လက်ရှိ အများသုံးစွဲနိုင်မှုဆိုင်ရာ ဝန်ဆောင်မှု−\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n ဝန်ဆောင်မှုကို ဆက်တင်များ &gt; အများသုံးစွဲနိုင်မှုတွင် ပြောင်းလဲနိုင်ပါသည်။"</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"ဖြတ်လမ်းများကို တည်းဖြတ်ရန်"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"မလုပ်တော့"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ဖြတ်လမ်းလင့်ခ်ကို ပိတ်ရန်"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ကို တားမြစ်ထားသော သိမ်းဆည်းမှုအတွင်းသို့ ထည့်ပြီးပါပြီ"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"ကိုယ်ပိုင်"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"အလုပ်"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 5a3a588..7145ef3 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administratoren overførte enheten til personlig bruk"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Enheten administreres"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Organisasjonen din kontrollerer denne enheten og kan overvåke nettverkstrafikk. Trykk for å få mer informasjon."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Posisjonsinnstillingene er endret av administratoren din"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Trykk for å se posisjonsinnstillingene dine."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Enheten blir slettet"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Administratorappen kan ikke brukes. Enheten din blir nå tømt.\n\nTa kontakt med administratoren for organisasjonen din hvis du har spørsmål."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> har slått av utskrift."</string>
@@ -293,7 +295,7 @@
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"åpne bilder, medieinnhold og filer på enheten din"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ta opp lyd"</string>
-    <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fysisk aktivitet-"</string>
+    <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fysisk aktivitet"</string>
     <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"tilgang til den fysiske aktiviteten din"</string>
     <string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
     <string name="permgroupdesc_camera" msgid="7585150538459320326">"ta bilder og ta opp video"</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Denne privilegerte | systemappen kan når som helst ta bilder og spille inn videoer med et systemkamera. Dette krever at appen også har tillatelsen android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"kontrollere vibreringen"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Lar appen kontrollere vibreringsfunksjonen."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Gir appen tilgang til vibreringstilstanden."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ringe telefonnummer direkte"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Lar appen ringe telefonnumre uten at du gjør noe. Dette kan resultere i uventede oppringninger og kostnader. Appen kan imidlertid ikke ringe nødnumre. Merk at skadelige apper kan påføre deg kostnader ved å ringe uten bekreftelse fra deg."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"få tilgang til nettprattjenesten for ringing"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Prøv igjen."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ingen fingeravtrykk er registrert."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Denne enheten har ikke fingeravtrykkssensor."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Kan ikke bekrefte ansiktet. Prøv igjen."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Du har ikke konfigurert Ansiktslås."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Ansiktslås støttes ikke på denne enheten"</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Ansikt <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Forgrunnstjenesten fra <xliff:g id="PACKAGENAME">%1$s</xliff:g>, som ble startet i bakgrunnen, kommer ikke til å ha tillatelser mens den er i bruk i fremtidige R-delversjoner. Les go/r-bg-fgs-restriction og send inn en feilrapport."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vil du øke volumet til over anbefalt nivå?\n\nHvis du hører på et høyt volum over lengre perioder, kan det skade hørselen din."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Vil du bruke tilgjengelighetssnarveien?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Når snarveien er på, starter en tilgjengelighetsfunksjon når du trykker inn begge volumknappene i tre sekunder.\n\n Nåværende tilgjengelighetsfunksjon:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Du kan endre funksjonen i Innstillinger &gt; Tilgjengelighet."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Endre snarveier"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Avbryt"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Slå av snarveien"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> er blitt plassert i TILGANGSBEGRENSET-toppmappen"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Personlig"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Jobb"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index e95866b..6a61636 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"व्यवस्थापकले यन्त्रलाई व्यक्तिगत प्रयोगका लागि अस्वीकार गर्नुभयो"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"यन्त्र व्यवस्थित गरिएको छ"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"तपाईंको संगठनले यस यन्त्रको व्यवस्थापन गर्दछ र नेटवर्क ट्राफिकको अनुगमन गर्न सक्छ। विवरणहरूका लागि ट्याप गर्नुहोस्।"</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"तपाईंका प्रशासकले परिवर्तन गरेका स्थानसम्बन्धी सेटिङहरू"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"आफ्नो स्थानका सेटिङहरू हेर्न ट्याप गर्नुहोस्।"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"तपाईंको यन्त्र मेटिनेछ"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"प्रशासकको अनुप्रयोग प्रयोग गर्न मिल्दैन। तपाईंको यन्त्रको डेटा अब मेटाइने छ।\n\nतपाईंसँग प्रश्नहरू भएका खण्डमा आफ्नो संगठनका प्रशासकसँग सम्पर्क गर्नुहोस्।"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ले छाप्ने कार्यलाई असक्षम पार्यो।"</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"यस विशेषाधिकार प्राप्त अनुप्रयोगले जुनसुकै समय प्रणालीको क्यामेरा प्रयोग गरी तस्बिर खिच्न र भिडियो रेकर्ड गर्न सक्छ। अनुप्रयोगसँग पनि android.permission.CAMERA सम्बन्धी अनुमति हुनु पर्छ"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"कम्पन नियन्त्रण गर्नुहोस्"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"अनुप्रयोगलाई भाइब्रेटर नियन्त्रण गर्न अनुमति दिन्छ।"</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"यो अनुप्रयोगलाई कम्पनको स्थितिमाथि पहुँच राख्न दिनुहोस्।"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"फोन नम्बरहरूमा सीधै कल गर्नुहोस्"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"तपाईँको हस्तक्षेप बेगरै फोन नम्बर कल गर्न अनुप्रयोगलाई अनुमति दिन्छ। यसले अनपेक्षित शुल्क वा कलहरू गराउन सक्छ। यसले अनुप्रयोगलाई आपतकालीन नम्बरहरू कल गर्न अनुमति दिँदैन विचार गर्नुहोस्। खराब अनुप्रयोगहरूले तपाईँको स्वीकार बिना कलहरू गरेर तपाईँलाई बढी पैसा तिराउन सक्छ।"</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS कल सेवा पहुँच गर्नुहोस्"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"पुन: प्रयास गर्नुहोला।"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"कुनै पनि फिंगरप्रिन्ट दर्ता गरिएको छैन।"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"यो यन्त्रमा कुनै पनि फिंगरप्रिन्ट सेन्सर छैन।"</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"औंला <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"अनुहार पुष्टि गर्न सकिएन। फेरि प्रयास गर्नुहोस्।"</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"तपाईंले फेस अनलक सुविधा सेट अप गर्नुभएको छैन।"</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"यस यन्त्रमा फेस अनलक सुविधा प्रयोग गर्न मिल्दैन।"</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"अनुहार <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1620,7 +1627,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> को पृष्ठभूमिबाट सुरु गरिने अग्रभूमि सेवाका भविष्यमा आउने R बिल्डहरूमा चलाउँदै गर्दा प्रयोग गर्ने अनुमतिको दिइने छैन। कृपया go/r-bg-fgs-restriction हेर्नुहोस् र कुनै बगसम्बन्धी रिपोर्ट फाइल गर्नुहोस्।"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"सिफारिस तहभन्दा आवाज ठुलो गर्नुहुन्छ?\n\nलामो समय सम्म उच्च आवाजमा सुन्दा तपाईँको सुन्ने शक्तिलाई हानी गर्न सक्छ।"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"पहुँच सम्बन्धी सर्टकट प्रयोग गर्ने हो?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"सर्टकट सक्रिय हुँदा, भोल्युमका दुवै बटनहरूलाई ३ सेकेन्डसम्म थिची राख्नाले पहुँच सम्बन्धी कुनै सुविधा सुरु हुनेछ।\n\n हाल व्यवहारमा रहेको पहुँच सम्बन्धी सुविधा:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n तपाईं सेटिङहरू अन्तर्गतको पहुँच सम्बन्धी विकल्पमा गई उक्त सुविधालाई बदल्न सक्नुहुन्छ।"</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"सर्टकटहरू सम्पादन गर्नुहोस्"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"रद्द गर्नुहोस्"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"सर्टकटलाई निष्क्रिय पार्नुहोस्"</string>
@@ -2016,4 +2024,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> लाई प्रतिबन्धित बाल्टीमा राखियो"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"व्यक्तिगत"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"काम"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index e524c1b..e959a07 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"De beheerder heeft het apparaat afgestaan voor persoonlijk gebruik"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Apparaat wordt beheerd"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Dit apparaat wordt beheerd door je organisatie. Het netwerkverkeer kan worden bijgehouden. Tik voor meer informatie."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Locatie-instellingen gewijzigd door je beheerder"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Tik om je locatie-instellingen te bekijken."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Je apparaat wordt gewist"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"De beheer-app kan niet worden gebruikt. Je apparaat wordt nu gewist.\n\nNeem contact op met de beheerder van je organisatie als je vragen hebt."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Afdrukken uitgeschakeld door <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Deze gemachtigde app/systeem-app kan op elk gewenst moment foto\'s maken en video\'s opnemen met een systeemcamera. De app moet ook het recht android.permission.CAMERA hebben."</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"trilling beheren"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Hiermee kan de app de trilstand beheren."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Hiermee heeft de app toegang tot de status van de trilstand."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"telefoonnummers rechtstreeks bellen"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Hiermee kan de app zonder je tussenkomst telefoonnummers bellen. Dit kan tot onverwachte kosten of gesprekken leiden. De app kan hiermee geen noodnummers bellen. Schadelijke apps kunnen u geld kosten door nummers te bellen zonder om je bevestiging te vragen."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"toegang tot IMS-service voor bellen"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Probeer het opnieuw."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Geen vingerafdrukken geregistreerd."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dit apparaat heeft geen vingerafdruksensor."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Kan gezicht niet verifiëren. Probeer het nog eens."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Je hebt ontgrendelen via gezichtsherkenning niet ingesteld."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Ontgrendelen via gezichtsherkenning wordt niet ondersteund op dit apparaat."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Gezicht <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"De op de achtergrond gestarte voorgrondservice van <xliff:g id="PACKAGENAME">%1$s</xliff:g> heeft geen rechten tijdens gebruik in toekomstige R-builds. Ga naar go/r-bg-fgs-restriction en dien een bugrapport in."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Volume verhogen tot boven het aanbevolen niveau?\n\nAls je langere tijd op hoog volume naar muziek luistert, raakt je gehoor mogelijk beschadigd."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Snelkoppeling toegankelijkheid gebruiken?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Wanneer de snelkoppeling is ingeschakeld, kun je drie seconden op beide volumeknoppen drukken om een toegankelijkheidsfunctie te starten.\n\n Huidige toegankelijkheidsfunctie:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Je kunt de functie wijzigen in Instellingen &gt; Toegankelijkheid."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Snelkoppelingen bewerken"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Annuleren"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Sneltoets uitschakelen"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> is in de bucket RESTRICTED geplaatst"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Persoonlijk"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Werk"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 246b4d9..53b231c 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"ବ୍ୟକ୍ତିଗତ ବ୍ୟବହାର ପାଇଁ ଆଡ୍‌ମିନ୍ ଡିଭାଇସ୍‌କୁ ଅଲଗା କରିଛନ୍ତି"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"ଡିଭାଇସକୁ ପରିଚାଳନା କରାଯାଉଛି"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"ଆପଣଙ୍କ ସଂସ୍ଥା ଏହି ଡିଭାଇସକୁ ପରିଚାଳନା କରନ୍ତି ଏବଂ ନେଟୱର୍କ ଟ୍ରାଫିକ୍‍ ନୀରିକ୍ଷଣ କରନ୍ତି। ବିବରଣୀ ପାଇଁ ଟାପ୍‍ କରନ୍ତୁ।"</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"ଲୋକେସନ୍ ସେଟିଂସ୍ ଆପଣଙ୍କର ଆଡମିନଙ୍କ ଦ୍ୱରା ବଦଳାଯାଇଛି"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"ଆପଣଙ୍କର ଲୋକେସନ୍ ସେଟିଂସ୍ ଦେଖିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"ଆପଣଙ୍କ ଡିଭାଇସ୍‍ ବର୍ତ୍ତମାନ ଲିଭାଯିବ"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"ଆଡମିନ୍‍ ଆପ୍‍‍ ବ୍ୟବହାର କରାଯାଇପାରିବ ନାହିଁ। ଆପଣଙ୍କ ଡିଭାଇସ୍‍‌ର ସମସ୍ତ ଡାଟାକୁ ବର୍ତ୍ତମାନ ଲିଭାଇଦିଆଯିବ। \n\nଯଦି ଆପଣଙ୍କର କୌଣସି ପ୍ରଶ୍ନ ରହିଥାଏ, ଆପଣଙ୍କ ସଂସ୍ଥାର ଆଡମିନ୍‌ଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ଦ୍ଵାରା ପ୍ରିଣ୍ଟିଙ୍ଗ ଅକ୍ଷମ କରାଯାଇଛି"</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"ଏହି ପ୍ରମୁଖ | ସିଷ୍ଟମ୍ ଆପ୍ ଯେକୌଣସି ସମୟରେ ଏକ ସିଷ୍ଟମ୍ କ୍ୟାମେରା ବ୍ୟବହାର କରି ଛବିଗୁଡ଼ିକ ନେଇପାରେ ଏବଂ ଭିଡିଓଗୁଡ଼ିକ ରେକର୍ଡ କରିପାରେ। ଆପ୍ ମଧ୍ୟ android.permission.CAMERA ଅନୁମତି ଆବଶ୍ୟକ କରେ"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"କମ୍ପନ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"ଆପ୍‍କୁ, ଭାଇବ୍ରେଟର୍‍ ନିୟନ୍ତ୍ରଣ କରିବାକୁ ଦେଇଥାଏ।"</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"ଭାଇବ୍ରେଟର୍ ସ୍ଥିତି ଆକ୍ସେସ୍ କରିବାକୁ ଆପକୁ ଅନୁମତି ଦିଏ।"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ସିଧାସଳଖ ଫୋନ୍ ନମ୍ବରଗୁଡ଼ିକୁ କଲ୍ କରନ୍ତୁ"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"ଆପଣଙ୍କ ହସ୍ତକ୍ଷେପ ବିନା ଫୋନ୍‌ ନମ୍ଵରକୁ କଲ୍ କରିବା ପାଇଁ ଆପ୍‌କୁ ଅନୁମତି ଦେଇଥାଏ। ଏହାଦ୍ୱାରା ଅପ୍ରତ୍ୟାଶିତ ଶୁଳ୍କ ଲାଗୁ ହୋଇପାରେ କିମ୍ବା କଲ୍ ହୋଇପାରେ। ଧ୍ୟାନଦିଅନ୍ତୁ ଯେ, ଏହା ଆପ୍‌କୁ କୌଣସି ଜରୁରୀକାଳୀନ ନମ୍ବରରେ କଲ୍ କରିବାକୁ ଅନୁମତି ଦିଏନାହିଁ। ହାନୀକାରକ ଆପ୍‌ ଆପଣଙ୍କ ବିନା ସ୍ୱୀକୃତିରେ କଲ୍ କରି ଆପଣଙ୍କ ପଇସା ଖର୍ଚ୍ଚ କରାଇପାରେ।"</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS କଲ୍‍ ସେବା ଆକ୍ସେସ୍‍ କରେ"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"କୌଣସି ଆଙ୍ଗୁଠି ଚିହ୍ନ ପଞ୍ଜୀକୃତ ହୋଇନାହିଁ।"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ଏହି ଡିଭାଇସ୍‌ରେ ଟିପଚିହ୍ନ ସେନ୍‍ସର୍ ନାହିଁ।"</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ଆଙ୍ଗୁଠି <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"ମୁହଁ ଚିହ୍ନଟ କରିପାରିଲା ନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"ଆପଣ ଫେସ୍ ଅନ୍‌ଲକ୍ ସେଟ୍ ଅପ୍ କରିନାହାଁନ୍ତି"</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"ଏହି ଡିଭାଇସ୍‌ରେ ଫେସ୍ ଅନ୍‌ଲକ୍ ସମର୍ଥିତ ନୁହେଁ।"</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"<xliff:g id="FACEID">%d</xliff:g>ଙ୍କ ଫେସ୍‍"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"ପୃଷ୍ଠଭୂମିରେ <xliff:g id="PACKAGENAME">%1$s</xliff:g>ରୁ ଆରମ୍ଭ ହୋଇଥିବା ସମ୍ମୁଖଭାଗ ସେବା ପାଇଁ ଭବିଷ୍ୟତର R ବିଲ୍ଡଗୁଡ଼ିକରେ ବ୍ୟବହାର କରାଯିବା ସମୟରେ ଅନୁମତି ସୁବିଧା ରହିବ ନାହିଁ। ଦୟାକରି go/r-bg-fgs-restriction ଦେଖନ୍ତୁ ଏବଂ ଏକ ବଗରିପୋର୍ଟ ଫାଇଲ୍ କରନ୍ତୁ।"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ମାତ୍ରା ବଢ଼ାଇ ସୁପାରିଶ ସ୍ତର ବଢ଼ାଉଛନ୍ତି? \n\n ଲମ୍ବା ସମୟ ପର୍ଯ୍ୟନ୍ତ ଉଚ୍ଚ ଶବ୍ଦରେ ଶୁଣିଲେ ଆପଣଙ୍କ ଶ୍ରବଣ ଶକ୍ତି ଖରାପ ହୋଇପାରେ।"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ଆକ୍ସେସବିଲିଟି ଶର୍ଟକଟ୍‍ ବ୍ୟବହାର କରିବେ?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"ସର୍ଟକଟ୍‌ ଅନ୍‌ ଥିବା ବେଳେ, ଉଭୟ ଭଲ୍ୟୁମ୍‍ ବଟନ୍‍ 3 ସେକେଣ୍ଡ ପାଇଁ ଦବାଇବା ଦ୍ୱାରା ଆକ୍ସେସବିଲିଟି ବୈଶିଷ୍ଟ ଆରମ୍ଭ ହେବ।\n\n ସମ୍ପ୍ରତି ଆକ୍ସେସବିଲିଟି ବୈଶିଷ୍ଟ୍ୟ:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n ସେଟିଙ୍ଗ ଓ ଆକ୍ସେସବିଲିଟିରେ ଆପଣ ବୈଶିଷ୍ଟ୍ୟ ବଦଳାଇ ପାରିବେ।"</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"ସର୍ଟକଟଗୁଡ଼ିକୁ ସମ୍ପାଦନ କରନ୍ତୁ"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"ବାତିଲ୍ କରନ୍ତୁ"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ଶର୍ଟକଟ୍‍ ବନ୍ଦ କରନ୍ତୁ"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>କୁ ପ୍ରତିବନ୍ଧିତ ବକେଟରେ ରଖାଯାଇଛି"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"ବ୍ୟକ୍ତିଗତ"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"କାର୍ଯ୍ୟ"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 3d68832..b5194eb7 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"ਪ੍ਰਸ਼ਾਸਕ ਨੇ ਨਿੱਜੀ ਵਰਤੋਂ ਲਈ ਡੀਵਾਈਸ ਤਿਆਗਿਆ"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"ਡੀਵਾਈਸ ਪ੍ਰਬੰਧਨ ਅਧੀਨ ਹੈ"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"ਤੁਹਾਡਾ ਸੰਗਠਨ ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਦਾ ਹੈ ਅਤੇ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦਾ ਹੈ। ਵੇਰਵਿਆਂ ਲਈ ਟੈਪ ਕਰੋ।"</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਨੇ ਟਿਕਾਣਾ ਸੈਟਿੰਗਾਂ ਨੂੰ ਬਦਲ ਦਿੱਤਾ ਹੈ"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"ਆਪਣੀਆਂ ਟਿਕਾਣਾ ਸੈਟਿੰਗਾਂ ਨੂੰ ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਮਿਟਾਇਆ ਜਾਏਗਾ"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"ਪ੍ਰਸ਼ਾਸਕ ਐਪ ਵਰਤੀ ਨਹੀਂ ਜਾ ਸਕਦੀ। ਹੁਣ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦਾ ਡਾਟਾ ਮਿਟਾਇਆ ਜਾਵੇਗਾ।\n\nਜੇਕਰ ਤੁਹਾਡੇ ਕੋਲ ਕੋਈ ਸਵਾਲ ਹਨ, ਤਾਂ ਆਪਣੀ ਸੰਸਥਾ ਦੇ ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ਵੱਲੋਂ ਪ੍ਰਿੰਟ ਕਰਨਾ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"ਇਹ ਵਿਸ਼ੇਸ਼ ਅਧਿਕਾਰ ਸਿਸਟਮ ਐਪ ਕਿਸੇ ਵੇਲੇ ਵੀ ਸਿਸਟਮ ਕੈਮਰੇ ਨੂੰ ਵਰਤ ਕੇ ਤਸਵੀਰਾਂ ਖਿੱਚ ਸਕਦੀ ਹੈ ਅਤੇ ਵੀਡੀਓ ਫ਼ਾਈਲਾਂ ਰਿਕਾਰਡ ਕਰ ਸਕਦੀ ਹੈ। ਐਪ ਨੂੰ ਵੀ android.permission.CAMERA ਇਜਾਜ਼ਤ ਦੀ ਲੋੜ ਹੈ।"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"ਵਾਈਬ੍ਰੇਸ਼ਨ ਤੇ ਨਿਯੰਤਰਣ ਪਾਓ"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"ਐਪ ਨੂੰ ਵਾਈਬ੍ਰੇਟਰ ਤੇ ਨਿਯੰਤਰਣ ਪਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"ਐਪ ਨੂੰ ਥਰਥਰਾਹਟ ਸਥਿਤੀ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ਫ਼ੋਨ ਨੰਬਰਾਂ ਤੇ ਸਿੱਧੇ ਕਾਲ ਕਰੋ"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਦਖਲ ਤੋਂ ਬਿਨਾਂ ਫ਼ੋਨ ਨੰਬਰਾਂ ਤੇ ਕਾਲ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸਦੇ ਸਿੱਟੇ ਵਜੋਂ ਅਕਲਪਿਤ ਖਰਚੇ ਜਾਂ ਕਾਲਾਂ ਹੋ ਸਕਦੀਆਂ ਹਨ। ਧਿਆਨ ਦਿਓ ਕਿ ਇਹ ਐਪ ਨੂੰ ਸੰਕਟਕਾਲੀਨ ਨੰਬਰਾਂ ਤੇ ਕਾਲ ਕਰਨ ਦੀ ਆਗਿਆ ਨਹੀਂ ਦਿੰਦਾ। ਖਰਾਬ ਐਪਾਂ ਤੁਹਾਡੀ ਪੁਸ਼ਟੀ ਤੋਂ ਬਿਨਾਂ ਕਾਲਾਂ ਕਰਕੇ ਤੁਹਾਨੂੰ ਖਰਚੇ ਪਾ ਸਕਦੀਆਂ ਹਨ।"</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS ਕਾਲ ਸੇਵਾ ਤੱਕ ਪਹੁੰਚ"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ਕੋਈ ਫਿੰਗਰਪ੍ਰਿੰਟ ਦਰਜ ਨਹੀਂ ਕੀਤੇ ਗਏ।"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ਇਸ ਡੀਵਾਈਸ ਵਿੱਚ ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨਹੀਂ ਹੈ।"</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ਉਂਗਲ <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"ਚਿਹਰੇ ਦੀ ਪੁਸ਼ਟੀ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕੀ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"ਤੁਸੀਂ ਚਿਹਰਾ ਅਣਲਾਕ ਸੈੱਟਅੱਪ ਨਹੀਂ ਕੀਤਾ ਹੈ।"</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"ਇਸ ਡੀਵਾਈਸ ਵਿੱਚ ਚਿਹਰਾ ਅਣਲਾਕ ਦੀ ਸੁਵਿਧਾ ਨਹੀਂ ਹੈ।"</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"ਚਿਹਰਾ <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> ਤੋਂ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਸ਼ੁਰੂ ਕੀਤੀ ਗਈ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾ ਲਈ ਭਵਿੱਖੀ R ਬਿਲਡ ਵਿੱਚ \'ਵਰਤੋਂ ਵਿੱਚ ਹੋਣ \'ਤੇ ਇਜਾਜ਼ਤ\' ਵਿਸ਼ੇਸ਼ਤਾ ਨਹੀਂ ਹੋਵੇਗੀ। ਕਿਰਪਾ ਕਰਕੇ go/r-bg-fgs-restriction ਦੇਖੋ ਅਤੇ ਬੱਗ ਰਿਪੋਰਟ ਫ਼ਾਈਲ ਕਰੋ।"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ਕੀ ਵੌਲਿਊਮ  ਸਿਫ਼ਾਰਸ਼  ਕੀਤੇ ਪੱਧਰ ਤੋਂ ਵਧਾਉਣੀ ਹੈ?\n\nਲੰਮੇ ਸਮੇਂ ਤੱਕ ਉੱਚ ਵੌਲਿਊਮ ਤੇ ਸੁਣਨ ਨਾਲ ਤੁਹਾਡੀ ਸੁਣਨ ਸ਼ਕਤੀ ਨੂੰ ਨੁਕਸਾਨ ਪਹੁੰਚ ਸਕਦਾ ਹੈ।"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ਕੀ ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ ਵਰਤਣਾ ਹੈ?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"ਸ਼ਾਰਟਕੱਟ ਚਾਲੂ ਹੋਣ \'ਤੇ, ਕਿਸੇ ਪਹੁੰਚਯੋਗਤਾ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਅਵਾਜ਼ ਬਟਨਾਂ ਨੂੰ 3 ਸਕਿੰਟ ਲਈ ਦਬਾ ਕੇ ਰੱਖੋ।\n\n ਵਰਤਮਾਨ ਪਹੁੰਚਯੋਗਤਾ ਵਿਸ਼ੇਸ਼ਤਾ:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n ਤੁਸੀਂ ਸੈਟਿੰਗਾਂ &gt; ਪਹੁੰਚਯੋਗਤਾ ਵਿੱਚ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਬਦਲ ਸਕਦੇ ਹੋ।"</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"ਸ਼ਾਰਟਕੱਟਾਂ ਦਾ ਸੰਪਾਦਨ ਕਰੋ"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"ਰੱਦ ਕਰੋ"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ਸ਼ਾਰਟਕੱਟ ਬੰਦ ਕਰੋ"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ਨੂੰ ਪ੍ਰਤਿਬੰਧਿਤ ਖਾਨੇ ਵਿੱਚ ਪਾਇਆ ਗਿਆ ਹੈ"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"ਨਿੱਜੀ"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"ਕੰਮ"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 2fb9ac2..50e6974 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -195,6 +195,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrator odstąpił urządzenie do użytku osobistego"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Urządzenie jest zarządzane"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Twoja organizacja zarządza tym urządzeniem i może monitorować ruch w sieci. Kliknij, by dowiedzieć się więcej."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Ustawienia lokalizacji zmienione przez administratora"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Kliknij, aby zobaczyć ustawienia lokalizacji."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Twoje urządzenie zostanie wyczyszczone"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Nie można użyć aplikacji administratora. Dane z urządzenia zostaną wykasowane.\n\nJeśli masz pytania, skontaktuj się z administratorem organizacji."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Drukowanie wyłączone przez: <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -435,6 +437,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Ta aplikacja systemowa | o podwyższonych uprawnieniach może w dowolnym momencie robić zdjęcia i nagrywać filmy przy użyciu aparatu systemu. Wymaga przyznania uprawnień android.permission.CAMERA również aplikacji"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"sterowanie wibracjami"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Pozwala aplikacji na sterowanie wibracjami."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Zezwala aplikacji na dostęp do stanu wibracji"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"bezpośrednie wybieranie numerów telefonów"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Pozwala aplikacji na dzwonienie pod numery telefonów bez Twojej wiedzy. Może to skutkować nieoczekiwanymi opłatami lub połączeniami. Aplikacja nie może dzwonić pod numery alarmowe. Złośliwe aplikacje mogą generować koszty, wykonując połączenia bez Twojego potwierdzenia."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"usługa telefoniczna z dostępem do komunikatora"</string>
@@ -549,6 +552,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Spróbuj ponownie."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nie zarejestrowano odcisków palców."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"To urządzenie nie jest wyposażone w czytnik linii papilarnych."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Odcisk palca <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -592,6 +597,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Nie można zweryfikować twarzy. Spróbuj ponownie."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Rozpoznawanie twarzy nie jest skonfigurowane."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"To urządzenie nie obsługuje rozpoznawania twarzy."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Twarz <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1658,7 +1665,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Uruchomiona w tle usługa działająca w pierwszym planie z pakietu <xliff:g id="PACKAGENAME">%1$s</xliff:g> nie będzie miała uprawnień obowiązujących podczas używania w przyszłych kompilacjach R. Zapoznaj się z ograniczeniem go/r-bg-fgs-restriction i zgłoś błąd."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Zwiększyć głośność ponad zalecany poziom?\n\nSłuchanie głośno przez długi czas może uszkodzić Twój słuch."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Użyć skrótu do ułatwień dostępu?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Gdy skrót jest włączony, jednoczesne naciśnięcie przez trzy sekundy obu klawiszy sterowania głośnością uruchomi funkcję ułatwień dostępu.\n\nBieżąca funkcja ułatwień dostępu:\n<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\nFunkcję możesz zmienić, wybierając Ustawienia &gt; Ułatwienia dostępu."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Edytuj skróty"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Anuluj"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Wyłącz skrót"</string>
@@ -2078,4 +2086,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Umieszczono pakiet <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> w zasobniku danych RESTRICTED"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Osobiste"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Do pracy"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 1ae0c36..5677ab2 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"O administrador renunciou ao dispositivo para uso pessoal"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"O dispositivo é gerenciado"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Sua organização gerencia este dispositivo e pode monitorar o tráfego de rede. Toque para ver detalhes."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Configurações de localização modificadas pelo administrador"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Toque para ver as configurações de localização."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Seu dispositivo será limpo"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Não é possível usar o aplicativo para administrador. Seu dispositivo passará por uma limpeza agora.\n\nEm caso de dúvidas, entre em contato com o administrador da sua organização."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Impressão desativada por <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Este app do sistema/com privilégios pode tirar fotos e gravar vídeos a qualquer momento usando a câmera do sistema. É necessário que o app tenha também a permissão android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"controlar vibração"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Permite que o app controle a vibração."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permite que o app acesse o estado da vibração."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ligar diretamente para números de telefone"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Permite que o app ligue para números de telefone sem sua intervenção. Isso pode resultar em cobranças ou chamadas inesperadas. Esta opção não permite que o app ligue para números de emergência. Apps maliciosos podem gerar custos com chamadas feitas sem sua confirmação."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"acessar serviço de mensagens instantâneas para chamadas"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Tente novamente."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nenhuma impressão digital registrada."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem um sensor de impressão digital."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Não é possível verificar o rosto. Tente novamente."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"O desbloqueio facial não foi configurado."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"O desbloqueio facial não é compatível com este dispositivo."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Rosto <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"O serviço em primeiro plano iniciado em segundo plano por <xliff:g id="PACKAGENAME">%1$s</xliff:g> não receberá uma permissão durante o uso em futuras versões R. Consulte go/r-bg-fgs-restriction e crie um relatório de bug."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Aumentar o volume acima do nível recomendado?\n\nOuvir em volume alto por longos períodos pode danificar sua audição."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Usar atalho de Acessibilidade?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Quando o atalho está ativado, pressione os dois botões de volume por três segundos para iniciar um recurso de acessibilidade.\n\n Recurso de acessibilidade atual:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n É possível alterar o recurso em Configurações &gt; Acessibilidade."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editar atalhos"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Cancelar"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desativar atalho"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> foi colocado no intervalo \"RESTRITO\""</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Pessoal"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Trabalho"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index c381709..4bdb07f 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"O administrador anulou o dispositivo para utilização pessoal."</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"O dispositivo é gerido"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"A sua entidade gere este dispositivo e pode monitorizar o tráfego de rede. Toque para obter mais detalhes."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Definições de localização alteradas pelo administrador"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Toque para ver as definições de localização."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"O seu dispositivo será apagado"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Não é possível utilizar a aplicação de administrador. O seu dispositivo será agora apagado.\n\nSe tiver questões, contacte o administrador da entidade."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Impressão desativada por <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Esta aplicação do sistema | privilegiada pode tirar fotos e gravar vídeos através de uma câmara do sistema em qualquer altura. Também necessita da autorização android.permission.CAMERA para a aplicação."</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"controlar vibração"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Permite à aplicação controlar o vibrador."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permite que a app aceda ao estado de vibração."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"marcar números de telefone diretamente"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Permite que a aplicação ligue para números de telefone sem a intervenção do utilizador. Esta ação pode resultar em cobranças ou chamadas inesperadas. Tenha em atenção que isto não permite que a aplicação ligue para números de emergência. As aplicações maliciosas podem fazer com que incorra em custos, fazendo chamadas sem a sua confirmação."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"aceder ao serviço de chamadas IMS"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Tente novamente."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nenhuma impressão digital registada."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem sensor de impressões digitais."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Não é possível validar o rosto. Tente novamente."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Não configurou o Desbloqueio Através do Rosto."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Desbloqueio Através do Rosto não suportado neste dispositivo."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Rosto <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"O serviço em primeiro plano iniciado em segundo plano de <xliff:g id="PACKAGENAME">%1$s</xliff:g> não terá a autorização durante a utilização em compilações R futuras. Aceda a go/r-bg-fgs-restriction e envie um relatório de erros."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Aumentar o volume acima do nível recomendado?\n\nOuvir com um volume elevado durante longos períodos poderá ser prejudicial para a sua audição."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Pretende utilizar o atalho de acessibilidade?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Quando o atalho está ativado, premir ambos os botões de volume durante 3 segundos inicia uma funcionalidade de acessibilidade.\n\n Funcionalidade de acessibilidade atual:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Pode alterar a funcionalidade em Definições &gt; Acessibilidade."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editar atalhos"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Cancelar"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desativar atalho"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> foi colocado no contentor RESTRITO."</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Pessoal"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Trabalho"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 1ae0c36..5677ab2 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"O administrador renunciou ao dispositivo para uso pessoal"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"O dispositivo é gerenciado"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Sua organização gerencia este dispositivo e pode monitorar o tráfego de rede. Toque para ver detalhes."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Configurações de localização modificadas pelo administrador"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Toque para ver as configurações de localização."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Seu dispositivo será limpo"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Não é possível usar o aplicativo para administrador. Seu dispositivo passará por uma limpeza agora.\n\nEm caso de dúvidas, entre em contato com o administrador da sua organização."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Impressão desativada por <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Este app do sistema/com privilégios pode tirar fotos e gravar vídeos a qualquer momento usando a câmera do sistema. É necessário que o app tenha também a permissão android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"controlar vibração"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Permite que o app controle a vibração."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permite que o app acesse o estado da vibração."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ligar diretamente para números de telefone"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Permite que o app ligue para números de telefone sem sua intervenção. Isso pode resultar em cobranças ou chamadas inesperadas. Esta opção não permite que o app ligue para números de emergência. Apps maliciosos podem gerar custos com chamadas feitas sem sua confirmação."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"acessar serviço de mensagens instantâneas para chamadas"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Tente novamente."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nenhuma impressão digital registrada."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem um sensor de impressão digital."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Não é possível verificar o rosto. Tente novamente."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"O desbloqueio facial não foi configurado."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"O desbloqueio facial não é compatível com este dispositivo."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Rosto <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"O serviço em primeiro plano iniciado em segundo plano por <xliff:g id="PACKAGENAME">%1$s</xliff:g> não receberá uma permissão durante o uso em futuras versões R. Consulte go/r-bg-fgs-restriction e crie um relatório de bug."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Aumentar o volume acima do nível recomendado?\n\nOuvir em volume alto por longos períodos pode danificar sua audição."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Usar atalho de Acessibilidade?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Quando o atalho está ativado, pressione os dois botões de volume por três segundos para iniciar um recurso de acessibilidade.\n\n Recurso de acessibilidade atual:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n É possível alterar o recurso em Configurações &gt; Acessibilidade."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editar atalhos"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Cancelar"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desativar atalho"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> foi colocado no intervalo \"RESTRITO\""</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Pessoal"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Trabalho"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 7c5b63e..99cdc0b 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -193,6 +193,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administratorul a retras dispozitivul pentru uz personal"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Dispozitivul este gestionat"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Organizația dvs. gestionează acest dispozitiv și poate monitoriza traficul în rețea. Atingeți pentru mai multe detalii."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Setările privind locația au fost modificate de administrator"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Atingeți pentru a vedea setările privind locația."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Datele de pe dispozitiv vor fi șterse"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Aplicația de administrare nu poate fi utilizată. Dispozitivul va fi șters.\n\nDacă aveți întrebări, contactați administratorul organizației dvs."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Printare dezactivată de <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -432,6 +434,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Această aplicație de sistem | privilegiată poate să fotografieze și să înregistreze videoclipuri folosind o cameră de sistem în orice moment. Necesită și permisiunea android.permission.CAMERA pentru aplicație"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"controlează vibrarea"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Permite aplicației să controleze mecanismul de vibrare."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permite aplicației să acceseze modul de vibrații."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"apelare directă numere de telefon"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Permite aplicației să apeleze numere de telefon fără intervenția dvs. Acest lucru poate determina apariția unor taxe sau a unor apeluri neașteptate. Cu această permisiune aplicația nu poate apela numerele de urgență. Aplicațiile rău intenționate pot acumula costuri prin efectuarea unor apeluri fără confirmare."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"accesează serviciul de apelare IMS"</string>
@@ -546,6 +549,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Încercați din nou."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nu au fost înregistrate amprente."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dispozitivul nu are senzor de amprentă."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Degetul <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -589,6 +594,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Nu se poate confirma fața. Încercați din nou."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Nu ați configurat deblocarea facială."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Deblocarea facială nu este acceptată pe dispozitiv."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Chip <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1636,7 +1643,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Serviciul în prim-plan inițializat în fundal din <xliff:g id="PACKAGENAME">%1$s</xliff:g> nu va avea permisiunea în timpul utilizării în versiunile R viitoare. Consultați go/r-bg-fgs-restriction și trimiteți un raport de eroare."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Ridicați volumul mai sus de nivelul recomandat?\n\nAscultarea la volum ridicat pe perioade lungi de timp vă poate afecta auzul."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Utilizați comanda rapidă pentru accesibilitate?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Când comanda rapidă este activată, dacă apăsați ambele butoane de volum timp de 3 secunde, veți lansa o funcție de accesibilitate.\n\n Funcția actuală de accesibilitate:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Puteți schimba funcția în Setări &gt; Accesibilitate."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Editați comenzile rapide"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Anulați"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Dezactivați comanda rapidă"</string>
@@ -2044,4 +2052,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> a fost adăugat la grupul RESTRICȚIONATE"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Personal"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Serviciu"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index fa2c9f5..244d0e6 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -195,6 +195,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Администратор освободил устройство для личного использования"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Это управляемое устройство"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Ваша организация управляет этим устройством и может отслеживать сетевой трафик. Подробнее…"</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Настройки геолокации изменены администратором"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Нажмите, чтобы открыть настройки геолокации."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Все данные с устройства будут удалены"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Невозможно использовать приложение для администрирования. С устройства будут удалены все данные.\n\nЕсли у вас возникли вопросы, обратитесь к администратору."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Функция печати отключена приложением \"<xliff:g id="OWNER_APP">%s</xliff:g>\""</string>
@@ -435,6 +437,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Это привилегированное или системное приложение может в любое время делать фотографии и снимать видео с помощью камеры. Для этого приложению также требуется разрешение android.permission.CAMERA."</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"Управление функцией вибросигнала"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Приложение сможет контролировать вибросигналы."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Приложение сможет получать доступ к состоянию виброотклика."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"Осуществление телефонных вызовов"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Приложение сможет без вашего участия звонить на любой номер телефона. Это не относится к номерам экстренных служб. Вредоносные программы смогут совершать вызовы без вашего разрешения, что может привести к непредвиденным расходам."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"совершение звонков с помощью службы IMS"</string>
@@ -549,6 +552,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Повторите попытку."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Нет отсканированных отпечатков пальцев"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На этом устройстве нет сканера отпечатков пальцев."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Отпечаток <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -592,6 +597,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Не удалось распознать лицо. Повторите попытку."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Вы не настроили фейсконтроль."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Это устройство не поддерживает функцию \"Фейсконтроль\"."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Лицо <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1658,7 +1665,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Службы из пакета <xliff:g id="PACKAGENAME">%1$s</xliff:g>, переведенные из фонового режима в активный, не будут получать разрешение while-in-use в будущих сборках на языке R. Перейдите на страницу go/r-bg-fgs-restriction и отправьте отчет об ошибке."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Установить громкость выше рекомендуемого уровня?\n\nВоздействие громкого звука в течение долгого времени может привести к повреждению слуха."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Использовать быстрое включение?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Чтобы использовать функцию специальных возможностей, когда она включена, нажмите и удерживайте три секунды обе кнопки регулировки громкости.\n\nТекущая функция специальных возможностей:\n<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\nВы можете изменить ее в разделе \"Настройки &gt; Специальные возможности\"."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Изменить быстрые клавиши"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Отмена"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Деактивировать быстрое включение"</string>
@@ -2078,4 +2086,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Приложение \"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>\" помещено в категорию с ограниченным доступом."</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Личный"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Рабочий"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index dbe1f22..6583f94 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"පරිපාලක පුද්ගලික භාවිතය සඳහා උපාංගය අත්හැර දමන ලදී"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"උපාංගය කළමනාකරණය කෙරේ"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"ඔබගේ ආයතනය මෙම උපාංගය කළමනාකරණය කරන අතර එය ජාල තදබදය නිරීක්ෂණය කළ හැක. විස්තර සඳහා තට්ටු කරන්න."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"ස්ථාන සැකසීම් ඔබේ පරිපාලක විසින් වෙනස් කරන ලදී"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"ඔබේ ස්ථාන සැකසීම් බැලීමට තට්ටු කරන්න."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"ඔබගේ උපාංගය මකා දැමෙනු ඇත"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"පරිපාලක යෙදුම භාවිතා කළ නොහැකිය. ඔබේ උපාංගය දැන් මකා දමනු ඇත.\n\nඔබට ප්‍රශ්න තිබේ නම්, ඔබේ සංවිධානයේ පරිපාලකට අමතන්න."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> විසින් මුද්‍රණය කිරීම අබල කර ඇත."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"මෙම වරප්‍රසාද ලත් | යෙදුමට ඕනෑම වේලාවක කැමරාව භාවිත කර පින්තූර ගැනීමට සහ වීඩියෝ පටිගත කිරීමට හැකිය. යෙදුම විසින් රඳවා තබා ගැනීමට android.permission.CAMERA ප්‍රවේශයද අවශ්‍ය වේ"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"කම්පනය පාලනය කිරීම"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"කම්පකය පාලනයට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"යෙදුමට කම්පන තත්ත්වයට ප්‍රවේශ වීමට ඉඩ දෙන්න."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"දුරකථන අංක වෙත ඍජුවම අමතන්න"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"ඔබගේ මැදිහත් වීමක් නොමැතිව දුරකථන අංක ඇමතීමට යෙදුමට අවසර දෙන්න. මෙහි ප්‍රතිඑලය වන්නේ අනපේක්ෂිත අයකිරීම් හෝ ඇමතුම් ඇතිවීමයි. මෙයන් හදිසි අංක වලට ඇමතුම් ගැනීමට යෙදුමට අවසර නොදෙන බවට සටහන් කරගන්න. ඔබගේ අනුදැනුමක් නොමැතිව ඇමතුම් ගැනීමෙන් අනිෂ්ට යෙදුම් ඔබගේ මුදල් නිකරුණේ වැය කරයි."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS ඇමතුම් සේවාවට පිවිසෙන්න"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"නැවත උත්සාහ කරන්න."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ඇඟිලි සලකුණු ඇතුළත් කර නොමැත."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"මෙම උපාංගයේ ඇඟිලි සලකුණු සංවේදකයක් නොමැත."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"ඇඟිලි <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"මුහුණ සත්‍යාපන කළ නොහැක. නැවත උත්සාහ කරන්න."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"ඔබ මුහුණු අඟුලු ඇරීම සකසා නැත"</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"මෙම උපාංගයෙහි මුහුණු අඟුලු ඇරීමට සහය නොදැක්වේ"</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"මුහුණු <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1616,7 +1623,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> වෙතින් පසුබිම ආරම්භ කරන ලද පෙරබිම් සේවාව අනාගත R තැනුම්වලදී භාවිතයේ අවසරය නැත. කරුණාකර go/r-bg-fgs-අවහිරතාව බලා දෝෂ වාර්තාවක් ගොනු කරන්න."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"නිර්දේශිතයි මට්ටමට වඩා ශබ්දය වැඩිද?\n\nදිගු කාලයක් සඳහා ඉහළ ශබ්දයක් ඇසීමෙන් ඇතැම් විට ඔබගේ ඇසීමට හානි විය හැක."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ප්‍රවේශ්‍යතා කෙටිමඟ භාවිතා කරන්නද?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"කෙටිමඟ සක්‍රිය විට, හඬ බොත්තම් දෙකම තත්පර 3ක් අල්ලාගෙන සිටීමෙන් ප්‍රවේශ්‍යත අංගයක් ඇරඹේ.\n\n වත්මන් ප්‍රවේශ්‍යතා අංගය:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n සැකසීම් &gt; ප්‍රවේශ්‍යතාව තුළ ඔබට අංගය වෙනස් කළ හැක."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"කෙටිමං සංස්කරණ කරන්න"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"අවලංගු කරන්න"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"කෙටිමඟ ක්‍රියාවිරහිත කරන්න"</string>
@@ -2012,4 +2020,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> අවහිර කළ බාල්දියට දමා ඇත"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"පුද්ගලික"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"කාර්යාල"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 5483efd..d8006e7 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -195,6 +195,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Správca uvoľnil toto zariadenie na osobné používanie"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Zariadenie je spravované"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Vaša organizácia spravuje toto zariadenie a môže sledovať sieťovú premávku. Klepnutím zobrazíte podrobnosti."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Nastavenia polohy zmenil váš správca"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Klepnutím zobrazíte nastavenia polohy."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Vaše zariadenie bude vymazané"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Daná aplikácia na správu sa nedá použiť. Vaše zariadenie bude vymazané.\n\nV prípade otázok kontaktujte správcu organizácie."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Tlač zakázala aplikácia <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -435,6 +437,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Táto oprávnená alebo systémová aplikácia môže kedykoľvek fotiť a nahrávať videá fotoaparátom systému. Aplikácia musí mať tiež povolenie android.permission.CAMERA."</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"ovládať vibrovanie"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Umožňuje aplikácii ovládať vibrácie."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Povoľuje aplikácii získať prístup k stavu vibrácií."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"priamo volať na telefónne čísla"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Umožňuje aplikácii volať telefónne čísla bez vášho zásahu. V dôsledku toho sa môžu účtovať neočakávané poplatky alebo sa môžu uskutočniť neočakávané hovory. Toto povolenie neumožňuje aplikácii volať na tiesňovú linku."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"prístup k službe volania IMS"</string>
@@ -549,6 +552,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Skúste to znova"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Neregistrovali ste žiadne odtlačky prstov."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Toto zariadenie nemá senzor odtlačkov prstov."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst: <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -592,6 +597,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Nedá sa overiť tvár. Skúste to znova."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Nenastavili ste odomknutie tvárou."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Toto zariadenie nepodporuje odomknutie tvárou."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Tvár <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1658,7 +1665,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Služba na popredí spustená na pozadí z balíka <xliff:g id="PACKAGENAME">%1$s</xliff:g> nebude mať v budúcich zostavách R povolenie Počas používania. Prejdite na go/r-bg-fgs-restriction a odošlite hlásenie chyby."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Zvýšiť hlasitosť nad odporúčanú úroveň?\n\nDlhodobé počúvanie pri vysokej hlasitosti môže poškodiť váš sluch."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Použiť skratku dostupnosti?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Keď je skratka zapnutá, stlačením obidvoch tlačidiel hlasitosti na tri sekundy spustíte funkciu dostupnosti.\n\n Aktuálna funkcia dostupnosti:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Funkciu môžete zmeniť v časti Nastavenia &gt; Dostupnosť."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Upraviť skratky"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Zrušiť"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Vypnúť skratku"</string>
@@ -2078,4 +2086,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Balík <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> bol vložený do kontajnera OBMEDZENÉ"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Osobné"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Práca"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index fed39e8..93a1d34 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -195,6 +195,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Skrbnik je napravo prepustil osebni uporabi"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Naprava je upravljana"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Vaša organizacija upravlja to napravo in lahko nadzira omrežni promet. Dotaknite se za podrobnosti."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Skrbnik je spremenil nastavitve lokacije"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Dotaknite se za ogled nastavitev lokacije."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Podatki v napravi bodo izbrisani"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Skrbniške aplikacije ni mogoče uporabljati. Podatki v napravi bodo izbrisani.\n\nČe imate vprašanja, se obrnite na skrbnika organizacije."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Tiskanje je onemogočil pravilnik <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -435,6 +437,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Ta odobrena/sistemska aplikacija lahko z vgrajenim fotoaparatom kadar koli snema fotografije in videoposnetke. Aplikacija mora imeti omogočeno tudi dovoljenje android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"nadzor vibriranja"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Aplikaciji omogoča nadzor vibriranja."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Aplikaciji dovoljuje dostop do stanja vibriranja."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"neposredno klicanje telefonskih številk"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Aplikaciji omogoča klicanje telefonskih številk brez vašega posredovanja. Zaradi tega lahko pride do nepričakovanih stroškov ali klicev. Aplikaciji to ne dovoljuje opravljanja klicev v sili. Zlonamerne aplikacije lahko kličejo brez vaše potrditve, kar vas lahko drago stane."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"dostop do storitve za klicanje IMS"</string>
@@ -549,6 +552,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Poskusite znova."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Ni včlanjenih prstnih odtisov."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ta naprava nima tipala prstnih odtisov."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -592,6 +597,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Obraza ni mogoče preveriti. Poskusite znova."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Odklepanja z obrazom niste nastavili."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Ta naprava ne podpira odklepanja z obrazom."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Obraz <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1658,7 +1665,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"V prihodnjih različicah R storitev v ospredju z zagonom iz ozadja iz paketa <xliff:g id="PACKAGENAME">%1$s</xliff:g> ne bo imela dovoljenja med uporabo aplikacije. Oglejte si go/r-bg-fgs-restriction in pošljite poročilo o napakah."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Ali želite povečati glasnost nad priporočeno raven?\n\nDolgotrajno poslušanje pri veliki glasnosti lahko poškoduje sluh."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Želite uporabljati bližnjico funkcij za ljudi s posebnimi potrebami?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Ko je bližnjica vklopljena, pritisnite gumba za glasnost in ju pridržite tri sekunde, če želite zagnati funkcijo za ljudi s posebnimi potrebami.\n\n Trenutna funkcija za ljudi s posebnimi potrebami:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Funkcijo lahko spremenite v »Nastavitve &gt; Funkcije za ljudi s posebnimi potrebami«."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Uredi bližnjice"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Prekliči"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Izklopi bližnjico"</string>
@@ -2078,4 +2086,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Paket <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> je bil dodan v segment OMEJENO"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Osebno"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Služba"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index ec61fb9..f708fe4 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administratori e refuzoi pajisjen për përdorim personal"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Pajisja është e menaxhuar"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Organizata jote e menaxhon këtë pajisje dhe mund të monitorojë trafikun e rrjetit. Trokit për detaje."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Cilësimet e vendndodhjes u ndryshuan nga administratori yt"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Trokit për të parë cilësimet e tua të vendndodhjes."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Pajisja do të spastrohet"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Aplikacioni i administratorit nuk mund të përdoret. Pajisja jote tani do të fshihet.\n\nNëse ke pyetje, kontakto me administratorin e organizatës."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Printimi është çaktivizuar nga <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Ky aplikacion sistemi | i privilegjuar mund të shkrepë fotografi dhe të regjistrojë video duke përdorur një kamerë në çdo moment. Kërkon që autorizimi i android.permission.CAMERA të mbahet edhe nga aplikacioni"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"kontrollo dridhjen"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Lejon aplikacionin të kontrollojë dridhësin."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Lejon që aplikacioni të ketë qasje te gjendja e dridhësit."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"telefono drejtpërdrejt numrat e telefonit"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Lejon aplikacionin të telefonojë numra pa ndërhyrjen tënde. Kjo mund të rezultojë në tarifa ose telefonata të papritura. Ki parasysh se kjo nuk e lejon aplikacionin të telefonojë numra urgjence. Aplikacione keqdashëse mund të të kushtojnë para duke kryer telefonata pa konfirmimin tënd."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"qasje në shërbimin e telefonatave IMS"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Provo përsëri."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Nuk ka asnjë gjurmë gishti të regjistruar."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Kjo pajisje nuk ka sensor të gjurmës së gishtit."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Gishti <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Fytyra nuk mund të verifikohet. Provo përsëri."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Nuk e ke konfiguruar shkyçjen me fytyrë."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Shkyçja me fytyrë nuk mbështetet në këtë pajisje"</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Fytyra <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Shërbimi në plan të parë i nisur në sfond nga <xliff:g id="PACKAGENAME">%1$s</xliff:g> nuk do të ketë lejen e nevojshme gjatë përdorimit në ndërtimet e ardhshme R. Shiko go/r-bg-fgs-restriction dhe dërgo një raport të defekteve në kod."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Të ngrihet volumi mbi nivelin e rekomanduar?\n\nDëgjimi me volum të lartë për periudha të gjata mund të dëmtojë dëgjimin."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Të përdoret shkurtorja e qasshmërisë?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Kur shkurtorja është e aktivizuar, shtypja e të dy butonave për 3 sekonda do të nisë një funksion qasshmërie.\n\n Funksioni aktual i qasshmërisë:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Mund ta ndryshosh funksionin te Cilësimet &gt; Qasshmëria."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Redakto shkurtoret"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Anulo"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Çaktivizo shkurtoren"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> është vendosur në grupin E KUFIZUAR"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Personal"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Puna"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index e1c4e18..51e2674 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -193,6 +193,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Администратор је уступио уређај за личну употребу"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Уређајем се управља"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Организација управља овим уређајем и може да надгледа мрежни саобраћај. Додирните за детаље."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Администратор је променио подешавања локације"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Додирните да бисте видели подешавања локације."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Уређај ће бити обрисан"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Не можете да користите ову апликацију за администраторе. Уређај ће сада бити обрисан.\n\nАко имате питања, контактирајте администратора организације."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Штампање је онемогућила апликација <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -432,6 +434,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Ова привилегована | системска апликација може да снима слике и видео снимке помоћу камере система у било ком тренутку. Апликација треба да има и дозволу android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"контрола вибрације"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Дозвољава апликацији да контролише вибрацију."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Дозвољава апликацији да приступа стању вибрирања."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"директно позивање бројева телефона"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Дозвољава апликацији да позива бројеве телефона без ваше дозволе. Ово може да доведе до неочекиваних трошкова или позива. Имајте на уму да ово не дозвољава апликацији да позива бројеве за хитне случајеве. Злонамерне апликације могу да позивају без ваше потврде, што може да доведе до трошкова."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"приступ услузи позива помоћу размене тренутних порука"</string>
@@ -546,6 +549,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Пробајте поново."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Није регистрован ниједан отисак прста."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Овај уређај нема сензор за отисак прста."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -589,6 +594,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Провера лица није успела. Пробајте поново."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Нисте подесили откључавање лицем"</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Откључавање лицем није подржано на овом уређају"</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Лице <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1636,7 +1643,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Услуга у првом плану са <xliff:g id="PACKAGENAME">%1$s</xliff:g> која је покренута у позадини неће имати дозволу током коришћења у будућим R верзијама. Посетите go/r-bg-fgs-restriction и пошаљите извештај о грешци."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Желите да појачате звук изнад препорученог нивоа?\n\nСлушање гласне музике дуже време може да вам оштети слух."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Желите ли да користите пречицу за приступачност?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Када је пречица укључена, притисните оба дугмета за јачину звука да бисте покренули функцију приступачности.\n\n Актуелна функција приступачности:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Можете да промените функцију у одељку Подешавања &gt; Приступачност."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Измените пречице"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Откажи"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Искључи пречицу"</string>
@@ -2044,4 +2052,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Пакет <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> је додат у сегмент ОГРАНИЧЕНО"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Лични"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Пословни"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 0737b22..88b62f4 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administratören tillåter inte längre privat bruk av enheten"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Enheten hanteras"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Organisationen hanterar den här enheten och kan övervaka nätverkstrafiken. Tryck om du vill veta mer."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Platsinställningarna har ändrats av administratören"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Tryck för att se dina platsinställningar."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Enheten kommer att rensas"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Det går inte att använda administratörsappen. Enheten rensas.\n\nKontakta organisationens administratör om du har några frågor."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Utskrift har inaktiverats av <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -212,7 +214,7 @@
     <string name="reboot_to_update_prepare" msgid="6978842143587422365">"Förbereder uppdatering …"</string>
     <string name="reboot_to_update_package" msgid="4644104795527534811">"Uppdateringspaketet behandlas ..."</string>
     <string name="reboot_to_update_reboot" msgid="4474726009984452312">"Startar om …"</string>
-    <string name="reboot_to_reset_title" msgid="2226229680017882787">"Återställ standardinställning"</string>
+    <string name="reboot_to_reset_title" msgid="2226229680017882787">"Återställer standardinställning"</string>
     <string name="reboot_to_reset_message" msgid="3347690497972074356">"Startar om …"</string>
     <string name="shutdown_progress" msgid="5017145516412657345">"Avslutar…"</string>
     <string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"Din surfplatta stängs av."</string>
@@ -293,7 +295,7 @@
     <string name="permgroupdesc_storage" msgid="6351503740613026600">"få åtkomst till foton, media och filer på din enhet"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"spela in ljud"</string>
-    <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fysiska aktivitet"</string>
+    <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Fysisk aktivitet"</string>
     <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"åtkomst till data om fysisk aktivitet"</string>
     <string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
     <string name="permgroupdesc_camera" msgid="7585150538459320326">"ta bilder och spela in video"</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Denna systemapp | med behörighet kan ta bilder och spela in videor med systemets kamera när som helst. Appen måste även ha behörigheten android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"styra vibration"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Tillåter att appen styr vibrationen."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Appen beviljas åtkomst till vibrationsstatus."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ringa telefonnummer direkt"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Tillåter att appen ringer telefonnummer utan någon aktiv åtgärd från dig. Detta kan leda till oväntade avgifter och samtal. Observera att appen inte tillåts ringa nödsamtal. Skadliga appar kan ringa utan ditt godkännande och detta kan kosta pengar."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"tillgång till tjänsten för snabbmeddelanden vid samtal"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Försök igen."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Inga fingeravtryck har registrerats."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Enheten har ingen fingeravtryckssensor."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Det gick inte att verifiera ansiktet. Försök igen."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Du har inte konfigurerat ansiktslås."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Ansiktslås stöds inte på den här enheten."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Ansikte <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Förgrundstjänsten från <xliff:g id="PACKAGENAME">%1$s</xliff:g> som startades i bakgrunden får inte behörighet som gäller vid användning i framtida R-versioner. Besök go/r-bg-fgs-restriction och skicka en felrapport."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vill du höja volymen över den rekommenderade nivån?\n\nAtt lyssna med stark volym långa stunder åt gången kan skada hörseln."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Vill du använda Aktivera tillgänglighet snabbt?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"När kortkommandot har aktiverats startar du en tillgänglighetsfunktion genom att trycka ned båda volymknapparna i tre sekunder.\n\n Aktuell tillgänglighetsfunktion:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Du kan ändra funktionen i Inställningar &gt; Tillgänglighet."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Redigera genvägar"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Avbryt"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Inaktivera kortkommandot"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> har placerats i hinken RESTRICTED"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Privat"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Jobb"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 3c6b0fa..e94856b 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Msimamizi aliacha kutumia kifaa kwa matumizi ya binafsi"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Kifaa kinadhibitiwa"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Shirika lako linadhibiti kifaa hiki na huenda likafuatilia shughuli kwenye mtandao. Gusa ili upate maelezo zaidi."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Mipangilio ya mahali imebadilishwa na msimamizi wako"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Gusa ili uone mipangilio ya mahali ulipo."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Data iliyomo kwenye kifaa chako itafutwa"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Huwezi kutumia programu ya msimamizi. Sasa data iliyo kwenye kifaa chako itafutwa.\n\nIkiwa una maswali yoyote, wasiliana na msimamizi wa shirika lako."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Kipengele cha kuchapisha kimezimwa na <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Programu hii ya mfumo ya | inayopendelewa inaweza kupiga picha na kurekodi video ikitumia kamera ya mfumo wakati wowote. Inahitaji ruhusa ya android.permission.CAMERA iwepo kwenye programu pia"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"Kudhibiti mtetemo"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Inaruhusu programu kudhibiti kitingishi."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Huruhusu programu kufikia hali ya kitetemeshaji."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"piga simu moja kwa moja kwa nambari za simu"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Inaruhusu programu kupiga nambari za simu bila ya wewe kuingilia kati. Hii inaweza kusababisha gharama zisizotarajiwa au simu. Kumbuka kuwa hii hairuhusu programu kupiga nambari za dharura. Programu hasidi zinaweza kukugharimu pesa kwa kupiga simu bila uthibitisho wako."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"fikia huduma ya simu ya IMS"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Jaribu tena."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Hakuna alama za vidole zilizojumuishwa."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Kifaa hiki hakina kitambua alama ya kidole."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Kidole cha <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Imeshindwa kuthibitisha uso. Jaribu tena."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Hujaweka mipangilio ya kufungua kwa uso."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Kufungua kwa uso hakutumiki kwenye kifaa hiki."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Uso wa <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Huduma ya programu inayotumika iliyoanzishwa chinichini kwenye <xliff:g id="PACKAGENAME">%1$s</xliff:g> haitakuwa na ruhusa inapotumika katika miundo ijayo ya R. Tafadhali angalia go/r-bg-fgs-restriction na uwasilishe ripoti ya hitilafu."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Ungependa kupandisha sauti zaidi ya kiwango kinachopendekezwa?\n\nKusikiliza kwa sauti ya juu kwa muda mrefu kunaweza kuharibu uwezo wako wa kusikia."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Ungependa kutumia njia ya mkato ya ufikivu?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Unapowasha kipengele cha njia ya mkato, hatua ya kubonyeza vitufe vyote viwili vya sauti kwa dakika 3 itafungua kipengele cha ufikivu.\n\n Kipengele cha ufikivu kilichopo kwa sasa:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Unaweza kubadilisha kipengele hiki katika Mipangilio &gt; Zana za ufikivu."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Kubadilisha njia za mkato"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Ghairi"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Zima kipengele cha Njia ya Mkato"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> kimewekwa katika kikundi KILICHODHIBITIWA"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Binafsi"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Kazini"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index e80f37b..8245786 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -191,6 +191,10 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"நிர்வாகியால் தனிப்பட்ட உபயோகத்திற்காக ஒதுக்கப்பட்ட சாதனம்"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"சாதனம் நிர்வகிக்கப்படுகிறது"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"உங்கள் நிறுவனம் இந்தச் சாதனத்தை நிர்வகிக்கும், அத்துடன் அது நெட்வொர்க் ட்ராஃபிக்கைக் கண்காணிக்கலாம். விவரங்களுக்கு, தட்டவும்."</string>
+    <!-- no translation found for location_changed_notification_title (4119726617105166830) -->
+    <skip />
+    <!-- no translation found for location_changed_notification_text (198907268219396399) -->
+    <skip />
     <string name="factory_reset_warning" msgid="6858705527798047809">"சாதனத் தரவு அழிக்கப்படும்"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"நிர்வாகி ஆப்ஸை உபயோகிக்க முடியாது. இப்போது, உங்கள் சாதனம் ஆரம்ப நிலைக்கு மீட்டமைக்கப்படும்.\n\nஏதேனும் கேள்விகள் இருப்பின், உங்கள் நிறுவனத்தின் நிர்வாகியைத் தொடர்புகொள்ளவும்."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"பிரிண்ட் செய்வதை <xliff:g id="OWNER_APP">%s</xliff:g> தடுத்துள்ளது."</string>
@@ -429,6 +433,8 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"இந்த முன்னுரிமை பெற்ற சிஸ்டம் ஆப்ஸால் சிஸ்டம் கேமராவைப் பயன்படுத்தி எப்போது வேண்டுமானாலும் படங்களை எடுக்கவோ வீடியோக்களை ரெக்கார்டு செய்யவோ முடியும். android.permission.CAMERA அனுமதியும் ஆப்ஸிற்குத் தேவை"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"அதிர்வைக் கட்டுப்படுத்துதல்"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"அதிர்வைக் கட்டுப்படுத்தப் ஆப்ஸை அனுமதிக்கிறது."</string>
+    <!-- no translation found for permdesc_vibrator_state (7050024956594170724) -->
+    <skip />
     <string name="permlab_callPhone" msgid="1798582257194643320">"தொலைபேசி எண்களை நேரடியாக அழைத்தல்"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"உங்கள் தலையீட்டின்றி மொபைல் எண்களை அழைக்கப் ஆப்ஸை அனுமதிக்கிறது. இதன் விளைவாக எதிர்பாராத கட்டணங்களோ அழைப்புகளோ ஏற்படலாம். அவசரகால எண்களை அழைக்க இது ஆப்ஸை அனுமதிக்காது என்பதை நினைவில்கொள்ளவும். தீங்கிழைக்கும் ஆப்ஸ், உங்கள் உறுதிப்படுத்தல் இன்றி அழைப்புகளைச் செய்வதால் உங்களுக்குச் செலவு ஏற்படக்கூடும்."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS அழைப்புச் சேவையை அணுகுதல்"</string>
@@ -543,6 +549,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"மீண்டும் முயற்சிக்கவும்."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"கைரேகைப் பதிவுகள் எதுவும் இல்லை."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"இந்தச் சாதனத்தில் கைரேகை சென்சார் இல்லை."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"கைரேகை <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +594,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"முகத்தைச் சரிபார்க்க இயலவில்லை. மீண்டும் முயலவும்."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"’முகம் காட்டித் திறத்தலை’ நீங்கள் அமைக்கவில்லை."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"இந்த சாதனத்தில் ’முகம் காட்டித் திறத்தல்’ ஆதரிக்கப்படவில்லை."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"முகம் <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1624,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> இல் இருந்து பின்னணியில் தொடங்கப்பட்ட முன்புலச் சேவைக்கு, வரவுள்ள R பதிப்புகளில் உபயோகத்தின்போது மட்டுமான அனுமதி இருக்காது. go/r-bg-fgs-restriction என்பதைப் பார்த்து பிழை அறிக்கை ஒன்றைச் சமர்ப்பிக்கவும்."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"பரிந்துரைத்த அளவை விட ஒலியை அதிகரிக்கவா?\n\nநீண்ட நேரத்திற்கு அதிகளவில் ஒலி கேட்பது கேட்கும் திறனைப் பாதிக்கலாம்."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"அணுகல்தன்மை ஷார்ட்கட்டைப் பயன்படுத்தவா?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"ஷார்ட்கட் இயக்கத்தில் இருந்தால், இரண்டு ஒலியளவு பொத்தான்களையும் 3 வினாடிகள் அழுத்தி, அணுகல்தன்மை அம்சத்தை இயக்கலாம்.\n\n தற்போதைய அணுகல்தன்மை அம்சம்:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n அமைப்புகள் &gt; அணுகல்தன்மை என்பதற்குச் சென்று, அம்சத்தை மாற்றலாம்."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"ஷார்ட்கட்களை மாற்று"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"ரத்துசெய்"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ஷார்ட்கட்டை முடக்கு"</string>
@@ -2010,4 +2021,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> என்பதை வரம்பிடப்பட்ட பக்கெட்திற்குள் சேர்க்கப்பட்டது"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"தனிப்பட்ட சுயவிவரம்"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"பணிச் சுயவிவரம்"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 81d4b4f..7d01f58 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"వ్యక్తిగత వినియోగం కోసం నిర్వాహకులు పరికరాన్ని తీసి వేశారు"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"పరికరం నిర్వహించబడింది"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"మీ సంస్థ ఈ పరికరాన్ని నిర్వహిస్తుంది మరియు నెట్‌వర్క్ ట్రాఫిక్‌ని పర్యవేక్షించవచ్చు. వివరాల కోసం నొక్కండి."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"మీ అడ్మిన్ లొకేషన్ సెట్టింగ్‌లను మార్చారు"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"మీ లొకేషన్ సెట్టింగ్‌లను చుడటానికి ట్యాప్ చేయండి."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"మీ పరికరంలోని డేటా తొలగించబడుతుంది"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"నిర్వాహక యాప్‌ ఉపయోగించడం సాధ్యపడదు. మీ పరికరంలోని డేటా ఇప్పుడు తొలగించబడుతుంది.\n\nమీకు ప్రశ్నలు ఉంటే, మీ సంస్థ యొక్క నిర్వాహకులను సంప్రదించండి."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"ముద్రణ <xliff:g id="OWNER_APP">%s</xliff:g> ద్వారా నిలిపివేయబడింది."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"ఈ విశేష | సిస్టమ్ యాప్ ఎప్పుడైనా సిస్టమ్ కెమెరాను ఉపయోగించి ఫోటోలు తీయగలదు, వీడియోలను రికార్డ్ చేయగలదు. యాప్‌కు android.permission.CAMERA అనుమతి ఇవ్వడం కూడా అవసరం"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"వైబ్రేషన్‌ను నియంత్రించడం"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"వైబ్రేటర్‌ను నియంత్రించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"వైబ్రేటర్ స్థితిని యాక్సెస్ చేసేందుకు యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"నేరుగా కాల్ చేసే ఫోన్ నంబర్‌లు"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"మీ ప్రమేయం లేకుండా ఫోన్ నంబర్‌లకు కాల్ చేయడానికి యాప్‌ను అనుమతిస్తుంది. దీని వలన అనుకోని ఛార్జీలు విధించబడవచ్చు లేదా కాల్‌లు రావచ్చు. ఇది అత్యవసర నంబర్‌లకు కాల్ చేయడానికి యాప్‌ను అనుమతించదని గుర్తుంచుకోండి. హానికరమైన యాప్‌లు మీ నిర్ధారణ లేకుండానే కాల్‌లు చేయడం ద్వారా మీకు డబ్బు ఖర్చయ్యేలా చేయవచ్చు."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS కాల్ సేవ యాక్సెస్ అనుమతి"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"మళ్లీ ప్రయత్నించండి."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"వేలిముద్రలు నమోదు చేయబడలేదు."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ఈ పరికరంలో వేలిముద్ర సెన్సార్ ఎంపిక లేదు."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"వేలు <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"ముఖం ధృవీకరించలేకపోయింది. మళ్లీ ప్రయత్నించండి."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"మీరు ముఖంతో అన్‌లాక్‌ను సెటప్ చేయలేదు."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"ఈ పరికరంలో ముఖంతో అన్‌లాక్‌ను ఉపయోగించడానికి మద్దతు లేదు."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"ముఖ <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> నుండి, బ్యాక్‌గ్రౌండ్‌లో ప్రారంభమైన ఫోర్ గ్రౌండ్ సేవకు భవిష్యత్తు R బిల్డ్స్‌లో \'ఉపయోగంలో వున్నప్పుడు\' అనుమతి ఉండదు. దయచేసి go/r-bg-fgs-restrictionను చూసి బగ్ నివేదికను ఫైల్ చేయండి."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"వాల్యూమ్‌ను సిఫార్సు చేయబడిన స్థాయి కంటే ఎక్కువగా పెంచాలా?\n\nసుదీర్ఘ వ్యవధుల పాటు అధిక వాల్యూమ్‌లో వినడం వలన మీ వినికిడి శక్తి దెబ్బ తినవచ్చు."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"యాక్సెస్ సామర్థ్యం షార్ట్‌కట్‌ను ఉపయోగించాలా?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"షార్ట్‌కట్ ఆన్‌లో ఉన్నప్పుడు, రెండు వాల్యూమ్ బటన్‌లను 3 సెకన్ల పాటు నొక్కితే యాక్సెస్ సామర్థ్య ఫీచర్ ప్రారంభం అవుతుంది.\n\n ప్రస్తుత యాక్సెస్ సామర్థ్య ఫీచర్:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n సెట్టింగ్‌లు &gt; యాక్సెస్ సామర్థ్యంలో మీరు ఫీచర్‌ను మార్చవచ్చు."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"షార్ట్‌కట్‌లను ఎడిట్ చేయి"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"రద్దు చేయి"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"సత్వరమార్గాన్ని ఆఫ్ చేయి"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> పరిమితం చేయబడిన బకెట్‌లో ఉంచబడింది"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"వ్యక్తిగతం"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"కార్యాలయం"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 46530ca..7f966db 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"ผู้ดูแลระบบปล่อยอุปกรณ์ให้คุณใช้งานส่วนตัว"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"อุปกรณ์มีการจัดการ"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"องค์กรของคุณจัดการอุปกรณ์นี้และอาจตรวจสอบการจราจรของข้อมูลในเครือข่าย แตะเพื่อดูรายละเอียด"</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"ผู้ดูแลระบบได้เปลี่ยนการตั้งค่าตำแหน่ง"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"แตะเพื่อดูการตั้งค่าตำแหน่ง"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"ระบบจะลบข้อมูลในอุปกรณ์ของคุณ"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"ใช้แอปผู้ดูแลระบบนี้ไม่ได้ ขณะนี้ระบบจะลบข้อมูลในอุปกรณ์ของคุณ\n\nโปรดติดต่อผู้ดูแลระบบขององค์กรหากมีคำถาม"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ปิดใช้การพิมพ์แล้ว"</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"แอปของระบบ | ที่ได้รับสิทธิ์นี้จะถ่ายภาพและบันทึกวิดีโอโดยใช้กล้องของระบบได้ทุกเมื่อ แอปต้องมีสิทธิ์ android.permission.CAMERA ด้วย"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"ควบคุมการสั่นเตือน"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"อนุญาตให้แอปพลิเคชันควบคุมการสั่นเตือน"</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"อนุญาตให้แอปเข้าถึงสถานะการสั่น"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"โทรติดต่อหมายเลขโทรศัพท์โดยตรง"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"อนุญาตให้แอปพลิเคชันโทรเข้าโทรศัพท์โดยไม่ต้องให้คุณจัดการ ซึ่งอาจทำให้มีการเรียกเก็บเงินหรือการโทรที่ไม่คาดคิด โปรดทราบว่าการทำงานนี้ไม่ได้อนุญาตให้แอปพลิเคชันโทรไปหมายเลขฉุกเฉิน แอปพลิเคชันที่เป็นอันตรายอาจทำให้คุณต้องเสียค่าบริการด้วยการโทรโดยไม่ขอการยืนยันจากคุณ"</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"เข้าถึงบริการโทร IMS"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"ลองอีกครั้ง"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"ไม่มีลายนิ้วมือที่ลงทะเบียน"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"อุปกรณ์นี้ไม่มีเซ็นเซอร์ลายนิ้วมือ"</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"นิ้ว <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"ยืนยันใบหน้าไม่ได้ ลองอีกครั้ง"</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"คุณยังไม่ได้ตั้งค่า Face Unlock"</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"อุปกรณ์นี้ไม่รองรับ Face Unlock"</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"ใบหน้า <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"บริการที่ทำงานอยู่เบื้องหน้าซึ่งเริ่มขึ้นในเบื้องหลังจาก <xliff:g id="PACKAGENAME">%1$s</xliff:g> จะไม่มีสิทธิ์ขณะใช้งานใน R บิลด์ต่อๆ ไป โปรดดู go/r-bg-fgs-restriction และส่งรายงานข้อบกพร่อง"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"นี่เป็นการเพิ่มระดับเสียงเกินระดับที่แนะนำ\n\nการฟังเสียงดังเป็นเวลานานอาจทำให้การได้ยินของคุณบกพร่องได้"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ใช้ทางลัดการช่วยเหลือพิเศษไหม"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"เมื่อทางลัดเปิดอยู่ การกดปุ่มปรับระดับเสียงทั้ง 2 ปุ่มเป็นเวลา 3 วินาทีจะเริ่มฟีเจอร์การช่วยเหลือพิเศษ\n\n ฟีเจอร์การช่วยเหลือพิเศษปัจจุบัน:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n คุณสามารถเปลี่ยนฟีเจอร์ในการตั้งค่า &gt; การช่วยเหลือพิเศษ"</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"แก้ไขทางลัด"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"ยกเลิก"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ปิดทางลัด"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"ใส่ <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ในที่เก็บข้อมูลที่ถูกจำกัดแล้ว"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"ส่วนตัว"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"งาน"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index b9f1f29..53818ed 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Inalis ng admin ang device para sa personal na paggamit"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Pinamamahalaan ang device"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Pinamamahalaan ng iyong organisasyon ang device na ito, at maaari nitong subaybayan ang trapiko sa network. I-tap para sa mga detalye."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Binago ang mga setting ng lokasyon ng iyong admin"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"I-tap para makita ang iyong mga setting ng lokasyon."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Buburahin ang iyong device"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Hindi magamit ang admin app. Mabubura na ang iyong device.\n\nKung mayroon kang mga tanong, makipag-ugnayan sa admin ng iyong organisasyon."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Na-disable ng <xliff:g id="OWNER_APP">%s</xliff:g> ang pag-print."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Ang privileged | system app na ito ay makakakuha ng mga larawan at makakapag-record ng mga video gamit ang isang camera ng system anumang oras. Nangangailangang may android.permission.CAMERA na pahintulot din ang app"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"kontrolin ang pag-vibrate"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Pinapayagan ang app na kontrolin ang vibrator."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Pinapayagan ang app na ma-access ang naka-vibrate na status."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"direktang tawagan ang mga numero ng telepono"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Pinapayagan ang app na tumawag sa mga numero ng telepono nang wala ng iyong panghihimasok. Maaari itong magresulta sa mga hindi inaasahang pagsingil o tawag. Tandaan na hindi nito pinapayagan ang app na tumawag sa mga numerong pang-emergency. Maaaring magpagastos sa iyo ng pera ang nakakahamak na apps sa pamamagitan ng pagtawag nang wala ng iyong kumpirmasyon."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"i-access ang serbisyo sa tawag ng IMS"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Subukang muli."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Walang naka-enroll na fingerprint."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Walang sensor ng fingerprint ang device na ito."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Daliri <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Hindi ma-verify ang mukha. Subukang muli."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Hindi mo pa nase-set up ang face unlock."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Hindi sinusuportahan ang face unlock sa device na ito."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Mukha <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Ang sinimulan sa background na serbisyo sa foreground mula sa <xliff:g id="PACKAGENAME">%1$s</xliff:g> ay hindi magkakaroon ng pahintulot habang ginagamit sa mga R build sa hinaharap. Pakipuntahan ang go/r-bg-fgs-restriction at maghain ng bugreport."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Lakasan ang volume nang lagpas sa inirerekomendang antas?\n\nMaaaring mapinsala ng pakikinig sa malakas na volume sa loob ng mahahabang panahon ang iyong pandinig."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Gagamitin ang Shortcut sa Pagiging Accessible?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Kapag naka-on ang shortcut, magsisimula ang isang feature ng pagiging naa-access kapag pinindot ang parehong button ng volume sa loob ng 3 segundo.\n\n Kasalukuyang feature ng pagiging naa-access:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Maaari mong baguhin ang feature sa Mga Setting &gt; Pagiging Accessible."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"I-edit ang mga shortcut"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Kanselahin"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"I-off ang Shortcut"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Inilagay ang <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> sa PINAGHIHIGPITANG bucket"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Personal"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Trabaho"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 81fb079..2e3bf3a 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Yönetici, cihazı kişisel kullanım için serbest bıraktı"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Cihaz yönetiliyor"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Kuruluşunuz bu cihazı yönetmekte olup ağ trafiğini izleyebilir. Ayrıntılar için dokunun."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Konum ayarları, yöneticiniz tarafından değiştirildi"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Konum ayarlarınızı görmek için dokunun."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Cihazınız silinecek"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Yönetim uygulaması kullanılamıyor. Cihazınız şimdi silinecek.\n\nSorularınız varsa kuruluşunuzun yöneticisine başvurun."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Yazdırma işlemi <xliff:g id="OWNER_APP">%s</xliff:g> tarafından devre dışı bırakıldı."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Ayrıcalık tanınmış bu | sistem uygulaması herhangi bir zamanda sistem kamerası kullanarak fotoğraf çekebilir ve video kaydedebilir. Uygulamanın da bu ayrıcalığa sahip olması için android.permission.CAMERA izni gerektirir"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"titreşimi denetleme"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Uygulamaya, titreşimi denetleme izni verir."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Uygulamanın titreşim durumuna erişimesine izni verir."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"telefon numaralarına doğrudan çağrı yap"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Uygulamaya sizin müdahaleniz olmadan telefon numaralarına çağrı yapma izni verir. Bu durum beklenmeyen ödemelere veya çağrılara neden olabilir. Ancak bu iznin, uygulamanın acil numaralara çağrı yapmasına olanak sağlamadığını unutmayın. Kötü amaçlı uygulamalar onayınız olmadan çağrılar yaparak sizi zarara sokabilir."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS çağrı hizmetine erişme"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Tekrar deneyin."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Parmak izi kaydedilmedi."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu cihazda parmak izi sensörü yok."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. parmak"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Yüz doğrulanamıyor. Tekrar deneyin."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Yüz tanıma kilidi ayarlamadınız."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Bu cihazda yüz tanıma kilidi desteklenmiyor"</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Yüz <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> paketinden ön plan hizmetini başlatan arka plan, sonraki R derlemelerinde kullanım sırasında iznine sahip olmayacak. Lütfen go/r-bg-fgs-restriction sayfasına bakıp hata raporu girin."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Ses seviyesi önerilen düzeyin üzerine yükseltilsin mi?\n\nUzun süre yüksek ses seviyesinde dinlemek işitme duyunuza zarar verebilir."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Erişilebilirlik Kısayolu Kullanılsın mı?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Kısayol açık olduğunda, ses düğmelerinin ikisini birden 3 saniyeliğine basılı tutmanız bir erişilebilirlik özelliğini başlatır.\n\n Geçerli erişilebilirlik özelliği:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Özelliği, Ayarlar &gt; Erişilebilirlik seçeneğinden değiştirebilirsiniz."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Kısayolları düzenle"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"İptal"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Kısayolu Kapat"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> KISITLANMIŞ gruba yerleştirildi"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Kişisel"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"İş"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index c71ea74..37bb5cd 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -195,6 +195,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Адміністратор не дозволив використовувати пристрій для особистих потреб"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Пристрій контролюється"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Адміністратор вашої організації контролює цей пристрій і відстежує мережевий трафік. Торкніться, щоб дізнатися більше."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Доступ до геоданих змінено адміністратором"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Натисніть, щоб переглянути доступ до геоданих."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"З вашого пристрою буде стерто всі дані"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Не можна запускати додаток для адміністраторів. Буде відновлено заводські налаштування пристрою.\n\nЯкщо у вас є запитання, зв’яжіться з адміністратором своєї організації."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Додаток <xliff:g id="OWNER_APP">%s</xliff:g> вимкнув друк."</string>
@@ -435,6 +437,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Цей пріоритетний | системний додаток може будь-коли робити фото й записувати відео, використовуючи камеру системи. Додатку потрібен дозвіл android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"контролювати вібросигнал"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Дозволяє програмі контролювати вібросигнал."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Надає додатку доступ до стану вібрації."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"прямо набирати номери тел."</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Дозволяє програмі набирати номери телефону без вашого відома. Це може спричинити неочікуване стягнення плати чи здійснення дзвінків. Зауважте, що це не дозволяє програмі набирати екстрені номери. Шкідливі програми можуть здійснювати дзвінки без вашого підтвердження, за що з вас стягуватимуться кошти."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"отримувати доступ до телефонної служби IMS"</string>
@@ -549,6 +552,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Повторіть спробу."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Відбитки пальців не зареєстровано."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На цьому пристрої немає сканера відбитків пальців."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Відбиток пальця <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -592,6 +597,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Не вдається перевірити обличчя. Повторіть спробу."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Ви не налаштували Фейсконтроль"</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"На цьому пристрої не підтримується Фейсконтроль."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Обличчя <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1658,7 +1665,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Активний сервіс пакета <xliff:g id="PACKAGENAME">%1$s</xliff:g>, запущений у фоновому режимі, не матиме дозволу \"Коли додаток використовується\" в майбутніх складаннях R. Перегляньте go/r-bg-fgs-restriction і надішліть звіт про помилки."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Збільшити гучність понад рекомендований рівень?\n\nЯкщо слухати надто гучну музику тривалий час, можна пошкодити слух."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Використовувати швидке ввімкнення?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Коли ярлик увімкнено, після натискання обох клавіш гучності й утримування їх протягом 3 секунд увімкнеться функція спеціальних можливостей.\n\n Поточна функція спеціальних можливостей:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Цю функцію можна змінити в меню \"Налаштування\" &gt; \"Спеціальні можливості\"."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Редагувати засоби"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Скасувати"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Вимкнути ярлик"</string>
@@ -2078,4 +2086,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Пакет \"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>\" додано в сегмент з обмеженнями"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Особисте"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Робоче"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 8a0425b..f2157bd 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"منتظم نے ذاتی استعمال کے لیے آلہ کو دستبردار کیا ہے"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"آلہ زیر انتظام ہے"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"آپ کی تنظیم اس آلے کا نظم کرتی ہے اور وہ نیٹ ورک ٹریفک کی نگرانی کر سکتی ہے۔ تفاصیل کیلئے تھپتھپائیں۔"</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"آپ کے منتظم نے مقام کی ترتیبات تبدیل کر دی"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"اپنے مقام کی ترتیبات دیکھنے کے لیے تھپتھپائیں۔"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"آپ کا آلہ صاف کر دیا جائے گا"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"منتظم کی ایپ استعمال نہیں کی جا سکتی۔ آپ کا آلہ اب مٹا دیا جائے گا۔\n\nاگر آپ کے سوالات ہیں تو اپنی تنظیم کے منتظم سے رابطہ کریں۔"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> نے پرنٹنگ کو غیر فعال کر دیا ہے۔"</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"‏یہ مراعات یافتہ سسٹم ایپ کسی بھی وقت ایک سسٹم کیمرا استعمال کرتے ہوئے تصاویر اور ویڈیوز ریکارڈ کر سکتی ہے۔ ایپ کے پاس android.permission.CAMERA کے ليے بھی اجازت ہونا ضروری ہے۔"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"ارتعاش کو کنٹرول کریں"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"ایپ کو وائبریٹر کنٹرول کرنے کی اجازت دیتا ہے۔"</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"ایپ کو وائبریٹر اسٹیٹ تک رسائی حاصل کرنے کی اجازت دیتا ہے۔"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"براہ راست فون نمبرز پر کال کریں"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"ایپ کو آپ کی مداخلت کے بغیر فون نمبروں پر کال کرنے کی اجازت دیتا ہے۔ اس کے نتیجے میں غیر متوقع چارجز یا کالیں ہوسکتی ہیں۔ نوٹ کرلیں کہ یہ ایپ کو ہنگامی نمبروں پر کال کرنے کی اجازت نہیں دیتا ہے۔ نقصان دہ ایپس آپ کی تصدیق کے بغیر کالیں کرکے آپ کی رقم صرف کروا سکتے ہیں۔"</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"‏IMS کال سروس تک رسائی حاصل کریں"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"دوبارہ کوشش کریں۔"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"کوئی فنگر پرنٹ مندرج شدہ نہیں ہے۔"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"اس آلہ میں فنگر پرنٹ سینسر نہیں ہے۔"</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"انگلی <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"چہرے کی توثیق نہیں کی جا سکی۔ پھر آزمائيں۔"</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"آپ نے بذریعہ چہرہ غیر مقفل کرنے کو سیٹ نہیں کیا ہے۔"</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"اس آلہ پر چہرے کے ذریعے غیر مقفل کرنا تعاون یافتہ نہیں ہے۔"</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"چہرہ <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"‏پس منظر <xliff:g id="PACKAGENAME">%1$s</xliff:g> سے شروع کی گئی پیش منظر کی سروس کو مستقبل کے R بلڈز میں استعمال کے دوران اجازت نہیں ہوگی۔ براہ کرم go/r-bg-fgs-restriction دیکھیں اور بگ رپورٹ دائر کریں۔"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"والیوم کو تجویز کردہ سطح سے زیادہ کریں؟\n\nزیادہ وقت تک اونچی آواز میں سننے سے آپ کی سماعت کو نقصان پہنچ سکتا ہے۔"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ایکسیسبیلٹی شارٹ کٹ استعمال کریں؟"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"شارٹ کٹ آن ہونے پر، 3 سیکنڈ تک دونوں والیوم بٹنز کو دبانے سے ایک ایکسیسبیلٹی خصوصیت شروع ہو جائے گی۔\n\n موجودہ ایکسیسبیلٹی خصوصیت:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n آپ خصوصیت کو ترتیبات &gt; ایکسیسبیلٹی میں جا کر تبدیل کر سکتے ہیں۔"</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"شارٹ کٹس میں ترمیم کریں"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"منسوخ کریں"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"شارٹ کٹ آف کریں"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> کو پابند کردہ بکٹ میں رکھ دیا گیا ہے"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"ذاتی"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"دفتر"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index b5c31c2..ee5a7d2 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Administrator shaxsiy foydalanishga qoldirilgan qurilmani rad etdi"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Bu – boshqariladigan qurilma"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Tashkilotingiz bu qurilmani boshqaradi va tarmoq trafigini nazorat qilishi mumkin. Tafsilotlar uchun bosing."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Joylashuv sozlamalari administratoringiz tomonidan oʻzgartirildi"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Joylashuv sozlamalarini koʻrish uchun bosing."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Qurilmangizdagi ma’lumotlar o‘chirib tashlanadi"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Administrator ilovasini ishlatib bo‘lmaydi. Qurilmada barcha ma’lumotlar o‘chirib tashlanadi.\n\nSavollaringiz bo‘lsa, administrator bilan bog‘laning."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Chop etish funksiyasi <xliff:g id="OWNER_APP">%s</xliff:g> tomonidan faolsizlantirilgan."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Bu imtiyozli | tizim ilovasi istalgan vaqtda tizim kamerasi orqali surat va videolar olishi mumkin. Ilovada android.permission.CAMERA ruxsati ham yoqilgan boʻlishi talab qilinadi"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"tebranishni boshqarish"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Ilova tebranishli signallarni boshqarishi mumkin."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Ilovaga tebranish holatiga kirish ruxsatini beradi."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"telefon raqamlariga tog‘ridan to‘g‘ri qo‘ng‘iroq qilish"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Ilovaga sizning yordamingizsiz telefonga qo‘ng‘iroq qilish imkonini beradi. Bu kutilmagan qo‘ng‘iroqlarni amalga oshirishi yoki ortiqcha to‘lovlarni yuzaga keltirishi mumkin. Shunga e’tibor qilinki, u favqulodda telefon raqamlariga qo‘ng‘iroqlar qilishga ruxsat bermaydi. Zararli ilovalar sizdan so‘ramasdan qo‘ng‘iroqlarni amalga oshirib, pulingizni sarflashi mumkin."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"IMS qo‘ng‘iroq xizmatiga kirish"</string>
@@ -543,6 +546,7 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Qayta urinib ko‘ring."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Hech qanday barmoq izi qayd qilinmagan."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu qurilmada barmoq izi skaneri mavjud emas."</string>
+    <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor vaqtincha faol emas."</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Barmoq izi <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +590,7 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Yuzingiz tasdiqlanmadi. Qaytadan urining."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Hali yuz bilan ochishni sozlamagansiz"</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Yuz bilan ochish bu qurilmada ishlamaydi"</string>
+    <string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor vaqtincha faol emas."</string>
     <string name="face_name_template" msgid="3877037340223318119">"Yuz <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1619,7 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Fonda faol <xliff:g id="PACKAGENAME">%1$s</xliff:g> xizmatini ishga tushirish uchun kelgusi R nashrlarida ishlatilayotganda ruxsat berish imkoniyati boʻlmaydi. go/r-bg-fgs-restriction sahifasiga kiring va xatolik hisobotini yuboring."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Tovush balandligi tavsiya etilgan darajadan ham yuqori qilinsinmi?\n\nUzoq vaqt davomida baland ovozda tinglash eshitish qobiliyatingizga salbiy ta’sir ko‘rsatishi mumkin."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Tezkor ishga tushirishdan foydalanilsinmi?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Maxsus imkoniyatlar funksiyasidan foydalanish uchun u yoniqligida ikkala ovoz balandligini boshqarish tugmasini 3 soniya bosib turing.\n\n Joriy maxsus imkoniyatlar funksiyasi:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Bu funksiyani Sozlamalar &gt; Maxsus imkoniyatlar orqali o‘zgartirish mumkin."</string>
+    <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Maxsus imkoniyatlar funksiyasidan foydalanish uchun u yoniqligida ikkala ovoz balandligini boshqarish tugmasini 3 soniya bosib turing."</string>
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Tezkor tugmalarni tahrirlash"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Bekor qilish"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Tezkor ishga tushirishni o‘chirib qo‘yish"</string>
@@ -2010,4 +2015,12 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> cheklangan turkumga joylandi"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Shaxsiy"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Ish"</string>
+    <string name="resolver_cant_share_with_work_apps" msgid="7539495559434146897">"Ishchi ilovalarga ulashilmaydi"</string>
+    <string name="resolver_cant_share_with_personal_apps" msgid="8020581735267157241">"Shaxsiy ilovalarga ulashilmaydi"</string>
+    <string name="resolver_cant_share_cross_profile_explanation" msgid="3536237105241882679">"Shaxsiy va ishchi ilovalararo axborot ulashish AT administratori tomonidan taqiqlangan"</string>
+    <string name="resolver_turn_on_work_apps" msgid="8987359079870455469">"Ishchi ilovalarni yoqish"</string>
+    <string name="resolver_turn_on_work_apps_explanation" msgid="6322467455509618928">"Ishchi ilova va kontaktlarni ochish uchun ishchi ilovalarni yoqing"</string>
+    <string name="resolver_no_apps_available" msgid="7710339903040989654">"Mos ilova topilmadi"</string>
+    <string name="resolver_no_apps_available_explanation" msgid="4662694431121196560">"Hech qanday ilova topilmadi"</string>
+    <string name="resolver_switch_on_work" msgid="8294542702883688533">"Ishchi rejimni yoqish"</string>
 </resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 970d41f..1a8a275 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Quản trị viên đã từ bỏ quyền sở hữu thiết bị để cho phép dùng vào mục đích cá nhân"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Thiết bị được quản lý"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Tổ chức của bạn sẽ quản lý thiết bị này và có thể theo dõi lưu lượng truy cập mạng. Nhấn để biết chi tiết."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Quản trị viên của bạn đã thay đổi các tùy chọn cài đặt vị trí"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Nhấn để xem các tùy chọn cài đặt vị trí của bạn."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Thiết bị của bạn sẽ bị xóa"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Không thể sử dụng ứng dụng quản trị. Thiết bị của bạn sẽ bị xóa ngay bây giờ.\n\nHãy liên hệ với quản trị viên của tổ chức nếu bạn có thắc mắc."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> đã tắt tính năng in."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Ứng dụng hệ thống/đặc quyền này có thể dùng máy ảnh hệ thống để chụp ảnh và quay video bất cứ lúc nào. Ngoài ra, ứng dụng này cũng cần có quyền android.permission.CAMERA"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"kiểm soát rung"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Cho phép ứng dụng kiểm soát bộ rung."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Cho phép ứng dụng truy cập vào trạng thái bộ rung."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"gọi trực tiếp số điện thoại"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Cho phép ứng dụng gọi các số điện thoại mà không cần sự can thiệp của bạn. Việc này có thể dẫn đến các khoản phí hoặc cuộc gọi không mong muốn. Lưu ý rằng quyền này không cho phép ứng dụng gọi các số khẩn cấp. Các ứng dụng độc hại có thể khiến bạn tốn tiền do thực hiện cuộc gọi mà không cần sự xác nhận của bạn."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"truy cập dịch vụ gọi điện qua IMS"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Thử lại."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Chưa đăng ký vân tay."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Thiết bị này không có cảm biến vân tay."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Ngón tay <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Không thể xác minh khuôn mặt. Hãy thử lại."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Bạn chưa thiết lập tính năng mở khóa bằng khuôn mặt."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"Thiết bị này không hỗ trợ tính năng mở khóa bằng khuôn mặt."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Khuôn mặt <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Dịch vụ trên nền trước đã bắt đầu ở nền từ <xliff:g id="PACKAGENAME">%1$s</xliff:g> sẽ không có quyền khi đang sử dụng trong các bản dựng R trong tương lai. Vui lòng xem go/r-bg-fgs-restriction và gửi báo cáo lỗi."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Bạn tăng âm lượng lên quá mức khuyên dùng?\n\nViệc nghe ở mức âm lượng cao trong thời gian dài có thể gây tổn thương thính giác của bạn."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Sử dụng phím tắt Hỗ trợ tiếp cận?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Khi phím tắt được bật, nhấn cả hai nút âm lượng trong 3 giây sẽ bắt đầu một tính năng trợ năng.\n\n Tính năng trợ năng hiện tại:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Bạn có thể thay đổi tính năng trong Cài đặt &gt; Trợ năng."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Chỉnh sửa phím tắt"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Hủy"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Tắt phím tắt"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Đã đưa <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> vào bộ chứa BỊ HẠN CHẾ"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Cá nhân"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Cơ quan"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index c9bba59..2339a44 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"管理员已将该设备开放给个人使用"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"设备为受管理设备"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"贵单位会管理该设备,且可能会监控网络流量。点按即可了解详情。"</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"您的管理员已更改位置信息设置"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"点按即可查看您的位置信息设置。"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"系统将清空您的设备"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"无法使用管理应用,系统现在将清空您的设备。\n\n如有疑问,请与您所在单位的管理员联系。"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"“<xliff:g id="OWNER_APP">%s</xliff:g>”已停用打印功能。"</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"获取访问权限后,这个系统应用就随时可以使用系统相机拍照及录制视频。另外,应用还需要获取 android.permission.CAMERA 权限"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"控制振动"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"允许应用控制振动器。"</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"允许该应用访问振动器状态。"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"拨打电话"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"允许该应用在您未执行操作的情况下拨打电话号码。此权限可能会导致意外收费或呼叫。请注意,此权限不允许该应用拨打紧急电话号码。恶意应用可通过拨打电话产生相关费用,而无需您的确认。"</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"使用即时通讯通话服务"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"请重试。"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"未注册任何指纹。"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此设备没有指纹传感器。"</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"无法验证人脸,请重试。"</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"您尚未设置人脸解锁。"</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"此设备不支持人脸解锁。"</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"面孔 <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"在未来的 R 版本中,在后台启动的 <xliff:g id="PACKAGENAME">%1$s</xliff:g> 中的前台服务将不具有仅在使用时授予的权限。请访问 go/r-bg-fgs-restriction 并提交错误报告。"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"要将音量调高到建议的音量以上吗?\n\n长时间保持高音量可能会损伤听力。"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"要使用无障碍快捷方式吗?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"开启快捷方式后,同时按下两个音量按钮 3 秒钟即可启动所设定的无障碍功能。\n\n当前设定的无障碍功能:\n<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n如需更改设定的功能,请依次转到“设置”&gt;“无障碍”。"</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"修改快捷方式"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"取消"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"关闭快捷方式"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> 已被放入受限存储分区"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"个人"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"工作"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index fc652e3..94783a0 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"管理員已開放裝置供個人使用"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"裝置已受管理"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"您的機構會管理此裝置,並可能會監控網絡流量。輕按即可瞭解詳情。"</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"您的管理員變更了位置設定"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"輕按即可查看位置設定。"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"您的裝置將被清除"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"無法使用管理員應用程式。系統會現在清除您的裝置。\n\n如有任何疑問,請聯絡您的機構管理員。"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"「<xliff:g id="OWNER_APP">%s</xliff:g>」暫停了列印。"</string>
@@ -283,7 +285,7 @@
     <string name="managed_profile_label" msgid="7316778766973512382">"切換至工作設定檔"</string>
     <string name="permgrouplab_contacts" msgid="4254143639307316920">"通訊錄"</string>
     <string name="permgroupdesc_contacts" msgid="9163927941244182567">"存取您的通訊錄"</string>
-    <string name="permgrouplab_location" msgid="1858277002233964394">"位置資訊"</string>
+    <string name="permgrouplab_location" msgid="1858277002233964394">"位置"</string>
     <string name="permgroupdesc_location" msgid="1995955142118450685">"存取此裝置的位置"</string>
     <string name="permgrouplab_calendar" msgid="6426860926123033230">"日曆"</string>
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"存取您的日曆"</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"這個獲特別權限的系統應用程式可以在任何時候使用系統相機來拍照和攝錄。此外,應用程式亦需要 android.permission.CAMERA 權限"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"控制震動"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"允許應用程式控制震動。"</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"允許應用程式存取震動狀態。"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"直接撥打電話號碼"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"允許應用程式繞過您自行撥打電話號碼,但可能會產生未預期的費用或撥打未預期的電話。注意:這項權限不允許應用程式撥打緊急電話。惡意應用程式可能未經您確認擅自撥打電話,增加您的支出。"</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"使用 IMS 通話服務"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"再試一次。"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"未註冊任何指紋"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此裝置沒有指紋感應器。"</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"無法驗證臉孔。請再試一次。"</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"您尚未設定「臉孔解鎖」。"</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"此裝置不支援「臉孔解鎖」。"</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"臉孔 <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"從「<xliff:g id="PACKAGENAME">%1$s</xliff:g>」啟動前景服務的背景將不會在未來的 R 版本中提供「僅在使用此應用程式時允許」權限。請參閱 go/r-bg-fgs-restriction,提交錯誤報告。"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"要調高音量 (比建議的音量更大聲) 嗎?\n\n長時間聆聽高分貝音量可能會導致您的聽力受損。"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"要使用無障礙功能快速鍵嗎?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"快速鍵開啟後,同時按住音量按鈕 3 秒,無障礙功能便會啟用。\n\n目前的無障礙功能:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n如要變更功能,請前往「設定」&gt;「無障礙功能」。"</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"編輯捷徑"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"取消"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"關閉快速鍵"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> 已納入受限制的儲存區"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"個人"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"公司"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 75d05a2..f3da0d8 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"管理員將這部裝置開放給個人使用"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"裝置受到管理"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"貴機構會管理這個裝置,且可能監控網路流量。輕觸即可瞭解詳情。"</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"你的管理員變更了位置資訊設定"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"輕觸即可查看位置資訊設定。"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"你的裝置資料將遭到清除"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"無法使用管理應用程式,系統現在將清除你裝置中的資料。\n\n如有任何問題,請與貴機構的管理員聯絡。"</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"「<xliff:g id="OWNER_APP">%s</xliff:g>」已停用列印功能。"</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"取得存取權後,這個系統應用程式就隨時可以使用系統攝影機拍照及錄影。此外,你也必須將 android.permission.CAMERA 權限授予這個應用程式"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"控制震動"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"允許應用程式控制震動。"</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"允許應用程式存取震動狀態。"</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"直接撥打電話號碼"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"允許應用程式自行撥打電話,但可能產生非預期的費用或撥打非預期的電話。注意:這項權限不允許應用程式撥打緊急電話。惡意應用程式可能利用此功能擅自撥打電話,增加你不必要的額外支出。"</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"存取 IMS 撥號服務"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"請再試一次。"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"未登錄任何指紋。"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"這個裝置沒有指紋感應器。"</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"無法驗證臉孔,請再試一次。"</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"你尚未設定人臉解鎖功能。"</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"這個裝置不支援人臉解鎖功能。"</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"臉孔 <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"來自「<xliff:g id="PACKAGENAME">%1$s</xliff:g>」的背景啟動前景服務不會具備未來 R 版本的使用狀態權限。請前往 go/r-bg-fgs-restriction 並提交錯誤報告。"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"要調高音量,比建議的音量更大聲嗎?\n\n長時間聆聽高分貝音量可能會使你的聽力受損。"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"要使用無障礙捷徑嗎?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"啟用捷徑功能後,只要同時按下兩個音量鍵 3 秒,就能啟動無障礙功能。\n\n 目前設定的無障礙功能為:\n<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n 如要變更設定的功能,請依序輕觸 [設定] &gt; [無障礙設定]。"</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"編輯捷徑"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"取消"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"停用捷徑"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"已將「<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>」移入受限制的值區"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"個人"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"工作"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 0d2abc0..d4a6c26 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -191,6 +191,8 @@
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"Umphathi udedela idivayisi ngokusetshenziswa komuntu siqu"</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"Idivayisi iphethwe"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Inhlangano yakho iphethe le divayisi futhi kungenzeka ingaqaphi ithrafikhi yenethiwekhi. Thephela imininingwane."</string>
+    <string name="location_changed_notification_title" msgid="4119726617105166830">"Izilungiselelo zendawo zishintshwe umphathi wakho"</string>
+    <string name="location_changed_notification_text" msgid="198907268219396399">"Thepha ukuze ubone izilungiselelo zakho zendawo."</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Idivayisi yakho izosulwa"</string>
     <string name="factory_reset_message" msgid="2657049595153992213">"Uhlelo lokusebenza lomlawuli alikwazi ukusetshenziswa. Idivayisi yakho manje izosuswa.\n\nUma unemibuzo, xhumana nomlawuli wezinhlangano zakho."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Ukuphrinta kukhutshazwe nge-<xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -429,6 +431,7 @@
     <string name="permdesc_systemCamera" msgid="544730545441964482">"Lolu hlelo lokusebenza lesistimu le-| lingathatha izithombe futhi lirekhode amavidiyo lisebenzisa ikhamera yesistimu noma kunini. Idinga imvume ye-android.permission.CAMERA permission ukuthi iphathwa uhlelo lokusebenza futhi"</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"lawula ukudlidliza"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Ivumela uhlelo lokusebenza ukulawula isidlidlizi."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Ivumela uhlelo lokusebenza ukuthi lufinyelele kusimo sesidlidlizeli."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"ngokuqondile shayela izinombolo zocingo"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Ivumela uhlelo lokusebenza ukushayela izinombolo zefoni ngaphandle kokuhlanganyela kwakho. Lokhu kungaholela emashajini noma amakholi angalindelekile. Qaphela ukuthi lokhu akuvumeli uhlelo lokusebenza ukushayela izinombolo zesimo esiphuthumayo. Izinhlelo zokusebenza ezingalungile zingabiza imali ngokwenze amakholi ngaphandle kokuqinisekisa kwakho."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"finyelela kusevisi yekholi ye-IMS"</string>
@@ -543,6 +546,8 @@
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Zama futhi."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Azikho izigxivizo zeminwe ezibhalisiwe."</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Le divayisi ayinayo inzwa yezigxivizo zeminwe."</string>
+    <!-- no translation found for fingerprint_error_security_update_required (7750187320640856433) -->
+    <skip />
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Umunwe ongu-<xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
@@ -586,6 +591,8 @@
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Ayikwazi ukuqinisekisa ubuso. Zama futhi."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Awukakasethi i-face unlock."</string>
     <string name="face_error_hw_not_present" msgid="1070600921591729944">"I-face unlock ayisekelwe kule divayisi."</string>
+    <!-- no translation found for face_error_security_update_required (5076017208528750161) -->
+    <skip />
     <string name="face_name_template" msgid="3877037340223318119">"Ubuso be-<xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1614,7 +1621,8 @@
     <string name="allow_while_in_use_permission_in_fgs" msgid="4101339676785053656">"Ingemuva eqalise isevisi yasemuva kusuka ku-<xliff:g id="PACKAGENAME">%1$s</xliff:g> ngeke ithole imvume yokusebenzisa yesikhathi ekwakheni kwe-R ezayo. Sicela ubone i-go/r-bg-fgs-restriction bese ufayele umbiko wesiphazamiso."</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Khuphukisa ivolumu ngaphezu kweleveli enconyiwe?\n\nUkulalela ngevolumu ephezulu izikhathi ezide kungahle kulimaze ukuzwa kwakho."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Sebenzisa isinqamuleli sokufinyelela?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="8306239551412868396">"Uma kuvulwe isinqamuleli, ukucindezela zombili izinkinobho zevolumu amasekhondi angu-3 kuzoqala isici sokufinyelela.\n\n Isici samanje sokufinyelela:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Ungashintsha isici kuzilungiselelo &gt; Ukufinyelela."</string>
+    <!-- no translation found for accessibility_shortcut_toogle_warning (4161716521310929544) -->
+    <skip />
     <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"Hlela izinqamuleli"</string>
     <string name="cancel_accessibility_shortcut_menu_button" msgid="1817413122335452474">"Khansela"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Vala isinqamuleli"</string>
@@ -2010,4 +2018,20 @@
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"I-<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ifakwe kubhakede LOKUKHAWULELWE"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Okomuntu siqu"</string>
     <string name="resolver_work_tab" msgid="2690019516263167035">"Umsebenzi"</string>
+    <!-- no translation found for resolver_cant_share_with_work_apps (7539495559434146897) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_with_personal_apps (8020581735267157241) -->
+    <skip />
+    <!-- no translation found for resolver_cant_share_cross_profile_explanation (3536237105241882679) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps (8987359079870455469) -->
+    <skip />
+    <!-- no translation found for resolver_turn_on_work_apps_explanation (6322467455509618928) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available (7710339903040989654) -->
+    <skip />
+    <!-- no translation found for resolver_no_apps_available_explanation (4662694431121196560) -->
+    <skip />
+    <!-- no translation found for resolver_switch_on_work (8294542702883688533) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 7fc041c..9cdd3ed 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -9207,12 +9207,4 @@
     </declare-styleable>
 
     <attr name="autoSizePresetSizes" />
-
-    <declare-styleable name="AutofillInlineSuggestion">
-        <!-- @hide @SystemApi -->
-        <attr name="isAutofillInlineSuggestionTheme" format="boolean" />
-        <attr name="autofillInlineSuggestionChip" format="reference" />
-        <attr name="autofillInlineSuggestionTitle" format="reference" />
-        <attr name="autofillInlineSuggestionSubtitle" format="reference" />
-    </declare-styleable>
 </resources>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index e231c3a..16bed503 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1770,6 +1770,21 @@
              -->
         <attr name="requestLegacyExternalStorage" format="boolean" />
 
+        <!-- If {@code true} this app would like to preserve the legacy storage
+             model from a previously installed version. Note that this may not always be
+             respected due to policy or backwards compatibility reasons.
+
+             <p>This has no effect on the first install of an app on a device.
+             For an updating app, setting this to {@code true} will preserve the legacy behaviour
+             configured by the {@code requestLegacyExternalStorage} flag. If on an update, this
+             flag is set to {@code false} then the legacy access is not preserved, such an app can
+             only have legacy access with the {@code requestLegacyExternalStorage} flag.
+             <p>
+
+             The default value is {@code false}.
+             -->
+        <attr name="preserveLegacyExternalStorage" format="boolean" />
+
         <!-- If {@code true} this app declares that it should be visible to all other apps on
              device, regardless of what they declare via the {@code queries} tags in their
              manifest.
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 9282925..b82591f 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -59,6 +59,7 @@
         <item><xliff:g id="id">@string/status_bar_airplane</xliff:g></item>
         <item><xliff:g id="id">@string/status_bar_battery</xliff:g></item>
         <item><xliff:g id="id">@string/status_bar_sensors_off</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_screen_record</xliff:g></item>
     </string-array>
 
     <string translatable="false" name="status_bar_rotate">rotate</string>
@@ -94,6 +95,7 @@
     <string translatable="false" name="status_bar_camera">camera</string>
     <string translatable="false" name="status_bar_airplane">airplane</string>
     <string translatable="false" name="status_bar_sensors_off">sensors_off</string>
+    <string translatable="false" name="status_bar_screen_record">screen_record</string>
 
     <!-- Flag indicating whether the surface flinger has limited
          alpha compositing functionality in hardware.  If set, the window
@@ -272,7 +274,7 @@
     <!-- When true, Android uses the PAC implementation included in WebView to handle
          networks with PAC scripts.
          When false, Android's own implementation of libpac is used.-->
-    <bool name ="config_useWebViewPacProcessor">false</bool>
+    <bool name ="config_useWebViewPacProcessor">true</bool>
 
     <!-- XXXXX NOTE THE FOLLOWING RESOURCES USE THE WRONG NAMING CONVENTION.
          Please don't copy them, copy anything else. -->
@@ -2830,13 +2832,13 @@
          "logout" =  Logout the current user
          -->
     <string-array translatable="false" name="config_globalActionsList">
+        <item>emergency</item>
         <item>power</item>
         <item>restart</item>
         <item>lockdown</item>
         <item>logout</item>
         <item>bugreport</item>
         <item>screenshot</item>
-        <item>emergency</item>
     </string-array>
 
     <!-- Number of milliseconds to hold a wake lock to ensure that drawing is fully
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 0edad3b..80e5d1b 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3012,19 +3012,14 @@
       <public name="sdkVersion" />
       <!-- @hide @SystemApi -->
       <public name="minExtensionVersion" />
-      <public name="autofillInlineSuggestionChip" />
-      <public name="autofillInlineSuggestionTitle" />
-      <public name="autofillInlineSuggestionSubtitle" />
-      <!-- @hide @SystemApi -->
-      <public name="isAutofillInlineSuggestionTheme" />
       <public name="allowNativeHeapPointerTagging" />
+      <public name="preserveLegacyExternalStorage" />
     </public-group>
 
     <public-group type="drawable" first-id="0x010800b5">
     </public-group>
 
     <public-group type="style" first-id="0x010302e5">
-      <public name="Theme.AutofillInlineSuggestion" />
     </public-group>
 
     <public-group type="id" first-id="0x0102004a">
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 751eca0..bcce1f0 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1482,22 +1482,6 @@
         <item name="android:windowExitAnimation">@anim/slide_out_down</item>
     </style>
 
-    <!-- The style for the Autofill inline suggestion chip. -->
-    <!-- @hide -->
-    <style name="AutofillInlineSuggestionChip">
-        <item name="background">@drawable/autofill_dataset_picker_background</item>
-    </style>
-
-    <!-- @hide -->
-    <style name="AutofillInlineSuggestionTitle">
-        <item name="android:textAppearance">@style/TextAppearance</item>
-    </style>
-
-    <!-- @hide -->
-    <style name="AutofillInlineSuggestionSubtitle">
-        <item name="android:textAppearance">@style/TextAppearance.Small</item>
-    </style>
-
     <!-- The style for the container of media actions in a notification. -->
     <!-- @hide -->
     <style name="NotificationMediaActionContainer">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 5aefe11..02d90a7 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2908,6 +2908,7 @@
   <java-symbol type="string" name="status_bar_microphone" />
   <java-symbol type="string" name="status_bar_camera" />
   <java-symbol type="string" name="status_bar_sensors_off" />
+  <java-symbol type="string" name="status_bar_screen_record" />
 
   <!-- Locale picker -->
   <java-symbol type="id" name="locale_search_menu" />
@@ -3260,7 +3261,6 @@
   <java-symbol type="layout" name="autofill_dataset_picker"/>
   <java-symbol type="layout" name="autofill_dataset_picker_fullscreen"/>
   <java-symbol type="layout" name="autofill_dataset_picker_header_footer"/>
-  <java-symbol type="layout" name="autofill_inline_suggestion" />
   <java-symbol type="id" name="autofill" />
   <java-symbol type="id" name="autofill_dataset_footer"/>
   <java-symbol type="id" name="autofill_dataset_header"/>
@@ -3268,10 +3268,6 @@
   <java-symbol type="id" name="autofill_dataset_list"/>
   <java-symbol type="id" name="autofill_dataset_picker"/>
   <java-symbol type="id" name="autofill_dataset_title" />
-  <java-symbol type="id" name="autofill_inline_suggestion_end_icon" />
-  <java-symbol type="id" name="autofill_inline_suggestion_start_icon" />
-  <java-symbol type="id" name="autofill_inline_suggestion_subtitle" />
-  <java-symbol type="id" name="autofill_inline_suggestion_title" />
   <java-symbol type="id" name="autofill_save_custom_subtitle" />
   <java-symbol type="id" name="autofill_save_icon" />
   <java-symbol type="id" name="autofill_save_no" />
@@ -3902,4 +3898,6 @@
 
   <!-- Whether to expand the lock screen user switcher by default -->
   <java-symbol type="bool" name="config_expandLockScreenUserSwitcher" />
+
+  <java-symbol type="string" name="loading" />
 </resources>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 5e6dd82..5d9cb48 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -892,12 +892,4 @@
         <item name="windowContentTransitions">false</item>
         <item name="windowActivityTransitions">false</item>
     </style>
-
-    <!-- Theme for the Autofill inline suggestion on IME -->
-    <style name="Theme.AutofillInlineSuggestion" parent="Theme.DeviceDefault">
-        <item name="isAutofillInlineSuggestionTheme">true</item>
-        <item name="autofillInlineSuggestionChip">@style/AutofillInlineSuggestionChip</item>
-        <item name="autofillInlineSuggestionTitle">@style/AutofillInlineSuggestionTitle</item>
-        <item name="autofillInlineSuggestionSubtitle">@style/AutofillInlineSuggestionSubtitle</item>
-    </style>
 </resources>
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index be94f02..59335a5 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -138,9 +138,6 @@
     <!-- vr test permissions -->
     <uses-permission android:name="android.permission.RESTRICTED_VR_ACCESS" />
 
-    <!-- WindowMetricsTest permissions -->
-    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
-
     <application android:theme="@style/Theme" android:supportsRtl="true">
         <uses-library android:name="android.test.runner" />
         <uses-library android:name="org.apache.http.legacy" android:required="false" />
diff --git a/core/tests/coretests/src/android/app/NotificationHistoryTest.java b/core/tests/coretests/src/android/app/NotificationHistoryTest.java
index d1608d0..8d8acb7 100644
--- a/core/tests/coretests/src/android/app/NotificationHistoryTest.java
+++ b/core/tests/coretests/src/android/app/NotificationHistoryTest.java
@@ -21,6 +21,7 @@
 import android.app.NotificationHistory.HistoricalNotification;
 import android.graphics.drawable.Icon;
 import android.os.Parcel;
+import android.util.Slog;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
@@ -48,6 +49,10 @@
         String expectedText = "text" + index;
         Icon expectedIcon = Icon.createWithResource(InstrumentationRegistry.getContext(),
                 index);
+        String conversationId = null;
+        if (index % 2 == 0) {
+            conversationId = "convo" + index;
+        }
 
         return new HistoricalNotification.Builder()
                 .setPackage(packageName)
@@ -59,6 +64,7 @@
                 .setTitle(expectedTitle)
                 .setText(expectedText)
                 .setIcon(expectedIcon)
+                .setConversationId(conversationId)
                 .build();
     }
 
@@ -74,6 +80,7 @@
         String expectedText = "text";
         Icon expectedIcon = Icon.createWithResource(InstrumentationRegistry.getContext(),
                 android.R.drawable.btn_star);
+        String expectedConversationId = "convo";
 
         HistoricalNotification n = new HistoricalNotification.Builder()
                 .setPackage(expectedPackage)
@@ -85,6 +92,7 @@
                 .setTitle(expectedTitle)
                 .setText(expectedText)
                 .setIcon(expectedIcon)
+                .setConversationId(expectedConversationId)
                 .build();
 
         assertThat(n.getPackage()).isEqualTo(expectedPackage);
@@ -96,6 +104,7 @@
         assertThat(n.getTitle()).isEqualTo(expectedTitle);
         assertThat(n.getText()).isEqualTo(expectedText);
         assertThat(expectedIcon.sameAs(n.getIcon())).isTrue();
+        assertThat(n.getConversationId()).isEqualTo(expectedConversationId);
     }
 
     @Test
@@ -153,6 +162,9 @@
             expectedStrings.add(n.getPackage());
             expectedStrings.add(n.getChannelName());
             expectedStrings.add(n.getChannelId());
+            if (n.getConversationId() != null) {
+                expectedStrings.add(n.getConversationId());
+            }
             history.addNotificationToWrite(n);
         }
 
@@ -180,6 +192,9 @@
             expectedStrings.add(n.getPackage());
             expectedStrings.add(n.getChannelName());
             expectedStrings.add(n.getChannelId());
+            if (n.getConversationId() != null) {
+                expectedStrings.add(n.getConversationId());
+            }
             history.addNotificationToWrite(n);
         }
 
@@ -212,6 +227,9 @@
                 postRemoveExpectedStrings.add(n.getPackage());
                 postRemoveExpectedStrings.add(n.getChannelName());
                 postRemoveExpectedStrings.add(n.getChannelId());
+                if (n.getConversationId() != null) {
+                    postRemoveExpectedStrings.add(n.getConversationId());
+                }
                 postRemoveExpectedEntries.add(n);
             }
 
@@ -221,14 +239,14 @@
         history.poolStringsFromNotifications();
 
         assertThat(history.getNotificationsToWrite().size()).isEqualTo(10);
-        // 2 package names and 10 * 2 unique channel names and ids
-        assertThat(history.getPooledStringsToWrite().length).isEqualTo(22);
+        // 2 package names and 10 * 2 unique channel names and ids and 5 conversation ids
+        assertThat(history.getPooledStringsToWrite().length).isEqualTo(27);
 
         history.removeNotificationsFromWrite("pkgOdd");
 
 
-        // 1 package names and 5 * 2 unique channel names and ids
-        assertThat(history.getPooledStringsToWrite().length).isEqualTo(11);
+        // 1 package names and 5 * 2 unique channel names and ids and 5 conversation ids
+        assertThat(history.getPooledStringsToWrite().length).isEqualTo(16);
         assertThat(history.getNotificationsToWrite())
                 .containsExactlyElementsIn(postRemoveExpectedEntries);
     }
@@ -246,6 +264,9 @@
                 postRemoveExpectedStrings.add(n.getPackage());
                 postRemoveExpectedStrings.add(n.getChannelName());
                 postRemoveExpectedStrings.add(n.getChannelId());
+                if (n.getConversationId() != null) {
+                    postRemoveExpectedStrings.add(n.getConversationId());
+                }
                 postRemoveExpectedEntries.add(n);
             }
 
@@ -255,14 +276,14 @@
         history.poolStringsFromNotifications();
 
         assertThat(history.getNotificationsToWrite().size()).isEqualTo(10);
-        // 1 package name and 10 unique channel names and ids
-        assertThat(history.getPooledStringsToWrite().length).isEqualTo(21);
+        // 1 package name and 20 unique channel names and ids and 5 conversation ids
+        assertThat(history.getPooledStringsToWrite().length).isEqualTo(26);
 
         history.removeNotificationFromWrite("pkg", 987654323);
 
 
-        // 1 package names and 9 * 2 unique channel names and ids
-        assertThat(history.getPooledStringsToWrite().length).isEqualTo(19);
+        // 1 package names and 9 * 2 unique channel names and ids and 4 conversation ids
+        assertThat(history.getPooledStringsToWrite().length).isEqualTo(23);
         assertThat(history.getNotificationsToWrite())
                 .containsExactlyElementsIn(postRemoveExpectedEntries);
     }
diff --git a/core/tests/coretests/src/android/os/BundleTest.java b/core/tests/coretests/src/android/os/BundleTest.java
index e4dc993..4cc70ba 100644
--- a/core/tests/coretests/src/android/os/BundleTest.java
+++ b/core/tests/coretests/src/android/os/BundleTest.java
@@ -30,12 +30,23 @@
  * Unit tests for bundle that requires accessing hidden APS.  Tests that can be written only with
  * public APIs should go in the CTS counterpart.
  *
- * Run with:
- * bit FrameworksCoreTests:android.os.BundleTest
+ * Run with: atest FrameworksCoreTests:android.os.BundleTest
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class BundleTest {
+
+    /**
+     * Take a bundle, write it to a parcel and return the parcel.
+     */
+    private Parcel getParcelledBundle(Bundle bundle) {
+        final Parcel p = Parcel.obtain();
+        // Don't use p.writeParcelabe(), which would write the creator, which we don't need.
+        bundle.writeToParcel(p, 0);
+        p.setDataPosition(0);
+        return p;
+    }
+
     /**
      * Create a test bundle, parcel it and return the parcel.
      */
@@ -48,12 +59,7 @@
             pipe[1].close();
             source.putParcelable("fd", pipe[0]);
         }
-        final Parcel p = Parcel.obtain();
-        // Don't use p.writeParcelabe(), which would write the creator, which we don't need.
-        source.writeToParcel(p, 0);
-        p.setDataPosition(0);
-
-        return p;
+        return getParcelledBundle(source);
     }
 
     /**
@@ -137,4 +143,78 @@
         checkBundle(b, withFd);
         p.recycle();
     }
+
+    @Test
+    public void kindofEquals_bothUnparcelled_same() {
+        Bundle bundle1 = new Bundle();
+        bundle1.putString("StringKey", "S");
+        bundle1.putInt("IntKey", 2);
+
+        Bundle bundle2 = new Bundle();
+        bundle2.putString("StringKey", "S");
+        bundle2.putInt("IntKey", 2);
+
+        assertTrue(BaseBundle.kindofEquals(bundle1, bundle2));
+    }
+
+    @Test
+    public void kindofEquals_bothUnparcelled_different() {
+        Bundle bundle1 = new Bundle();
+        bundle1.putString("StringKey", "S");
+        bundle1.putInt("IntKey", 2);
+
+        Bundle bundle2 = new Bundle();
+        bundle2.putString("StringKey", "T");
+        bundle2.putLong("LongKey", 30L);
+
+        assertFalse(BaseBundle.kindofEquals(bundle1, bundle2));
+    }
+
+    @Test
+    public void kindofEquals_bothParcelled_same() {
+        Bundle bundle1 = new Bundle();
+        bundle1.putString("StringKey", "S");
+        bundle1.putInt("IntKey", 2);
+        bundle1.readFromParcel(getParcelledBundle(bundle1));
+
+        Bundle bundle2 = new Bundle();
+        bundle2.putString("StringKey", "S");
+        bundle2.putInt("IntKey", 2);
+        bundle2.readFromParcel(getParcelledBundle(bundle2));
+
+        assertTrue(bundle1.isParcelled());
+        assertTrue(bundle2.isParcelled());
+        assertTrue(BaseBundle.kindofEquals(bundle1, bundle2));
+    }
+
+    @Test
+    public void kindofEquals_bothParcelled_different() {
+        Bundle bundle1 = new Bundle();
+        bundle1.putString("StringKey", "S");
+        bundle1.putInt("IntKey", 2);
+        bundle1.readFromParcel(getParcelledBundle(bundle1));
+
+        Bundle bundle2 = new Bundle();
+        bundle2.putString("StringKey", "T");
+        bundle2.putLong("LongKey", 5);
+        bundle2.readFromParcel(getParcelledBundle(bundle2));
+
+        assertTrue(bundle1.isParcelled());
+        assertTrue(bundle2.isParcelled());
+        assertFalse(BaseBundle.kindofEquals(bundle1, bundle2));
+    }
+
+    @Test
+    public void kindofEquals_ParcelledUnparcelled_empty() {
+        Bundle bundle1 = new Bundle();
+        bundle1.readFromParcel(getParcelledBundle(bundle1));
+
+        Bundle bundle2 = new Bundle();
+
+        assertTrue(bundle1.isParcelled());
+        assertFalse(bundle2.isParcelled());
+        // Even though one is parcelled and the other is not, both are empty, so it should
+        // return true
+        assertTrue(BaseBundle.kindofEquals(bundle1, bundle2));
+    }
 }
diff --git a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
index bdb8021..aa5101e 100644
--- a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
+++ b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
@@ -11,7 +11,7 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
  */
 
 package android.view;
@@ -23,7 +23,6 @@
 import static android.view.WindowInsets.Type.systemBars;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
diff --git a/core/tests/coretests/src/android/view/WindowMetricsTest.java b/core/tests/coretests/src/android/view/WindowMetricsTest.java
deleted file mode 100644
index d2eb8f5..0000000
--- a/core/tests/coretests/src/android/view/WindowMetricsTest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
-
-import android.content.Context;
-import android.hardware.display.DisplayManager;
-import android.os.Handler;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-/**
- * Tests for {@link WindowManager#getCurrentWindowMetrics()} and
- * {@link WindowManager#getMaximumWindowMetrics()}.
- *
- * <p>Build/Install/Run:
- *  atest FrameworksCoreTests:WindowMetricsTest
- *
- * <p>This test class is a part of Window Manager Service tests and specified in
- * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
- */
-@FlakyTest(bugId = 148789183, detail = "Remove after confirmed it's stable.")
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-@Presubmit
-public class WindowMetricsTest {
-    private Context mWindowContext;
-    private WindowManager mWm;
-
-    @Before
-    public void setUp() {
-        final Context insetContext = InstrumentationRegistry.getInstrumentation()
-                .getTargetContext();
-        final Display display = insetContext.getSystemService(DisplayManager.class)
-                .getDisplay(DEFAULT_DISPLAY);
-        mWindowContext = insetContext.createDisplayContext(display)
-                .createWindowContext(TYPE_APPLICATION_OVERLAY, null /* options */);
-        mWm = mWindowContext.getSystemService(WindowManager.class);
-    }
-
-    @Test
-    public void testAddViewANdRemoveView_GetMetrics_DoNotCrash() {
-        final View view = new View(mWindowContext);
-        final WindowManager.LayoutParams params =
-                new WindowManager.LayoutParams(TYPE_APPLICATION_OVERLAY);
-        Handler.getMain().runWithScissors(() -> {
-            mWm.addView(view, params);
-            // Check get metrics do not crash.
-            mWm.getCurrentWindowMetrics();
-            mWm.getMaximumWindowMetrics();
-
-            mWm.removeViewImmediate(view);
-            // Check get metrics do not crash.
-            mWm.getCurrentWindowMetrics();
-            mWm.getMaximumWindowMetrics();
-        }, 0);
-    }
-}
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 6784ede..bbf3b12 100644
--- a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
+++ b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
@@ -362,9 +362,10 @@
         accessibilityShortcutController.performAccessibilityShortcut();
         accessibilityShortcutController.performAccessibilityShortcut();
         verify(mToast).show();
-        assertEquals(WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS,
-                mLayoutParams.privateFlags
-                        & WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS);
+        // TODO(b/149408635): Reintroduce assertion
+        // assertEquals(WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS,
+        //        mLayoutParams.privateFlags
+        //                & WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS);
         verify(mAccessibilityManagerService, times(1)).performAccessibilityShortcut(null);
     }
 
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index ce71beb..6d0e58b 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -18,6 +18,7 @@
 
 import static androidx.test.espresso.Espresso.onView;
 import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.action.ViewActions.swipeUp;
 import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
 import static androidx.test.espresso.assertion.ViewAssertions.matches;
 import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
@@ -355,18 +356,14 @@
     public void hasOtherProfileOneOption() throws Exception {
         // enable the work tab feature flag
         ResolverActivity.ENABLE_TABBED_VIEW = true;
-
+        List<ResolvedComponentInfo> personalResolvedComponentInfos =
+                createResolvedComponentsForTestWithOtherProfile(2, /* userId */ 10);
+        List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
+        setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
         markWorkProfileUserAvailable();
+
+        ResolveInfo toChoose = personalResolvedComponentInfos.get(1).getResolveInfoAt(0);
         Intent sendIntent = createSendTextIntent();
-        List<ResolvedComponentInfo> resolvedComponentInfos =
-                createResolvedComponentsForTestWithOtherProfile(2);
-        ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0);
-
-        when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent(
-                Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
-
         final ChooserWrapperActivity activity = mActivityRule
                 .launchActivity(Intent.createChooser(sendIntent, null));
         waitForIdle();
@@ -382,9 +379,11 @@
 
         // Make a stable copy of the components as the original list may be modified
         List<ResolvedComponentInfo> stableCopy =
-                createResolvedComponentsForTestWithOtherProfile(2);
+                createResolvedComponentsForTestWithOtherProfile(2, /* userId= */ 10);
         waitForIdle();
-        onView(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name))
+        Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+
+        onView(first(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name)))
                 .perform(click());
         waitForIdle();
         assertThat(chosen[0], is(toChoose));
@@ -1218,17 +1217,7 @@
         int workProfileTargets = 4;
         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(
                 workProfileTargets);
-        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class)))
-                .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
-        when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class))).thenReturn(new ArrayList<>(workResolvedComponentInfos));
-        when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class),
-                eq(UserHandle.SYSTEM))).thenReturn(new ArrayList<>(personalResolvedComponentInfos));
+        setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
         Intent sendIntent = createSendTextIntent();
         sendIntent.setType("TestType");
         markWorkProfileUserAvailable();
@@ -1245,7 +1234,7 @@
     }
 
     @Test
-    public void testWorkTab_workProfileHasExpectedNumberOfTargets() {
+    public void testWorkTab_workProfileHasExpectedNumberOfTargets() throws InterruptedException {
         // enable the work tab feature flag
         ResolverActivity.ENABLE_TABBED_VIEW = true;
         markWorkProfileUserAvailable();
@@ -1254,18 +1243,7 @@
                 createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
         List<ResolvedComponentInfo> workResolvedComponentInfos =
                 createResolvedComponentsForTest(workProfileTargets);
-        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class)))
-                .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
-        when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos);
-        when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class),
-                eq(UserHandle.SYSTEM)))
-                .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
+        setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
         Intent sendIntent = createSendTextIntent();
         sendIntent.setType("TestType");
 
@@ -1284,12 +1262,12 @@
         // enable the work tab feature flag
         ResolverActivity.ENABLE_TABBED_VIEW = true;
         markWorkProfileUserAvailable();
+        List<ResolvedComponentInfo> personalResolvedComponentInfos =
+                createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
         int workProfileTargets = 4;
         List<ResolvedComponentInfo> workResolvedComponentInfos =
                 createResolvedComponentsForTest(workProfileTargets);
-        when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos);
+        setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
         Intent sendIntent = createSendTextIntent();
         sendIntent.setType("TestType");
         ResolveInfo[] chosen = new ResolveInfo[1];
@@ -1312,6 +1290,85 @@
         assertThat(chosen[0], is(workResolvedComponentInfos.get(0).getResolveInfoAt(0)));
     }
 
+    @Test
+    public void testWorkTab_crossProfileIntentsDisabled_personalToWork_emptyStateShown() {
+        // enable the work tab feature flag
+        ResolverActivity.ENABLE_TABBED_VIEW = true;
+        markWorkProfileUserAvailable();
+        int workProfileTargets = 4;
+        List<ResolvedComponentInfo> personalResolvedComponentInfos =
+                createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
+        List<ResolvedComponentInfo> workResolvedComponentInfos =
+                createResolvedComponentsForTest(workProfileTargets);
+        sOverrides.hasCrossProfileIntents = false;
+        setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
+        Intent sendIntent = createSendTextIntent();
+        sendIntent.setType("TestType");
+
+        final ChooserWrapperActivity activity =
+                mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
+        waitForIdle();
+        onView(withText(R.string.resolver_work_tab)).perform(click());
+        waitForIdle();
+        onView(withId(R.id.contentPanel))
+                .perform(swipeUp());
+
+        onView(withText(R.string.resolver_cant_share_with_work_apps))
+                .check(matches(isDisplayed()));
+    }
+
+    @Test
+    public void testWorkTab_workProfileDisabled_emptyStateShown() {
+        // enable the work tab feature flag
+        ResolverActivity.ENABLE_TABBED_VIEW = true;
+        markWorkProfileUserAvailable();
+        int workProfileTargets = 4;
+        List<ResolvedComponentInfo> personalResolvedComponentInfos =
+                createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
+        List<ResolvedComponentInfo> workResolvedComponentInfos =
+                createResolvedComponentsForTest(workProfileTargets);
+        sOverrides.isQuietModeEnabled = true;
+        setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
+        Intent sendIntent = createSendTextIntent();
+        sendIntent.setType("TestType");
+
+        final ChooserWrapperActivity activity =
+                mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
+        waitForIdle();
+        onView(withId(R.id.contentPanel))
+                .perform(swipeUp());
+        onView(withText(R.string.resolver_work_tab)).perform(click());
+        waitForIdle();
+
+        onView(withText(R.string.resolver_turn_on_work_apps))
+                .check(matches(isDisplayed()));
+    }
+
+    @Test
+    public void testWorkTab_noWorkTargets_emptyStateShown() {
+        // enable the work tab feature flag
+        ResolverActivity.ENABLE_TABBED_VIEW = true;
+        markWorkProfileUserAvailable();
+        List<ResolvedComponentInfo> personalResolvedComponentInfos =
+                createResolvedComponentsForTest(3);
+        List<ResolvedComponentInfo> workResolvedComponentInfos =
+                createResolvedComponentsForTest(0);
+        setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
+        Intent sendIntent = createSendTextIntent();
+        sendIntent.setType("TestType");
+
+        final ChooserWrapperActivity activity =
+                mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
+        waitForIdle();
+        onView(withId(R.id.contentPanel))
+                .perform(swipeUp());
+        onView(withText(R.string.resolver_work_tab)).perform(click());
+        waitForIdle();
+
+        onView(withText(R.string.resolver_no_apps_available))
+                .check(matches(isDisplayed()));
+    }
+
     private Intent createSendTextIntent() {
         Intent sendIntent = new Intent();
         sendIntent.setAction(Intent.ACTION_SEND);
@@ -1486,4 +1543,21 @@
     private void markWorkProfileUserAvailable() {
         sOverrides.workProfileUserHandle = UserHandle.of(10);
     }
+
+    private void setupResolverControllers(
+            List<ResolvedComponentInfo> personalResolvedComponentInfos,
+            List<ResolvedComponentInfo> workResolvedComponentInfos) {
+        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
+                Mockito.isA(List.class)))
+                .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
+        when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
+                Mockito.isA(List.class))).thenReturn(new ArrayList<>(workResolvedComponentInfos));
+        when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
+                Mockito.isA(List.class),
+                eq(UserHandle.SYSTEM)))
+                .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
+    }
 }
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
index a68b5908..363551b 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
@@ -16,15 +16,10 @@
 
 package com.android.internal.app;
 
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import android.annotation.Nullable;
-import android.app.prediction.AppPredictionContext;
-import android.app.prediction.AppPredictionManager;
-import android.app.prediction.AppPredictor;
 import android.app.usage.UsageStatsManager;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -35,7 +30,6 @@
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.net.Uri;
-import android.os.Bundle;
 import android.os.UserHandle;
 import android.util.Size;
 
@@ -45,8 +39,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 
-import org.mockito.Mockito;
-
+import java.util.List;
 import java.util.function.Function;
 
 public class ChooserWrapperActivity extends ChooserActivity {
@@ -56,6 +49,15 @@
     static final OverrideData sOverrides = new OverrideData();
     private UsageStatsManager mUsm;
 
+    @Override
+    protected AbstractMultiProfilePagerAdapter createMultiProfilePagerAdapter(
+            Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed) {
+        AbstractMultiProfilePagerAdapter multiProfilePagerAdapter =
+                super.createMultiProfilePagerAdapter(initialIntents, rList, filterLastUsed);
+        multiProfilePagerAdapter.setInjector(sOverrides.multiPagerAdapterInjector);
+        return multiProfilePagerAdapter;
+    }
+
     ChooserListAdapter getAdapter() {
         return mChooserMultiProfilePagerAdapter.getActiveListAdapter();
     }
@@ -206,6 +208,9 @@
         public int alternateProfileSetting;
         public Resources resources;
         public UserHandle workProfileUserHandle;
+        public boolean hasCrossProfileIntents;
+        public boolean isQuietModeEnabled;
+        public AbstractMultiProfilePagerAdapter.Injector multiPagerAdapterInjector;
 
         public void reset() {
             onSafelyStartCallback = null;
@@ -221,6 +226,26 @@
             alternateProfileSetting = 0;
             resources = null;
             workProfileUserHandle = null;
+            hasCrossProfileIntents = true;
+            isQuietModeEnabled = false;
+            multiPagerAdapterInjector = new AbstractMultiProfilePagerAdapter.Injector() {
+                @Override
+                public boolean hasCrossProfileIntents(List<Intent> intents, int sourceUserId,
+                        int targetUserId) {
+                    return hasCrossProfileIntents;
+                }
+
+                @Override
+                public boolean isQuietModeEnabled(UserHandle workProfileUserHandle) {
+                    return isQuietModeEnabled;
+                }
+
+                @Override
+                public void requestQuietModeEnabled(boolean enabled,
+                        UserHandle workProfileUserHandle) {
+                    isQuietModeEnabled = enabled;
+                }
+            };
         }
     }
 }
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
index 5f4194a..a7bf488 100644
--- a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
@@ -18,16 +18,16 @@
 
 import static androidx.test.espresso.Espresso.onView;
 import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.action.ViewActions.swipeUp;
 import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
 import static androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
 import static androidx.test.espresso.matcher.ViewMatchers.isEnabled;
 import static androidx.test.espresso.matcher.ViewMatchers.withId;
 import static androidx.test.espresso.matcher.ViewMatchers.withText;
 
 import static com.android.internal.app.MatcherUtils.first;
 import static com.android.internal.app.ResolverDataProvider.createPackageManagerMockedInfo;
-import static com.android.internal.app.ResolverDataProvider.createResolvedComponentInfoWithOtherId;
 import static com.android.internal.app.ResolverWrapperActivity.sOverrides;
 
 import static org.hamcrest.CoreMatchers.allOf;
@@ -56,9 +56,6 @@
 import com.android.internal.app.ResolverListAdapter.ResolveInfoPresentationGetter;
 import com.android.internal.widget.ResolverDrawerLayout;
 
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Rule;
@@ -224,17 +221,14 @@
     public void hasOtherProfileOneOption() throws Exception {
         // enable the work tab feature flag
         ResolverActivity.ENABLE_TABBED_VIEW = true;
-
+        List<ResolvedComponentInfo> personalResolvedComponentInfos =
+                createResolvedComponentsForTestWithOtherProfile(2, /* userId */ 10);
+        List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
+        setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
         markWorkProfileUserAvailable();
+
+        ResolveInfo toChoose = personalResolvedComponentInfos.get(1).getResolveInfoAt(0);
         Intent sendIntent = createSendImageIntent();
-        List<ResolvedComponentInfo> resolvedComponentInfos =
-                createResolvedComponentsForTestWithOtherProfile(2);
-        ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0);
-
-        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
-
         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
         Espresso.registerIdlingResources(activity.getAdapter().getLabelIdlingResource());
         waitForIdle();
@@ -249,8 +243,9 @@
         };
         // Make a stable copy of the components as the original list may be modified
         List<ResolvedComponentInfo> stableCopy =
-                createResolvedComponentsForTestWithOtherProfile(2);
-        onView(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name))
+                createResolvedComponentsForTestWithOtherProfile(2, /* userId= */ 10);
+        // We pick the first one as there is another one in the work profile side
+        onView(first(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name)))
                 .perform(click());
         onView(withId(R.id.button_once))
                 .perform(click());
@@ -415,18 +410,14 @@
     }
 
     @Test
-    public void testWorkTab_workTabListEmptyBeforeGoingToTab() {
+    public void testWorkTab_workTabListPopulatedBeforeGoingToTab() throws InterruptedException {
         // enable the work tab feature flag
         ResolverActivity.ENABLE_TABBED_VIEW = true;
         List<ResolvedComponentInfo> personalResolvedComponentInfos =
-                createResolvedComponentsForTest(3);
+                createResolvedComponentsForTestWithOtherProfile(3, /* userId = */ 10);
         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
-        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class))).thenReturn(personalResolvedComponentInfos);
-        when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos);
+        setupResolverControllers(personalResolvedComponentInfos,
+                new ArrayList<>(workResolvedComponentInfos));
         Intent sendIntent = createSendImageIntent();
         markWorkProfileUserAvailable();
 
@@ -434,8 +425,8 @@
         waitForIdle();
 
         assertThat(activity.getCurrentUserHandle().getIdentifier(), is(0));
-        // The work list adapter must only be filled when we open the work tab
-        assertThat(activity.getWorkListAdapter().getCount(), is(0));
+        // The work list adapter must be populated in advance before tapping the other tab
+        assertThat(activity.getWorkListAdapter().getCount(), is(4));
     }
 
     @Test
@@ -445,17 +436,7 @@
         List<ResolvedComponentInfo> personalResolvedComponentInfos =
                 createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
-        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class))).thenReturn(personalResolvedComponentInfos);
-        when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos);
-        when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class),
-                eq(UserHandle.SYSTEM)))
-                .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
+        setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
         Intent sendIntent = createSendImageIntent();
         markWorkProfileUserAvailable();
 
@@ -474,34 +455,7 @@
         List<ResolvedComponentInfo> personalResolvedComponentInfos =
                 createResolvedComponentsForTestWithOtherProfile(3);
         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
-        when(sOverrides.resolverListController.getResolversForIntentAsUser(
-                Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class),
-                eq(UserHandle.SYSTEM))).thenReturn(new ArrayList<>(personalResolvedComponentInfos));
-        when(sOverrides.resolverListController.getResolversForIntentAsUser(
-                Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class),
-                eq(sOverrides.workProfileUserHandle)))
-                .thenReturn(new ArrayList<>(workResolvedComponentInfos));
-        when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class),
-                eq(sOverrides.workProfileUserHandle)))
-                .thenReturn(new ArrayList<>(workResolvedComponentInfos));
-        when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class))).thenReturn(new ArrayList<>(workResolvedComponentInfos));
-        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class)))
-                .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
-        when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class),
-                eq(UserHandle.SYSTEM))).thenReturn(new ArrayList<>(personalResolvedComponentInfos));
-
+        setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
         Intent sendIntent = createSendImageIntent();
         markWorkProfileUserAvailable();
 
@@ -521,18 +475,7 @@
         List<ResolvedComponentInfo> personalResolvedComponentInfos =
                 createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
-        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class)))
-                .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
-        when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos);
-        when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class),
-                eq(UserHandle.SYSTEM)))
-                .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
+        setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
         Intent sendIntent = createSendImageIntent();
 
         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
@@ -552,18 +495,7 @@
         List<ResolvedComponentInfo> personalResolvedComponentInfos =
                 createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
-        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class)))
-                .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
-        when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos);
-        when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class),
-                eq(UserHandle.SYSTEM)))
-                .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
+        setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
         Intent sendIntent = createSendImageIntent();
         ResolveInfo[] chosen = new ResolveInfo[1];
         sOverrides.onSafelyStartCallback = targetInfo -> {
@@ -597,35 +529,7 @@
         List<ResolvedComponentInfo> personalResolvedComponentInfos =
                 createResolvedComponentsForTestWithOtherProfile(1);
         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
-
-        when(sOverrides.resolverListController.getResolversForIntentAsUser(
-                Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class),
-                eq(UserHandle.SYSTEM))).thenReturn(new ArrayList<>(personalResolvedComponentInfos));
-        when(sOverrides.resolverListController.getResolversForIntentAsUser(
-                Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class),
-                eq(sOverrides.workProfileUserHandle)))
-                .thenReturn(new ArrayList<>(workResolvedComponentInfos));
-        when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class),
-                eq(sOverrides.workProfileUserHandle)))
-                .thenReturn(new ArrayList<>(workResolvedComponentInfos));
-        when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class))).thenReturn(new ArrayList<>(workResolvedComponentInfos));
-        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class)))
-                .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
-        when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class),
-                eq(UserHandle.SYSTEM))).thenReturn(new ArrayList<>(personalResolvedComponentInfos));
-
+        setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
         Intent sendIntent = createSendImageIntent();
 
         final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
@@ -644,10 +548,10 @@
         // enable the work tab feature flag
         ResolverActivity.ENABLE_TABBED_VIEW = true;
         markWorkProfileUserAvailable();
+        List<ResolvedComponentInfo> personalResolvedComponentInfos =
+                createResolvedComponentsForTestWithOtherProfile(3, /* userId= */ 10);
         List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4);
-        when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
-                Mockito.anyBoolean(),
-                Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos);
+        setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
         Intent sendIntent = createSendImageIntent();
         ResolveInfo[] chosen = new ResolveInfo[1];
         sOverrides.onSafelyStartCallback = targetInfo -> {
@@ -672,6 +576,82 @@
         assertThat(chosen[0], is(workResolvedComponentInfos.get(0).getResolveInfoAt(0)));
     }
 
+    @Test
+    public void testWorkTab_crossProfileIntentsDisabled_personalToWork_emptyStateShown() {
+        // enable the work tab feature flag
+        ResolverActivity.ENABLE_TABBED_VIEW = true;
+        markWorkProfileUserAvailable();
+        int workProfileTargets = 4;
+        List<ResolvedComponentInfo> personalResolvedComponentInfos =
+                createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
+        List<ResolvedComponentInfo> workResolvedComponentInfos =
+                createResolvedComponentsForTest(workProfileTargets);
+        sOverrides.hasCrossProfileIntents = false;
+        setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
+        Intent sendIntent = createSendImageIntent();
+        sendIntent.setType("TestType");
+
+        mActivityRule.launchActivity(sendIntent);
+        waitForIdle();
+        onView(withText(R.string.resolver_work_tab)).perform(click());
+        waitForIdle();
+        onView(withId(R.id.contentPanel))
+                .perform(swipeUp());
+
+        onView(withText(R.string.resolver_cant_share_with_work_apps))
+                .check(matches(isDisplayed()));
+    }
+
+    @Test
+    public void testWorkTab_workProfileDisabled_emptyStateShown() {
+        // enable the work tab feature flag
+        ResolverActivity.ENABLE_TABBED_VIEW = true;
+        markWorkProfileUserAvailable();
+        int workProfileTargets = 4;
+        List<ResolvedComponentInfo> personalResolvedComponentInfos =
+                createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10);
+        List<ResolvedComponentInfo> workResolvedComponentInfos =
+                createResolvedComponentsForTest(workProfileTargets);
+        sOverrides.isQuietModeEnabled = true;
+        setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
+        Intent sendIntent = createSendImageIntent();
+        sendIntent.setType("TestType");
+
+        mActivityRule.launchActivity(sendIntent);
+        waitForIdle();
+        onView(withId(R.id.contentPanel))
+                .perform(swipeUp());
+        onView(withText(R.string.resolver_work_tab)).perform(click());
+        waitForIdle();
+
+        onView(withText(R.string.resolver_turn_on_work_apps))
+                .check(matches(isDisplayed()));
+    }
+
+    @Test
+    public void testWorkTab_noWorkTargets_emptyStateShown() {
+        // enable the work tab feature flag
+        ResolverActivity.ENABLE_TABBED_VIEW = true;
+        markWorkProfileUserAvailable();
+        List<ResolvedComponentInfo> personalResolvedComponentInfos =
+                createResolvedComponentsForTest(3);
+        List<ResolvedComponentInfo> workResolvedComponentInfos =
+                createResolvedComponentsForTest(0);
+        setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos);
+        Intent sendIntent = createSendImageIntent();
+        sendIntent.setType("TestType");
+
+        mActivityRule.launchActivity(sendIntent);
+        waitForIdle();
+        onView(withId(R.id.contentPanel))
+                .perform(swipeUp());
+        onView(withText(R.string.resolver_work_tab)).perform(click());
+        waitForIdle();
+
+        onView(withText(R.string.resolver_no_apps_available))
+                .check(matches(isDisplayed()));
+    }
+
     private Intent createSendImageIntent() {
         Intent sendIntent = new Intent();
         sendIntent.setAction(Intent.ACTION_SEND);
@@ -722,4 +702,21 @@
     private void markWorkProfileUserAvailable() {
         ResolverWrapperActivity.sOverrides.workProfileUserHandle = UserHandle.of(10);
     }
+
+    private void setupResolverControllers(
+            List<ResolvedComponentInfo> personalResolvedComponentInfos,
+            List<ResolvedComponentInfo> workResolvedComponentInfos) {
+        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
+                Mockito.isA(List.class)))
+                .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
+        when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
+                Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos);
+        when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
+                Mockito.isA(List.class),
+                eq(UserHandle.SYSTEM)))
+                .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
+    }
 }
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java
index 36c8724..2087104 100644
--- a/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java
@@ -47,6 +47,15 @@
                 filterLastUsed, createListController(userHandle), useLayoutForBrowsables, this);
     }
 
+    @Override
+    protected AbstractMultiProfilePagerAdapter createMultiProfilePagerAdapter(
+            Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed) {
+        AbstractMultiProfilePagerAdapter multiProfilePagerAdapter =
+                super.createMultiProfilePagerAdapter(initialIntents, rList, filterLastUsed);
+        multiProfilePagerAdapter.setInjector(sOverrides.multiPagerAdapterInjector);
+        return multiProfilePagerAdapter;
+    }
+
     ResolverWrapperAdapter getAdapter() {
         return (ResolverWrapperAdapter) mMultiProfilePagerAdapter.getActiveListAdapter();
     }
@@ -124,6 +133,9 @@
         public ResolverListController workResolverListController;
         public Boolean isVoiceInteraction;
         public UserHandle workProfileUserHandle;
+        public boolean hasCrossProfileIntents;
+        public boolean isQuietModeEnabled;
+        public AbstractMultiProfilePagerAdapter.Injector multiPagerAdapterInjector;
 
         public void reset() {
             onSafelyStartCallback = null;
@@ -132,6 +144,26 @@
             resolverListController = mock(ResolverListController.class);
             workResolverListController = mock(ResolverListController.class);
             workProfileUserHandle = null;
+            hasCrossProfileIntents = true;
+            isQuietModeEnabled = false;
+            multiPagerAdapterInjector = new AbstractMultiProfilePagerAdapter.Injector() {
+                @Override
+                public boolean hasCrossProfileIntents(List<Intent> intents, int sourceUserId,
+                        int targetUserId) {
+                    return hasCrossProfileIntents;
+                }
+
+                @Override
+                public boolean isQuietModeEnabled(UserHandle workProfileUserHandle) {
+                    return isQuietModeEnabled;
+                }
+
+                @Override
+                public void requestQuietModeEnabled(boolean enabled,
+                        UserHandle workProfileUserHandle) {
+                    isQuietModeEnabled = enabled;
+                }
+            };
         }
     }
 }
\ No newline at end of file
diff --git a/core/xsd/vts/Android.bp b/core/xsd/vts/Android.bp
index 9cf68c1..a2a2168 100644
--- a/core/xsd/vts/Android.bp
+++ b/core/xsd/vts/Android.bp
@@ -25,10 +25,18 @@
     ],
     shared_libs: [
         "liblog",
-	"libbase",
+        "libbase",
     ],
     cflags: [
         "-Wall",
         "-Werror",
     ],
+    data: [
+        ":permission",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts-core"
+    ],
+    test_config: "vts_permission_validate_test.xml",
 }
diff --git a/core/xsd/vts/vts_permission_validate_test.xml b/core/xsd/vts/vts_permission_validate_test.xml
new file mode 100644
index 0000000..228ffc4
--- /dev/null
+++ b/core/xsd/vts/vts_permission_validate_test.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs vts_permission_validate_test.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="permission.xsd->/data/local/tmp/permission.xsd" />
+        <option name="push" value="vts_permission_validate_test->/data/local/tmp/vts_permission_validate_test" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="vts_permission_validate_test" />
+    </test>
+</configuration>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 4b95e4d..08b30f7 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -219,6 +219,9 @@
         <permission name="android.permission.WATCH_APPOPS"/>
         <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
         <permission name="android.permission.UPDATE_DEVICE_STATS"/>
+        <!-- Permissions required for reading and logging compat changes -->
+        <permission name="android.permission.LOG_COMPAT_CHANGE" />
+        <permission name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
     </privapp-permissions>
 
     <privapp-permissions package="com.android.providers.telephony">
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 9da185b..5b23dc0 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -223,6 +223,12 @@
       "group": "WM_DEBUG_ADD_REMOVE",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
+    "-1670695197": {
+      "message": "Attempted to add presentation window to a non-suitable display.  Aborting.",
+      "level": "WARN",
+      "group": "WM_ERROR",
+      "at": "com\/android\/server\/wm\/WindowManagerService.java"
+    },
     "-1661704580": {
       "message": "Attempted to set replacing window on non-existing app token %s",
       "level": "WARN",
diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
index 3835b2d..752695f 100644
--- a/graphics/java/android/graphics/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -22,8 +22,8 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.graphics.animation.RenderNodeAnimator;
 import android.view.NativeVectorDrawableAnimator;
-import android.view.RenderNodeAnimator;
 import android.view.Surface;
 import android.view.View;
 
diff --git a/core/java/com/android/internal/view/animation/FallbackLUTInterpolator.java b/graphics/java/android/graphics/animation/FallbackLUTInterpolator.java
similarity index 89%
rename from core/java/com/android/internal/view/animation/FallbackLUTInterpolator.java
rename to graphics/java/android/graphics/animation/FallbackLUTInterpolator.java
index d28ab07..36062c1 100644
--- a/core/java/com/android/internal/view/animation/FallbackLUTInterpolator.java
+++ b/graphics/java/android/graphics/animation/FallbackLUTInterpolator.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.view.animation;
+package android.graphics.animation;
 
 import android.animation.TimeInterpolator;
 import android.util.TimeUtils;
@@ -26,14 +26,15 @@
  * with {@link HasNativeInterpolator}
  *
  * This implements TimeInterpolator to allow for easier interop with Animators
+ * @hide
  */
 @HasNativeInterpolator
-public class FallbackLUTInterpolator implements NativeInterpolatorFactory, TimeInterpolator {
+public class FallbackLUTInterpolator implements NativeInterpolator, TimeInterpolator {
 
     // If the duration of an animation is more than 300 frames, we cap the sample size to 300.
     private static final int MAX_SAMPLE_POINTS = 300;
     private TimeInterpolator mSourceInterpolator;
-    private final float mLut[];
+    private final float[] mLut;
 
     /**
      * Used to cache the float[] LUT for use across multiple native
@@ -50,7 +51,7 @@
         // We need 2 frame values as the minimal.
         int numAnimFrames = Math.max(2, (int) Math.ceil(((double) duration) / animIntervalMs));
         numAnimFrames = Math.min(numAnimFrames, MAX_SAMPLE_POINTS);
-        float values[] = new float[numAnimFrames];
+        float[] values = new float[numAnimFrames];
         float lastFrame = numAnimFrames - 1;
         for (int i = 0; i < numAnimFrames; i++) {
             float inValue = i / lastFrame;
@@ -61,7 +62,7 @@
 
     @Override
     public long createNativeInterpolator() {
-        return NativeInterpolatorFactoryHelper.createLutInterpolator(mLut);
+        return NativeInterpolatorFactory.createLutInterpolator(mLut);
     }
 
     /**
@@ -69,7 +70,7 @@
      */
     public static long createNativeInterpolator(TimeInterpolator interpolator, long duration) {
         float[] lut = createLUT(interpolator, duration);
-        return NativeInterpolatorFactoryHelper.createLutInterpolator(lut);
+        return NativeInterpolatorFactory.createLutInterpolator(lut);
     }
 
     @Override
diff --git a/core/java/com/android/internal/view/animation/HasNativeInterpolator.java b/graphics/java/android/graphics/animation/HasNativeInterpolator.java
similarity index 89%
rename from core/java/com/android/internal/view/animation/HasNativeInterpolator.java
rename to graphics/java/android/graphics/animation/HasNativeInterpolator.java
index 48ea4da..c53d5a4 100644
--- a/core/java/com/android/internal/view/animation/HasNativeInterpolator.java
+++ b/graphics/java/android/graphics/animation/HasNativeInterpolator.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.view.animation;
+package android.graphics.animation;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
@@ -23,10 +23,10 @@
 
 /**
  * This is a class annotation that signals that it is safe to create
- * a native interpolator counterpart via {@link NativeInterpolatorFactory}
+ * a native interpolator counterpart via {@link NativeInterpolator}
  *
  * The idea here is to prevent subclasses of interpolators from being treated as a
- * NativeInterpolatorFactory, and instead have them fall back to the LUT & LERP
+ * NativeInterpolator, and instead have them fall back to the LUT & LERP
  * method like a custom interpolator.
  *
  * @hide
diff --git a/core/java/com/android/internal/view/animation/NativeInterpolatorFactory.java b/graphics/java/android/graphics/animation/NativeInterpolator.java
similarity index 71%
copy from core/java/com/android/internal/view/animation/NativeInterpolatorFactory.java
copy to graphics/java/android/graphics/animation/NativeInterpolator.java
index fcacd52..1e6fea8 100644
--- a/core/java/com/android/internal/view/animation/NativeInterpolatorFactory.java
+++ b/graphics/java/android/graphics/animation/NativeInterpolator.java
@@ -14,8 +14,16 @@
  * limitations under the License.
  */
 
-package com.android.internal.view.animation;
+package android.graphics.animation;
 
-public interface NativeInterpolatorFactory {
+/**
+ * @hide
+ */
+public interface NativeInterpolator {
+    /**
+     * Generates a native interpolator object that can be used by HardwareRenderer to draw
+     * RenderNodes.
+     * @return ptr to native object
+     */
     long createNativeInterpolator();
 }
diff --git a/graphics/java/android/graphics/animation/NativeInterpolatorFactory.java b/graphics/java/android/graphics/animation/NativeInterpolatorFactory.java
new file mode 100644
index 0000000..3886614
--- /dev/null
+++ b/graphics/java/android/graphics/animation/NativeInterpolatorFactory.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics.animation;
+
+import android.animation.TimeInterpolator;
+
+/**
+ * Static utility class for constructing native interpolators to keep the
+ * JNI simpler
+ *
+ * @hide
+ */
+public final class NativeInterpolatorFactory {
+    private NativeInterpolatorFactory() {}
+
+    /**
+     * Create a native interpolator from the provided param generating a LUT variant if a native
+     * implementation does not exist.
+     */
+    public static long createNativeInterpolator(TimeInterpolator interpolator, long
+            duration) {
+        if (interpolator == null) {
+            return createLinearInterpolator();
+        } else if (RenderNodeAnimator.isNativeInterpolator(interpolator)) {
+            return ((NativeInterpolator) interpolator).createNativeInterpolator();
+        } else {
+            return FallbackLUTInterpolator.createNativeInterpolator(interpolator, duration);
+        }
+    }
+
+    /** Creates a specialized native interpolator for Accelerate/Decelerate */
+    public static native long createAccelerateDecelerateInterpolator();
+    /** Creates a specialized native interpolator for Accelerate */
+    public static native long createAccelerateInterpolator(float factor);
+    /** Creates a specialized native interpolator for Anticipate */
+    public static native long createAnticipateInterpolator(float tension);
+    /** Creates a specialized native interpolator for Anticipate with Overshoot */
+    public static native long createAnticipateOvershootInterpolator(float tension);
+    /** Creates a specialized native interpolator for Bounce */
+    public static native long createBounceInterpolator();
+    /** Creates a specialized native interpolator for Cycle */
+    public static native long createCycleInterpolator(float cycles);
+    /** Creates a specialized native interpolator for Decelerate */
+    public static native long createDecelerateInterpolator(float factor);
+    /** Creates a specialized native interpolator for Linear interpolation */
+    public static native long createLinearInterpolator();
+    /** Creates a specialized native interpolator for Overshoot */
+    public static native long createOvershootInterpolator(float tension);
+    /** Creates a specialized native interpolator for along traveling along a Path */
+    public static native long createPathInterpolator(float[] x, float[] y);
+    /** Creates a specialized native interpolator for LUT */
+    public static native long createLutInterpolator(float[] values);
+}
diff --git a/graphics/java/android/graphics/animation/RenderNodeAnimator.java b/graphics/java/android/graphics/animation/RenderNodeAnimator.java
new file mode 100644
index 0000000..282b2f9
--- /dev/null
+++ b/graphics/java/android/graphics/animation/RenderNodeAnimator.java
@@ -0,0 +1,513 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics.animation;
+
+import android.animation.Animator;
+import android.animation.TimeInterpolator;
+import android.animation.ValueAnimator;
+import android.graphics.CanvasProperty;
+import android.graphics.Paint;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.Choreographer;
+
+import com.android.internal.util.VirtualRefBasePtr;
+
+import java.util.ArrayList;
+
+/**
+ * @hide
+ */
+public class RenderNodeAnimator extends Animator {
+    // Keep in sync with enum RenderProperty in Animator.h
+    public static final int TRANSLATION_X = 0;
+    public static final int TRANSLATION_Y = 1;
+    public static final int TRANSLATION_Z = 2;
+    public static final int SCALE_X = 3;
+    public static final int SCALE_Y = 4;
+    public static final int ROTATION = 5;
+    public static final int ROTATION_X = 6;
+    public static final int ROTATION_Y = 7;
+    public static final int X = 8;
+    public static final int Y = 9;
+    public static final int Z = 10;
+    public static final int ALPHA = 11;
+    // The last value in the enum, used for array size initialization
+    public static final int LAST_VALUE = ALPHA;
+
+    // Keep in sync with enum PaintFields in Animator.h
+    public static final int PAINT_STROKE_WIDTH = 0;
+
+    /**
+     * Field for the Paint alpha channel, which should be specified as a value
+     * between 0 and 255.
+     */
+    public static final int PAINT_ALPHA = 1;
+
+    private VirtualRefBasePtr mNativePtr;
+
+    private Handler mHandler;
+    private RenderNode mTarget;
+    private ViewListener mViewListener;
+    private int mRenderProperty = -1;
+    private float mFinalValue;
+    private TimeInterpolator mInterpolator;
+
+    private static final int STATE_PREPARE = 0;
+    private static final int STATE_DELAYED = 1;
+    private static final int STATE_RUNNING = 2;
+    private static final int STATE_FINISHED = 3;
+    private int mState = STATE_PREPARE;
+
+    private long mUnscaledDuration = 300;
+    private long mUnscaledStartDelay = 0;
+    // If this is true, we will run any start delays on the UI thread. This is
+    // the safe default, and is necessary to ensure start listeners fire at
+    // the correct time. Animators created by RippleDrawable (the
+    // CanvasProperty<> ones) do not have this expectation, and as such will
+    // set this to false so that the renderthread handles the startdelay instead
+    private final boolean mUiThreadHandlesDelay;
+    private long mStartDelay = 0;
+    private long mStartTime;
+
+    /**
+     * Interface used by the view system to update the view hierarchy in conjunction
+     * with this animator.
+     */
+    public interface ViewListener {
+        /** notify the listener that an alpha animation has begun. */
+        void onAlphaAnimationStart(float finalAlpha);
+        /** notify the listener that the animator has mutated a value that requires invalidation */
+        void invalidateParent(boolean forceRedraw);
+    }
+
+    public RenderNodeAnimator(int property, float finalValue) {
+        mRenderProperty = property;
+        mFinalValue = finalValue;
+        mUiThreadHandlesDelay = true;
+        init(nCreateAnimator(property, finalValue));
+    }
+
+    public RenderNodeAnimator(CanvasProperty<Float> property, float finalValue) {
+        init(nCreateCanvasPropertyFloatAnimator(
+                property.getNativeContainer(), finalValue));
+        mUiThreadHandlesDelay = false;
+    }
+
+    /**
+     * Creates a new render node animator for a field on a Paint property.
+     *
+     * @param property The paint property to target
+     * @param paintField Paint field to animate, one of {@link #PAINT_ALPHA} or
+     *            {@link #PAINT_STROKE_WIDTH}
+     * @param finalValue The target value for the property
+     */
+    public RenderNodeAnimator(CanvasProperty<Paint> property, int paintField, float finalValue) {
+        init(nCreateCanvasPropertyPaintAnimator(
+                property.getNativeContainer(), paintField, finalValue));
+        mUiThreadHandlesDelay = false;
+    }
+
+    public RenderNodeAnimator(int x, int y, float startRadius, float endRadius) {
+        init(nCreateRevealAnimator(x, y, startRadius, endRadius));
+        mUiThreadHandlesDelay = true;
+    }
+
+    private void init(long ptr) {
+        mNativePtr = new VirtualRefBasePtr(ptr);
+    }
+
+    private void checkMutable() {
+        if (mState != STATE_PREPARE) {
+            throw new IllegalStateException("Animator has already started, cannot change it now!");
+        }
+        if (mNativePtr == null) {
+            throw new IllegalStateException("Animator's target has been destroyed "
+                    + "(trying to modify an animation after activity destroy?)");
+        }
+    }
+
+    static boolean isNativeInterpolator(TimeInterpolator interpolator) {
+        return interpolator.getClass().isAnnotationPresent(HasNativeInterpolator.class);
+    }
+
+    private void applyInterpolator() {
+        if (mInterpolator == null || mNativePtr == null) return;
+
+        long ni;
+        if (isNativeInterpolator(mInterpolator)) {
+            ni = ((NativeInterpolator) mInterpolator).createNativeInterpolator();
+        } else {
+            long duration = nGetDuration(mNativePtr.get());
+            ni = FallbackLUTInterpolator.createNativeInterpolator(mInterpolator, duration);
+        }
+        nSetInterpolator(mNativePtr.get(), ni);
+    }
+
+    @Override
+    public void start() {
+        if (mTarget == null) {
+            throw new IllegalStateException("Missing target!");
+        }
+
+        if (mState != STATE_PREPARE) {
+            throw new IllegalStateException("Already started!");
+        }
+
+        mState = STATE_DELAYED;
+        if (mHandler == null) {
+            mHandler = new Handler(true);
+        }
+        applyInterpolator();
+
+        if (mNativePtr == null) {
+            // It's dead, immediately cancel
+            cancel();
+        } else if (mStartDelay <= 0 || !mUiThreadHandlesDelay) {
+            nSetStartDelay(mNativePtr.get(), mStartDelay);
+            doStart();
+        } else {
+            getHelper().addDelayedAnimation(this);
+        }
+    }
+
+    private void doStart() {
+        // Alpha is a special snowflake that has the canonical value stored
+        // in mTransformationInfo instead of in RenderNode, so we need to update
+        // it with the final value here.
+        if (mRenderProperty == RenderNodeAnimator.ALPHA && mViewListener != null) {
+            mViewListener.onAlphaAnimationStart(mFinalValue);
+        }
+
+        moveToRunningState();
+
+        if (mViewListener != null) {
+            // Kick off a frame to start the process
+            mViewListener.invalidateParent(false);
+        }
+    }
+
+    private void moveToRunningState() {
+        mState = STATE_RUNNING;
+        if (mNativePtr != null) {
+            nStart(mNativePtr.get());
+        }
+        notifyStartListeners();
+    }
+
+    private void notifyStartListeners() {
+        final ArrayList<AnimatorListener> listeners = cloneListeners();
+        final int numListeners = listeners == null ? 0 : listeners.size();
+        for (int i = 0; i < numListeners; i++) {
+            listeners.get(i).onAnimationStart(this);
+        }
+    }
+
+    @Override
+    public void cancel() {
+        if (mState != STATE_PREPARE && mState != STATE_FINISHED) {
+            if (mState == STATE_DELAYED) {
+                getHelper().removeDelayedAnimation(this);
+                moveToRunningState();
+            }
+
+            final ArrayList<AnimatorListener> listeners = cloneListeners();
+            final int numListeners = listeners == null ? 0 : listeners.size();
+            for (int i = 0; i < numListeners; i++) {
+                listeners.get(i).onAnimationCancel(this);
+            }
+
+            end();
+        }
+    }
+
+    @Override
+    public void end() {
+        if (mState != STATE_FINISHED) {
+            if (mState < STATE_RUNNING) {
+                getHelper().removeDelayedAnimation(this);
+                doStart();
+            }
+            if (mNativePtr != null) {
+                nEnd(mNativePtr.get());
+                if (mViewListener != null) {
+                    // Kick off a frame to flush the state change
+                    mViewListener.invalidateParent(false);
+                }
+            } else {
+                // It's already dead, jump to onFinish
+                onFinished();
+            }
+        }
+    }
+
+    @Override
+    public void pause() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void resume() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    public void setViewListener(ViewListener listener) {
+        mViewListener = listener;
+    }
+
+    /** Sets the animation target to the owning view of the RecordingCanvas */
+    public final void setTarget(RecordingCanvas canvas) {
+        setTarget(canvas.mNode);
+    }
+
+    /** Sets the node that is to be the target of this animation */
+    protected void setTarget(RenderNode node) {
+        checkMutable();
+        if (mTarget != null) {
+            throw new IllegalStateException("Target already set!");
+        }
+        nSetListener(mNativePtr.get(), this);
+        mTarget = node;
+        mTarget.addAnimator(this);
+    }
+
+    /** Set the start value for the animation */
+    public void setStartValue(float startValue) {
+        checkMutable();
+        nSetStartValue(mNativePtr.get(), startValue);
+    }
+
+    @Override
+    public void setStartDelay(long startDelay) {
+        checkMutable();
+        if (startDelay < 0) {
+            throw new IllegalArgumentException("startDelay must be positive; " + startDelay);
+        }
+        mUnscaledStartDelay = startDelay;
+        mStartDelay = (long) (ValueAnimator.getDurationScale() * startDelay);
+    }
+
+    @Override
+    public long getStartDelay() {
+        return mUnscaledStartDelay;
+    }
+
+    @Override
+    public RenderNodeAnimator setDuration(long duration) {
+        checkMutable();
+        if (duration < 0) {
+            throw new IllegalArgumentException("duration must be positive; " + duration);
+        }
+        mUnscaledDuration = duration;
+        nSetDuration(mNativePtr.get(), (long) (duration * ValueAnimator.getDurationScale()));
+        return this;
+    }
+
+    @Override
+    public long getDuration() {
+        return mUnscaledDuration;
+    }
+
+    @Override
+    public long getTotalDuration() {
+        return mUnscaledDuration + mUnscaledStartDelay;
+    }
+
+    @Override
+    public boolean isRunning() {
+        return mState == STATE_DELAYED || mState == STATE_RUNNING;
+    }
+
+    @Override
+    public boolean isStarted() {
+        return mState != STATE_PREPARE;
+    }
+
+    @Override
+    public void setInterpolator(TimeInterpolator interpolator) {
+        checkMutable();
+        mInterpolator = interpolator;
+    }
+
+    @Override
+    public TimeInterpolator getInterpolator() {
+        return mInterpolator;
+    }
+
+    protected void onFinished() {
+        if (mState == STATE_PREPARE) {
+            // Unlikely but possible, the native side has been destroyed
+            // before we have started.
+            releaseNativePtr();
+            return;
+        }
+        if (mState == STATE_DELAYED) {
+            getHelper().removeDelayedAnimation(this);
+            notifyStartListeners();
+        }
+        mState = STATE_FINISHED;
+
+        final ArrayList<AnimatorListener> listeners = cloneListeners();
+        final int numListeners = listeners == null ? 0 : listeners.size();
+        for (int i = 0; i < numListeners; i++) {
+            listeners.get(i).onAnimationEnd(this);
+        }
+
+        // Release the native object, as it has a global reference to us. This
+        // breaks the cyclic reference chain, and allows this object to be
+        // GC'd
+        releaseNativePtr();
+    }
+
+    private void releaseNativePtr() {
+        if (mNativePtr != null) {
+            mNativePtr.release();
+            mNativePtr = null;
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private ArrayList<AnimatorListener> cloneListeners() {
+        ArrayList<AnimatorListener> listeners = getListeners();
+        if (listeners != null) {
+            listeners = (ArrayList<AnimatorListener>) listeners.clone();
+        }
+        return listeners;
+    }
+
+    public long getNativeAnimator() {
+        return mNativePtr.get();
+    }
+
+    /**
+     * @return true if the animator was started, false if still delayed
+     */
+    private boolean processDelayed(long frameTimeMs) {
+        if (mStartTime == 0) {
+            mStartTime = frameTimeMs;
+        } else if ((frameTimeMs - mStartTime) >= mStartDelay) {
+            doStart();
+            return true;
+        }
+        return false;
+    }
+
+    private static DelayedAnimationHelper getHelper() {
+        DelayedAnimationHelper helper = sAnimationHelper.get();
+        if (helper == null) {
+            helper = new DelayedAnimationHelper();
+            sAnimationHelper.set(helper);
+        }
+        return helper;
+    }
+
+    private static ThreadLocal<DelayedAnimationHelper> sAnimationHelper =
+            new ThreadLocal<DelayedAnimationHelper>();
+
+    private static class DelayedAnimationHelper implements Runnable {
+
+        private ArrayList<RenderNodeAnimator> mDelayedAnims = new ArrayList<RenderNodeAnimator>();
+        private final Choreographer mChoreographer;
+        private boolean mCallbackScheduled;
+
+        DelayedAnimationHelper() {
+            mChoreographer = Choreographer.getInstance();
+        }
+
+        public void addDelayedAnimation(RenderNodeAnimator animator) {
+            mDelayedAnims.add(animator);
+            scheduleCallback();
+        }
+
+        public void removeDelayedAnimation(RenderNodeAnimator animator) {
+            mDelayedAnims.remove(animator);
+        }
+
+        private void scheduleCallback() {
+            if (!mCallbackScheduled) {
+                mCallbackScheduled = true;
+                mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, this, null);
+            }
+        }
+
+        @Override
+        public void run() {
+            long frameTimeMs = mChoreographer.getFrameTime();
+            mCallbackScheduled = false;
+
+            int end = 0;
+            for (int i = 0; i < mDelayedAnims.size(); i++) {
+                RenderNodeAnimator animator = mDelayedAnims.get(i);
+                if (!animator.processDelayed(frameTimeMs)) {
+                    if (end != i) {
+                        mDelayedAnims.set(end, animator);
+                    }
+                    end++;
+                }
+            }
+            while (mDelayedAnims.size() > end) {
+                mDelayedAnims.remove(mDelayedAnims.size() - 1);
+            }
+
+            if (mDelayedAnims.size() > 0) {
+                scheduleCallback();
+            }
+        }
+    }
+
+    // Called by native
+    private static void callOnFinished(RenderNodeAnimator animator) {
+        if (animator.mHandler != null) {
+            animator.mHandler.post(animator::onFinished);
+        } else {
+            new Handler(Looper.getMainLooper(), null, true).post(animator::onFinished);
+        }
+    }
+
+    @Override
+    public Animator clone() {
+        throw new IllegalStateException("Cannot clone this animator");
+    }
+
+    @Override
+    public void setAllowRunningAsynchronously(boolean mayRunAsync) {
+        checkMutable();
+        nSetAllowRunningAsync(mNativePtr.get(), mayRunAsync);
+    }
+
+    private static native long nCreateAnimator(int property, float finalValue);
+    private static native long nCreateCanvasPropertyFloatAnimator(
+            long canvasProperty, float finalValue);
+    private static native long nCreateCanvasPropertyPaintAnimator(
+            long canvasProperty, int paintField, float finalValue);
+    private static native long nCreateRevealAnimator(
+            int x, int y, float startRadius, float endRadius);
+
+    private static native void nSetStartValue(long nativePtr, float startValue);
+    private static native void nSetDuration(long nativePtr, long duration);
+    private static native long nGetDuration(long nativePtr);
+    private static native void nSetStartDelay(long nativePtr, long startDelay);
+    private static native void nSetInterpolator(long animPtr, long interpolatorPtr);
+    private static native void nSetAllowRunningAsync(long animPtr, boolean mayRunAsync);
+    private static native void nSetListener(long animPtr, RenderNodeAnimator listener);
+
+    private static native void nStart(long animPtr);
+    private static native void nEnd(long animPtr);
+}
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 1acf6c5..9fb72cf 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -42,6 +42,7 @@
 import android.graphics.RecordingCanvas;
 import android.graphics.Rect;
 import android.graphics.RenderNode;
+import android.graphics.animation.NativeInterpolatorFactory;
 import android.os.Build;
 import android.os.Handler;
 import android.util.ArrayMap;
@@ -54,7 +55,6 @@
 import android.util.TimeUtils;
 import android.view.Choreographer;
 import android.view.NativeVectorDrawableAnimator;
-import android.view.RenderNodeAnimatorSetHelper;
 import android.view.View;
 
 import com.android.internal.R;
@@ -1532,7 +1532,7 @@
             long startDelay = extraDelay + animator.getStartDelay();
             TimeInterpolator interpolator = animator.getInterpolator();
             long nativeInterpolator =
-                    RenderNodeAnimatorSetHelper.createNativeInterpolator(interpolator, duration);
+                    NativeInterpolatorFactory.createNativeInterpolator(interpolator, duration);
 
             startDelay *= ValueAnimator.getDurationScale();
             duration *= ValueAnimator.getDurationScale();
@@ -1548,7 +1548,7 @@
          * to the last seen RenderNode target and start right away.
          */
         protected void recordLastSeenTarget(RecordingCanvas canvas) {
-            final RenderNode node = RenderNodeAnimatorSetHelper.getTarget(canvas);
+            final RenderNode node = canvas.mNode;
             mLastSeenTarget = new WeakReference<RenderNode>(node);
             // Add the animator to the list of animators on every draw
             if (mInitialized || mPendingAnimationActions.size() > 0) {
diff --git a/graphics/java/android/graphics/drawable/RippleForeground.java b/graphics/java/android/graphics/drawable/RippleForeground.java
index cce9ba3..0f37695 100644
--- a/graphics/java/android/graphics/drawable/RippleForeground.java
+++ b/graphics/java/android/graphics/drawable/RippleForeground.java
@@ -25,9 +25,9 @@
 import android.graphics.Paint;
 import android.graphics.RecordingCanvas;
 import android.graphics.Rect;
+import android.graphics.animation.RenderNodeAnimator;
 import android.util.FloatProperty;
 import android.util.MathUtils;
-import android.view.RenderNodeAnimator;
 import android.view.animation.AnimationUtils;
 import android.view.animation.LinearInterpolator;
 import android.view.animation.PathInterpolator;
diff --git a/identity/java/android/security/identity/CredstoreIdentityCredential.java b/identity/java/android/security/identity/CredstoreIdentityCredential.java
index c520331..7c0af6d 100644
--- a/identity/java/android/security/identity/CredstoreIdentityCredential.java
+++ b/identity/java/android/security/identity/CredstoreIdentityCredential.java
@@ -152,8 +152,8 @@
             derivedKey = Util.computeHkdf("HmacSha256", sharedSecret, salt, info, 32);
             mReaderSecretKey = new SecretKeySpec(derivedKey, "AES");
 
-            mEphemeralCounter = 0;
-            mReadersExpectedEphemeralCounter = 0;
+            mEphemeralCounter = 1;
+            mReadersExpectedEphemeralCounter = 1;
 
         } catch (NoSuchAlgorithmException e) {
             throw new RuntimeException("Error performing key agreement", e);
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index debb38b..81dedda 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -84,7 +84,6 @@
                 "libGLESv3",
                 "libvulkan",
                 "libui",
-                "libgui",
                 "libnativedisplay",
                 "libnativewindow",
                 "libprotobuf-cpp-lite",
@@ -289,6 +288,13 @@
     name: "hwui_test_defaults",
     defaults: ["hwui_defaults"],
     test_suites: ["device-tests"],
+    target: {
+        android: {
+            shared_libs: [
+	        "libgui",
+	    ],
+	}
+    },
     srcs: [
         "tests/common/scenes/*.cpp",
         "tests/common/LeakChecker.cpp",
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 58cc08b..914c046 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -32,7 +32,6 @@
 
 #ifndef _WIN32
 #include <binder/IServiceManager.h>
-#include <private/gui/ComposerService.h>
 #endif
 #include <ui/PixelFormat.h>
 
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
index e482cad..fc6e114 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
@@ -16,8 +16,10 @@
 
 #pragma once
 
-#include "SkiaPipeline.h"
+#include <EGL/egl.h>
+#include <system/window.h>
 
+#include "SkiaPipeline.h"
 #include "renderstate/RenderState.h"
 
 namespace android {
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 29b4dd7..41aa1ff 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -24,18 +24,19 @@
 #include <SkOverdrawColorFilter.h>
 #include <SkPicture.h>
 #include <SkPictureRecorder.h>
-#include <SkTypeface.h>
 #include <SkSerialProcs.h>
+#include <SkTypeface.h>
+#include <android-base/properties.h>
+#include <unistd.h>
+
+#include <sstream>
+
 #include "LightingInfo.h"
 #include "VectorDrawable.h"
 #include "thread/CommonPool.h"
 #include "tools/SkSharingProc.h"
-#include "utils/TraceUtils.h"
 #include "utils/String8.h"
-
-#include <unistd.h>
-
-#include <android-base/properties.h>
+#include "utils/TraceUtils.h"
 
 using namespace android::uirenderer::renderthread;
 
@@ -600,27 +601,24 @@
 // Overdraw debugging
 
 // These colors should be kept in sync with Caches::getOverdrawColor() with a few differences.
-// This implementation:
-// (1) Requires transparent entries for "no overdraw" and "single draws".
-// (2) Requires premul colors (instead of unpremul).
-// (3) Requires RGBA colors (instead of BGRA).
-static const uint32_t kOverdrawColors[2][6] = {
-        {
-                0x00000000,
-                0x00000000,
-                0x2f2f0000,
-                0x2f002f00,
-                0x3f00003f,
-                0x7f00007f,
-        },
-        {
-                0x00000000,
-                0x00000000,
-                0x2f2f0000,
-                0x4f004f4f,
-                0x5f50335f,
-                0x7f00007f,
-        },
+// This implementation requires transparent entries for "no overdraw" and "single draws".
+static const SkColor kOverdrawColors[2][6] = {
+    {
+        0x00000000,
+        0x00000000,
+        0x2f0000ff,
+        0x2f00ff00,
+        0x3fff0000,
+        0x7fff0000,
+    },
+    {
+        0x00000000,
+        0x00000000,
+        0x2f0000ff,
+        0x4fffff00,
+        0x5fff89d7,
+        0x7fff0000,
+    },
 };
 
 void SkiaPipeline::renderOverdraw(const SkRect& clip,
@@ -642,8 +640,8 @@
 
     // Draw overdraw colors to the canvas.  The color filter will convert counts to colors.
     SkPaint paint;
-    const SkPMColor* colors = kOverdrawColors[static_cast<int>(Properties::overdrawColorSet)];
-    paint.setColorFilter(SkOverdrawColorFilter::Make(colors));
+    const SkColor* colors = kOverdrawColors[static_cast<int>(Properties::overdrawColorSet)];
+    paint.setColorFilter(SkOverdrawColorFilter::MakeWithSkColors(colors));
     surface->getCanvas()->drawImage(counts.get(), 0.0f, 0.0f, &paint);
 }
 
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 91f9447..4299dd3 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -139,15 +139,15 @@
     mAnimationContext->destroy();
 }
 
-void CanvasContext::setSurface(sp<Surface>&& surface, bool enableTimeout) {
+void CanvasContext::setSurface(ANativeWindow* window, bool enableTimeout) {
     ATRACE_CALL();
 
-    if (surface) {
-        mNativeSurface = std::make_unique<ReliableSurface>(std::move(surface));
+    if (window) {
+        mNativeSurface = std::make_unique<ReliableSurface>(window);
         mNativeSurface->init();
         if (enableTimeout) {
             // TODO: Fix error handling & re-shorten timeout
-            ANativeWindow_setDequeueTimeout(mNativeSurface->getNativeWindow(), 4000_ms);
+            ANativeWindow_setDequeueTimeout(window, 4000_ms);
         }
     } else {
         mNativeSurface = nullptr;
@@ -167,7 +167,7 @@
 
     mFrameNumber = -1;
 
-    if (hasSurface) {
+    if (window != nullptr && hasSurface) {
         mHaveNewSurface = true;
         mSwapHistory.clear();
         // Enable frame stats after the surface has been bound to the appropriate graphics API.
@@ -204,8 +204,7 @@
 
 void CanvasContext::allocateBuffers() {
     if (mNativeSurface) {
-        ANativeWindow* anw = mNativeSurface->getNativeWindow();
-        ANativeWindow_allocateBuffers(anw);
+        ANativeWindow_tryAllocateBuffers(mNativeSurface->getNativeWindow());
     }
 }
 
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 629c741..0f1b8ae 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -35,7 +35,6 @@
 #include <SkRect.h>
 #include <SkSize.h>
 #include <cutils/compiler.h>
-#include <gui/Surface.h>
 #include <utils/Functor.h>
 
 #include <functional>
@@ -111,7 +110,7 @@
     // Won't take effect until next EGLSurface creation
     void setSwapBehavior(SwapBehavior swapBehavior);
 
-    void setSurface(sp<Surface>&& surface, bool enableTimeout = true);
+    void setSurface(ANativeWindow* window, bool enableTimeout = true);
     bool pauseSurface();
     void setStopped(bool stopped);
     bool hasSurface() const { return mNativeSurface.get(); }
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index c1fed26..5e0471c 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -20,7 +20,6 @@
 #include <GLES/gl.h>
 #include <cutils/properties.h>
 #include <log/log.h>
-#include <private/gui/SyncFeatures.h>
 #include <sync/sync.h>
 #include <utils/Trace.h>
 
@@ -79,6 +78,9 @@
     bool displayP3 = false;
     bool contextPriority = false;
     bool surfacelessContext = false;
+    bool nativeFenceSync = false;
+    bool fenceSync = false;
+    bool waitSync = false;
 } EglExtensions;
 
 EglManager::EglManager()
@@ -226,6 +228,9 @@
     EglExtensions.displayP3 = extensions.has("EGL_EXT_gl_colorspace_display_p3_passthrough");
     EglExtensions.contextPriority = extensions.has("EGL_IMG_context_priority");
     EglExtensions.surfacelessContext = extensions.has("EGL_KHR_surfaceless_context");
+    EglExtensions.nativeFenceSync = extensions.has("EGL_ANDROID_native_fence_sync");
+    EglExtensions.fenceSync = extensions.has("EGL_KHR_fence_sync");
+    EglExtensions.waitSync = extensions.has("EGL_KHR_wait_sync");
 }
 
 bool EglManager::hasEglContext() {
@@ -527,8 +532,7 @@
         return INVALID_OPERATION;
     }
 
-    if (SyncFeatures::getInstance().useWaitSync() &&
-        SyncFeatures::getInstance().useNativeFenceSync()) {
+    if (EglExtensions.waitSync && EglExtensions.nativeFenceSync) {
         // Block GPU on the fence.
         // Create an EGLSyncKHR from the current fence.
         int fenceFd = ::dup(fence);
@@ -572,7 +576,7 @@
         return INVALID_OPERATION;
     }
 
-    if (SyncFeatures::getInstance().useNativeFenceSync()) {
+    if (EglExtensions.nativeFenceSync) {
         EGLSyncKHR sync = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
         if (sync == EGL_NO_SYNC_KHR) {
             ALOGE("EglManager::createReleaseFence: error creating EGL fence: %#x", eglGetError());
@@ -589,7 +593,7 @@
         }
         *nativeFence = fenceFd;
         *eglFence = EGL_NO_SYNC_KHR;
-    } else if (useFenceSync && SyncFeatures::getInstance().useFenceSync()) {
+    } else if (useFenceSync && EglExtensions.fenceSync) {
         if (*eglFence != EGL_NO_SYNC_KHR) {
             // There is already a fence for the current slot.  We need to
             // wait on that before replacing it with another fence to
diff --git a/libs/hwui/renderthread/ReliableSurface.cpp b/libs/hwui/renderthread/ReliableSurface.cpp
index e92500f..8a0b4e8 100644
--- a/libs/hwui/renderthread/ReliableSurface.cpp
+++ b/libs/hwui/renderthread/ReliableSurface.cpp
@@ -16,7 +16,10 @@
 
 #include "ReliableSurface.h"
 
+#include <log/log_main.h>
 #include <private/android/AHardwareBufferHelpers.h>
+// TODO: this should be including apex instead.
+#include <vndk/window.h>
 
 namespace android::uirenderer::renderthread {
 
@@ -26,8 +29,9 @@
 // to propagate this error back to the caller
 constexpr bool DISABLE_BUFFER_PREFETCH = true;
 
-ReliableSurface::ReliableSurface(sp<Surface>&& surface) : mSurface(std::move(surface)) {
-    LOG_ALWAYS_FATAL_IF(!mSurface, "Error, unable to wrap a nullptr");
+ReliableSurface::ReliableSurface(ANativeWindow* window) : mWindow(window) {
+    LOG_ALWAYS_FATAL_IF(!mWindow, "Error, unable to wrap a nullptr");
+    ANativeWindow_acquire(mWindow);
 }
 
 ReliableSurface::~ReliableSurface() {
@@ -36,26 +40,27 @@
     // As a concrete example, if the underlying ANativeWindow is associated with
     // an EGLSurface that is still in use, then if we don't clear out the
     // interceptors then we walk into undefined behavior.
-    ANativeWindow_setCancelBufferInterceptor(mSurface.get(), nullptr, nullptr);
-    ANativeWindow_setDequeueBufferInterceptor(mSurface.get(), nullptr, nullptr);
-    ANativeWindow_setQueueBufferInterceptor(mSurface.get(), nullptr, nullptr);
-    ANativeWindow_setPerformInterceptor(mSurface.get(), nullptr, nullptr);
+    ANativeWindow_setCancelBufferInterceptor(mWindow, nullptr, nullptr);
+    ANativeWindow_setDequeueBufferInterceptor(mWindow, nullptr, nullptr);
+    ANativeWindow_setQueueBufferInterceptor(mWindow, nullptr, nullptr);
+    ANativeWindow_setPerformInterceptor(mWindow, nullptr, nullptr);
+    ANativeWindow_release(mWindow);
 }
 
 void ReliableSurface::init() {
-    int result = ANativeWindow_setCancelBufferInterceptor(mSurface.get(), hook_cancelBuffer, this);
+    int result = ANativeWindow_setCancelBufferInterceptor(mWindow, hook_cancelBuffer, this);
     LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set cancelBuffer interceptor: error = %d",
                         result);
 
-    result = ANativeWindow_setDequeueBufferInterceptor(mSurface.get(), hook_dequeueBuffer, this);
+    result = ANativeWindow_setDequeueBufferInterceptor(mWindow, hook_dequeueBuffer, this);
     LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set dequeueBuffer interceptor: error = %d",
                         result);
 
-    result = ANativeWindow_setQueueBufferInterceptor(mSurface.get(), hook_queueBuffer, this);
+    result = ANativeWindow_setQueueBufferInterceptor(mWindow, hook_queueBuffer, this);
     LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set queueBuffer interceptor: error = %d",
                         result);
 
-    result = ANativeWindow_setPerformInterceptor(mSurface.get(), hook_perform, this);
+    result = ANativeWindow_setPerformInterceptor(mWindow, hook_perform, this);
     LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set perform interceptor: error = %d",
                         result);
 }
@@ -87,7 +92,7 @@
     ANativeWindowBuffer* buffer = nullptr;
 
     // Note that this calls back into our own hooked method.
-    int result = ANativeWindow_dequeueBuffer(mSurface.get(), &buffer, &fenceFd);
+    int result = ANativeWindow_dequeueBuffer(mWindow, &buffer, &fenceFd);
 
     {
         std::lock_guard _lock{mMutex};
@@ -117,7 +122,7 @@
         // Note that clearReservedBuffer may be reentrant here, so
         // mReservedBuffer must be cleared once we reach here to avoid recursing
         // forever.
-        ANativeWindow_cancelBuffer(mSurface.get(), buffer, releaseFd);
+        ANativeWindow_cancelBuffer(mWindow, buffer, releaseFd);
     }
 }
 
@@ -239,10 +244,10 @@
             case ANATIVEWINDOW_PERFORM_SET_BUFFERS_GEOMETRY:
                 /* width */ va_arg(args, uint32_t);
                 /* height */ va_arg(args, uint32_t);
-                rs->mFormat = va_arg(args, PixelFormat);
+                rs->mFormat = static_cast<AHardwareBuffer_Format>(va_arg(args, int32_t));
                 break;
             case ANATIVEWINDOW_PERFORM_SET_BUFFERS_FORMAT:
-                rs->mFormat = va_arg(args, PixelFormat);
+                rs->mFormat = static_cast<AHardwareBuffer_Format>(va_arg(args, int32_t));
                 break;
         }
     }
diff --git a/libs/hwui/renderthread/ReliableSurface.h b/libs/hwui/renderthread/ReliableSurface.h
index e3cd8c0..58cd067 100644
--- a/libs/hwui/renderthread/ReliableSurface.h
+++ b/libs/hwui/renderthread/ReliableSurface.h
@@ -16,12 +16,14 @@
 
 #pragma once
 
+#include <android-base/unique_fd.h>
 #include <apex/window.h>
-#include <gui/Surface.h>
+#include <utils/Errors.h>
 #include <utils/Macros.h>
 #include <utils/StrongPointer.h>
 
 #include <memory>
+#include <mutex>
 
 namespace android::uirenderer::renderthread {
 
@@ -29,7 +31,7 @@
     PREVENT_COPY_AND_ASSIGN(ReliableSurface);
 
 public:
-    ReliableSurface(sp<Surface>&& surface);
+    ReliableSurface(ANativeWindow* window);
     ~ReliableSurface();
 
     // Performs initialization that is not safe to do in the constructor.
@@ -37,12 +39,10 @@
     // passed as the data pointer is not safe.
     void init();
 
-    ANativeWindow* getNativeWindow() { return mSurface.get(); }
+    ANativeWindow* getNativeWindow() { return mWindow; }
 
     int reserveNext();
 
-    int query(int what, int* value) const { return mSurface->query(what, value); }
-
     int getAndClearError() {
         int ret = mBufferQueueState;
         mBufferQueueState = OK;
@@ -50,12 +50,12 @@
     }
 
 private:
-    sp<Surface> mSurface;
+    ANativeWindow* mWindow;
 
     mutable std::mutex mMutex;
 
     uint64_t mUsage = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;
-    PixelFormat mFormat = PIXEL_FORMAT_RGBA_8888;
+    AHardwareBuffer_Format mFormat = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
     std::unique_ptr<AHardwareBuffer, void (*)(AHardwareBuffer*)> mScratchBuffer{
             nullptr, AHardwareBuffer_release};
     ANativeWindowBuffer* mReservedBuffer = nullptr;
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 1e7fc71..b66a13d 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -16,8 +16,6 @@
 
 #include "RenderProxy.h"
 
-#include <gui/Surface.h>
-
 #include "DeferredLayerUpdater.h"
 #include "DisplayList.h"
 #include "Properties.h"
@@ -78,9 +76,11 @@
     mRenderThread.queue().runSync([this, name]() { mContext->setName(std::string(name)); });
 }
 
-void RenderProxy::setSurface(const sp<Surface>& surface, bool enableTimeout) {
-    mRenderThread.queue().post([this, surf = surface, enableTimeout]() mutable {
-        mContext->setSurface(std::move(surf), enableTimeout);
+void RenderProxy::setSurface(ANativeWindow* window, bool enableTimeout) {
+    ANativeWindow_acquire(window);
+    mRenderThread.queue().post([this, win = window, enableTimeout]() mutable {
+        mContext->setSurface(win, enableTimeout);
+        ANativeWindow_release(win);
     });
 }
 
@@ -314,10 +314,9 @@
             [context = mContext, renderAhead] { context->setRenderAheadDepth(renderAhead); });
 }
 
-int RenderProxy::copySurfaceInto(sp<Surface>& surface, int left, int top, int right, int bottom,
+int RenderProxy::copySurfaceInto(ANativeWindow* window, int left, int top, int right, int bottom,
                                  SkBitmap* bitmap) {
     auto& thread = RenderThread::getInstance();
-    ANativeWindow* window = surface.get();
     return static_cast<int>(thread.queue().runSync([&]() -> auto {
         return thread.readback().copySurfaceInto(window, Rect(left, top, right, bottom), bitmap);
     }));
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index ab0dd2b..3baeb2f 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -18,6 +18,7 @@
 #define RENDERPROXY_H_
 
 #include <SkBitmap.h>
+#include <android/native_window.h>
 #include <cutils/compiler.h>
 #include <utils/Functor.h>
 
@@ -69,7 +70,7 @@
     ANDROID_API bool loadSystemProperties();
     ANDROID_API void setName(const char* name);
 
-    ANDROID_API void setSurface(const sp<Surface>& surface, bool enableTimeout = true);
+    ANDROID_API void setSurface(ANativeWindow* window, bool enableTimeout = true);
     ANDROID_API void allocateBuffers();
     ANDROID_API bool pause();
     ANDROID_API void setStopped(bool stopped);
@@ -140,11 +141,7 @@
      */
     ANDROID_API void setRenderAheadDepth(int renderAhead);
 
-    // TODO: This api will need to take in an ANativeWindow instead, but the
-    // caller, ThreadedRenderer, doesn't have access to libandroid due to a
-    // circular dependency, so it can't use the JNI ANativeWindow methods. Once
-    // that is resolved then replace the surface type here.
-    ANDROID_API static int copySurfaceInto(sp<Surface>& surface, int left, int top, int right,
+    ANDROID_API static int copySurfaceInto(ANativeWindow* window, int left, int top, int right,
                                            int bottom, SkBitmap* bitmap);
     ANDROID_API static void prepareToDraw(Bitmap& bitmap);
 
diff --git a/libs/hwui/tests/common/scenes/MagnifierAnimation.cpp b/libs/hwui/tests/common/scenes/MagnifierAnimation.cpp
index f6cff1c..f4fce27 100644
--- a/libs/hwui/tests/common/scenes/MagnifierAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/MagnifierAnimation.cpp
@@ -70,7 +70,7 @@
             magnifier->getSkBitmap(&temp);
             constexpr int x = 90;
             constexpr int y = 325;
-            RenderProxy::copySurfaceInto(renderTarget, x, y, x + magnifier->width(),
+            RenderProxy::copySurfaceInto(renderTarget.get(), x, y, x + magnifier->width(),
                                          y + magnifier->height(), &temp);
         }
     }
diff --git a/libs/hwui/tests/macrobench/TestSceneRunner.cpp b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
index 3b6baa7..801cb7d 100644
--- a/libs/hwui/tests/macrobench/TestSceneRunner.cpp
+++ b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
@@ -131,7 +131,7 @@
     ContextFactory factory;
     std::unique_ptr<RenderProxy> proxy(new RenderProxy(false, rootNode.get(), &factory));
     proxy->loadSystemProperties();
-    proxy->setSurface(surface);
+    proxy->setSurface(surface.get());
     float lightX = width / 2.0;
     proxy->setLightAlpha(255 * 0.075, 255 * 0.15);
     proxy->setLightGeometry((Vector3){lightX, dp(-200.0f), dp(800.0f)}, dp(800.0f));
diff --git a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp
index 7d999c4..d08aea6 100644
--- a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp
+++ b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp
@@ -210,7 +210,7 @@
     auto surface = testContext.surface();
     int width = ANativeWindow_getWidth(surface.get());
     int height = ANativeWindow_getHeight(surface.get());
-    canvasContext->setSurface(std::move(surface));
+    canvasContext->setSurface(surface.get());
 
     TreeInfo info(TreeInfo::MODE_FULL, *canvasContext.get());
     DamageAccumulator damageAccumulator;
diff --git a/libs/protoutil/Android.bp b/libs/protoutil/Android.bp
index b0af997..d2b7d5c 100644
--- a/libs/protoutil/Android.bp
+++ b/libs/protoutil/Android.bp
@@ -45,6 +45,12 @@
     defaults: ["libprotoutil_defaults"],
 
     export_include_dirs: ["include"],
+
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.os.statsd",
+        "test_com.android.os.statsd",
+    ],
 }
 
 cc_test {
diff --git a/location/java/android/location/AbstractListenerManager.java b/location/java/android/location/AbstractListenerManager.java
index f075a53..3dc7cfc 100644
--- a/location/java/android/location/AbstractListenerManager.java
+++ b/location/java/android/location/AbstractListenerManager.java
@@ -16,6 +16,8 @@
 
 package android.location;
 
+import static com.android.internal.util.function.pooled.PooledLambda.obtainRunnable;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.Binder;
@@ -62,20 +64,24 @@
         }
 
         private void execute(Consumer<TListener> operation) {
-            mExecutor.execute(() -> {
-                TListener listener = mListener;
-                if (listener == null) {
-                    return;
-                }
+            mExecutor.execute(
+                    obtainRunnable(Registration<TRequest, TListener>::accept, this, operation)
+                            .recycleOnUse());
+        }
 
-                // we may be under the binder identity if a direct executor is used
-                long identity = Binder.clearCallingIdentity();
-                try {
-                    operation.accept(listener);
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-            });
+        private void accept(Consumer<TListener> operation) {
+            TListener listener = mListener;
+            if (listener == null) {
+                return;
+            }
+
+            // we may be under the binder identity if a direct executor is used
+            long identity = Binder.clearCallingIdentity();
+            try {
+                operation.accept(listener);
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
         }
     }
 
diff --git a/location/java/android/location/GnssMeasurementCorrections.java b/location/java/android/location/GnssMeasurementCorrections.java
index 19c3992..ffbe11a 100644
--- a/location/java/android/location/GnssMeasurementCorrections.java
+++ b/location/java/android/location/GnssMeasurementCorrections.java
@@ -179,6 +179,10 @@
      * Gets the environment bearing in degrees clockwise from true north, in the direction of user
      * motion. Environment bearing is provided when it is known with high probability that
      * velocity is aligned with an environment feature (such as edge of a building, or road).
+     *
+     * {@link #hasEnvironmentBearing} should be called to check the environment bearing is available
+     * before calling this method. The value is undefined if {@link #hasEnvironmentBearing} returns
+     * false.
      */
     @FloatRange(from = 0.0f, to = 360.0f)
     public float getEnvironmentBearingDegrees() {
@@ -186,7 +190,15 @@
     }
 
     /**
-     * Gets the environment bearing uncertainty in degrees.
+     * Gets the environment bearing uncertainty in degrees. It represents the standard deviation of
+     * the physical structure in the circle of position uncertainty. The uncertainty can take values
+     * between 0 and 180 degrees. The {@link #hasEnvironmentBearing} becomes false as the
+     * uncertainty value passes a predefined threshold depending on the physical structure around
+     * the user.
+     *
+     * {@link #hasEnvironmentBearing} should be called to check the environment bearing is available
+     * before calling this method. The value is undefined if {@link #hasEnvironmentBearing} returns
+     * false.
      */
     @FloatRange(from = 0.0f, to = 180.0f)
     public float getEnvironmentBearingUncertaintyDegrees() {
@@ -358,6 +370,8 @@
          * user motion. Environment bearing is provided when it is known with high probability
          * that velocity is aligned with an environment feature (such as edge of a building, or
          * road).
+         *
+         * Both the bearing and uncertainty must be set for the environment bearing to be valid.
          */
         @NonNull public Builder setEnvironmentBearingDegrees(
                 @FloatRange(from = 0.0f, to = 360.0f)
@@ -369,6 +383,8 @@
 
         /**
          * Sets the environment bearing uncertainty in degrees.
+         *
+         * Both the bearing and uncertainty must be set for the environment bearing to be valid.
          */
         @NonNull public Builder setEnvironmentBearingUncertaintyDegrees(
                 @FloatRange(from = 0.0f, to = 180.0f)
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 3d0765b..03e1c75 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -22,6 +22,8 @@
 import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
 import static android.app.AlarmManager.ELAPSED_REALTIME;
 
+import static com.android.internal.util.function.pooled.PooledLambda.obtainRunnable;
+
 import android.Manifest;
 import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
@@ -57,6 +59,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.location.ProviderProperties;
 import com.android.internal.util.Preconditions;
+import com.android.internal.util.function.pooled.PooledRunnable;
 
 import java.util.Collections;
 import java.util.List;
@@ -81,8 +84,6 @@
 @RequiresFeature(PackageManager.FEATURE_LOCATION)
 public class LocationManager {
 
-    private static final String TAG = "LocationManager";
-
     /**
      * For apps targeting Android K and above, supplied {@link PendingIntent}s must be targeted to a
      * specific package.
@@ -91,7 +92,7 @@
      */
     @ChangeId
     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.JELLY_BEAN)
-    public static final long TARGETED_PENDING_INTENT = 148963590L;
+    private static final long TARGETED_PENDING_INTENT = 148963590L;
 
     /**
      * For apps targeting Android K and above, incomplete locations may not be passed to
@@ -2604,18 +2605,28 @@
                 return;
             }
 
-            mExecutor.execute(() -> {
-                Consumer<Location> consumer;
-                synchronized (GetCurrentLocationTransport.this) {
-                    if (mConsumer == null) {
-                        return;
-                    }
-                    consumer = mConsumer;
-                    cancel();
-                }
+            PooledRunnable runnable =
+                    obtainRunnable(GetCurrentLocationTransport::acceptResult, this, location)
+                            .recycleOnUse();
+            try {
+                mExecutor.execute(runnable);
+            } catch (RejectedExecutionException e) {
+                runnable.recycle();
+                throw e;
+            }
+        }
 
-                consumer.accept(location);
-            });
+        private void acceptResult(Location location) {
+            Consumer<Location> consumer;
+            synchronized (this) {
+                if (mConsumer == null) {
+                    return;
+                }
+                consumer = mConsumer;
+                cancel();
+            }
+
+            consumer.accept(location);
         }
     }
 
@@ -2649,30 +2660,36 @@
                 return;
             }
 
+            PooledRunnable runnable =
+                    obtainRunnable(LocationListenerTransport::acceptLocation, this, currentExecutor,
+                            location).recycleOnUse();
             try {
-                currentExecutor.execute(() -> {
-                    try {
-                        if (currentExecutor != mExecutor) {
-                            return;
-                        }
-
-                        // we may be under the binder identity if a direct executor is used
-                        long identity = Binder.clearCallingIdentity();
-                        try {
-                            mListener.onLocationChanged(location);
-                        } finally {
-                            Binder.restoreCallingIdentity(identity);
-                        }
-                    } finally {
-                        locationCallbackFinished();
-                    }
-                });
+                currentExecutor.execute(runnable);
             } catch (RejectedExecutionException e) {
+                runnable.recycle();
                 locationCallbackFinished();
                 throw e;
             }
         }
 
+        private void acceptLocation(Executor currentExecutor, Location location) {
+            try {
+                if (currentExecutor != mExecutor) {
+                    return;
+                }
+
+                // we may be under the binder identity if a direct executor is used
+                long identity = Binder.clearCallingIdentity();
+                try {
+                    mListener.onLocationChanged(location);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            } finally {
+                locationCallbackFinished();
+            }
+        }
+
         @Override
         public void onProviderEnabled(String provider) {
             Executor currentExecutor = mExecutor;
@@ -2680,25 +2697,13 @@
                 return;
             }
 
+            PooledRunnable runnable =
+                    obtainRunnable(LocationListenerTransport::acceptProviderChange, this,
+                            currentExecutor, provider, true).recycleOnUse();
             try {
-                currentExecutor.execute(() -> {
-                    try {
-                        if (currentExecutor != mExecutor) {
-                            return;
-                        }
-
-                        // we may be under the binder identity if a direct executor is used
-                        long identity = Binder.clearCallingIdentity();
-                        try {
-                            mListener.onProviderEnabled(provider);
-                        } finally {
-                            Binder.restoreCallingIdentity(identity);
-                        }
-                    } finally {
-                        locationCallbackFinished();
-                    }
-                });
+                currentExecutor.execute(runnable);
             } catch (RejectedExecutionException e) {
+                runnable.recycle();
                 locationCallbackFinished();
                 throw e;
             }
@@ -2711,30 +2716,41 @@
                 return;
             }
 
+            PooledRunnable runnable =
+                    obtainRunnable(LocationListenerTransport::acceptProviderChange, this,
+                            currentExecutor, provider, false).recycleOnUse();
             try {
-                currentExecutor.execute(() -> {
-                    try {
-                        if (currentExecutor != mExecutor) {
-                            return;
-                        }
-
-                        // we may be under the binder identity if a direct executor is used
-                        long identity = Binder.clearCallingIdentity();
-                        try {
-                            mListener.onProviderDisabled(provider);
-                        } finally {
-                            Binder.restoreCallingIdentity(identity);
-                        }
-                    } finally {
-                        locationCallbackFinished();
-                    }
-                });
+                currentExecutor.execute(runnable);
             } catch (RejectedExecutionException e) {
+                runnable.recycle();
                 locationCallbackFinished();
                 throw e;
             }
         }
 
+        private void acceptProviderChange(Executor currentExecutor, String provider,
+                boolean enabled) {
+            try {
+                if (currentExecutor != mExecutor) {
+                    return;
+                }
+
+                // we may be under the binder identity if a direct executor is used
+                long identity = Binder.clearCallingIdentity();
+                try {
+                    if (enabled) {
+                        mListener.onProviderEnabled(provider);
+                    } else {
+                        mListener.onProviderDisabled(provider);
+                    }
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            } finally {
+                locationCallbackFinished();
+            }
+        }
+
         @Override
         public void onRemoved() {
             // TODO: onRemoved is necessary to GC hanging listeners, but introduces some interesting
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 0a0f7f6..53379b87 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -1024,7 +1024,18 @@
                                                       String device_name,
                                                       int codecFormat);
     @UnsupportedAppUsage
-    public static native int setPhoneState(int state);
+    public static int setPhoneState(int state) {
+        Log.w(TAG, "Do not use this method! Use AudioManager.setMode() instead.");
+        return 0;
+    }
+    /**
+     * @hide
+     * Send the current audio mode to audio policy manager and audio HAL.
+     * @param state the audio mode
+     * @param uid the UID of the app owning the audio mode
+     * @return command completion status.
+     */
+    public static native int setPhoneState(int state, int uid);
     @UnsupportedAppUsage
     public static native int setForceUse(int usage, int config);
     @UnsupportedAppUsage
diff --git a/media/java/android/media/IMediaRoute2Provider.aidl b/media/java/android/media/IMediaRoute2Provider.aidl
index 0c64564..7097166 100644
--- a/media/java/android/media/IMediaRoute2Provider.aidl
+++ b/media/java/android/media/IMediaRoute2Provider.aidl
@@ -35,7 +35,6 @@
     void deselectRoute(String sessionId, String routeId);
     void transferToRoute(String sessionId, String routeId);
 
-    void notifyControlRequestSent(String id, in Intent request);
     void setRouteVolume(String routeId, int volume);
     void setSessionVolume(String sessionId, int volume);
 }
diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl
index f919dce..8be2884 100644
--- a/media/java/android/media/IMediaRouterService.aidl
+++ b/media/java/android/media/IMediaRouterService.aidl
@@ -49,8 +49,6 @@
     RoutingSessionInfo getSystemSessionInfo();
     void registerClient2(IMediaRouter2Client client, String packageName);
     void unregisterClient2(IMediaRouter2Client client);
-    void sendControlRequest(IMediaRouter2Client client, in MediaRoute2Info route,
-            in Intent request);
     void setRouteVolume2(IMediaRouter2Client client, in MediaRoute2Info route, int volume);
     void setSessionVolume2(IMediaRouter2Client client, String sessionId, int volume);
 
diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index 6689080..70d79378 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -26,6 +26,7 @@
 import libcore.content.type.MimeMap;
 
 import java.util.HashMap;
+import java.util.Locale;
 
 /**
  * MediaScanner helper class.
@@ -215,23 +216,23 @@
             return true;
         }
 
-        switch (normalizedMimeType) {
+        switch (normalizedMimeType.toLowerCase(Locale.ROOT)) {
             case "application/epub+zip":
             case "application/msword":
             case "application/pdf":
             case "application/rtf":
             case "application/vnd.ms-excel":
-            case "application/vnd.ms-excel.addin.macroEnabled.12":
-            case "application/vnd.ms-excel.sheet.binary.macroEnabled.12":
-            case "application/vnd.ms-excel.sheet.macroEnabled.12":
-            case "application/vnd.ms-excel.template.macroEnabled.12":
+            case "application/vnd.ms-excel.addin.macroenabled.12":
+            case "application/vnd.ms-excel.sheet.binary.macroenabled.12":
+            case "application/vnd.ms-excel.sheet.macroenabled.12":
+            case "application/vnd.ms-excel.template.macroenabled.12":
             case "application/vnd.ms-powerpoint":
-            case "application/vnd.ms-powerpoint.addin.macroEnabled.12":
-            case "application/vnd.ms-powerpoint.presentation.macroEnabled.12":
-            case "application/vnd.ms-powerpoint.slideshow.macroEnabled.12":
-            case "application/vnd.ms-powerpoint.template.macroEnabled.12":
-            case "application/vnd.ms-word.document.macroEnabled.12":
-            case "application/vnd.ms-word.template.macroEnabled.12":
+            case "application/vnd.ms-powerpoint.addin.macroenabled.12":
+            case "application/vnd.ms-powerpoint.presentation.macroenabled.12":
+            case "application/vnd.ms-powerpoint.slideshow.macroenabled.12":
+            case "application/vnd.ms-powerpoint.template.macroenabled.12":
+            case "application/vnd.ms-word.document.macroenabled.12":
+            case "application/vnd.ms-word.template.macroenabled.12":
             case "application/vnd.oasis.opendocument.chart":
             case "application/vnd.oasis.opendocument.database":
             case "application/vnd.oasis.opendocument.formula":
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index 57405d7..b57182e 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -20,8 +20,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
-import android.media.MediaCodec;
-import android.media.MediaParser;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -116,6 +114,7 @@
  * <table>
  * <tr><td>{@link #KEY_MIME}</td><td>String</td><td>The type of the format.</td></tr>
  * <tr><td>{@link #KEY_LANGUAGE}</td><td>String</td><td>The language of the content.</td></tr>
+ * <tr><td>{@link #KEY_CAPTION_SERVICE_NUMBER}</td><td>int</td><td>optional, the closed-caption service or channel number.</td></tr>
  * </table>
  *
  * Image formats have the following keys:
@@ -245,6 +244,13 @@
     public static final String KEY_LANGUAGE = "language";
 
     /**
+     * A key describing the closed caption service number. For CEA-608 caption tracks, holds the
+     * channel number. For CEA-708, holds the service number.
+     * The associated value is an int.
+     */
+    public static final String KEY_CAPTION_SERVICE_NUMBER = "caption-service-number";
+
+    /**
      * A key describing the sample rate of an audio format.
      * The associated value is an integer
      */
diff --git a/media/java/android/media/MediaRoute2ProviderService.java b/media/java/android/media/MediaRoute2ProviderService.java
index aac195d..7d72b1c 100644
--- a/media/java/android/media/MediaRoute2ProviderService.java
+++ b/media/java/android/media/MediaRoute2ProviderService.java
@@ -115,16 +115,6 @@
     }
 
     /**
-     * Called when sendControlRequest is called on a route of the provider
-     *
-     * @param routeId the id of the target route
-     * @param request the media control request intent
-     * @hide
-     */
-    //TODO: Discuss what to use for request (e.g., Intent? Request class?)
-    public void onControlRequest(@NonNull String routeId, @NonNull Intent request) {}
-
-    /**
      * Called when a volume setting is requested on a route of the provider
      *
      * @param routeId the id of the route
@@ -513,15 +503,6 @@
         }
 
         @Override
-        public void notifyControlRequestSent(String routeId, Intent request) {
-            if (!checkCallerisSystem()) {
-                return;
-            }
-            mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onControlRequest,
-                    MediaRoute2ProviderService.this, routeId, request));
-        }
-
-        @Override
         public void setRouteVolume(String routeId, int volume) {
             if (!checkCallerisSystem()) {
                 return;
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index 9837e1c..12fc3a6 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -64,7 +64,12 @@
  *
  * <p>The media router API is not thread-safe; all interactions with it must be
  * done from the main thread of the process.</p>
+ *
+ * <p>
+ * We recommend using {@link android.media.MediaRouter2} APIs for new applications.
+ * </p>
  */
+//TODO: Link androidx.media2.MediaRouter when we are ready.
 @SystemService(Context.MEDIA_ROUTER_SERVICE)
 public class MediaRouter {
     private static final String TAG = "MediaRouter";
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 2178393..274169c 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -22,7 +22,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
-import android.content.Intent;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -412,32 +411,6 @@
     }
 
     /**
-     * Sends a media control request to be performed asynchronously by the route's destination.
-     *
-     * @param route the route that will receive the control request
-     * @param request the media control request
-     * @hide
-     */
-    //TODO: Discuss what to use for request (e.g., Intent? Request class?)
-    //TODO: Provide a way to obtain the result
-    public void sendControlRequest(@NonNull MediaRoute2Info route, @NonNull Intent request) {
-        Objects.requireNonNull(route, "route must not be null");
-        Objects.requireNonNull(request, "request must not be null");
-
-        Client2 client;
-        synchronized (sRouterLock) {
-            client = mClient;
-        }
-        if (client != null) {
-            try {
-                mMediaRouterService.sendControlRequest(client, route, request);
-            } catch (RemoteException ex) {
-                Log.e(TAG, "Unable to send control request.", ex);
-            }
-        }
-    }
-
-    /**
      * Requests a volume change for the route asynchronously.
      * <p>
      * It may have no effect if the route is currently not selected.
diff --git a/media/java/android/media/RouteDiscoveryPreference.java b/media/java/android/media/RouteDiscoveryPreference.java
index ebcb9ed..2e038e6 100644
--- a/media/java/android/media/RouteDiscoveryPreference.java
+++ b/media/java/android/media/RouteDiscoveryPreference.java
@@ -31,8 +31,16 @@
 import java.util.Set;
 
 /**
- * A media route discovery preference describing the kinds of routes that media router
+ * A media route discovery preference describing the features of routes that media router
  * would like to discover and whether to perform active scanning.
+ * <p>
+ * When {@link MediaRouter2} instances set discovery preferences by calling
+ * {@link MediaRouter2#registerRouteCallback}, they are merged into a single discovery preference
+ * and it is delivered to call {@link MediaRoute2ProviderService#onDiscoveryPreferenceChanged}.
+ * </p><p>
+ * According to the given discovery preference, {@link MediaRoute2ProviderService} discovers
+ * routes and publishes them.
+ * </p>
  *
  * @see MediaRouter2#registerRouteCallback
  */
@@ -53,12 +61,12 @@
 
     @NonNull
     private final List<String> mPreferredFeatures;
-    private final boolean mActiveScan;
+    private final boolean mShouldPerformActiveScan;
     @Nullable
     private final Bundle mExtras;
 
     /**
-     * An empty discovery preference.
+     * An empty discovery preference
      * @hide
      */
     public static final RouteDiscoveryPreference EMPTY =
@@ -66,23 +74,39 @@
 
     RouteDiscoveryPreference(@NonNull Builder builder) {
         mPreferredFeatures = builder.mPreferredFeatures;
-        mActiveScan = builder.mActiveScan;
+        mShouldPerformActiveScan = builder.mActiveScan;
         mExtras = builder.mExtras;
     }
 
     RouteDiscoveryPreference(@NonNull Parcel in) {
         mPreferredFeatures = in.createStringArrayList();
-        mActiveScan = in.readBoolean();
+        mShouldPerformActiveScan = in.readBoolean();
         mExtras = in.readBundle();
     }
 
+    /**
+     * Gets the features of routes that media router would like to discover.
+     * <p>
+     * Routes that have at least one of the features will be discovered.
+     * They may include predefined features such as
+     * {@link MediaRoute2Info#FEATURE_LIVE_AUDIO}, {@link MediaRoute2Info#FEATURE_LIVE_VIDEO},
+     * or {@link MediaRoute2Info#FEATURE_REMOTE_PLAYBACK} or custom features defined by a provider.
+     * </p>
+     */
     @NonNull
     public List<String> getPreferredFeatures() {
         return mPreferredFeatures;
     }
 
-    public boolean isActiveScan() {
-        return mActiveScan;
+    /**
+     * Gets whether active scanning should be performed.
+     * <p>
+     * If any of discovery preferences sets this as {@code true}, active scanning will
+     * be performed regardless of other discovery preferences.
+     * </p>
+     */
+    public boolean shouldPerformActiveScan() {
+        return mShouldPerformActiveScan;
     }
 
     /**
@@ -100,7 +124,7 @@
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeStringList(mPreferredFeatures);
-        dest.writeBoolean(mActiveScan);
+        dest.writeBoolean(mShouldPerformActiveScan);
         dest.writeBundle(mExtras);
     }
 
@@ -112,7 +136,7 @@
                 .append(String.join(", ", mPreferredFeatures))
                 .append("}")
                 .append(", activeScan=")
-                .append(mActiveScan)
+                .append(mShouldPerformActiveScan)
                 .append(" }");
 
         return result.toString();
@@ -128,12 +152,12 @@
         }
         RouteDiscoveryPreference other = (RouteDiscoveryPreference) o;
         return Objects.equals(mPreferredFeatures, other.mPreferredFeatures)
-                && mActiveScan == other.mActiveScan;
+                && mShouldPerformActiveScan == other.mShouldPerformActiveScan;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mPreferredFeatures, mActiveScan);
+        return Objects.hash(mPreferredFeatures, mShouldPerformActiveScan);
     }
 
     /**
@@ -154,12 +178,12 @@
             Objects.requireNonNull(preference, "preference must not be null");
 
             mPreferredFeatures = preference.getPreferredFeatures();
-            mActiveScan = preference.isActiveScan();
+            mActiveScan = preference.shouldPerformActiveScan();
             mExtras = preference.getExtras();
         }
 
         /**
-         * A constructor to combine all of the preferences into a single preference .
+         * A constructor to combine all of the preferences into a single preference.
          * It ignores extras of preferences.
          *
          * @hide
@@ -171,13 +195,19 @@
             mActiveScan = false;
             for (RouteDiscoveryPreference preference : preferences) {
                 routeFeatureSet.addAll(preference.mPreferredFeatures);
-                mActiveScan |= preference.mActiveScan;
+                mActiveScan |= preference.mShouldPerformActiveScan;
             }
             mPreferredFeatures = new ArrayList<>(routeFeatureSet);
         }
 
         /**
          * Sets preferred route features to discover.
+         * @param preferredFeatures features of routes that media router would like to discover.
+         *                          May include predefined features
+         *                          such as {@link MediaRoute2Info#FEATURE_LIVE_AUDIO},
+         *                          {@link MediaRoute2Info#FEATURE_LIVE_VIDEO},
+         *                          or {@link MediaRoute2Info#FEATURE_REMOTE_PLAYBACK}
+         *                          or custom features defined by a provider.
          */
         @NonNull
         public Builder setPreferredFeatures(@NonNull List<String> preferredFeatures) {
@@ -188,9 +218,13 @@
 
         /**
          * Sets if active scanning should be performed.
+         * <p>
+         * Since active scanning uses more system resources, set this as {@code true} only
+         * when it's necessary.
+         * </p>
          */
         @NonNull
-        public Builder setActiveScan(boolean activeScan) {
+        public Builder setShouldPerformActiveScan(boolean activeScan) {
             mActiveScan = activeScan;
             return this;
         }
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index 44142e3..bd00201 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -34,6 +34,7 @@
 import android.media.tv.tuner.filter.Filter.Type;
 import android.media.tv.tuner.filter.FilterCallback;
 import android.media.tv.tuner.filter.TimeFilter;
+import android.media.tv.tuner.frontend.Atsc3PlpInfo;
 import android.media.tv.tuner.frontend.FrontendInfo;
 import android.media.tv.tuner.frontend.FrontendSettings;
 import android.media.tv.tuner.frontend.FrontendStatus;
@@ -511,6 +512,90 @@
         }
     }
 
+    private void onLocked() {
+        if (mScanCallbackExecutor != null && mScanCallback != null) {
+            mScanCallbackExecutor.execute(() -> mScanCallback.onLocked());
+        }
+    }
+
+    private void onScanStopped() {
+        if (mScanCallbackExecutor != null && mScanCallback != null) {
+            mScanCallbackExecutor.execute(() -> mScanCallback.onScanStopped());
+        }
+    }
+
+    private void onProgress(int percent) {
+        if (mScanCallbackExecutor != null && mScanCallback != null) {
+            mScanCallbackExecutor.execute(() -> mScanCallback.onProgress(percent));
+        }
+    }
+
+    private void onFrequenciesReport(int[] frequency) {
+        if (mScanCallbackExecutor != null && mScanCallback != null) {
+            mScanCallbackExecutor.execute(() -> mScanCallback.onFrequenciesReport(frequency));
+        }
+    }
+
+    private void onSymbolRates(int[] rate) {
+        if (mScanCallbackExecutor != null && mScanCallback != null) {
+            mScanCallbackExecutor.execute(() -> mScanCallback.onSymbolRates(rate));
+        }
+    }
+
+    private void onHierarchy(int hierarchy) {
+        if (mScanCallbackExecutor != null && mScanCallback != null) {
+            mScanCallbackExecutor.execute(() -> mScanCallback.onHierarchy(hierarchy));
+        }
+    }
+
+    private void onSignalType(int signalType) {
+        if (mScanCallbackExecutor != null && mScanCallback != null) {
+            mScanCallbackExecutor.execute(() -> mScanCallback.onSignalType(signalType));
+        }
+    }
+
+    private void onPlpIds(int[] plpIds) {
+        if (mScanCallbackExecutor != null && mScanCallback != null) {
+            mScanCallbackExecutor.execute(() -> mScanCallback.onPlpIds(plpIds));
+        }
+    }
+
+    private void onGroupIds(int[] groupIds) {
+        if (mScanCallbackExecutor != null && mScanCallback != null) {
+            mScanCallbackExecutor.execute(() -> mScanCallback.onGroupIds(groupIds));
+        }
+    }
+
+    private void onInputStreamIds(int[] inputStreamIds) {
+        if (mScanCallbackExecutor != null && mScanCallback != null) {
+            mScanCallbackExecutor.execute(() -> mScanCallback.onInputStreamIds(inputStreamIds));
+        }
+    }
+
+    private void onDvbsStandard(int dvbsStandandard) {
+        if (mScanCallbackExecutor != null && mScanCallback != null) {
+            mScanCallbackExecutor.execute(() -> mScanCallback.onDvbsStandard(dvbsStandandard));
+        }
+    }
+
+    private void onDvbtStandard(int dvbtStandard) {
+        if (mScanCallbackExecutor != null && mScanCallback != null) {
+            mScanCallbackExecutor.execute(() -> mScanCallback.onDvbtStandard(dvbtStandard));
+        }
+    }
+
+    private void onAnalogSifStandard(int sif) {
+        if (mScanCallbackExecutor != null && mScanCallback != null) {
+            mScanCallbackExecutor.execute(() -> mScanCallback.onAnalogSifStandard(sif));
+        }
+    }
+
+    private void onAtsc3PlpInfos(Atsc3PlpInfo[] atsc3PlpInfos) {
+        if (mScanCallbackExecutor != null && mScanCallback != null) {
+            mScanCallbackExecutor.execute(() -> mScanCallback.onAtsc3PlpInfos(atsc3PlpInfos));
+        }
+    }
+
     /**
      * Opens a filter object based on the given types and buffer size.
      *
@@ -612,10 +697,10 @@
      *
      * @return  a {@link Descrambler} object.
      */
-    @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
+    @RequiresPermission(android.Manifest.permission.ACCESS_TV_DESCRAMBLER)
     @Nullable
     public Descrambler openDescrambler() {
-        TunerUtils.checkTunerPermission(mContext);
+        TunerUtils.checkDescramblerPermission(mContext);
         return nativeOpenDescrambler();
     }
 
diff --git a/media/java/android/media/tv/tuner/TunerConstants.java b/media/java/android/media/tv/tuner/TunerConstants.java
index f54808d..82af658 100644
--- a/media/java/android/media/tv/tuner/TunerConstants.java
+++ b/media/java/android/media/tv/tuner/TunerConstants.java
@@ -38,6 +38,14 @@
      * Invalid stream ID.
      */
     public static final int INVALID_STREAM_ID = Constants.Constant.INVALID_STREAM_ID;
+    /**
+     * Invalid filter ID.
+     */
+    public static final int INVALID_FILTER_ID = Constants.Constant.INVALID_FILTER_ID;
+    /**
+     * Invalid AV Sync ID.
+     */
+    public static final int INVALID_AV_SYNC_ID = Constants.Constant.INVALID_AV_SYNC_ID;
 
     /** @hide */
     @IntDef(prefix = "SCAN_TYPE_", value = {SCAN_TYPE_UNDEFINED, SCAN_TYPE_AUTO, SCAN_TYPE_BLIND})
diff --git a/media/java/android/media/tv/tuner/TunerUtils.java b/media/java/android/media/tv/tuner/TunerUtils.java
index 30aaa02..5ecb8f0 100644
--- a/media/java/android/media/tv/tuner/TunerUtils.java
+++ b/media/java/android/media/tv/tuner/TunerUtils.java
@@ -27,7 +27,9 @@
  * @hide
  */
 public final class TunerUtils {
-    private static final String PERMISSION = android.Manifest.permission.ACCESS_TV_TUNER;
+    private static final String TUNER_PERMISSION = android.Manifest.permission.ACCESS_TV_TUNER;
+    private static final String DESCRAMBLER_PERMISSION =
+            android.Manifest.permission.ACCESS_TV_DESCRAMBLER;
 
     /**
      * Checks whether the caller has permission to access tuner.
@@ -36,9 +38,30 @@
      * @throws SecurityException if the caller doesn't have the permission.
      */
     public static void checkTunerPermission(Context context) {
-        if (context.checkCallingOrSelfPermission(PERMISSION)
+        checkPermission(context, TUNER_PERMISSION);
+    }
+
+    /**
+     * Checks whether the caller has permission to access the descrambler.
+     *
+     * @param context context of the caller.
+     * @throws SecurityException if the caller doesn't have the permission.
+     */
+    public static void checkDescramblerPermission(Context context) {
+        checkPermission(context, DESCRAMBLER_PERMISSION);
+    }
+
+    /**
+     * Checks whether the caller has the given permission.
+     *
+     * @param context context of the caller.
+     * @param permission the given permission.
+     * @throws SecurityException if the caller doesn't have the permission.
+     */
+    public static void checkPermission(Context context, String permission) {
+        if (context.checkCallingOrSelfPermission(permission)
                 != PackageManager.PERMISSION_GRANTED) {
-            throw new SecurityException("Caller must have " + PERMISSION + " permission.");
+            throw new SecurityException("Caller must have " + permission + " permission.");
         }
     }
 
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index ac59003..f4d2d03 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -108,6 +108,7 @@
 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtMode;
 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtModulation;
 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtSettings;
+using ::android::hardware::tv::tuner::V1_0::FrontendScanAtsc3PlpInfo;
 using ::android::hardware::tv::tuner::V1_0::FrontendType;
 using ::android::hardware::tv::tuner::V1_0::ITuner;
 using ::android::hardware::tv::tuner::V1_0::PlaybackSettings;
@@ -249,14 +250,152 @@
             (jint)frontendEventType);
     return Void();
 }
-Return<void> FrontendCallback::onDiseqcMessage(const hidl_vec<uint8_t>& /*diseqcMessage*/) {
-    ALOGD("FrontendCallback::onDiseqcMessage");
-    return Void();
-}
 
-Return<void> FrontendCallback::onScanMessage(
-        FrontendScanMessageType type, const FrontendScanMessage& /*message*/) {
+Return<void> FrontendCallback::onScanMessage(FrontendScanMessageType type, const FrontendScanMessage& message) {
     ALOGD("FrontendCallback::onScanMessage, type=%d", type);
+    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    jclass clazz = env->FindClass("android/media/tv/tuner/Tuner");
+    switch(type) {
+        case FrontendScanMessageType::LOCKED: {
+            if (message.isLocked()) {
+                env->CallVoidMethod(
+                        mObject,
+                        env->GetMethodID(clazz, "onLocked", "()V"));
+            }
+            break;
+        }
+        case FrontendScanMessageType::END: {
+            if (message.isEnd()) {
+                env->CallVoidMethod(
+                        mObject,
+                        env->GetMethodID(clazz, "onScanStopped", "()V"));
+            }
+            break;
+        }
+        case FrontendScanMessageType::PROGRESS_PERCENT: {
+            env->CallVoidMethod(
+                    mObject,
+                    env->GetMethodID(clazz, "onProgress", "(I)V"),
+                    (jint) message.progressPercent());
+            break;
+        }
+        case FrontendScanMessageType::FREQUENCY: {
+            std::vector<uint32_t> v = message.frequencies();
+            jintArray freqs = env->NewIntArray(v.size());
+            env->SetIntArrayRegion(freqs, 0, v.size(), reinterpret_cast<jint*>(&v[0]));
+
+            env->CallVoidMethod(
+                    mObject,
+                    env->GetMethodID(clazz, "onFrequenciesReport", "([I)V"),
+                    freqs);
+            break;
+        }
+        case FrontendScanMessageType::SYMBOL_RATE: {
+            std::vector<uint32_t> v = message.symbolRates();
+            jintArray symbolRates = env->NewIntArray(v.size());
+            env->SetIntArrayRegion(symbolRates, 0, v.size(), reinterpret_cast<jint*>(&v[0]));
+
+            env->CallVoidMethod(
+                    mObject,
+                    env->GetMethodID(clazz, "onSymbolRates", "([I)V"),
+                    symbolRates);
+            break;
+        }
+        case FrontendScanMessageType::HIERARCHY: {
+            env->CallVoidMethod(
+                    mObject,
+                    env->GetMethodID(clazz, "onHierarchy", "(I)V"),
+                    (jint) message.hierarchy());
+            break;
+        }
+        case FrontendScanMessageType::ANALOG_TYPE: {
+            env->CallVoidMethod(
+                    mObject,
+                    env->GetMethodID(clazz, "onSignalType", "(I)V"),
+                    (jint) message.analogType());
+            break;
+        }
+        case FrontendScanMessageType::PLP_IDS: {
+            std::vector<uint8_t> v = message.plpIds();
+            std::vector<jint> jintV(v.begin(), v.end());
+            jintArray plpIds = env->NewIntArray(v.size());
+            env->SetIntArrayRegion(plpIds, 0, jintV.size(), &jintV[0]);
+
+            env->CallVoidMethod(
+                    mObject,
+                    env->GetMethodID(clazz, "onPlpIds", "([I)V"),
+                    plpIds);
+            break;
+        }
+        case FrontendScanMessageType::GROUP_IDS: {
+            std::vector<uint8_t> v = message.groupIds();
+            std::vector<jint> jintV(v.begin(), v.end());
+            jintArray groupIds = env->NewIntArray(v.size());
+            env->SetIntArrayRegion(groupIds, 0, jintV.size(), &jintV[0]);
+
+            env->CallVoidMethod(
+                    mObject,
+                    env->GetMethodID(clazz, "onGroupIds", "([I)V"),
+                    groupIds);
+            break;
+        }
+        case FrontendScanMessageType::INPUT_STREAM_IDS: {
+            std::vector<uint16_t> v = message.inputStreamIds();
+            std::vector<jint> jintV(v.begin(), v.end());
+            jintArray streamIds = env->NewIntArray(v.size());
+            env->SetIntArrayRegion(streamIds, 0, jintV.size(), &jintV[0]);
+
+            env->CallVoidMethod(
+                    mObject,
+                    env->GetMethodID(clazz, "onInputStreamIds", "([I)V"),
+                    streamIds);
+            break;
+        }
+        case FrontendScanMessageType::STANDARD: {
+            FrontendScanMessage::Standard std = message.std();
+            jint standard;
+            if (std.getDiscriminator() == FrontendScanMessage::Standard::hidl_discriminator::sStd) {
+                standard = (jint) std.sStd();
+                env->CallVoidMethod(
+                        mObject,
+                        env->GetMethodID(clazz, "onDvbsStandard", "(I)V"),
+                        standard);
+            } else if (std.getDiscriminator() == FrontendScanMessage::Standard::hidl_discriminator::tStd) {
+                standard = (jint) std.tStd();
+                env->CallVoidMethod(
+                        mObject,
+                        env->GetMethodID(clazz, "onDvbtStandard", "(I)V"),
+                        standard);
+            } else if (std.getDiscriminator() == FrontendScanMessage::Standard::hidl_discriminator::sifStd) {
+                standard = (jint) std.sifStd();
+                env->CallVoidMethod(
+                        mObject,
+                        env->GetMethodID(clazz, "onAnalogSifStandard", "(I)V"),
+                        standard);
+            }
+            break;
+        }
+        case FrontendScanMessageType::ATSC3_PLP_INFO: {
+            jclass plpClazz = env->FindClass("android/media/tv/tuner/frontend/Atsc3PlpInfo");
+            jmethodID init = env->GetMethodID(plpClazz, "<init>", "(IZ)V");
+            std::vector<FrontendScanAtsc3PlpInfo> plpInfos = message.atsc3PlpInfos();
+            jobjectArray array = env->NewObjectArray(plpInfos.size(), plpClazz, NULL);
+
+            for (int i = 0; i < plpInfos.size(); i++) {
+                auto info = plpInfos[i];
+                jint plpId = (jint) info.plpId;
+                jboolean lls = (jboolean) info.bLlsFlag;
+
+                jobject obj = env->NewObject(plpClazz, init, plpId, lls);
+                env->SetObjectArrayElement(array, i, obj);
+            }
+            env->CallVoidMethod(
+                    mObject,
+                    env->GetMethodID(clazz, "onAtsc3PlpInfos", "([Landroid/media/tv/tuner/frontend/Atsc3PlpInfo;)V"),
+                    array);
+            break;
+        }
+    }
     return Void();
 }
 
diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h
index cfe99b3..d899bbd 100644
--- a/media/jni/android_media_tv_Tuner.h
+++ b/media/jni/android_media_tv_Tuner.h
@@ -109,7 +109,6 @@
     FrontendCallback(jweak tunerObj, FrontendId id);
 
     virtual Return<void> onEvent(FrontendEventType frontendEventType);
-    virtual Return<void> onDiseqcMessage(const hidl_vec<uint8_t>& diseqcMessage);
     virtual Return<void> onScanMessage(
             FrontendScanMessageType type, const FrontendScanMessage& message);
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaFileTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaFileTest.java
index 507dd4a..15a501d 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaFileTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaFileTest.java
@@ -97,6 +97,9 @@
         assertTrue(isDocumentMimeType("text/plain"));
         assertTrue(isDocumentMimeType("application/pdf"));
         assertTrue(isDocumentMimeType("application/msword"));
+        assertTrue(isDocumentMimeType("application/vnd.ms-excel.addin.macroEnabled.12"));
+        assertTrue(isDocumentMimeType("application/vnd.ms-powerpoint.addin.macroEnabled.12"));
+        assertTrue(isDocumentMimeType("application/vnd.ms-word.document.macroEnabled.12"));
         assertFalse(isDocumentMimeType("audio/mpeg"));
     }
 
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java
index 615dc48..ca7c36c 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java
@@ -20,7 +20,6 @@
 import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_FIXED;
 import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE;
 
-import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.ACTION_REMOVE_ROUTE;
 import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.FEATURE_SAMPLE;
 import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.FEATURE_SPECIAL;
 import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.ROUTE_ID1;
@@ -29,7 +28,6 @@
 import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.ROUTE_ID_FIXED_VOLUME;
 import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.ROUTE_ID_SPECIAL_FEATURE;
 import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.ROUTE_ID_VARIABLE_VOLUME;
-import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.ROUTE_NAME1;
 import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.ROUTE_NAME2;
 import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.VOLUME_MAX;
 
@@ -38,7 +36,6 @@
 import static org.junit.Assert.assertTrue;
 
 import android.content.Context;
-import android.content.Intent;
 import android.media.MediaRoute2Info;
 import android.media.MediaRouter2;
 import android.media.MediaRouter2.RouteCallback;
@@ -116,34 +113,18 @@
         clearCallbacks();
     }
 
-    /**
-     * Tests if routes are added correctly when a new callback is registered.
-     */
     @Test
-    public void testOnRoutesAdded() throws Exception {
-        CountDownLatch latch = new CountDownLatch(1);
-        addManagerCallback(new MediaRouter2Manager.Callback() {
-            @Override
-            public void onRoutesAdded(List<MediaRoute2Info> routes) {
-                assertTrue(routes.size() > 0);
-                for (MediaRoute2Info route : routes) {
-                    if (route.getOriginalId().equals(ROUTE_ID1)
-                            && route.getName().equals(ROUTE_NAME1)) {
-                        latch.countDown();
-                    }
-                }
-            }
-        });
+    public void testOnRoutesRemovedAndAdded() throws Exception {
+        RouteCallback routeCallback = new RouteCallback();
+        mRouteCallbacks.add(routeCallback);
+        mRouter2.registerRouteCallback(mExecutor, routeCallback,
+                new RouteDiscoveryPreference.Builder(FEATURES_ALL, true).build());
 
-        assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testOnRoutesRemoved() throws Exception {
-        CountDownLatch latch = new CountDownLatch(1);
         Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(FEATURES_ALL);
 
-        addRouterCallback(new RouteCallback());
+        CountDownLatch removedLatch = new CountDownLatch(1);
+        CountDownLatch addedLatch = new CountDownLatch(1);
+
         addManagerCallback(new MediaRouter2Manager.Callback() {
             @Override
             public void onRoutesRemoved(List<MediaRoute2Info> routes) {
@@ -151,16 +132,39 @@
                 for (MediaRoute2Info route : routes) {
                     if (route.getOriginalId().equals(ROUTE_ID2)
                             && route.getName().equals(ROUTE_NAME2)) {
-                        latch.countDown();
+                        removedLatch.countDown();
+                    }
+                }
+            }
+            @Override
+            public void onRoutesAdded(List<MediaRoute2Info> routes) {
+                assertTrue(routes.size() > 0);
+                if (removedLatch.getCount() > 0) {
+                    return;
+                }
+                for (MediaRoute2Info route : routes) {
+                    if (route.getOriginalId().equals(ROUTE_ID2)
+                            && route.getName().equals(ROUTE_NAME2)) {
+                        addedLatch.countDown();
                     }
                 }
             }
         });
 
-        //TODO: Figure out a more proper way to test.
-        // (Control requests shouldn't be used in this way.)
-        mRouter2.sendControlRequest(routes.get(ROUTE_ID2), new Intent(ACTION_REMOVE_ROUTE));
-        assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        MediaRoute2Info routeToRemove = routes.get(ROUTE_ID2);
+
+        try {
+            SampleMediaRoute2ProviderService sInstance =
+                    SampleMediaRoute2ProviderService.getInstance();
+            assertNotNull(sInstance);
+            sInstance.removeRoute(ROUTE_ID2);
+            assertTrue(removedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+
+            sInstance.addRoute(routeToRemove);
+            assertTrue(addedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        } finally {
+            mRouter2.unregisterRouteCallback(routeCallback);
+        }
     }
 
     /**
@@ -409,7 +413,8 @@
 
     Map<String, MediaRoute2Info> waitAndGetRoutesWithManager(List<String> routeFeatures)
             throws Exception {
-        CountDownLatch latch = new CountDownLatch(2);
+        CountDownLatch addedLatch = new CountDownLatch(1);
+        CountDownLatch featuresLatch = new CountDownLatch(1);
 
         // A dummy callback is required to send route feature info.
         RouteCallback routeCallback = new RouteCallback();
@@ -418,7 +423,7 @@
             public void onRoutesAdded(List<MediaRoute2Info> routes) {
                 for (int i = 0; i < routes.size(); i++) {
                     if (!routes.get(i).isSystemRoute()) {
-                        latch.countDown();
+                        addedLatch.countDown();
                         break;
                     }
                 }
@@ -428,8 +433,8 @@
             public void onControlCategoriesChanged(String packageName,
                     List<String> preferredFeatures) {
                 if (TextUtils.equals(mPackageName, packageName)
-                        && preferredFeatures.equals(preferredFeatures)) {
-                    latch.countDown();
+                        && preferredFeatures.equals(routeFeatures)) {
+                    featuresLatch.countDown();
                 }
             }
         };
@@ -437,7 +442,8 @@
         mRouter2.registerRouteCallback(mExecutor, routeCallback,
                 new RouteDiscoveryPreference.Builder(routeFeatures, true).build());
         try {
-            latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+            addedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+            featuresLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
             return createRouteMap(mManager.getAvailableRoutes(mPackageName));
         } finally {
             mRouter2.unregisterRouteCallback(routeCallback);
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/SampleMediaRoute2ProviderService.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/SampleMediaRoute2ProviderService.java
index f1dcf3d..3faefdb 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/SampleMediaRoute2ProviderService.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/SampleMediaRoute2ProviderService.java
@@ -20,6 +20,7 @@
 import static android.media.MediaRoute2Info.DEVICE_TYPE_REMOTE_TV;
 import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Intent;
 import android.media.MediaRoute2Info;
@@ -31,9 +32,13 @@
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Objects;
+
+import javax.annotation.concurrent.GuardedBy;
 
 public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService {
     private static final String TAG = "SampleMR2ProviderSvc";
+    private static final Object sLock = new Object();
 
     public static final String ROUTE_ID1 = "route_id1";
     public static final String ROUTE_NAME1 = "Sample Route 1";
@@ -59,9 +64,6 @@
     public static final String ROUTE_ID_VARIABLE_VOLUME = "route_variable_volume";
     public static final String ROUTE_NAME_VARIABLE_VOLUME = "Variable Volume Route";
 
-    public static final String ACTION_REMOVE_ROUTE =
-            "com.android.mediarouteprovider.action_remove_route";
-
     public static final String FEATURE_SAMPLE =
             "com.android.mediarouteprovider.FEATURE_SAMPLE";
     public static final String FEATURE_SPECIAL =
@@ -71,6 +73,9 @@
     Map<String, String> mRouteIdToSessionId = new HashMap<>();
     private int mNextSessionId = 1000;
 
+    @GuardedBy("sLock")
+    private static SampleMediaRoute2ProviderService sInstance;
+
     private void initializeRoutes() {
         MediaRoute2Info route1 = new MediaRoute2Info.Builder(ROUTE_ID1, ROUTE_NAME1)
                 .addFeature(FEATURE_SAMPLE)
@@ -92,6 +97,7 @@
                 ROUTE_ID5_TO_TRANSFER_TO, ROUTE_NAME5)
                 .addFeature(FEATURE_SAMPLE)
                 .build();
+
         MediaRoute2Info routeSpecial =
                 new MediaRoute2Info.Builder(ROUTE_ID_SPECIAL_FEATURE, ROUTE_NAME_SPECIAL_FEATURE)
                         .addFeature(FEATURE_SAMPLE)
@@ -114,36 +120,65 @@
         mRoutes.put(route3.getId(), route3);
         mRoutes.put(route4.getId(), route4);
         mRoutes.put(route5.getId(), route5);
+
         mRoutes.put(routeSpecial.getId(), routeSpecial);
         mRoutes.put(fixedVolumeRoute.getId(), fixedVolumeRoute);
         mRoutes.put(variableVolumeRoute.getId(), variableVolumeRoute);
     }
 
+    public static SampleMediaRoute2ProviderService getInstance() {
+        synchronized (sLock) {
+            return sInstance;
+        }
+    }
+
+    /**
+     * Adds a route and publishes it. It could replace a route in the provider if
+     * they have the same route id.
+     */
+    public void addRoute(@NonNull MediaRoute2Info route) {
+        Objects.requireNonNull(route, "route must not be null");
+        mRoutes.put(route.getOriginalId(), route);
+        publishRoutes();
+    }
+
+    /**
+     * Removes a route and publishes it.
+     */
+    public void removeRoute(@NonNull String routeId) {
+        Objects.requireNonNull(routeId, "routeId must not be null");
+        MediaRoute2Info route = mRoutes.get(routeId);
+        if (route != null) {
+            mRoutes.remove(routeId);
+            publishRoutes();
+        }
+    }
+
     @Override
     public void onCreate() {
+        synchronized (sLock) {
+            sInstance = this;
+        }
         initializeRoutes();
     }
 
     @Override
+    public void onDestroy() {
+        super.onDestroy();
+        synchronized (sLock) {
+            if (sInstance == this) {
+                sInstance = null;
+            }
+        }
+    }
+
+    @Override
     public IBinder onBind(Intent intent) {
         publishRoutes();
         return super.onBind(intent);
     }
 
     @Override
-    public void onControlRequest(String routeId, Intent request) {
-        String action = request.getAction();
-        if (ACTION_REMOVE_ROUTE.equals(action)) {
-            MediaRoute2Info route = mRoutes.get(routeId);
-            if (route != null) {
-                mRoutes.remove(routeId);
-                publishRoutes();
-                mRoutes.put(routeId, route);
-            }
-        }
-    }
-
-    @Override
     public void onSetRouteVolume(String routeId, int volume) {
         MediaRoute2Info route = mRoutes.get(routeId);
         if (route == null) {
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
index 07b7b22..8eeaefd 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
@@ -17,8 +17,10 @@
 package com.android.systemui;
 
 import com.android.systemui.biometrics.AuthController;
+import com.android.systemui.bubbles.dagger.BubbleModule;
 import com.android.systemui.globalactions.GlobalActionsComponent;
 import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.keyguard.dagger.KeyguardModule;
 import com.android.systemui.navigationbar.car.CarNavigationBar;
 import com.android.systemui.pip.PipUI;
 import com.android.systemui.power.PowerUI;
@@ -29,6 +31,7 @@
 import com.android.systemui.statusbar.car.CarStatusBar;
 import com.android.systemui.statusbar.car.CarStatusBarModule;
 import com.android.systemui.statusbar.notification.InstantAppNotifier;
+import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.tv.TvStatusBar;
 import com.android.systemui.theme.ThemeOverlayController;
@@ -42,7 +45,8 @@
 import dagger.multibindings.IntoMap;
 
 /** Binder for car specific {@link SystemUI} modules. */
-@Module(includes = {RecentsModule.class, CarStatusBarModule.class})
+@Module(includes = {RecentsModule.class, CarStatusBarModule.class, NotificationsModule.class,
+        BubbleModule.class, KeyguardModule.class})
 public abstract class CarSystemUIBinder {
     /** Inject into AuthController. */
     @Binds
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
index 498bd87..7f64990 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
@@ -54,10 +54,10 @@
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.NotificationViewHierarchyManager;
 import com.android.systemui.statusbar.PulseExpansionHandler;
-import com.android.systemui.statusbar.StatusBarDependenciesModule;
 import com.android.systemui.statusbar.SuperStatusBarViewFactory;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.VibratorHelper;
+import com.android.systemui.statusbar.dagger.StatusBarDependenciesModule;
 import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
 import com.android.systemui.statusbar.notification.NotificationAlertingManager;
@@ -67,6 +67,7 @@
 import com.android.systemui.statusbar.notification.init.NotificationsController;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
+import com.android.systemui.statusbar.notification.row.NotificationRowModule;
 import com.android.systemui.statusbar.phone.AutoHideController;
 import com.android.systemui.statusbar.phone.BiometricUnlockController;
 import com.android.systemui.statusbar.phone.DozeParameters;
@@ -87,6 +88,7 @@
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarter;
 import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
+import com.android.systemui.statusbar.phone.dagger.StatusBarPhoneDependenciesModule;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -112,7 +114,8 @@
 /**
  * Dagger Module providing {@link CarStatusBar}.
  */
-@Module(includes = {StatusBarDependenciesModule.class})
+@Module(includes = {StatusBarDependenciesModule.class, StatusBarPhoneDependenciesModule.class,
+        NotificationRowModule.class})
 public class CarStatusBarModule {
     /**
      * Provides our instance of StatusBar which is considered optional.
diff --git a/packages/SettingsLib/LayoutPreference/res/layout/cross_profiles_settings_entity_header.xml b/packages/SettingsLib/LayoutPreference/res/layout/cross_profiles_settings_entity_header.xml
index e6f8c01..dc6dddb 100644
--- a/packages/SettingsLib/LayoutPreference/res/layout/cross_profiles_settings_entity_header.xml
+++ b/packages/SettingsLib/LayoutPreference/res/layout/cross_profiles_settings_entity_header.xml
@@ -18,75 +18,39 @@
 <RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/entity_header"
-    style="@style/EntityHeader"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
-    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-    android:orientation="horizontal">
+    style="@style/EntityHeader">
 
     <LinearLayout
         android:id="@+id/entity_header_content"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:paddingTop="32dp"
+        android:paddingBottom="32dp"
         android:layout_centerHorizontal="true"
-        android:gravity="center_horizontal"
-        android:orientation="horizontal">
+        android:orientation="vertical">
 
         <LinearLayout
             android:id="@+id/entity_header_content"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_centerHorizontal="true"
-            android:gravity="center_horizontal"
-            android:orientation="vertical">
+            android:layout_gravity="center"
+            android:orientation="horizontal">
 
             <ImageView
                 android:id="@+id/entity_header_icon_personal"
-                android:layout_width="48dp"
-                android:layout_height="48dp"
-                android:scaleType="fitCenter"
-                android:antialias="true"/>
+                style="@style/CrossProfileEntityHeaderIcon" />
 
-            <TextView
-                android:id="@+id/install_type"
-                style="@style/TextAppearance.EntityHeaderSummary"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="2dp"
-                android:text="Personal"/>
-        </LinearLayout>
-
-        <ImageView
-            android:id="@+id/entity_header_swap_horiz"
-            android:layout_width="24dp"
-            android:layout_height="24dp"
-            android:scaleType="fitCenter"
-            android:antialias="true"
-            android:src="@drawable/ic_swap_horiz_grey"/>
-
-        <LinearLayout
-            android:id="@+id/entity_header_content"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_centerHorizontal="true"
-            android:gravity="center_horizontal"
-            android:orientation="vertical">
+            <ImageView
+                android:id="@+id/entity_header_swap_horiz"
+                style="@style/CrossProfileSwapHorizIcon "/>
 
             <ImageView
                 android:id="@+id/entity_header_icon_work"
-                android:layout_width="48dp"
-                android:layout_height="48dp"
-                android:scaleType="fitCenter"
-                android:antialias="true"/>
-            <TextView
-                android:id="@+id/install_type"
-                style="@style/TextAppearance.EntityHeaderSummary"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="2dp"
-                android:text="Work"/>
+                style="@style/CrossProfileEntityHeaderIcon" />
         </LinearLayout>
-    </LinearLayout>
 
+        <TextView
+            android:id="@+id/entity_header_title"
+            style="@style/CrossProfileEntityHeaderTitle" />
+    </LinearLayout>
 </RelativeLayout>
diff --git a/packages/SettingsLib/LayoutPreference/res/values/styles.xml b/packages/SettingsLib/LayoutPreference/res/values/styles.xml
index 6a2b729..4a99e84 100644
--- a/packages/SettingsLib/LayoutPreference/res/values/styles.xml
+++ b/packages/SettingsLib/LayoutPreference/res/values/styles.xml
@@ -37,4 +37,35 @@
         <item name="android:singleLine">true</item>
         <item name="android:ellipsize">marquee</item>
     </style>
+
+    <style name="CrossProfileEntityHeaderIcon">
+        <item name="android:layout_width">48dp</item>
+        <item name="android:layout_height">48dp</item>
+        <item name="android:layout_gravity">center</item>
+        <item name="android:gravity">center</item>
+        <item name="android:scaleType">fitCenter</item>
+        <item name="android:antialias">true</item>
+    </style>
+
+    <style name="CrossProfileSwapHorizIcon">
+        <item name="android:layout_width">24dp</item>
+        <item name="android:layout_height">24dp</item>
+        <item name="android:layout_gravity">center</item>
+        <item name="android:gravity">center</item>
+        <item name="android:scaleType">fitCenter</item>
+        <item name="android:layout_marginStart">10dp</item>
+        <item name="android:layout_marginEnd">10dp</item>
+        <item name="android:src">@drawable/ic_swap_horiz_grey</item>
+        <item name="android:antialias">true</item>
+    </style>
+
+    <style name="CrossProfileEntityHeaderTitle">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_gravity">center</item>
+        <item name="android:textSize">18sp</item>
+        <item name="android:textColor">?android:attr/textColorPrimary</item>
+        <item name="android:fontFamily">google-sans-medium</item>
+        <item name="android:layout_marginTop">8dp</item>
+    </style>
 </resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
index 8e4a982..5ff88ac 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
@@ -33,6 +33,7 @@
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
@@ -83,10 +84,179 @@
      * Get current device that played media.
      * @return MediaDevice
      */
-    public MediaDevice getCurrentConnectedDevice() {
+    MediaDevice getCurrentConnectedDevice() {
         return mCurrentConnectedDevice;
     }
 
+    /**
+     * Transfer MediaDevice for media without package name.
+     */
+    boolean connectDeviceWithoutPackageName(MediaDevice device) {
+        boolean isConnected = false;
+        final List<RoutingSessionInfo> infos = mRouterManager.getActiveSessions();
+        if (infos.size() > 0) {
+            final RoutingSessionInfo info = infos.get(0);
+            final MediaRouter2Manager.RoutingController controller =
+                    mRouterManager.getControllerForSession(info);
+
+            controller.transferToRoute(device.mRouteInfo);
+            isConnected = true;
+        }
+        return isConnected;
+    }
+
+    /**
+     * Add a MediaDevice to let it play current media.
+     *
+     * @param device MediaDevice
+     * @return If add device successful return {@code true}, otherwise return {@code false}
+     */
+    boolean addDeviceToPlayMedia(MediaDevice device) {
+        if (TextUtils.isEmpty(mPackageName)) {
+            Log.w(TAG, "addDeviceToPlayMedia() package name is null or empty!");
+            return false;
+        }
+
+        final RoutingSessionInfo info = getRoutingSessionInfo();
+        if (info != null && info.getSelectableRoutes().contains(device.mRouteInfo.getId())) {
+            mRouterManager.getControllerForSession(info).selectRoute(device.mRouteInfo);
+            return true;
+        }
+
+        Log.w(TAG, "addDeviceToPlayMedia() Ignoring selecting a non-selectable device : "
+                + device.getName());
+
+        return false;
+    }
+
+    private RoutingSessionInfo getRoutingSessionInfo() {
+        for (RoutingSessionInfo info : mRouterManager.getRoutingSessions(mPackageName)) {
+            if (TextUtils.equals(info.getClientPackageName(), mPackageName)) {
+                return info;
+            }
+        }
+
+        Log.w(TAG, "RoutingSessionInfo() cannot found match packagename : " + mPackageName);
+        return null;
+    }
+
+    /**
+     * Remove a {@code device} from current media.
+     *
+     * @param device MediaDevice
+     * @return If device stop successful return {@code true}, otherwise return {@code false}
+     */
+    boolean removeDeviceFromPlayMedia(MediaDevice device) {
+        if (TextUtils.isEmpty(mPackageName)) {
+            Log.w(TAG, "removeDeviceFromMedia() package name is null or empty!");
+            return false;
+        }
+
+        final RoutingSessionInfo info = getRoutingSessionInfo();
+        if (info != null && info.getSelectedRoutes().contains(device.mRouteInfo.getId())) {
+            mRouterManager.getControllerForSession(info).deselectRoute(device.mRouteInfo);
+            return true;
+        }
+
+        Log.w(TAG, "removeDeviceFromMedia() Ignoring deselecting a non-deselectable device : "
+                + device.getName());
+
+        return false;
+    }
+
+    /**
+     * Get the MediaDevice list that can be added to current media.
+     *
+     * @return list of MediaDevice
+     */
+    List<MediaDevice> getSelectableMediaDevice() {
+        final List<MediaDevice> deviceList = new ArrayList<>();
+        if (TextUtils.isEmpty(mPackageName)) {
+            Log.w(TAG, "getSelectableMediaDevice() package name is null or empty!");
+            return deviceList;
+        }
+
+        final RoutingSessionInfo info = getRoutingSessionInfo();
+        if (info != null) {
+            for (MediaRoute2Info route : mRouterManager.getControllerForSession(info)
+                    .getSelectableRoutes()) {
+                deviceList.add(new InfoMediaDevice(mContext, mRouterManager,
+                        route, mPackageName));
+            }
+            return deviceList;
+        }
+
+        Log.w(TAG, "getSelectableMediaDevice() cannot found selectable MediaDevice from : "
+                + mPackageName);
+
+        return deviceList;
+    }
+
+    /**
+     * Adjust the volume of {@link android.media.RoutingSessionInfo}.
+     *
+     * @param volume the value of volume
+     */
+    void adjustSessionVolume(int volume) {
+        if (TextUtils.isEmpty(mPackageName)) {
+            Log.w(TAG, "adjustSessionVolume() package name is null or empty!");
+            return;
+        }
+
+        final RoutingSessionInfo info = getRoutingSessionInfo();
+        if (info != null) {
+            Log.d(TAG, "adjustSessionVolume() adjust volume : " + volume + ", with : "
+                    + mPackageName);
+            mRouterManager.setSessionVolume(info, volume);
+            return;
+        }
+
+        Log.w(TAG, "adjustSessionVolume() can't found corresponding RoutingSession with : "
+                + mPackageName);
+    }
+
+    /**
+     * Gets the maximum volume of the {@link android.media.RoutingSessionInfo}.
+     *
+     * @return  maximum volume of the session, and return -1 if not found.
+     */
+    public int getSessionVolumeMax() {
+        if (TextUtils.isEmpty(mPackageName)) {
+            Log.w(TAG, "getSessionVolumeMax() package name is null or empty!");
+            return -1;
+        }
+
+        final RoutingSessionInfo info = getRoutingSessionInfo();
+        if (info != null) {
+            return info.getVolumeMax();
+        }
+
+        Log.w(TAG, "getSessionVolumeMax() can't found corresponding RoutingSession with : "
+                + mPackageName);
+        return -1;
+    }
+
+    /**
+     * Gets the current volume of the {@link android.media.RoutingSessionInfo}.
+     *
+     * @return current volume of the session, and return -1 if not found.
+     */
+    public int getSessionVolume() {
+        if (TextUtils.isEmpty(mPackageName)) {
+            Log.w(TAG, "getSessionVolume() package name is null or empty!");
+            return -1;
+        }
+
+        final RoutingSessionInfo info = getRoutingSessionInfo();
+        if (info != null) {
+            return info.getVolume();
+        }
+
+        Log.w(TAG, "getSessionVolume() can't found corresponding RoutingSession with : "
+                + mPackageName);
+        return -1;
+    }
+
     private void refreshDevices() {
         mMediaDevices.clear();
         mCurrentConnectedDevice = null;
@@ -150,23 +320,6 @@
         }
     }
 
-    /**
-     * Transfer MediaDevice for media without package name.
-     */
-    public boolean connectDeviceWithoutPackageName(MediaDevice device) {
-        boolean isConnected = false;
-        final List<RoutingSessionInfo> infos = mRouterManager.getActiveSessions();
-        if (infos.size() > 0) {
-            final RoutingSessionInfo info = infos.get(0);
-            final MediaRouter2Manager.RoutingController controller =
-                    mRouterManager.getControllerForSession(info);
-
-            controller.transferToRoute(device.mRouteInfo);
-            isConnected = true;
-        }
-        return isConnected;
-    }
-
     class RouterManagerCallback extends MediaRouter2Manager.Callback {
 
         @Override
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
index f8db70a..fc373a5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
@@ -252,6 +252,62 @@
         return devices;
     }
 
+    /**
+     * Add a MediaDevice to let it play current media.
+     *
+     * @param device MediaDevice
+     * @return If add device successful return {@code true}, otherwise return {@code false}
+     */
+    public boolean addDeviceToPlayMedia(MediaDevice device) {
+        return mInfoMediaManager.addDeviceToPlayMedia(device);
+    }
+
+    /**
+     * Remove a {@code device} from current media.
+     *
+     * @param device MediaDevice
+     * @return If device stop successful return {@code true}, otherwise return {@code false}
+     */
+    public boolean removeDeviceFromPlayMedia(MediaDevice device) {
+        return mInfoMediaManager.removeDeviceFromPlayMedia(device);
+    }
+
+    /**
+     * Get the MediaDevice list that can be added to current media.
+     *
+     * @return list of MediaDevice
+     */
+    public List<MediaDevice> getSelectableMediaDevice() {
+        return mInfoMediaManager.getSelectableMediaDevice();
+    }
+
+    /**
+     * Adjust the volume of session.
+     *
+     * @param volume the value of volume
+     */
+    public void adjustSessionVolume(int volume) {
+        mInfoMediaManager.adjustSessionVolume(volume);
+    }
+
+    /**
+     * Gets the maximum volume of the {@link android.media.RoutingSessionInfo}.
+     *
+     * @return  maximum volume of the session, and return -1 if not found.
+     */
+    public int getSessionVolumeMax() {
+        return mInfoMediaManager.getSessionVolumeMax();
+    }
+
+    /**
+     * Gets the current volume of the {@link android.media.RoutingSessionInfo}.
+     *
+     * @return current volume of the session, and return -1 if not found.
+     */
+    public int getSessionVolume() {
+        return mInfoMediaManager.getSessionVolume();
+    }
+
     private MediaDevice updateCurrentConnectedDevice() {
         MediaDevice phoneMediaDevice = null;
         for (MediaDevice device : mMediaDevices) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaOutputSliceConstants.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaOutputSliceConstants.java
index f341bf1..2821af9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/MediaOutputSliceConstants.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaOutputSliceConstants.java
@@ -27,6 +27,11 @@
     public static final String KEY_MEDIA_OUTPUT = "media_output";
 
     /**
+     * Key for the Media output group setting.
+     */
+    public static final String KEY_MEDIA_OUTPUT_GROUP = "media_output_group";
+
+    /**
      * Key for the Remote Media slice.
      */
     public static final String KEY_REMOTE_MEDIA = "remote_media";
@@ -48,6 +53,13 @@
             "com.android.settings.panel.action.MEDIA_OUTPUT";
 
     /**
+     * Activity Action: Show a settings dialog containing {@link MediaDevice} to handle media group
+     * operation.
+     */
+    public static final String ACTION_MEDIA_OUTPUT_GROUP =
+            "com.android.settings.panel.action.MEDIA_OUTPUT_GROUP";
+
+    /**
      * An string extra specifying a media package name.
      */
     public static final String EXTRA_PACKAGE_NAME =
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/ConversationIconFactory.java b/packages/SettingsLib/src/com/android/settingslib/notification/ConversationIconFactory.java
new file mode 100644
index 0000000..885b7d3
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/ConversationIconFactory.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.notification;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.LauncherApps;
+import android.content.pm.PackageManager;
+import android.content.pm.ShortcutInfo;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
+import android.util.IconDrawableFactory;
+
+import com.android.launcher3.icons.BaseIconFactory;
+import com.android.launcher3.icons.BitmapInfo;
+import com.android.launcher3.icons.ShadowGenerator;
+
+/**
+ * Factory for creating normalized conversation icons.
+ * We are not using Launcher's IconFactory because conversation rendering only runs on the UI
+ * thread, so there is no need to manage a pool across multiple threads.
+ */
+public class ConversationIconFactory extends BaseIconFactory {
+
+    final LauncherApps mLauncherApps;
+    final PackageManager mPackageManager;
+    final IconDrawableFactory mIconDrawableFactory;
+
+    public ConversationIconFactory(Context context, LauncherApps la, PackageManager pm,
+            IconDrawableFactory iconDrawableFactory, int iconSizePx) {
+        super(context, context.getResources().getConfiguration().densityDpi,
+                iconSizePx);
+        mLauncherApps = la;
+        mPackageManager = pm;
+        mIconDrawableFactory = iconDrawableFactory;
+    }
+
+    private int getBadgeSize() {
+        return mContext.getResources().getDimensionPixelSize(
+                com.android.launcher3.icons.R.dimen.profile_badge_size);
+    }
+    /**
+     * Returns the conversation info drawable
+     */
+    private Drawable getConversationDrawable(ShortcutInfo shortcutInfo) {
+        return mLauncherApps.getShortcutIconDrawable(shortcutInfo, mFillResIconDpi);
+    }
+
+    /**
+     * Get the {@link Drawable} that represents the app icon
+     */
+    private Drawable getBadgedIcon(String packageName, int userId) {
+        try {
+            final ApplicationInfo appInfo = mPackageManager.getApplicationInfoAsUser(
+                    packageName, PackageManager.GET_META_DATA, userId);
+            return mIconDrawableFactory.getBadgedIcon(appInfo, userId);
+        } catch (PackageManager.NameNotFoundException e) {
+            return mPackageManager.getDefaultActivityIcon();
+        }
+    }
+
+    /**
+     * Turns a Drawable into a Bitmap
+     */
+    BitmapInfo toBitmap(Drawable userBadgedAppIcon) {
+        Bitmap bitmap = createIconBitmap(
+                userBadgedAppIcon, 1f, getBadgeSize());
+
+        Canvas c = new Canvas();
+        ShadowGenerator shadowGenerator = new ShadowGenerator(getBadgeSize());
+        c.setBitmap(bitmap);
+        shadowGenerator.recreateIcon(Bitmap.createBitmap(bitmap), c);
+        return createIconBitmap(bitmap);
+    }
+
+    /**
+     * Returns a {@link BitmapInfo} for the entire conversation icon including the badge.
+     */
+    public Bitmap getConversationBitmap(ShortcutInfo info, String packageName, int uid) {
+        return getConversationBitmap(getConversationDrawable(info), packageName, uid);
+    }
+
+    /**
+     * Returns a {@link BitmapInfo} for the entire conversation icon including the badge.
+     */
+    public Bitmap getConversationBitmap(Drawable baseIcon, String packageName, int uid) {
+        int userId = UserHandle.getUserId(uid);
+        Drawable badge = getBadgedIcon(packageName, userId);
+        BitmapInfo iconInfo = createBadgedIconBitmap(baseIcon,
+                UserHandle.of(userId),
+                true /* shrinkNonAdaptiveIcons */);
+
+        badgeWithDrawable(iconInfo.icon,
+                new BitmapDrawable(mContext.getResources(), toBitmap(badge).icon));
+        return iconInfo.icon;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index 954eb9b..cefe690 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -359,7 +359,7 @@
         mPasspointUniqueId = config.getUniqueId();
         mFqdn = config.getHomeSp().getFqdn();
         mProviderFriendlyName = config.getHomeSp().getFriendlyName();
-        mSubscriptionExpirationTimeInMillis = config.getSubscriptionExpirationTimeInMillis();
+        mSubscriptionExpirationTimeInMillis = config.getSubscriptionExpirationTimeMillis();
         if (config.isOsuProvisioned()) {
             mPasspointConfigurationVersion = PasspointConfigurationVersion.OSU_PROVISIONED;
         } else {
@@ -1366,7 +1366,7 @@
             mConfig.allowedKeyManagement.set(KeyMgmt.NONE);
         } else {
             mConfig.allowedKeyManagement.set(KeyMgmt.OWE);
-            mConfig.requirePMF = true;
+            mConfig.requirePmf = true;
         }
     }
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
index 8b815bf..9668629 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
@@ -28,6 +28,7 @@
 import android.media.RoutingSessionInfo;
 
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.testutils.shadow.ShadowRouter2Manager;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -36,15 +37,18 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
 
 import java.util.ArrayList;
 import java.util.List;
 
 @RunWith(RobolectricTestRunner.class)
+@Config(shadows = {ShadowRouter2Manager.class})
 public class InfoMediaManagerTest {
 
     private static final String TEST_PACKAGE_NAME = "com.test.packagename";
     private static final String TEST_ID = "test_id";
+    private static final String TEST_NAME = "test_name";
 
     @Mock
     private MediaRouter2Manager mRouterManager;
@@ -53,6 +57,7 @@
 
     private InfoMediaManager mInfoMediaManager;
     private Context mContext;
+    private ShadowRouter2Manager mShadowRouter2Manager;
 
     @Before
     public void setUp() {
@@ -61,22 +66,8 @@
 
         mInfoMediaManager =
                 new InfoMediaManager(mContext, TEST_PACKAGE_NAME, null, mLocalBluetoothManager);
-        mInfoMediaManager.mRouterManager = mRouterManager;
-    }
-
-    @Test
-    public void stopScan_shouldRemoveCallback() {
-        mInfoMediaManager.stopScan();
-
-        verify(mRouterManager).unregisterCallback(mInfoMediaManager.mMediaRouterCallback);
-    }
-
-    @Test
-    public void startScan_shouldAddCallback() {
-        mInfoMediaManager.startScan();
-
-        verify(mRouterManager).registerCallback(mInfoMediaManager.mExecutor,
-                mInfoMediaManager.mMediaRouterCallback);
+        mShadowRouter2Manager = ShadowRouter2Manager.getShadow();
+        mInfoMediaManager.mRouterManager = MediaRouter2Manager.getInstance(mContext);
     }
 
     @Test
@@ -87,7 +78,7 @@
 
         final List<MediaRoute2Info> routes = new ArrayList<>();
         routes.add(info);
-        when(mRouterManager.getAvailableRoutes(TEST_PACKAGE_NAME)).thenReturn(routes);
+        mShadowRouter2Manager.setAvailableRoutes(routes);
 
         final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
         assertThat(mediaDevice).isNull();
@@ -108,7 +99,7 @@
 
         final List<MediaRoute2Info> routes = new ArrayList<>();
         routes.add(info);
-        when(mRouterManager.getAllRoutes()).thenReturn(routes);
+        mShadowRouter2Manager.setAllRoutes(routes);
 
         final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
         assertThat(mediaDevice).isNull();
@@ -129,7 +120,7 @@
 
         final List<MediaRoute2Info> routes = new ArrayList<>();
         routes.add(info);
-        when(mRouterManager.getAvailableRoutes(TEST_PACKAGE_NAME)).thenReturn(routes);
+        mShadowRouter2Manager.setAvailableRoutes(routes);
 
         final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
         assertThat(mediaDevice).isNull();
@@ -157,7 +148,7 @@
 
         final List<MediaRoute2Info> routes = new ArrayList<>();
         routes.add(info);
-        when(mRouterManager.getAvailableRoutes(TEST_PACKAGE_NAME)).thenReturn(routes);
+        mShadowRouter2Manager.setAvailableRoutes(routes);
 
         final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
         assertThat(mediaDevice).isNull();
@@ -178,7 +169,7 @@
 
         final List<MediaRoute2Info> routes = new ArrayList<>();
         routes.add(info);
-        when(mRouterManager.getAllRoutes()).thenReturn(routes);
+        mShadowRouter2Manager.setAllRoutes(routes);
 
         final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
         assertThat(mediaDevice).isNull();
@@ -194,12 +185,12 @@
     @Test
     public void connectDeviceWithoutPackageName_noSession_returnFalse() {
         final MediaRoute2Info info = mock(MediaRoute2Info.class);
-        final MediaDevice device = new InfoMediaDevice(mContext, mRouterManager, info,
-                TEST_PACKAGE_NAME);
+        final MediaDevice device = new InfoMediaDevice(mContext, mInfoMediaManager.mRouterManager,
+                info, TEST_PACKAGE_NAME);
 
         final List<RoutingSessionInfo> infos = new ArrayList<>();
 
-        when(mRouterManager.getActiveSessions()).thenReturn(infos);
+        mShadowRouter2Manager.setActiveSessions(infos);
 
         assertThat(mInfoMediaManager.connectDeviceWithoutPackageName(device)).isFalse();
     }
@@ -239,10 +230,212 @@
         assertThat(mediaDevice).isNull();
 
         mInfoMediaManager.mPackageName = "";
-        mInfoMediaManager.mMediaRouterCallback.onRoutesChanged(routes);
+        mInfoMediaManager.mMediaRouterCallback.onRoutesRemoved(routes);
 
         final MediaDevice infoDevice = mInfoMediaManager.mMediaDevices.get(0);
         assertThat(infoDevice.getId()).isEqualTo(TEST_ID);
         assertThat(mInfoMediaManager.mMediaDevices).hasSize(routes.size());
     }
+
+    @Test
+    public void addDeviceToPlayMedia_packageNameIsNull_returnFalse() {
+        mInfoMediaManager.mPackageName = null;
+        final MediaDevice device = mock(MediaDevice.class);
+
+        assertThat(mInfoMediaManager.addDeviceToPlayMedia(device)).isFalse();
+    }
+
+    @Test
+    public void addDeviceToPlayMedia_containSelectableRoutes_returnTrue() {
+        final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
+        final RoutingSessionInfo info = mock(RoutingSessionInfo.class);
+        routingSessionInfos.add(info);
+
+        final MediaRoute2Info route2Info = mock(MediaRoute2Info.class);
+        final MediaDevice device =
+                new InfoMediaDevice(mContext, mInfoMediaManager.mRouterManager, route2Info,
+                        TEST_PACKAGE_NAME);
+
+        final List<String> list = new ArrayList<>();
+        list.add(TEST_ID);
+
+        mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
+        when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
+        when(info.getSelectableRoutes()).thenReturn(list);
+        when(route2Info.getId()).thenReturn(TEST_ID);
+        when(route2Info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
+
+        assertThat(mInfoMediaManager.addDeviceToPlayMedia(device)).isTrue();
+    }
+
+    @Test
+    public void addDeviceToPlayMedia_notContainSelectableRoutes_returnFalse() {
+        final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
+        final RoutingSessionInfo info = mock(RoutingSessionInfo.class);
+        routingSessionInfos.add(info);
+
+        final MediaRoute2Info route2Info = mock(MediaRoute2Info.class);
+        final MediaDevice device =
+                new InfoMediaDevice(mContext, mInfoMediaManager.mRouterManager, route2Info,
+                        TEST_PACKAGE_NAME);
+
+        final List<String> list = new ArrayList<>();
+        list.add("fake_id");
+
+        mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
+        when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
+        when(info.getSelectableRoutes()).thenReturn(list);
+        when(route2Info.getId()).thenReturn(TEST_ID);
+        when(route2Info.getName()).thenReturn(TEST_NAME);
+        when(route2Info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
+
+        assertThat(mInfoMediaManager.addDeviceToPlayMedia(device)).isFalse();
+    }
+
+    @Test
+    public void removeDeviceFromMedia_packageNameIsNull_returnFalse() {
+        mInfoMediaManager.mPackageName = null;
+        final MediaDevice device = mock(MediaDevice.class);
+
+        assertThat(mInfoMediaManager.removeDeviceFromPlayMedia(device)).isFalse();
+    }
+
+    @Test
+    public void removeDeviceFromMedia_containSelectedRoutes_returnTrue() {
+        final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
+        final RoutingSessionInfo info = mock(RoutingSessionInfo.class);
+        routingSessionInfos.add(info);
+
+        final MediaRoute2Info route2Info = mock(MediaRoute2Info.class);
+        final MediaDevice device =
+                new InfoMediaDevice(mContext, mInfoMediaManager.mRouterManager, route2Info,
+                        TEST_PACKAGE_NAME);
+
+        final List<String> list = new ArrayList<>();
+        list.add(TEST_ID);
+
+        mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
+        when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
+        when(info.getSelectedRoutes()).thenReturn(list);
+        when(route2Info.getId()).thenReturn(TEST_ID);
+        when(route2Info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
+
+        assertThat(mInfoMediaManager.removeDeviceFromPlayMedia(device)).isTrue();
+    }
+
+    @Test
+    public void removeDeviceFromMedia_notContainSelectedRoutes_returnFalse() {
+        final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
+        final RoutingSessionInfo info = mock(RoutingSessionInfo.class);
+        routingSessionInfos.add(info);
+
+        final MediaRoute2Info route2Info = mock(MediaRoute2Info.class);
+        final MediaDevice device =
+                new InfoMediaDevice(mContext, mInfoMediaManager.mRouterManager, route2Info,
+                        TEST_PACKAGE_NAME);
+
+        final List<String> list = new ArrayList<>();
+        list.add("fake_id");
+
+        mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
+        when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
+        when(info.getSelectedRoutes()).thenReturn(list);
+        when(route2Info.getId()).thenReturn(TEST_ID);
+        when(route2Info.getName()).thenReturn(TEST_NAME);
+        when(route2Info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
+
+        assertThat(mInfoMediaManager.removeDeviceFromPlayMedia(device)).isFalse();
+    }
+
+    @Test
+    public void getSelectableMediaDevice_packageNameIsNull_returnFalse() {
+        mInfoMediaManager.mPackageName = null;
+
+        assertThat(mInfoMediaManager.getSelectableMediaDevice()).isEmpty();
+    }
+
+    @Test
+    public void getSelectableMediaDevice_notContainPackageName_returnEmpty() {
+        final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
+        final RoutingSessionInfo info = mock(RoutingSessionInfo.class);
+        routingSessionInfos.add(info);
+
+        mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
+        when(info.getClientPackageName()).thenReturn("com.fake.packagename");
+
+        assertThat(mInfoMediaManager.getSelectableMediaDevice()).isEmpty();
+    }
+
+    @Test
+    public void adjustSessionVolume_packageNameIsNull_noCrash() {
+        mInfoMediaManager.mPackageName = null;
+
+        mInfoMediaManager.adjustSessionVolume(10);
+    }
+
+    @Test
+    public void getSessionVolumeMax_packageNameIsNull_returnNotFound() {
+        mInfoMediaManager.mPackageName = null;
+
+        assertThat(mInfoMediaManager.getSessionVolumeMax()).isEqualTo(-1);
+    }
+
+    @Test
+    public void getSessionVolumeMax_containPackageName_returnMaxVolume() {
+        final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
+        final RoutingSessionInfo info = mock(RoutingSessionInfo.class);
+        routingSessionInfos.add(info);
+
+        mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
+        when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
+
+        mInfoMediaManager.getSessionVolumeMax();
+
+        verify(info).getVolumeMax();
+    }
+
+    @Test
+    public void getSessionVolumeMax_notContainPackageName_returnNotFound() {
+        final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
+        final RoutingSessionInfo info = mock(RoutingSessionInfo.class);
+        routingSessionInfos.add(info);
+
+        mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
+        when(info.getClientPackageName()).thenReturn("com.fake.packagename");
+
+        assertThat(mInfoMediaManager.getSessionVolumeMax()).isEqualTo(-1);
+    }
+
+    @Test
+    public void getSessionVolume_packageNameIsNull_returnNotFound() {
+        mInfoMediaManager.mPackageName = null;
+
+        assertThat(mInfoMediaManager.getSessionVolume()).isEqualTo(-1);
+    }
+
+    @Test
+    public void getSessionVolume_containPackageName_returnMaxVolume() {
+        final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
+        final RoutingSessionInfo info = mock(RoutingSessionInfo.class);
+        routingSessionInfos.add(info);
+
+        mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
+        when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
+
+        mInfoMediaManager.getSessionVolume();
+
+        verify(info).getVolume();
+    }
+
+    @Test
+    public void getSessionVolume_notContainPackageName_returnNotFound() {
+        final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
+        final RoutingSessionInfo info = mock(RoutingSessionInfo.class);
+        routingSessionInfos.add(info);
+
+        mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
+        when(info.getClientPackageName()).thenReturn("com.fake.packagename");
+
+        assertThat(mInfoMediaManager.getSessionVolume()).isEqualTo(-1);
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowRouter2Manager.java b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowRouter2Manager.java
new file mode 100644
index 0000000..db0cb06
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowRouter2Manager.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.testutils.shadow;
+
+import android.media.MediaRoute2Info;
+import android.media.MediaRouter2Manager;
+import android.media.RoutingSessionInfo;
+
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadow.api.Shadow;
+
+import java.util.List;
+
+@Implements(MediaRouter2Manager.class)
+public class ShadowRouter2Manager {
+
+    private List<MediaRoute2Info> mAvailableRoutes;
+    private List<MediaRoute2Info> mAllRoutes;
+    private List<RoutingSessionInfo> mActiveSessions;
+    private List<RoutingSessionInfo> mRoutingSessions;
+
+    @Implementation
+    protected List<MediaRoute2Info> getAvailableRoutes(String packageName) {
+        return mAvailableRoutes;
+    }
+
+    public void setAvailableRoutes(List<MediaRoute2Info> infos) {
+        mAvailableRoutes = infos;
+    }
+
+    @Implementation
+    protected List<MediaRoute2Info> getAllRoutes() {
+        return mAllRoutes;
+    }
+
+    public void setAllRoutes(List<MediaRoute2Info> infos) {
+        mAllRoutes = infos;
+    }
+
+    @Implementation
+    protected List<RoutingSessionInfo> getActiveSessions() {
+        return mActiveSessions;
+    }
+
+    public void setActiveSessions(List<RoutingSessionInfo> infos) {
+        mActiveSessions = infos;
+    }
+
+    @Implementation
+    protected List<RoutingSessionInfo> getRoutingSessions(String packageName) {
+        return mRoutingSessions;
+    }
+
+    public void setRoutingSessions(List<RoutingSessionInfo> infos) {
+        mRoutingSessions = infos;
+    }
+
+    public static ShadowRouter2Manager getShadow() {
+        return (ShadowRouter2Manager) Shadow.extract(
+                MediaRouter2Manager.getInstance(RuntimeEnvironment.application));
+    }
+}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
index 8037266..c5d4fa9 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
@@ -126,6 +126,7 @@
         VALIDATORS.put(System.SCREEN_OFF_TIMEOUT, NON_NEGATIVE_INTEGER_VALIDATOR);
         VALIDATORS.put(System.SCREEN_BRIGHTNESS_FOR_VR, new InclusiveIntegerRangeValidator(0, 255));
         VALIDATORS.put(System.SCREEN_BRIGHTNESS_MODE, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(System.ADAPTIVE_SLEEP, BOOLEAN_VALIDATOR);
         VALIDATORS.put(System.MODE_RINGER_STREAMS_AFFECTED, NON_NEGATIVE_INTEGER_VALIDATOR);
         VALIDATORS.put(System.MUTE_STREAMS_AFFECTED, NON_NEGATIVE_INTEGER_VALIDATOR);
         VALIDATORS.put(System.VIBRATE_ON, BOOLEAN_VALIDATOR);
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index d821050..99f8c7d 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -111,7 +111,6 @@
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE" />
-    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
     <uses-permission android:name="android.permission.CREATE_USERS" />
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 1814593..d126ee0 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -126,8 +126,6 @@
  * <li>This service calls startBugreport() and passes in local file descriptors to receive
  * bugreport artifacts.
  * </ol>
- *
- * TODO: There are multiple threads involved.  Add synchronization accordingly.
  */
 public class BugreportProgressService extends Service {
     private static final String TAG = "BugreportProgressService";
@@ -219,6 +217,7 @@
     private final Object mLock = new Object();
 
     /** Managed bugreport info (keyed by id) */
+    @GuardedBy("mLock")
     private final SparseArray<BugreportInfo> mBugreportInfos = new SparseArray<>();
 
     private Context mContext;
@@ -317,23 +316,26 @@
 
     @Override
     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
-        final int size = mBugreportInfos.size();
-        if (size == 0) {
-            writer.println("No monitored processes");
-            return;
-        }
-        writer.print("Foreground id: "); writer.println(mForegroundId);
-        writer.println("\n");
-        writer.println("Monitored dumpstate processes");
-        writer.println("-----------------------------");
-        for (int i = 0; i < size; i++) {
-            writer.print("#"); writer.println(i + 1);
-            writer.println(getInfo(mBugreportInfos.keyAt(i)));
+        synchronized (mLock) {
+            final int size = mBugreportInfos.size();
+            if (size == 0) {
+                writer.println("No monitored processes");
+                return;
+            }
+            writer.print("Foreground id: "); writer.println(mForegroundId);
+            writer.println("\n");
+            writer.println("Monitored dumpstate processes");
+            writer.println("-----------------------------");
+            for (int i = 0; i < size; i++) {
+                writer.print("#");
+                writer.println(i + 1);
+                writer.println(getInfoLocked(mBugreportInfos.keyAt(i)));
+            }
         }
     }
 
     private static String getFileName(BugreportInfo info, String suffix) {
-        return String.format("%s-%s%s", info.baseName, info.name, suffix);
+        return String.format("%s-%s%s", info.baseName, info.getName(), suffix);
     }
 
     private final class BugreportCallbackImpl extends BugreportCallback {
@@ -573,7 +575,8 @@
         }
     }
 
-    private BugreportInfo getInfo(int id) {
+    @GuardedBy("mLock")
+    private BugreportInfo getInfoLocked(int id) {
         final BugreportInfo bugreportInfo = mBugreportInfos.get(id);
         if (bugreportInfo == null) {
             Log.w(TAG, "Not monitoring bugreports with ID " + id);
@@ -606,26 +609,21 @@
 
         BugreportInfo info = new BugreportInfo(mContext, baseName, name,
                 shareTitle, shareDescription, bugreportType, mBugreportsDir);
-        ParcelFileDescriptor bugreportFd;
-        ParcelFileDescriptor screenshotFd;
-
-        try {
-            bugreportFd = info.createAndGetBugreportFd();
-            if (bugreportFd == null) {
-                Log.e(TAG, "Bugreport parcel file descriptor is null.");
-                return;
-            }
-            screenshotFd = info.createAndGetDefaultScreenshotFd();
-            if (screenshotFd == null) {
-                Log.e(TAG, "Screenshot parcel file descriptor is null. Deleting bugreport file");
-                FileUtils.closeQuietly(bugreportFd);
-                info.bugreportFile.delete();
-                return;
-            }
-        } catch (IOException e) {
-            Log.e(TAG, "Error in generating bugreport files: ", e);
+        ParcelFileDescriptor bugreportFd = info.getBugreportFd();
+        if (bugreportFd == null) {
+            Log.e(TAG, "Failed to start bugreport generation as "
+                    + " bugreport parcel file descriptor is null.");
             return;
         }
+        ParcelFileDescriptor screenshotFd = info.getDefaultScreenshotFd();
+        if (screenshotFd == null) {
+            Log.e(TAG, "Failed to start bugreport generation as"
+                    + " screenshot parcel file descriptor is null. Deleting bugreport file");
+            FileUtils.closeQuietly(bugreportFd);
+            info.bugreportFile.delete();
+            return;
+        }
+
         mBugreportManager = (BugreportManager) mContext.getSystemService(
                 Context.BUGREPORT_SERVICE);
         final Executor executor = ActivityThread.currentActivityThread().getExecutor();
@@ -639,7 +637,7 @@
             mBugreportManager.startBugreport(bugreportFd, screenshotFd,
                     new BugreportParams(bugreportType), executor, bugreportCallback);
         } catch (RuntimeException e) {
-            Log.i(TAG, "error in generating bugreports: ", e);
+            Log.i(TAG, "Error in generating bugreports: ", e);
             // The binder call didn't go through successfully, so need to close the fds.
             // If the calls went through API takes ownership.
             FileUtils.closeQuietly(bugreportFd);
@@ -657,11 +655,15 @@
         return null;
     }
 
-    private static void createReadWriteFile(File file) throws IOException {
-        if (!file.exists()) {
-            file.createNewFile();
-            file.setReadable(true, true);
-            file.setWritable(true, true);
+    private static void createReadWriteFile(File file) {
+        try {
+            if (!file.exists()) {
+                file.createNewFile();
+                file.setReadable(true, true);
+                file.setWritable(true, true);
+            }
+        } catch (IOException e) {
+            Log.e(TAG, "Error in creating bugreport file: ", e);
         }
     }
 
@@ -669,12 +671,12 @@
      * Updates the system notification for a given bugreport.
      */
     private void updateProgress(BugreportInfo info) {
-        if (info.progress < 0) {
-            Log.e(TAG, "Invalid progress value for " + info);
+        if (info.getProgress() < 0) {
+            Log.e(TAG, "Invalid progress values for " + info);
             return;
         }
 
-        if (info.finished) {
+        if (info.isFinished()) {
             Log.w(TAG, "Not sending progress notification because bugreport has finished already ("
                     + info + ")");
             return;
@@ -683,7 +685,7 @@
         final NumberFormat nf = NumberFormat.getPercentInstance();
         nf.setMinimumFractionDigits(2);
         nf.setMaximumFractionDigits(2);
-        final String percentageText = nf.format((double) info.progress / 100);
+        final String percentageText = nf.format((double) info.getProgress() / 100);
 
         String title = mContext.getString(R.string.bugreport_in_progress_title, info.id);
 
@@ -691,18 +693,19 @@
         if (mIsWatch) {
             nf.setMinimumFractionDigits(0);
             nf.setMaximumFractionDigits(0);
-            final String watchPercentageText = nf.format((double) info.progress / 100);
+            final String watchPercentageText = nf.format((double) info.getProgress() / 100);
             title = title + "\n" + watchPercentageText;
         }
 
         final String name =
-                info.name != null ? info.name : mContext.getString(R.string.bugreport_unnamed);
+                info.getName() != null ? info.getName()
+                        : mContext.getString(R.string.bugreport_unnamed);
 
         final Notification.Builder builder = newBaseNotification(mContext)
                 .setContentTitle(title)
                 .setTicker(title)
                 .setContentText(name)
-                .setProgress(100 /* max value of progress percentage */, info.progress, false)
+                .setProgress(100 /* max value of progress percentage */, info.getProgress(), false)
                 .setOngoing(true);
 
         // Wear and ATV bugreport doesn't need the bug info dialog, screenshot and cancel action.
@@ -731,10 +734,10 @@
                 .setActions(infoAction, screenshotAction, cancelAction);
         }
         // Show a debug log, every LOG_PROGRESS_STEP percent.
-        final int progress = info.progress;
+        final int progress = info.getProgress();
 
-        if ((info.progress == 0) || (info.progress >= 100) ||
-                ((progress / LOG_PROGRESS_STEP) != (mLastProgressPercent / LOG_PROGRESS_STEP))) {
+        if ((info.getProgress() == 0) || (info.getProgress() >= 100)
+                || ((progress / LOG_PROGRESS_STEP) != (mLastProgressPercent / LOG_PROGRESS_STEP))) {
             Log.d(TAG, "Progress #" + info.id + ": " + percentageText);
         }
         mLastProgressPercent = progress;
@@ -779,10 +782,10 @@
             mBugreportInfos.remove(id);
         }
         // Must stop foreground service first, otherwise notif.cancel() will fail below.
-        stopForegroundWhenDone(id);
+        stopForegroundWhenDoneLocked(id);
         Log.d(TAG, "stopProgress(" + id + "): cancel notification");
         NotificationManager.from(mContext).cancel(id);
-        stopSelfWhenDone();
+        stopSelfWhenDoneLocked();
     }
 
     /**
@@ -792,13 +795,13 @@
         MetricsLogger.action(this, MetricsEvent.ACTION_BUGREPORT_NOTIFICATION_ACTION_CANCEL);
         Log.v(TAG, "cancel: ID=" + id);
         mInfoDialog.cancel();
-        final BugreportInfo info = getInfo(id);
-        if (info != null && !info.finished) {
-            Log.i(TAG, "Cancelling bugreport service (ID=" + id + ") on user's request");
-            mBugreportManager.cancelBugreport();
-            deleteScreenshots(info);
-        }
         synchronized (mLock) {
+            final BugreportInfo info = getInfoLocked(id);
+            if (info != null && !info.isFinished()) {
+                Log.i(TAG, "Cancelling bugreport service (ID=" + id + ") on user's request");
+                mBugreportManager.cancelBugreport();
+                deleteScreenshots(info);
+            }
             stopProgressLocked(id);
         }
     }
@@ -809,7 +812,10 @@
      */
     private void launchBugreportInfoDialog(int id) {
         MetricsLogger.action(this, MetricsEvent.ACTION_BUGREPORT_NOTIFICATION_ACTION_DETAILS);
-        final BugreportInfo info = getInfo(id);
+        final BugreportInfo info;
+        synchronized (mLock) {
+            info = getInfoLocked(id);
+        }
         if (info == null) {
             // Most likely am killed Shell before user tapped the notification. Since system might
             // be too busy anwyays, it's better to ignore the notification and switch back to the
@@ -843,7 +849,11 @@
      */
     private void takeScreenshot(int id) {
         MetricsLogger.action(this, MetricsEvent.ACTION_BUGREPORT_NOTIFICATION_ACTION_SCREENSHOT);
-        if (getInfo(id) == null) {
+        BugreportInfo info;
+        synchronized (mLock) {
+            info = getInfoLocked(id);
+        }
+        if (info == null) {
             // Most likely am killed Shell before user tapped the notification. Since system might
             // be too busy anwyays, it's better to ignore the notification and switch back to the
             // non-interactive mode (where the bugerport will be shared upon completion).
@@ -878,9 +888,11 @@
             mServiceHandler.sendMessageDelayed(msg, DateUtils.SECOND_IN_MILLIS);
             return;
         }
-
+        final BugreportInfo info;
         // It's time to take the screenshot: let the proper thread handle it
-        final BugreportInfo info = getInfo(id);
+        synchronized (mLock) {
+            info = getInfoLocked(id);
+        }
         if (info == null) {
             return;
         }
@@ -896,11 +908,11 @@
      * SCREENSHOT button is enabled or disabled accordingly.
      */
     private void setTakingScreenshot(boolean flag) {
-        synchronized (BugreportProgressService.this) {
+        synchronized (mLock) {
             mTakingScreenshot = flag;
             for (int i = 0; i < mBugreportInfos.size(); i++) {
-                final BugreportInfo info = getInfo(mBugreportInfos.keyAt(i));
-                if (info.finished) {
+                final BugreportInfo info = getInfoLocked(mBugreportInfos.keyAt(i));
+                if (info.isFinished()) {
                     Log.d(TAG, "Not updating progress for " + info.id + " while taking screenshot"
                             + " because share notification was already sent");
                     continue;
@@ -921,7 +933,10 @@
 
     private void handleScreenshotResponse(Message resultMsg) {
         final boolean taken = resultMsg.arg2 != 0;
-        final BugreportInfo info = getInfo(resultMsg.arg1);
+        final BugreportInfo info;
+        synchronized (mLock) {
+            info = getInfoLocked(resultMsg.arg1);
+        }
         if (info == null) {
             return;
         }
@@ -930,7 +945,7 @@
         final String msg;
         if (taken) {
             info.addScreenshot(screenshotFile);
-            if (info.finished) {
+            if (info.isFinished()) {
                 Log.d(TAG, "Screenshot finished after bugreport; updating share notification");
                 info.renameScreenshots();
                 sendBugreportNotification(info, mTakingScreenshot);
@@ -956,9 +971,10 @@
     /**
      * Stop running on foreground once there is no more active bugreports being watched.
      */
-    private void stopForegroundWhenDone(int id) {
+    @GuardedBy("mLock")
+    private void stopForegroundWhenDoneLocked(int id) {
         if (id != mForegroundId) {
-            Log.d(TAG, "stopForegroundWhenDone(" + id + "): ignoring since foreground id is "
+            Log.d(TAG, "stopForegroundWhenDoneLocked(" + id + "): ignoring since foreground id is "
                     + mForegroundId);
             return;
         }
@@ -971,8 +987,8 @@
         final int total = mBugreportInfos.size();
         if (total > 0) {
             for (int i = 0; i < total; i++) {
-                final BugreportInfo info = getInfo(mBugreportInfos.keyAt(i));
-                if (!info.finished) {
+                final BugreportInfo info = getInfoLocked(mBugreportInfos.keyAt(i));
+                if (!info.isFinished()) {
                     updateProgress(info);
                     break;
                 }
@@ -983,7 +999,8 @@
     /**
      * Finishes the service when it's not monitoring any more processes.
      */
-    private void stopSelfWhenDone() {
+    @GuardedBy("mLock")
+    private void stopSelfWhenDoneLocked() {
         if (mBugreportInfos.size() > 0) {
             if (DEBUG) Log.d(TAG, "Staying alive, waiting for IDs " + mBugreportInfos);
             return;
@@ -996,12 +1013,14 @@
      * Wraps up bugreport generation and triggers a notification to share the bugreport.
      */
     private void onBugreportFinished(BugreportInfo info) {
-        Log.d(TAG, "Bugreport finished with title: " + info.title
+        Log.d(TAG, "Bugreport finished with title: " + info.getTitle()
                 + " and shareDescription:  " + info.shareDescription);
-        info.finished = true;
+        info.setFinished(true);
 
-        // Stop running on foreground, otherwise share notification cannot be dismissed.
-        stopForegroundWhenDone(info.id);
+        synchronized (mLock) {
+            // Stop running on foreground, otherwise share notification cannot be dismissed.
+            stopForegroundWhenDoneLocked(info.id);
+        }
 
         triggerLocalNotification(mContext, info);
     }
@@ -1063,8 +1082,8 @@
         intent.addCategory(Intent.CATEGORY_DEFAULT);
         intent.setType(mimeType);
 
-        final String subject = !TextUtils.isEmpty(info.title) ?
-                info.title : bugreportUri.getLastPathSegment();
+        final String subject = !TextUtils.isEmpty(info.getTitle())
+                ? info.getTitle() : bugreportUri.getLastPathSegment();
         intent.putExtra(Intent.EXTRA_SUBJECT, subject);
 
         // EXTRA_TEXT should be an ArrayList, but some clients are expecting a single String.
@@ -1075,9 +1094,9 @@
             .append("\nSerial number: ")
             .append(SystemProperties.get("ro.serialno"));
         int descriptionLength = 0;
-        if (!TextUtils.isEmpty(info.description)) {
-            messageBody.append("\nDescription: ").append(info.description);
-            descriptionLength = info.description.length();
+        if (!TextUtils.isEmpty(info.getDescription())) {
+            messageBody.append("\nDescription: ").append(info.getDescription());
+            descriptionLength = info.getDescription().length();
         }
         intent.putExtra(Intent.EXTRA_TEXT, messageBody.toString());
         final ClipData clipData = new ClipData(null, new String[] { mimeType },
@@ -1118,12 +1137,17 @@
      */
     private void shareBugreport(int id, BugreportInfo sharedInfo) {
         MetricsLogger.action(this, MetricsEvent.ACTION_BUGREPORT_NOTIFICATION_ACTION_SHARE);
-        BugreportInfo info = getInfo(id);
+        BugreportInfo info;
+        synchronized (mLock) {
+            info = getInfoLocked(id);
+        }
         if (info == null) {
             // Service was terminated but notification persisted
             info = sharedInfo;
-            Log.d(TAG, "shareBugreport(): no info for ID " + id + " on managed processes ("
-                    + mBugreportInfos + "), using info from intent instead (" + info + ")");
+            synchronized (mLock) {
+                Log.d(TAG, "shareBugreport(): no info for ID " + id + " on managed processes ("
+                        + mBugreportInfos + "), using info from intent instead (" + info + ")");
+            }
         } else {
             Log.v(TAG, "shareBugReport(): id " + id + " info = " + info);
         }
@@ -1195,10 +1219,10 @@
                 mContext.getString(R.string.bugreport_finished_pending_screenshot_text)
                 : mContext.getString(R.string.bugreport_finished_text);
         final String title;
-        if (TextUtils.isEmpty(info.title)) {
+        if (TextUtils.isEmpty(info.getTitle())) {
             title = mContext.getString(R.string.bugreport_finished_title, info.id);
         } else {
-            title = info.title;
+            title = info.getTitle();
             if (!TextUtils.isEmpty(info.shareDescription)) {
                 if(!takingScreenshot) content = info.shareDescription;
             }
@@ -1212,8 +1236,8 @@
                         PendingIntent.FLAG_UPDATE_CURRENT))
                 .setDeleteIntent(newCancelIntent(mContext, info));
 
-        if (!TextUtils.isEmpty(info.name)) {
-            builder.setSubText(info.name);
+        if (!TextUtils.isEmpty(info.getName())) {
+            builder.setSubText(info.getName());
         }
 
         Log.v(TAG, "Sending 'Share' notification for ID " + info.id + ": " + title);
@@ -1306,13 +1330,14 @@
         }
     }
 
+    @GuardedBy("mLock")
     private void addDetailsToZipFileLocked(BugreportInfo info) {
         if (info.bugreportFile == null) {
             // One possible reason is a bug in the Parcelization code.
             Log.wtf(TAG, "addDetailsToZipFile(): no bugreportFile on " + info);
             return;
         }
-        if (TextUtils.isEmpty(info.title) && TextUtils.isEmpty(info.description)) {
+        if (TextUtils.isEmpty(info.getTitle()) && TextUtils.isEmpty(info.getDescription())) {
             Log.d(TAG, "Not touching zip file since neither title nor description are set");
             return;
         }
@@ -1345,8 +1370,8 @@
             }
 
             // Then add the user-provided info.
-            addEntry(zos, "title.txt", info.title);
-            addEntry(zos, "description.txt", info.description);
+            addEntry(zos, "title.txt", info.getTitle());
+            addEntry(zos, "description.txt", info.getDescription());
         } catch (IOException e) {
             Log.e(TAG, "exception zipping file " + tmpZip, e);
             Toast.makeText(mContext, R.string.bugreport_add_details_to_zip_failed,
@@ -1356,7 +1381,7 @@
             // Make sure it only tries to add details once, even it fails the first time.
             info.addedDetailsToZip = true;
             info.addingDetailsToZip = false;
-            stopForegroundWhenDone(info.id);
+            stopForegroundWhenDoneLocked(info.id);
         }
 
         if (!tmpZip.renameTo(info.bugreportFile)) {
@@ -1509,24 +1534,27 @@
      * Updates the user-provided details of a bugreport.
      */
     private void updateBugreportInfo(int id, String name, String title, String description) {
-        final BugreportInfo info = getInfo(id);
+        final BugreportInfo info;
+        synchronized (mLock) {
+            info = getInfoLocked(id);
+        }
         if (info == null) {
             return;
         }
-        if (title != null && !title.equals(info.title)) {
+        if (title != null && !title.equals(info.getTitle())) {
             Log.d(TAG, "updating bugreport title: " + title);
             MetricsLogger.action(this, MetricsEvent.ACTION_BUGREPORT_DETAILS_TITLE_CHANGED);
         }
-        info.title = title;
-        if (description != null && !description.equals(info.description)) {
+        info.setTitle(title);
+        if (description != null && !description.equals(info.getDescription())) {
             Log.d(TAG, "updating bugreport description: " + description.length() + " chars");
             MetricsLogger.action(this, MetricsEvent.ACTION_BUGREPORT_DETAILS_DESCRIPTION_CHANGED);
         }
-        info.description = description;
-        if (name != null && !name.equals(info.name)) {
+        info.setDescription(description);
+        if (name != null && !name.equals(info.getName())) {
             Log.d(TAG, "updating bugreport name: " + name);
             MetricsLogger.action(this, MetricsEvent.ACTION_BUGREPORT_DETAILS_NAME_CHANGED);
-            info.name = name;
+            info.setName(name);
             updateProgress(info);
         }
     }
@@ -1641,14 +1669,14 @@
 
             // Then set fields.
             mId = info.id;
-            if (!TextUtils.isEmpty(info.name)) {
-                mInfoName.setText(info.name);
+            if (!TextUtils.isEmpty(info.getName())) {
+                mInfoName.setText(info.getName());
             }
-            if (!TextUtils.isEmpty(info.title)) {
-                mInfoTitle.setText(info.title);
+            if (!TextUtils.isEmpty(info.getTitle())) {
+                mInfoTitle.setText(info.getTitle());
             }
-            if (!TextUtils.isEmpty(info.description)) {
-                mInfoDescription.setText(info.description);
+            if (!TextUtils.isEmpty(info.getDescription())) {
+                mInfoDescription.setText(info.getDescription());
             }
 
             // And finally display it.
@@ -1667,7 +1695,7 @@
                     @Override
                     public void onClick(View view) {
                         MetricsLogger.action(context, MetricsEvent.ACTION_BUGREPORT_DETAILS_SAVED);
-                        sanitizeName(info.name);
+                        sanitizeName(info.getName());
                         final String name = mInfoName.getText().toString();
                         final String title = mInfoTitle.getText().toString();
                         final String description = mInfoDescription.getText().toString();
@@ -1818,6 +1846,8 @@
          */
         int type;
 
+        private final Object mLock = new Object();
+
         /**
          * Constructor for tracked bugreports - typically called upon receiving BUGREPORT_REQUESTED.
          */
@@ -1836,26 +1866,98 @@
 
         void createBugreportFile(File bugreportsDir) {
             bugreportFile = new File(bugreportsDir, getFileName(this, ".zip"));
+            createReadWriteFile(bugreportFile);
         }
 
         void createScreenshotFile(File bugreportsDir) {
             File screenshotFile = new File(bugreportsDir, getScreenshotName("default"));
             addScreenshot(screenshotFile);
+            createReadWriteFile(screenshotFile);
         }
 
-        ParcelFileDescriptor createAndGetBugreportFd() throws IOException {
-            createReadWriteFile(bugreportFile);
+        ParcelFileDescriptor getBugreportFd() {
             return getFd(bugreportFile);
         }
 
-        ParcelFileDescriptor createAndGetDefaultScreenshotFd() throws IOException {
+        ParcelFileDescriptor getDefaultScreenshotFd() {
             if (screenshotFiles.isEmpty()) {
                 return null;
             }
-            createReadWriteFile(screenshotFiles.get(0));
             return getFd(screenshotFiles.get(0));
         }
 
+        void setFinished(boolean isFinished) {
+            synchronized (mLock) {
+                this.finished = isFinished;
+            }
+        }
+
+        boolean isFinished() {
+            synchronized (mLock) {
+                return finished;
+            }
+        }
+
+        void setTitle(String title) {
+            synchronized (mLock) {
+                this.title = title;
+            }
+        }
+
+        String getTitle() {
+            synchronized (mLock) {
+                return title;
+            }
+        }
+
+        void setName(String name) {
+            synchronized (mLock) {
+                this.name = name;
+            }
+        }
+
+        String getName() {
+            synchronized (mLock) {
+                return name;
+            }
+        }
+
+        void setDescription(String description) {
+            synchronized (mLock) {
+                this.description = description;
+            }
+        }
+
+        String getDescription() {
+            synchronized (mLock) {
+                return description;
+            }
+        }
+
+        void setProgress(int progress) {
+            synchronized (mLock) {
+                this.progress = progress;
+            }
+        }
+
+        int getProgress() {
+            synchronized (mLock) {
+                return progress;
+            }
+        }
+
+        void setLastUpdate(long lastUpdate) {
+            synchronized (mLock) {
+                this.lastUpdate = lastUpdate;
+            }
+        }
+
+        long getLastUpdate() {
+            synchronized (mLock) {
+                return lastUpdate;
+            }
+        }
+
         /**
          * Gets the name for next user triggered screenshot file.
          */
@@ -1925,9 +2027,9 @@
             if (context == null) {
                 // Restored from Parcel
                 return formattedLastUpdate == null ?
-                        Long.toString(lastUpdate) : formattedLastUpdate;
+                        Long.toString(getLastUpdate()) : formattedLastUpdate;
             }
-            return DateUtils.formatDateTime(context, lastUpdate,
+            return DateUtils.formatDateTime(context, getLastUpdate(),
                     DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME);
         }
 
@@ -2048,13 +2150,13 @@
             progress = CAPPED_PROGRESS;
         }
         if (DEBUG) {
-            if (progress != info.progress) {
-                Log.v(TAG, "Updating progress for name " + info.name + "(id: " + info.id
-                        + ") from " + info.progress + " to " + progress);
+            if (progress != info.getProgress()) {
+                Log.v(TAG, "Updating progress for name " + info.getName() + "(id: " + info.id
+                        + ") from " + info.getProgress() + " to " + progress);
             }
         }
-        info.progress = progress;
-        info.lastUpdate = System.currentTimeMillis();
+        info.setProgress(progress);
+        info.setLastUpdate(System.currentTimeMillis());
 
         updateProgress(info);
     }
diff --git a/packages/SystemUI/res/color/control_background.xml b/packages/SystemUI/res/color/control_background.xml
index 646fe5d..977310c 100644
--- a/packages/SystemUI/res/color/control_background.xml
+++ b/packages/SystemUI/res/color/control_background.xml
@@ -2,5 +2,6 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
   <item android:state_enabled="false"
         android:color="@color/control_default_background" />
-  <item android:color="@color/GM2_blue_50" />
+  <item android:color="@color/GM2_blue_200"
+        android:alpha="0.2" />
 </selector>
diff --git a/packages/SystemUI/res/color/control_foreground.xml b/packages/SystemUI/res/color/control_foreground.xml
index bf028f1..339f1e2 100644
--- a/packages/SystemUI/res/color/control_foreground.xml
+++ b/packages/SystemUI/res/color/control_foreground.xml
@@ -2,5 +2,5 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false"
          android:color="@color/control_default_foreground" />
-   <item android:color="@color/GM2_blue_700" />
+   <item android:color="@color/GM2_blue_200" />
  </selector>
diff --git a/packages/SystemUI/res/color/light_background.xml b/packages/SystemUI/res/color/light_background.xml
index 2effd99..1299464 100644
--- a/packages/SystemUI/res/color/light_background.xml
+++ b/packages/SystemUI/res/color/light_background.xml
@@ -2,5 +2,6 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
   <item android:state_enabled="false"
         android:color="@color/control_default_background" />
-  <item android:color="@color/GM2_yellow_50" />
+  <item android:color="@color/GM2_yellow_200"
+        android:alpha="0.2" />
 </selector>
diff --git a/packages/SystemUI/res/color/light_foreground.xml b/packages/SystemUI/res/color/light_foreground.xml
index 8143028..7c02075 100644
--- a/packages/SystemUI/res/color/light_foreground.xml
+++ b/packages/SystemUI/res/color/light_foreground.xml
@@ -2,5 +2,5 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
   <item android:state_enabled="false"
         android:color="@color/control_default_foreground" />
-  <item android:color="@color/GM2_orange_900" />
+  <item android:color="@color/GM2_yellow_200" />
 </selector>
diff --git a/packages/SystemUI/res/color/thermo_cool_background.xml b/packages/SystemUI/res/color/thermo_cool_background.xml
index 646fe5d..977310c 100644
--- a/packages/SystemUI/res/color/thermo_cool_background.xml
+++ b/packages/SystemUI/res/color/thermo_cool_background.xml
@@ -2,5 +2,6 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
   <item android:state_enabled="false"
         android:color="@color/control_default_background" />
-  <item android:color="@color/GM2_blue_50" />
+  <item android:color="@color/GM2_blue_200"
+        android:alpha="0.2" />
 </selector>
diff --git a/packages/SystemUI/res/color/thermo_cool_foreground.xml b/packages/SystemUI/res/color/thermo_cool_foreground.xml
index bf028f1..339f1e2 100644
--- a/packages/SystemUI/res/color/thermo_cool_foreground.xml
+++ b/packages/SystemUI/res/color/thermo_cool_foreground.xml
@@ -2,5 +2,5 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false"
          android:color="@color/control_default_foreground" />
-   <item android:color="@color/GM2_blue_700" />
+   <item android:color="@color/GM2_blue_200" />
  </selector>
diff --git a/packages/SystemUI/res/color/thermo_heat_background.xml b/packages/SystemUI/res/color/thermo_heat_background.xml
index 6f29ed5..2709ebe 100644
--- a/packages/SystemUI/res/color/thermo_heat_background.xml
+++ b/packages/SystemUI/res/color/thermo_heat_background.xml
@@ -2,5 +2,6 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
   <item android:state_enabled="false"
         android:color="@color/control_default_background" />
-  <item android:color="@color/GM2_red_50" />
+  <item android:color="@color/GM2_red_200"
+        android:alpha="0.2" />
 </selector>
diff --git a/packages/SystemUI/res/color/thermo_heat_foreground.xml b/packages/SystemUI/res/color/thermo_heat_foreground.xml
index 72f4b8d..ffcf550 100644
--- a/packages/SystemUI/res/color/thermo_heat_foreground.xml
+++ b/packages/SystemUI/res/color/thermo_heat_foreground.xml
@@ -2,5 +2,5 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
   <item android:state_enabled="false"
         android:color="@color/control_default_foreground" />
-  <item android:color="@color/GM2_red_700" />
+  <item android:color="@color/GM2_red_200" />
 </selector>
diff --git a/packages/SystemUI/res/drawable/control_background.xml b/packages/SystemUI/res/drawable/control_background.xml
index b246ea0..29b4efa 100644
--- a/packages/SystemUI/res/drawable/control_background.xml
+++ b/packages/SystemUI/res/drawable/control_background.xml
@@ -19,7 +19,7 @@
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
   <item>
     <shape>
-      <solid android:color="?android:attr/colorBackgroundFloating"/>
+      <solid android:color="@color/control_default_background" />
       <corners android:radius="@dimen/control_corner_radius" />
     </shape>
   </item>
diff --git a/packages/SystemUI/res/drawable/ic_screen_record_background.xml b/packages/SystemUI/res/drawable/ic_screen_record_background.xml
new file mode 100644
index 0000000..9195305
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_screen_record_background.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2020 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:tint="?android:attr/colorError"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <path
+        android:pathData="M10,0L14,0A10,10 0,0 1,24 10L24,10A10,10 0,0 1,14 20L10,20A10,10 0,0 1,0 10L0,10A10,10 0,0 1,10 0z"
+        android:fillColor="@android:color/white"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_screen_record.xml b/packages/SystemUI/res/drawable/stat_sys_screen_record.xml
new file mode 100644
index 0000000..486af9e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_screen_record.xml
@@ -0,0 +1,16 @@
+<!--
+Copyright (C) 2020 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT 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.ScreenRecordDrawable />
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/stat_sys_screen_record_1.xml b/packages/SystemUI/res/drawable/stat_sys_screen_record_1.xml
new file mode 100644
index 0000000..ab2314e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_screen_record_1.xml
@@ -0,0 +1,18 @@
+<!--
+Copyright (C) 2020 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT 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.ScreenRecordDrawable
+    level="1"
+/>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/stat_sys_screen_record_2.xml b/packages/SystemUI/res/drawable/stat_sys_screen_record_2.xml
new file mode 100644
index 0000000..8764ff9
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_screen_record_2.xml
@@ -0,0 +1,18 @@
+<!--
+Copyright (C) 2020 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT 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.ScreenRecordDrawable
+    level="2"
+/>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/stat_sys_screen_record_3.xml b/packages/SystemUI/res/drawable/stat_sys_screen_record_3.xml
new file mode 100644
index 0000000..0ff4d9a
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_screen_record_3.xml
@@ -0,0 +1,18 @@
+<!--
+Copyright (C) 2020 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT 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.ScreenRecordDrawable
+    level="3"
+/>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/global_actions_grid_v2.xml b/packages/SystemUI/res/layout/global_actions_grid_v2.xml
index f90012d..4fe21e5 100644
--- a/packages/SystemUI/res/layout/global_actions_grid_v2.xml
+++ b/packages/SystemUI/res/layout/global_actions_grid_v2.xml
@@ -2,15 +2,17 @@
 <ScrollView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/global_actions_container"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
   <androidx.constraintlayout.widget.ConstraintLayout
       android:id="@+id/global_actions_grid_root"
       android:layout_width="match_parent"
-      android:layout_height="wrap_content"
+      android:layout_height="match_parent"
       android:clipChildren="false"
       android:clipToPadding="false"
+      android:paddingBottom="@dimen/global_actions_grid_container_shadow_offset"
       android:layout_marginBottom="@dimen/global_actions_grid_container_negative_shadow_offset">
 
     <com.android.systemui.globalactions.GlobalActionsFlatLayout
@@ -25,65 +27,20 @@
         android:gravity="top | center_horizontal"
         android:clipChildren="false"
         android:clipToPadding="false"
-        android:paddingBottom="@dimen/global_actions_grid_container_shadow_offset"
-        android:layout_marginTop="@dimen/global_actions_top_margin"
-        android:layout_marginBottom="@dimen/global_actions_grid_container_negative_shadow_offset">
+        android:layout_marginTop="@dimen/global_actions_top_margin">
       <LinearLayout
-          android:layout_height="wrap_content"
+          android:id="@android:id/list"
           android:layout_width="wrap_content"
-          android:layoutDirection="ltr"
-          android:clipChildren="false"
-          android:clipToPadding="false"
-          android:layout_marginBottom="@dimen/global_actions_grid_container_bottom_margin">
-        <!-- For separated items-->
-        <LinearLayout
-            android:id="@+id/separated_button"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_marginLeft="@dimen/global_actions_grid_side_margin"
-            android:layout_marginRight="@dimen/global_actions_grid_side_margin"
-            android:paddingLeft="@dimen/global_actions_grid_horizontal_padding"
-            android:paddingRight="@dimen/global_actions_grid_horizontal_padding"
-            android:paddingTop="@dimen/global_actions_grid_vertical_padding"
-            android:paddingBottom="@dimen/global_actions_grid_vertical_padding"
-            android:orientation="vertical"
-            android:gravity="center"
-            android:translationZ="@dimen/global_actions_translate"
-            />
-        <!-- Grid of action items -->
-        <com.android.systemui.globalactions.ListGridLayout
-            android:id="@android:id/list"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:orientation="vertical"
-            android:gravity="right"
-            android:layout_marginRight="@dimen/global_actions_grid_side_margin"
-            android:translationZ="@dimen/global_actions_translate"
-            android:paddingLeft="@dimen/global_actions_grid_horizontal_padding"
-            android:paddingRight="@dimen/global_actions_grid_horizontal_padding"
-            android:paddingTop="@dimen/global_actions_grid_vertical_padding"
-            android:paddingBottom="@dimen/global_actions_grid_vertical_padding"
-            >
-          <LinearLayout
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content"
-              android:visibility="gone"
-              android:layoutDirection="locale"
-              />
-          <LinearLayout
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content"
-              android:visibility="gone"
-              android:layoutDirection="locale"
-              />
-          <LinearLayout
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content"
-              android:visibility="gone"
-              android:layoutDirection="locale"
-              />
-        </com.android.systemui.globalactions.ListGridLayout>
-      </LinearLayout>
+          android:layout_height="wrap_content"
+          android:layout_marginLeft="@dimen/global_actions_grid_side_margin"
+          android:layout_marginRight="@dimen/global_actions_grid_side_margin"
+          android:paddingLeft="@dimen/global_actions_grid_horizontal_padding"
+          android:paddingRight="@dimen/global_actions_grid_horizontal_padding"
+          android:paddingTop="@dimen/global_actions_grid_vertical_padding"
+          android:paddingBottom="@dimen/global_actions_grid_vertical_padding"
+          android:orientation="horizontal"
+          android:gravity="left"
+          android:translationZ="@dimen/global_actions_translate" />
     </com.android.systemui.globalactions.GlobalActionsFlatLayout>
 
     <LinearLayout
@@ -110,8 +67,7 @@
         android:layout_marginLeft="@dimen/global_actions_grid_horizontal_padding"
         app:layout_constraintLeft_toLeftOf="parent"
         app:layout_constraintRight_toRightOf="parent"
-        app:layout_constraintTop_toBottomOf="@id/global_actions_panel">
-
-    </LinearLayout>
+        app:layout_constraintTop_toBottomOf="@id/global_actions_panel"
+        app:layout_constraintBottom_toBottomOf="parent" />
   </androidx.constraintlayout.widget.ConstraintLayout>
 </ScrollView>
diff --git a/packages/SystemUI/res/layout/global_screenshot.xml b/packages/SystemUI/res/layout/global_screenshot.xml
index d0151ff..0b74a11a 100644
--- a/packages/SystemUI/res/layout/global_screenshot.xml
+++ b/packages/SystemUI/res/layout/global_screenshot.xml
@@ -76,6 +76,7 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:src="@android:color/white"
+        android:elevation="8dp"
         android:visibility="gone"/>
     <com.android.systemui.screenshot.ScreenshotSelectorView
         android:id="@+id/global_screenshot_selector"
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 09058f2..43ceb4e 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -201,6 +201,7 @@
     <color name="GM2_grey_900">#202124</color>
 
     <color name="GM2_red_50">#FCE8E6</color>
+    <color name="GM2_red_200">#F6AEA9</color>
     <color name="GM2_red_300">#F28B82</color>
     <color name="GM2_red_500">#B71C1C</color>
     <color name="GM2_red_700">#C5221F</color>
@@ -213,6 +214,7 @@
     <color name="GM2_blue_700">#1967D2</color>
 
     <color name="GM2_yellow_50">#FEF7E0</color>
+    <color name="GM2_yellow_200">#FDE293</color>
     <color name="GM2_yellow_500">#FFFBBC04</color>
 
     <color name="GM2_green_500">#FF34A853</color>
@@ -222,6 +224,8 @@
     <color name="magnification_border_color">#FF9900</color>
 
     <!-- controls -->
-    <color name="control_default_foreground">?android:attr/textColorPrimary</color>
-    <color name="control_default_background">?android:attr/colorBackgroundFloating</color>
+    <color name="control_primary_text">@*android:color/foreground_material_dark</color>
+    <color name="control_secondary_text">@*android:color/dim_foreground_dark</color>
+    <color name="control_default_foreground">@*android:color/foreground_material_dark</color>
+    <color name="control_default_background">@*android:color/background_floating_material_dark</color>
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index ec56c1f..15575a4 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1228,6 +1228,8 @@
     <!-- Screen Record -->
     <dimen name="screenrecord_dialog_padding">18dp</dimen>
     <dimen name="screenrecord_logo_size">24dp</dimen>
+    <dimen name="screenrecord_status_text_size">14sp</dimen>
+    <dimen name="screenrecord_status_icon_radius">5dp</dimen>
 
     <dimen name="kg_user_switcher_text_size">16sp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 6fedac0..fecb75c 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -635,16 +635,16 @@
 
     <style name="TextAppearance.Control.Status">
         <item name="android:textSize">12sp</item>
-        <item name="android:textColor">?android:attr/textColorPrimary</item>
+        <item name="android:textColor">@color/control_primary_text</item>
     </style>
 
     <style name="TextAppearance.Control.Title">
         <item name="android:textSize">14sp</item>
-        <item name="android:textColor">?android:attr/textColorPrimary</item>
+        <item name="android:textColor">@color/control_primary_text</item>
     </style>
     <style name="TextAppearance.Control.Subtitle">
         <item name="android:textSize">12sp</item>
-        <item name="android:textColor">?android:attr/textColorSecondary</item>
+        <item name="android:textColor">@color/control_secondary_text</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 2d288ff..b1d39f5 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
@@ -123,4 +123,9 @@
      */
      void handleImageAsScreenshot(in Bitmap screenImage, in Rect locationInScreen,
               in Insets visibleInsets, int taskId) = 21;
+
+    /**
+     * Sets the split-screen divider minimized state
+     */
+    void setSplitScreenMinimized(boolean minimized) = 22;
 }
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 27fe37e..dc5cb1f 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -61,6 +61,7 @@
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.DevicePolicyManagerWrapper;
 import com.android.systemui.shared.system.PackageManagerWrapper;
+import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NavigationBarController;
 import com.android.systemui.statusbar.NotificationListener;
@@ -329,6 +330,7 @@
     @Inject Lazy<DisplayImeController> mDisplayImeController;
     @Inject Lazy<RecordingController> mRecordingController;
     @Inject Lazy<ProtoTracer> mProtoTracer;
+    @Inject Lazy<Divider> mDivider;
 
     @Inject
     public Dependency() {
@@ -530,6 +532,7 @@
         mProviders.put(AutoHideController.class, mAutoHideController::get);
 
         mProviders.put(RecordingController.class, mRecordingController::get);
+        mProviders.put(Divider.class, mDivider::get);
 
         sDependency = this;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/DockedStackExistsListener.java b/packages/SystemUI/src/com/android/systemui/DockedStackExistsListener.java
deleted file mode 100644
index 5c0df17..0000000
--- a/packages/SystemUI/src/com/android/systemui/DockedStackExistsListener.java
+++ /dev/null
@@ -1,92 +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;
-
-import android.os.RemoteException;
-import android.util.Log;
-import android.view.IDockedStackListener;
-import android.view.WindowManagerGlobal;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.function.Consumer;
-
-/**
- * Utility wrapper to listen for whether or not a docked stack exists, to be
- * used for things like the different overview icon in that mode.
- */
-public class DockedStackExistsListener {
-
-    private static final String TAG = "DockedStackExistsListener";
-
-    private static ArrayList<WeakReference<Consumer<Boolean>>> sCallbacks = new ArrayList<>();
-    private static boolean mLastExists;
-
-    static {
-        try {
-            WindowManagerGlobal.getWindowManagerService().registerDockedStackListener(
-                    new IDockedStackListener.Stub() {
-                        @Override
-                        public void onDividerVisibilityChanged(boolean b) throws RemoteException {
-
-                        }
-
-                        @Override
-                        public void onDockedStackExistsChanged(boolean exists)
-                                throws RemoteException {
-                            DockedStackExistsListener.onDockedStackExistsChanged(exists);
-                        }
-
-                        @Override
-                        public void onDockedStackMinimizedChanged(boolean b, long l, boolean b1)
-                                throws RemoteException {
-
-                        }
-
-                        @Override
-                        public void onAdjustedForImeChanged(boolean b, long l)
-                                throws RemoteException {
-
-                        }
-
-                        @Override
-                        public void onDockSideChanged(int i) throws RemoteException {
-
-                        }
-                    });
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed registering docked stack exists listener", e);
-        }
-    }
-
-
-    private static void onDockedStackExistsChanged(boolean exists) {
-        mLastExists = exists;
-        synchronized (sCallbacks) {
-            sCallbacks.removeIf(wf -> {
-                Consumer<Boolean> l = wf.get();
-                if (l != null) l.accept(exists);
-                return l == null;
-            });
-        }
-    }
-
-    public static void register(Consumer<Boolean> callback) {
-        callback.accept(mLastExists);
-        synchronized (sCallbacks) {
-            sCallbacks.add(new WeakReference<>(callback));
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/MultiListLayout.java b/packages/SystemUI/src/com/android/systemui/MultiListLayout.java
index d153fb0..611da0d 100644
--- a/packages/SystemUI/src/com/android/systemui/MultiListLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/MultiListLayout.java
@@ -57,7 +57,10 @@
     }
 
     protected void setSeparatedViewVisibility(boolean visible) {
-        getSeparatedView().setVisibility(visible ? View.VISIBLE : View.GONE);
+        ViewGroup separatedView = getSeparatedView();
+        if (separatedView != null) {
+            separatedView.setVisibility(visible ? View.VISIBLE : View.GONE);
+        }
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index e66b9f2..a2ae59e 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -22,12 +22,8 @@
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 
-import static com.android.systemui.tuner.TunablePadding.FLAG_END;
-import static com.android.systemui.tuner.TunablePadding.FLAG_START;
-
 import android.annotation.Dimension;
 import android.app.ActivityManager;
-import android.app.Fragment;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -69,13 +65,7 @@
 import com.android.systemui.RegionInterceptingFrameLayout.RegionInterceptableView;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.fragments.FragmentHostManager;
-import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
-import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.qs.SecureSetting;
-import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
-import com.android.systemui.statusbar.phone.StatusBar;
-import com.android.systemui.tuner.TunablePadding;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerService.Tunable;
 import com.android.systemui.util.leak.RotationUtils;
@@ -86,8 +76,6 @@
 import javax.inject.Inject;
 import javax.inject.Singleton;
 
-import dagger.Lazy;
-
 /**
  * An overlay that draws screen decorations in software (e.g for rounded corners or display cutout)
  * for antialiasing and emulation purposes.
@@ -102,7 +90,6 @@
     private static final boolean DEBUG_SCREENSHOT_ROUNDED_CORNERS =
             SystemProperties.getBoolean("debug.screenshot_rounded_corners", false);
     private static final boolean VERBOSE = false;
-    private final Lazy<StatusBar> mStatusBarLazy;
 
     private DisplayManager mDisplayManager;
     private final BroadcastDispatcher mBroadcastDispatcher;
@@ -146,12 +133,10 @@
 
     @Inject
     public ScreenDecorations(Context context,
-            Lazy<StatusBar> statusBarLazy,
             @Main Handler handler,
             BroadcastDispatcher broadcastDispatcher,
             TunerService tunerService) {
         super(context);
-        mStatusBarLazy = statusBarLazy;
         mMainHandler = handler;
         mBroadcastDispatcher = broadcastDispatcher;
         mTunerService = tunerService;
@@ -161,7 +146,6 @@
     public void start() {
         mHandler = startHandlerThread();
         mHandler.post(this::startOnScreenDecorationsThread);
-        setupStatusBarPaddingIfNeeded();
     }
 
     @VisibleForTesting
@@ -440,42 +424,6 @@
                 com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout);
     }
 
-
-    private void setupStatusBarPaddingIfNeeded() {
-        // TODO: This should be moved to a more appropriate place, as it is not related to the
-        // screen decorations overlay.
-        int padding = mContext.getResources().getDimensionPixelSize(
-                R.dimen.rounded_corner_content_padding);
-        if (padding != 0) {
-            setupStatusBarPadding(padding);
-        }
-
-    }
-
-    private void setupStatusBarPadding(int padding) {
-        // Add some padding to all the content near the edge of the screen.
-        StatusBar statusBar = mStatusBarLazy.get();
-        final View notificationShadeWindowView = statusBar.getNotificationShadeWindowView();
-        if (notificationShadeWindowView != null) {
-            TunablePadding.addTunablePadding(
-                    notificationShadeWindowView.findViewById(R.id.keyguard_header),
-                    PADDING, padding, FLAG_END);
-
-            final FragmentHostManager fragmentHostManager =
-                    FragmentHostManager.get(notificationShadeWindowView);
-            fragmentHostManager.addTagListener(QS.TAG,
-                    new TunablePaddingTagListener(padding, R.id.header));
-        }
-
-        final View statusBarWindow = statusBar.getStatusBarWindow();
-        if (statusBarWindow != null) {
-            final FragmentHostManager fragmentHostManager =
-                    FragmentHostManager.get(statusBarWindow);
-            fragmentHostManager.addTagListener(CollapsedStatusBarFragment.TAG,
-                    new TunablePaddingTagListener(padding, R.id.status_bar));
-        }
-    }
-
     @VisibleForTesting
     WindowManager.LayoutParams getWindowLayoutParams() {
         final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
@@ -566,32 +514,6 @@
         view.setLayoutParams(params);
     }
 
-    @VisibleForTesting
-    static class TunablePaddingTagListener implements FragmentListener {
-
-        private final int mPadding;
-        private final int mId;
-        private TunablePadding mTunablePadding;
-
-        public TunablePaddingTagListener(int padding, int id) {
-            mPadding = padding;
-            mId = id;
-        }
-
-        @Override
-        public void onFragmentViewCreated(String tag, Fragment fragment) {
-            if (mTunablePadding != null) {
-                mTunablePadding.destroy();
-            }
-            View view = fragment.getView();
-            if (mId != 0) {
-                view = view.findViewById(mId);
-            }
-            mTunablePadding = TunablePadding.addTunablePadding(view, PADDING, mPadding,
-                    FLAG_START | FLAG_END);
-        }
-    }
-
     public static class DisplayCutoutView extends View implements DisplayManager.DisplayListener,
             RegionInterceptableView {
 
@@ -763,11 +685,11 @@
                 return false;
             }
             if (mStart) {
-                return displayCutout.getSafeInsetLeft() > 0
-                        || displayCutout.getSafeInsetTop() > 0;
+                return !displayCutout.getBoundingRectLeft().isEmpty()
+                        || !displayCutout.getBoundingRectTop().isEmpty();
             } else {
-                return displayCutout.getSafeInsetRight() > 0
-                        || displayCutout.getSafeInsetBottom() > 0;
+                return !displayCutout.getBoundingRectRight().isEmpty()
+                        || !displayCutout.getBoundingRectBottom().isEmpty();
             }
         }
 
@@ -809,15 +731,15 @@
 
         private int getGravity(DisplayCutout displayCutout) {
             if (mStart) {
-                if (displayCutout.getSafeInsetLeft() > 0) {
+                if (!displayCutout.getBoundingRectLeft().isEmpty()) {
                     return Gravity.LEFT;
-                } else if (displayCutout.getSafeInsetTop() > 0) {
+                } else if (!displayCutout.getBoundingRectTop().isEmpty()) {
                     return Gravity.TOP;
                 }
             } else {
-                if (displayCutout.getSafeInsetRight() > 0) {
+                if (!displayCutout.getBoundingRectRight().isEmpty()) {
                     return Gravity.RIGHT;
-                } else if (displayCutout.getSafeInsetBottom() > 0) {
+                } else if (!displayCutout.getBoundingRectBottom().isEmpty()) {
                     return Gravity.BOTTOM;
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
index 1e39954..cdeb5c3 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
@@ -38,9 +38,11 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.service.notification.StatusBarNotification;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.shared.system.SysUiStatsLog;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 
 import java.io.FileDescriptor;
@@ -50,7 +52,7 @@
 /**
  * Encapsulates the data and UI elements of a bubble.
  */
-class Bubble {
+class Bubble implements BubbleViewProvider {
     private static final String TAG = "Bubble";
 
     private NotificationEntry mEntry;
@@ -148,12 +150,12 @@
     }
 
     @Nullable
-    BadgedImageView getIconView() {
+    public BadgedImageView getIconView() {
         return mIconView;
     }
 
     @Nullable
-    BubbleExpandedView getExpandedView() {
+    public BubbleExpandedView getExpandedView() {
         return mExpandedView;
     }
 
@@ -238,7 +240,7 @@
      * Note that this contents visibility doesn't affect visibility at {@link android.view.View},
      * and setting {@code false} actually means rendering the expanded view in transparent.
      */
-    void setContentVisibility(boolean visibility) {
+    public void setContentVisibility(boolean visibility) {
         if (mExpandedView != null) {
             mExpandedView.setContentVisibility(visibility);
         }
@@ -481,4 +483,36 @@
     public int hashCode() {
         return Objects.hash(mKey);
     }
+
+    public void logUIEvent(int bubbleCount, int action, float normalX, float normalY, int index) {
+        if (this.getEntry() == null
+                || this.getEntry().getSbn() == null) {
+            SysUiStatsLog.write(SysUiStatsLog.BUBBLE_UI_CHANGED,
+                    null /* package name */,
+                    null /* notification channel */,
+                    0 /* notification ID */,
+                    0 /* bubble position */,
+                    bubbleCount,
+                    action,
+                    normalX,
+                    normalY,
+                    false /* unread bubble */,
+                    false /* on-going bubble */,
+                    false /* isAppForeground (unused) */);
+        } else {
+            StatusBarNotification notification = this.getEntry().getSbn();
+            SysUiStatsLog.write(SysUiStatsLog.BUBBLE_UI_CHANGED,
+                    notification.getPackageName(),
+                    notification.getNotification().getChannelId(),
+                    notification.getId(),
+                    index,
+                    bubbleCount,
+                    action,
+                    normalX,
+                    normalY,
+                    this.showInShade(),
+                    this.isOngoing(),
+                    false /* isAppForeground (unused) */);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 762e5f2..1f94dbd 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -72,9 +72,7 @@
 import com.android.systemui.DumpController;
 import com.android.systemui.Dumpable;
 import com.android.systemui.R;
-import com.android.systemui.bubbles.BubbleController.BubbleExpandListener;
-import com.android.systemui.bubbles.BubbleController.BubbleStateChangeListener;
-import com.android.systemui.bubbles.BubbleController.NotifCallback;
+import com.android.systemui.bubbles.dagger.BubbleModule;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.PinnedStackListenerForwarder;
@@ -105,16 +103,12 @@
 import java.util.HashSet;
 import java.util.List;
 
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
 /**
  * Bubbles are a special type of content that can "float" on top of other apps or System UI.
  * Bubbles can be expanded to show more content.
  *
  * The controller manages addition, removal, and visible state of bubbles on screen.
  */
-@Singleton
 public class BubbleController implements ConfigurationController.ConfigurationListener, Dumpable {
 
     private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleController" : TAG_BUBBLES;
@@ -277,7 +271,6 @@
         }
     }
 
-    @Inject
     public BubbleController(Context context,
             NotificationShadeWindowController notificationShadeWindowController,
             StatusBarStateController statusBarStateController,
@@ -298,6 +291,9 @@
                 notifPipeline, featureFlags, dumpController);
     }
 
+    /**
+     * Injected constructor. See {@link BubbleModule}.
+     */
     public BubbleController(Context context,
             NotificationShadeWindowController notificationShadeWindowController,
             StatusBarStateController statusBarStateController,
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.java
new file mode 100644
index 0000000..6cf1086
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.bubbles;
+
+import static android.view.View.GONE;
+import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Color;
+import android.graphics.drawable.AdaptiveIconDrawable;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.InsetDrawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+import com.android.systemui.R;
+
+/**
+ * Class for showing aged out bubbles.
+ */
+public class BubbleOverflow implements BubbleViewProvider {
+
+    private ImageView mOverflowBtn;
+    private BubbleExpandedView mOverflowExpandedView;
+    private LayoutInflater mInflater;
+    private Context mContext;
+
+    public BubbleOverflow(Context context) {
+        mContext = context;
+        mInflater = LayoutInflater.from(context);
+    }
+
+    public void setUpOverflow(ViewGroup parentViewGroup) {
+        mOverflowExpandedView = (BubbleExpandedView) mInflater.inflate(
+                R.layout.bubble_expanded_view, parentViewGroup /* root */,
+                false /* attachToRoot */);
+        mOverflowExpandedView.setOverflow(true);
+
+        mOverflowBtn = (ImageView) mInflater.inflate(R.layout.bubble_overflow_button,
+                parentViewGroup /* root */,
+                false /* attachToRoot */);
+
+        setOverflowBtnTheme();
+        mOverflowBtn.setVisibility(GONE);
+    }
+
+    ImageView getBtn() {
+        return mOverflowBtn;
+    }
+
+    void setBtnVisible(int visible) {
+        mOverflowBtn.setVisibility(visible);
+    }
+
+    // TODO(b/149146374) Propagate theme change to bubbles in overflow.
+    void setOverflowBtnTheme() {
+        TypedArray ta = mContext.obtainStyledAttributes(
+                new int[]{android.R.attr.colorBackgroundFloating});
+        int bgColor = ta.getColor(0, Color.WHITE /* default */);
+        ta.recycle();
+
+        InsetDrawable fg = new InsetDrawable(mOverflowBtn.getDrawable(), 28);
+        ColorDrawable bg = new ColorDrawable(bgColor);
+        AdaptiveIconDrawable adaptiveIcon = new AdaptiveIconDrawable(bg, fg);
+        mOverflowBtn.setImageDrawable(adaptiveIcon);
+    }
+
+
+    public BubbleExpandedView getExpandedView() {
+        return mOverflowExpandedView;
+    }
+
+    public void setContentVisibility(boolean visible) {
+        mOverflowExpandedView.setContentVisibility(visible);
+    }
+
+    public void logUIEvent(int bubbleCount, int action, float normalX, float normalY,
+            int index) {
+        // TODO(b/149133814) Log overflow UI events.
+    }
+
+    public View getIconView() {
+        return mOverflowBtn;
+    }
+
+    public String getKey() {
+        return BubbleOverflowActivity.KEY;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java
index f3cfa83..756c598 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java
@@ -47,6 +47,7 @@
  * Must be public to be accessible to androidx...AppComponentFactory
  */
 public class BubbleOverflowActivity extends Activity {
+    public static final String KEY = "Overflow";
     private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleOverflowActivity" : TAG_BUBBLES;
 
     private LinearLayout mEmptyState;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index cff78cf..9a6295a 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -33,8 +33,6 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Color;
 import android.graphics.ColorMatrix;
 import android.graphics.ColorMatrixColorFilter;
 import android.graphics.Paint;
@@ -42,13 +40,9 @@
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.RectF;
-import android.graphics.drawable.AdaptiveIconDrawable;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.InsetDrawable;
 import android.os.Bundle;
 import android.os.VibrationEffect;
 import android.os.Vibrator;
-import android.service.notification.StatusBarNotification;
 import android.util.Log;
 import android.view.Choreographer;
 import android.view.DisplayCutout;
@@ -63,7 +57,6 @@
 import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 import android.view.animation.AccelerateDecelerateInterpolator;
 import android.widget.FrameLayout;
-import android.widget.ImageView;
 
 import androidx.annotation.MainThread;
 import androidx.annotation.Nullable;
@@ -199,7 +192,7 @@
     private int mPointerHeight;
     private int mStatusBarHeight;
     private int mImeOffset;
-    private Bubble mExpandedBubble;
+    private BubbleViewProvider mExpandedBubble;
     private boolean mIsExpanded;
 
     /** Whether the stack is currently on the left side of the screen, or animating there. */
@@ -322,8 +315,8 @@
     private Runnable mAfterMagnet;
 
     private int mOrientation = Configuration.ORIENTATION_UNDEFINED;
-    private BubbleExpandedView mOverflowExpandedView;
-    private ImageView mOverflowBtn;
+
+    private BubbleOverflow mBubbleOverflow;
 
     public BubbleStackView(Context context, BubbleData data,
             @Nullable SurfaceSynchronizer synchronizer) {
@@ -333,7 +326,6 @@
         mInflater = LayoutInflater.from(context);
         mTouchHandler = new BubbleTouchHandler(this, data, context);
         setOnTouchListener(mTouchHandler);
-        mInflater = LayoutInflater.from(context);
 
         Resources res = getResources();
         mMaxBubbles = res.getInteger(R.integer.bubbles_max_rendered);
@@ -407,12 +399,8 @@
                         .setStiffness(SpringForce.STIFFNESS_LOW)
                         .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY));
         mExpandedViewYAnim.addEndListener((anim, cancelled, value, velocity) -> {
-            if (mIsExpanded) {
-                if (mExpandedBubble == null) {
-                    mOverflowExpandedView.updateView();
-                } else {
-                    mExpandedBubble.getExpandedView().updateView();
-                }
+            if (mIsExpanded && mExpandedBubble != null) {
+                mExpandedBubble.getExpandedView().updateView();
             }
         });
 
@@ -420,8 +408,12 @@
         setFocusable(true);
         mBubbleContainer.bringToFront();
 
+        mBubbleOverflow = new BubbleOverflow(mContext);
         if (BubbleExperimentConfig.allowBubbleOverflow(mContext)) {
-            setUpOverflow();
+            mBubbleOverflow.setUpOverflow(this);
+            mBubbleContainer.addView(mBubbleOverflow.getBtn(), 0,
+                    new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
+
         }
 
         setOnApplyWindowInsetsListener((View view, WindowInsets insets) -> {
@@ -432,9 +424,7 @@
                     // Update the insets after we're done translating otherwise position
                     // calculation for them won't be correct.
                     () -> {
-                        if (mExpandedBubble == null) {
-                            mOverflowExpandedView.updateInsets(insets);
-                        } else {
+                        if (mExpandedBubble != null) {
                             mExpandedBubble.getExpandedView().updateInsets(insets);
                         }
                     });
@@ -449,9 +439,7 @@
                     // Reposition & adjust the height for new orientation
                     if (mIsExpanded) {
                         mExpandedViewContainer.setTranslationY(getExpandedViewY());
-                        if (mExpandedBubble == null) {
-                            mOverflowExpandedView.updateView();
-                        } else {
+                        if (mExpandedBubble != null) {
                             mExpandedBubble.getExpandedView().updateView();
                         }
                     }
@@ -516,40 +504,8 @@
         });
     }
 
-    private void setUpOverflow() {
-        mOverflowExpandedView = (BubbleExpandedView) mInflater.inflate(
-                R.layout.bubble_expanded_view, this /* root */, false /* attachToRoot */);
-        mOverflowExpandedView.setOverflow(true);
-
-        mOverflowBtn = (ImageView) mInflater.inflate(R.layout.bubble_overflow_button,
-                this /* root */,
-                false /* attachToRoot */);
-
-        mBubbleContainer.addView(mOverflowBtn, 0,
-                new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
-
-        setOverflowBtnTheme();
-        mOverflowBtn.setVisibility(GONE);
-    }
-
-    // TODO(b/149146374) Propagate theme change to bubbles in overflow.
-    private void setOverflowBtnTheme() {
-        TypedArray ta = mContext.obtainStyledAttributes(
-                new int[]{android.R.attr.colorBackgroundFloating});
-        int bgColor = ta.getColor(0, Color.WHITE /* default */);
-        ta.recycle();
-
-        InsetDrawable fg = new InsetDrawable(mOverflowBtn.getDrawable(), 28);
-        ColorDrawable bg = new ColorDrawable(bgColor);
-        AdaptiveIconDrawable adaptiveIcon = new AdaptiveIconDrawable(bg, fg);
-        mOverflowBtn.setImageDrawable(adaptiveIcon);
-    }
-
     void showExpandedViewContents(int displayId) {
-        if (mOverflowExpandedView != null
-                && mOverflowExpandedView.getVirtualDisplayId() == displayId) {
-            mOverflowExpandedView.setContentVisibility(true);
-        } else if (mExpandedBubble != null
+        if (mExpandedBubble != null
                 && mExpandedBubble.getExpandedView().getVirtualDisplayId() == displayId) {
             mExpandedBubble.setContentVisibility(true);
         }
@@ -573,7 +529,7 @@
     public void onThemeChanged() {
         setUpFlyout();
         if (BubbleExperimentConfig.allowBubbleOverflow(mContext)) {
-            setOverflowBtnTheme();
+            mBubbleOverflow.setOverflowBtnTheme();
         }
     }
 
@@ -756,15 +712,22 @@
     /**
      * The {@link BadgedImageView} that is expanded, null if one does not exist.
      */
-    BadgedImageView getExpandedBubbleView() {
+    View getExpandedBubbleView() {
         return mExpandedBubble != null ? mExpandedBubble.getIconView() : null;
     }
 
     /**
      * The {@link Bubble} that is expanded, null if one does not exist.
      */
+    @Nullable
     Bubble getExpandedBubble() {
-        return mExpandedBubble;
+        if (mExpandedBubble == null
+                || (BubbleExperimentConfig.allowBubbleOverflow(mContext)
+                    && mExpandedBubble.getIconView() == mBubbleOverflow.getBtn()
+                    && mExpandedBubble.getKey() == BubbleOverflowActivity.KEY)) {
+            return null;
+        }
+        return (Bubble) mExpandedBubble;
     }
 
     // via BubbleData.Listener
@@ -818,7 +781,7 @@
             if (DEBUG_BUBBLE_STACK_VIEW) {
                 Log.d(TAG, "Show overflow button.");
             }
-            mOverflowBtn.setVisibility(VISIBLE);
+            mBubbleOverflow.setBtnVisible(VISIBLE);
             if (apply) {
                 mExpandedAnimationController.expandFromStack(() -> {
                     updatePointerPosition();
@@ -828,7 +791,7 @@
             if (DEBUG_BUBBLE_STACK_VIEW) {
                 Log.d(TAG, "Collapsed. Hide overflow button.");
             }
-            mOverflowBtn.setVisibility(GONE);
+            mBubbleOverflow.setBtnVisible(GONE);
         }
     }
 
@@ -849,7 +812,7 @@
     }
 
     void showOverflow() {
-        setSelectedBubble(null);
+        setSelectedBubble(mBubbleOverflow);
     }
 
     /**
@@ -858,14 +821,14 @@
      * position of any bubble.
      */
     // via BubbleData.Listener
-    public void setSelectedBubble(@Nullable Bubble bubbleToSelect) {
+    public void setSelectedBubble(@Nullable BubbleViewProvider bubbleToSelect) {
         if (DEBUG_BUBBLE_STACK_VIEW) {
             Log.d(TAG, "setSelectedBubble: " + bubbleToSelect);
         }
         if (mExpandedBubble != null && mExpandedBubble.equals(bubbleToSelect)) {
             return;
         }
-        final Bubble previouslySelected = mExpandedBubble;
+        final BubbleViewProvider previouslySelected = mExpandedBubble;
         mExpandedBubble = bubbleToSelect;
 
         if (mIsExpanded) {
@@ -874,14 +837,11 @@
             // expanded view becomes visible on the screen. See b/126856255
             mExpandedViewContainer.setAlpha(0.0f);
             mSurfaceSynchronizer.syncSurfaceAndRun(() -> {
-                if (previouslySelected == null) {
-                    mOverflowExpandedView.setContentVisibility(false);
-                } else {
-                    previouslySelected.setContentVisibility(false);
-                }
+                previouslySelected.setContentVisibility(false);
                 updateExpandedBubble();
                 updatePointerPosition();
                 requestUpdate();
+
                 logBubbleEvent(previouslySelected,
                         SysUiStatsLog.BUBBLE_UICHANGED__ACTION__COLLAPSED);
                 logBubbleEvent(bubbleToSelect, SysUiStatsLog.BUBBLE_UICHANGED__ACTION__EXPANDED);
@@ -941,8 +901,8 @@
         if (mIsExpanded) {
             if (isIntersecting(mBubbleContainer, x, y)) {
                 if (BubbleExperimentConfig.allowBubbleOverflow(mContext)
-                        && isIntersecting(mOverflowBtn, x, y)) {
-                    return mOverflowBtn;
+                        && isIntersecting(mBubbleOverflow.getBtn(), x, y)) {
+                    return mBubbleOverflow.getBtn();
                 }
                 // Could be tapping or dragging a bubble while expanded
                 for (int i = 0; i < getBubbleCount(); i++) {
@@ -1030,7 +990,7 @@
 
     private void animateCollapse() {
         mIsExpanded = false;
-        final Bubble previouslySelected = mExpandedBubble;
+        final BubbleViewProvider previouslySelected = mExpandedBubble;
         beforeExpandedViewAnimation();
 
         if (DEBUG_BUBBLE_STACK_VIEW) {
@@ -1046,11 +1006,7 @@
                 () -> {
                     mBubbleContainer.setActiveController(mStackAnimationController);
                     afterExpandedViewAnimation();
-                    if (previouslySelected == null) {
-                        mOverflowExpandedView.setContentVisibility(false);
-                    } else {
-                        previouslySelected.setContentVisibility(false);
-                    }
+                    previouslySelected.setContentVisibility(false);
                 });
 
         mExpandedViewXAnim.animateToFinalPosition(getCollapsedX());
@@ -1093,7 +1049,7 @@
                 mExpandedAnimateYDistance);
     }
 
-    private void notifyExpansionChanged(Bubble bubble, boolean expanded) {
+    private void notifyExpansionChanged(BubbleViewProvider bubble, boolean expanded) {
         if (mExpandListener != null && bubble != null) {
             mExpandListener.onBubbleExpandChanged(expanded, bubble.getKey());
         }
@@ -1613,11 +1569,8 @@
             Log.d(TAG, "updateExpandedBubble()");
         }
         mExpandedViewContainer.removeAllViews();
-        if (mIsExpanded) {
-            BubbleExpandedView bev = mOverflowExpandedView;
-            if (mExpandedBubble != null) {
-                bev = mExpandedBubble.getExpandedView();
-            }
+        if (mIsExpanded && mExpandedBubble != null) {
+            BubbleExpandedView bev = mExpandedBubble.getExpandedView();
             mExpandedViewContainer.addView(bev);
             bev.populateExpandedView();
             mExpandedViewContainer.setVisibility(VISIBLE);
@@ -1636,9 +1589,7 @@
             if (!mExpandedViewYAnim.isRunning()) {
                 // We're not animating so set the value
                 mExpandedViewContainer.setTranslationY(y);
-                if (mExpandedBubble == null) {
-                    mOverflowExpandedView.updateView();
-                } else {
+                if (mExpandedBubble != null) {
                     mExpandedBubble.getExpandedView().updateView();
                 }
             } else {
@@ -1693,15 +1644,16 @@
     /**
      * Finds the bubble index within the stack.
      *
-     * @param bubble the bubble to look up.
+     * @param provider the bubble view provider with the bubble to look up.
      * @return the index of the bubble view within the bubble stack. The range of the position
      * is between 0 and the bubble count minus 1.
      */
-    int getBubbleIndex(@Nullable Bubble bubble) {
-        if (bubble == null) {
+    int getBubbleIndex(@Nullable BubbleViewProvider provider) {
+        if (provider == null || provider.getKey() == BubbleOverflowActivity.KEY) {
             return 0;
         }
-        return mBubbleContainer.indexOfChild(bubble.getIconView());
+        Bubble b = (Bubble) provider;
+        return mBubbleContainer.indexOfChild(b.getIconView());
     }
 
     /**
@@ -1733,36 +1685,12 @@
      *               the user interaction is not specific to one bubble.
      * @param action the user interaction enum.
      */
-    private void logBubbleEvent(@Nullable Bubble bubble, int action) {
-        if (bubble == null || bubble.getEntry() == null
-                || bubble.getEntry().getSbn() == null) {
-            SysUiStatsLog.write(SysUiStatsLog.BUBBLE_UI_CHANGED,
-                    null /* package name */,
-                    null /* notification channel */,
-                    0 /* notification ID */,
-                    0 /* bubble position */,
-                    getBubbleCount(),
-                    action,
-                    getNormalizedXPosition(),
-                    getNormalizedYPosition(),
-                    false /* unread bubble */,
-                    false /* on-going bubble */,
-                    false /* isAppForeground (unused) */);
-        } else {
-            StatusBarNotification notification = bubble.getEntry().getSbn();
-            SysUiStatsLog.write(SysUiStatsLog.BUBBLE_UI_CHANGED,
-                    notification.getPackageName(),
-                    notification.getNotification().getChannelId(),
-                    notification.getId(),
-                    getBubbleIndex(bubble),
-                    getBubbleCount(),
-                    action,
-                    getNormalizedXPosition(),
-                    getNormalizedYPosition(),
-                    bubble.showInShade(),
-                    bubble.isOngoing(),
-                    false /* isAppForeground (unused) */);
+    private void logBubbleEvent(@Nullable BubbleViewProvider bubble, int action) {
+        if (bubble == null) {
+            return;
         }
+        bubble.logUIEvent(getBubbleCount(), action, getNormalizedXPosition(),
+                getNormalizedYPosition(), getBubbleIndex(bubble));
     }
 
     /**
@@ -1770,14 +1698,10 @@
      * a back key down/up event pair is forwarded to the bubble Activity.
      */
     boolean performBackPressIfNeeded() {
-        if (!isExpanded()) {
+        if (!isExpanded() || mExpandedBubble == null) {
             return false;
         }
-        if (mExpandedBubble == null) {
-            return mOverflowExpandedView.performBackPressIfNeeded();
-        } else {
-            return mExpandedBubble.getExpandedView().performBackPressIfNeeded();
-        }
+        return mExpandedBubble.getExpandedView().performBackPressIfNeeded();
     }
 
     /** For debugging only */
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewProvider.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewProvider.java
new file mode 100644
index 0000000..59fc435
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewProvider.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.bubbles;
+
+import android.view.View;
+
+/**
+ * Interface to represent actual Bubbles and UI elements that act like bubbles, like BubbleOverflow.
+ */
+interface BubbleViewProvider {
+    BubbleExpandedView getExpandedView();
+    void setContentVisibility(boolean visible);
+    View getIconView();
+    void logUIEvent(int bubbleCount, int action, float normalX, float normalY, int index);
+    String getKey();
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java b/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java
new file mode 100644
index 0000000..0337ee3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.bubbles.dagger;
+
+import android.content.Context;
+
+import com.android.systemui.DumpController;
+import com.android.systemui.bubbles.BubbleController;
+import com.android.systemui.bubbles.BubbleData;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.FeatureFlags;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
+import com.android.systemui.statusbar.notification.collection.NotifPipeline;
+import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
+import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.ZenModeController;
+
+import javax.inject.Singleton;
+
+import dagger.Module;
+import dagger.Provides;
+
+/** */
+@Module
+public interface BubbleModule {
+
+    /**
+     */
+    @Singleton
+    @Provides
+    static BubbleController newBubbleController(
+            Context context,
+            NotificationShadeWindowController notificationShadeWindowController,
+            StatusBarStateController statusBarStateController,
+            ShadeController shadeController,
+            BubbleData data,
+            ConfigurationController configurationController,
+            NotificationInterruptionStateProvider interruptionStateProvider,
+            ZenModeController zenModeController,
+            NotificationLockscreenUserManager notifUserManager,
+            NotificationGroupManager groupManager,
+            NotificationEntryManager entryManager,
+            NotifPipeline notifPipeline,
+            FeatureFlags featureFlags,
+            DumpController dumpController) {
+        return new BubbleController(
+                context,
+                notificationShadeWindowController,
+                statusBarStateController,
+                shadeController,
+                data,
+                /* synchronizer */null,
+                configurationController,
+                interruptionStateProvider,
+                zenModeController,
+                notifUserManager,
+                groupManager,
+                entryManager,
+                notifPipeline,
+                featureFlags,
+                dumpController);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
index e09d20b..9ec71c7 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
@@ -86,7 +86,7 @@
         private const val MSG_ACTION = 2
         private const val MSG_UNBIND = 3
         private const val BIND_RETRY_DELAY = 1000L // ms
-        private const val LOAD_TIMEOUT = 5000L // ms
+        private const val LOAD_TIMEOUT_SECONDS = 30L // seconds
         private const val MAX_BIND_RETRIES = 5
         private const val MAX_CONTROLS_REQUEST = 100000L
         private const val DEBUG = true
@@ -231,7 +231,7 @@
             // Don't accept load callbacks after this
             lastLoadCallback = null
             unbindService()
-        }, LOAD_TIMEOUT, TimeUnit.MILLISECONDS)
+        }, LOAD_TIMEOUT_SECONDS, TimeUnit.SECONDS)
 
         invokeOrQueue(::load, Message.Load)
     }
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/Behavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/Behavior.kt
index 44f3fbc..275c778 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/Behavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/Behavior.kt
@@ -16,6 +16,20 @@
 
 package com.android.systemui.controls.ui
 
+/**
+ * All controls need to respond to changes in state and handle user-generated events.
+ * Implementations of this interface provide these different means by adding their own
+ * event handlers, and will update the control ui as they see fit.
+ */
 interface Behavior {
-    fun apply(cvh: ControlViewHolder, cws: ControlWithState)
+
+    /**
+     * Only called once per instance
+     */
+    fun initialize(cvh: ControlViewHolder)
+
+    /**
+     * Will be invoked on every update provided to the Control
+     */
+    fun bind(cws: ControlWithState)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
index 55c1b6a..feaea7c 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
@@ -17,14 +17,15 @@
 package com.android.systemui.controls.ui
 
 import android.content.Context
+import android.graphics.BlendMode
 import android.graphics.drawable.ClipDrawable
-import android.graphics.drawable.GradientDrawable
 import android.graphics.drawable.Icon
 import android.graphics.drawable.LayerDrawable
 import android.service.controls.Control
 import android.service.controls.actions.ControlAction
 import android.service.controls.templates.ControlTemplate
 import android.service.controls.templates.TemperatureControlTemplate
+import android.service.controls.templates.ThumbnailTemplate
 import android.service.controls.templates.ToggleRangeTemplate
 import android.service.controls.templates.ToggleTemplate
 import android.view.View
@@ -36,12 +37,15 @@
 import com.android.systemui.util.concurrency.DelayableExecutor
 import com.android.systemui.R
 
+import kotlin.reflect.KClass
+
 private const val UPDATE_DELAY_IN_MILLIS = 3000L
 
 class ControlViewHolder(
     val layout: ViewGroup,
     val controlsController: ControlsController,
-    val uiExecutor: DelayableExecutor
+    val uiExecutor: DelayableExecutor,
+    val bgExecutor: DelayableExecutor
 ) {
     val icon: ImageView = layout.requireViewById(R.id.icon)
     val status: TextView = layout.requireViewById(R.id.status)
@@ -50,15 +54,14 @@
     val subtitle: TextView = layout.requireViewById(R.id.subtitle)
     val context: Context = layout.getContext()
     val clipLayer: ClipDrawable
-    val gd: GradientDrawable
     lateinit var cws: ControlWithState
     var cancelUpdate: Runnable? = null
+    var behavior: Behavior? = null
 
     init {
         val ld = layout.getBackground() as LayerDrawable
         ld.mutate()
         clipLayer = ld.findDrawableByLayerId(R.id.clip_layer) as ClipDrawable
-        gd = clipLayer.getDrawable() as GradientDrawable
     }
 
     fun bindData(cws: ControlWithState) {
@@ -83,7 +86,14 @@
             })
         }
 
-        findBehavior(status, template).apply(this, cws)
+        val clazz = findBehavior(status, template)
+        if (behavior == null || behavior!!::class != clazz) {
+            // Behavior changes can signal a change in template from the app or
+            // first time setup
+            behavior = clazz.java.newInstance()
+            behavior?.initialize(this)
+        }
+        behavior?.bind(cws)
     }
 
     fun actionResponse(@ControlAction.ResponseResult response: Int) {
@@ -115,20 +125,14 @@
         controlsController.action(cws.ci, action)
     }
 
-    private fun findBehavior(status: Int, template: ControlTemplate): Behavior {
+    private fun findBehavior(status: Int, template: ControlTemplate): KClass<out Behavior> {
         return when {
-            status == Control.STATUS_UNKNOWN -> UnknownBehavior()
-            template is ToggleTemplate -> ToggleBehavior()
-            template is ToggleRangeTemplate -> ToggleRangeBehavior()
-            template is TemperatureControlTemplate -> TemperatureControlBehavior()
-            else -> {
-                object : Behavior {
-                    override fun apply(cvh: ControlViewHolder, cws: ControlWithState) {
-                        cvh.status.setText(cws.control?.getStatusText())
-                        cvh.applyRenderInfo(RenderInfo.lookup(cws.ci.deviceType, false))
-                    }
-                }
-            }
+            status == Control.STATUS_UNKNOWN -> UnknownBehavior::class
+            template is ToggleTemplate -> ToggleBehavior::class
+            template is ToggleRangeTemplate -> ToggleRangeBehavior::class
+            template is TemperatureControlTemplate -> TemperatureControlBehavior::class
+            template is ThumbnailTemplate -> StaticBehavior::class
+            else -> DefaultBehavior::class
         }
     }
 
@@ -141,7 +145,10 @@
         icon.setImageIcon(Icon.createWithResource(context, ri.iconResourceId))
         icon.setImageTintList(fg)
 
-        gd.setColor(bg)
+        clipLayer.getDrawable().apply {
+            setTintBlendMode(BlendMode.HUE)
+            setTintList(bg)
+        }
     }
 
     fun setEnabled(enabled: Boolean) {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
index 9e6636f..98cdf28 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
@@ -223,7 +223,7 @@
             val item = inflater.inflate(
                 R.layout.controls_base_item, lastRow, false) as ViewGroup
             lastRow.addView(item)
-            val cvh = ControlViewHolder(item, controlsController.get(), uiExecutor)
+            val cvh = ControlViewHolder(item, controlsController.get(), uiExecutor, bgExecutor)
             val key = ControlKey(it.component, it.controlId)
             cvh.bindData(controlsById.getValue(key))
             controlViewsById.put(key, cvh)
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/CornerDrawable.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/CornerDrawable.kt
new file mode 100644
index 0000000..af581e1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/CornerDrawable.kt
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.controls.ui
+
+import android.graphics.Canvas
+import android.graphics.Path
+import android.graphics.Rect
+import android.graphics.RectF
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.DrawableWrapper
+
+/**
+ * Use a path to add mask for corners around the drawable, to match the radius
+ * of the underlying shape.
+ */
+class CornerDrawable(val wrapped: Drawable, val cornerRadius: Float) : DrawableWrapper(wrapped) {
+    val path: Path = Path()
+
+    init {
+        val b = getBounds()
+        updatePath(RectF(b))
+    }
+
+    override fun draw(canvas: Canvas) {
+        canvas.clipPath(path)
+        super.draw(canvas)
+    }
+
+    override fun setBounds(l: Int, t: Int, r: Int, b: Int) {
+        updatePath(RectF(l.toFloat(), t.toFloat(), r.toFloat(), b.toFloat()))
+        super.setBounds(l, t, r, b)
+    }
+
+    override fun setBounds(r: Rect) {
+        updatePath(RectF(r))
+        super.setBounds(r)
+    }
+
+    private fun updatePath(r: RectF) {
+        path.reset()
+        path.addRoundRect(r, cornerRadius, cornerRadius, Path.Direction.CW)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/DefaultBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/DefaultBehavior.kt
new file mode 100644
index 0000000..1747929
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/DefaultBehavior.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.controls.ui
+
+class DefaultBehavior : Behavior {
+    lateinit var cvh: ControlViewHolder
+
+    override fun initialize(cvh: ControlViewHolder) {
+        this.cvh = cvh
+    }
+
+    override fun bind(cws: ControlWithState) {
+        cvh.status.setText(cws.control?.getStatusText() ?: "")
+        cvh.setEnabled(false)
+        cvh.applyRenderInfo(RenderInfo.lookup(cws.ci.deviceType, false))
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/StaticBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/StaticBehavior.kt
new file mode 100644
index 0000000..c006d6f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/StaticBehavior.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.controls.ui
+
+import android.graphics.drawable.ClipDrawable
+import android.graphics.drawable.LayerDrawable
+import android.service.controls.Control
+import android.service.controls.templates.ThumbnailTemplate
+
+import com.android.systemui.R
+import com.android.systemui.controls.ui.ControlActionCoordinator.MAX_LEVEL
+
+/**
+ * Used for controls that cannot be interacted with. Information is presented to the user
+ * but no actions can be taken. If using a ThumbnailTemplate, the background image will
+ * be changed.
+ */
+class StaticBehavior() : Behavior {
+    lateinit var control: Control
+    lateinit var cvh: ControlViewHolder
+
+    override fun initialize(cvh: ControlViewHolder) {
+        this.cvh = cvh
+    }
+
+    override fun bind(cws: ControlWithState) {
+        this.control = cws.control!!
+
+        cvh.status.setText(control.getStatusText())
+
+        val ld = cvh.layout.getBackground() as LayerDrawable
+        val clipLayer = ld.findDrawableByLayerId(R.id.clip_layer) as ClipDrawable
+
+        clipLayer.setLevel(MAX_LEVEL)
+        cvh.setEnabled(true)
+        cvh.applyRenderInfo(RenderInfo.lookup(control.getDeviceType(), true))
+
+        val template = control.getControlTemplate()
+        if (template is ThumbnailTemplate) {
+            cvh.bgExecutor.execute {
+                // clear the default tinting in favor of only using alpha
+                val drawable = template.getThumbnail().loadDrawable(cvh.context)
+                drawable.setTintList(null)
+                drawable.setAlpha((0.45 * 255).toInt())
+                cvh.uiExecutor.execute {
+                    val radius = cvh.context.getResources()
+                            .getDimensionPixelSize(R.dimen.control_corner_radius).toFloat()
+                    clipLayer.setDrawable(CornerDrawable(drawable, radius))
+                }
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/TemperatureControlBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/TemperatureControlBehavior.kt
index 7661c6f..239d2e5 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/TemperatureControlBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/TemperatureControlBehavior.kt
@@ -16,12 +16,10 @@
 
 package com.android.systemui.controls.ui
 
-import android.content.Context
 import android.graphics.drawable.Drawable
 import android.graphics.drawable.LayerDrawable
 import android.service.controls.Control
 import android.service.controls.templates.TemperatureControlTemplate
-import android.widget.TextView
 
 import com.android.systemui.R
 import com.android.systemui.controls.ui.ControlActionCoordinator.MIN_LEVEL
@@ -32,15 +30,15 @@
     lateinit var control: Control
     lateinit var cvh: ControlViewHolder
     lateinit var template: TemperatureControlTemplate
-    lateinit var status: TextView
-    lateinit var context: Context
 
-    override fun apply(cvh: ControlViewHolder, cws: ControlWithState) {
-        this.control = cws.control!!
+    override fun initialize(cvh: ControlViewHolder) {
         this.cvh = cvh
-        status = cvh.status
+    }
 
-        status.setText(control.getStatusText())
+    override fun bind(cws: ControlWithState) {
+        this.control = cws.control!!
+
+        cvh.status.setText(control.getStatusText())
 
         val ld = cvh.layout.getBackground() as LayerDrawable
         clipLayer = ld.findDrawableByLayerId(R.id.clip_layer)
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleBehavior.kt
index 4c35d26..d306d7c 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleBehavior.kt
@@ -16,11 +16,9 @@
 
 package com.android.systemui.controls.ui
 
-import android.content.Context
 import android.graphics.drawable.Drawable
 import android.graphics.drawable.LayerDrawable
 import android.view.View
-import android.widget.TextView
 import android.service.controls.Control
 import android.service.controls.templates.ToggleTemplate
 
@@ -33,21 +31,21 @@
     lateinit var template: ToggleTemplate
     lateinit var control: Control
     lateinit var cvh: ControlViewHolder
-    lateinit var context: Context
-    lateinit var status: TextView
 
-    override fun apply(cvh: ControlViewHolder, cws: ControlWithState) {
-        this.control = cws.control!!
+    override fun initialize(cvh: ControlViewHolder) {
         this.cvh = cvh
-        status = cvh.status
-
-        status.setText(control.getStatusText())
-
-        template = control.getControlTemplate() as ToggleTemplate
+        cvh.setEnabled(false)
 
         cvh.layout.setOnClickListener(View.OnClickListener() {
             ControlActionCoordinator.toggle(cvh, template.getTemplateId(), template.isChecked())
         })
+    }
+
+    override fun bind(cws: ControlWithState) {
+        this.control = cws.control!!
+
+        cvh.status.setText(control.getStatusText())
+        template = control.getControlTemplate() as ToggleTemplate
 
         val ld = cvh.layout.getBackground() as LayerDrawable
         clipLayer = ld.findDrawableByLayerId(R.id.clip_layer)
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
index 8d65ca3..45d7397 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
@@ -51,17 +51,13 @@
         private const val DEFAULT_FORMAT = "%.1f"
     }
 
-    override fun apply(cvh: ControlViewHolder, cws: ControlWithState) {
-        this.control = cws.control!!
+    override fun initialize(cvh: ControlViewHolder) {
         this.cvh = cvh
-
-        statusExtra = cvh.statusExtra
         status = cvh.status
-
-        status.setText(control.getStatusText())
-
         context = status.getContext()
 
+        cvh.setEnabled(false)
+
         val gestureListener = ToggleRangeGestureListener(cvh.layout)
         val gestureDetector = GestureDetector(context, gestureListener)
         cvh.layout.setOnTouchListener({ v: View, e: MotionEvent ->
@@ -77,6 +73,13 @@
 
             return@setOnTouchListener false
         })
+    }
+
+    override fun bind(cws: ControlWithState) {
+        this.control = cws.control!!
+
+        statusExtra = cvh.statusExtra
+        status.setText(control.getStatusText())
 
         val ld = cvh.layout.getBackground() as LayerDrawable
         clipLayer = ld.findDrawableByLayerId(R.id.clip_layer)
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/UnknownBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/UnknownBehavior.kt
index 5a6e5b4..1f33b85 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/UnknownBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/UnknownBehavior.kt
@@ -17,8 +17,14 @@
 package com.android.systemui.controls.ui
 
 class UnknownBehavior : Behavior {
-    override fun apply(cvh: ControlViewHolder, cws: ControlWithState) {
-        cvh.status.setText("Loading...")
+    lateinit var cvh: ControlViewHolder
+
+    override fun initialize(cvh: ControlViewHolder) {
+        this.cvh = cvh
+    }
+
+    override fun bind(cws: ControlWithState) {
+        cvh.status.setText(cvh.context.getString(com.android.internal.R.string.loading))
         cvh.setEnabled(false)
         cvh.applyRenderInfo(RenderInfo.lookup(cws.ci.deviceType, false))
     }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
index bf501ce..7c0033c 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
@@ -27,7 +27,6 @@
 import android.os.ServiceManager;
 import android.util.DisplayMetrics;
 import android.view.Choreographer;
-import android.view.IWindowManager;
 import android.view.LayoutInflater;
 import android.view.WindowManager;
 
@@ -46,8 +45,6 @@
 import com.android.systemui.shared.system.DevicePolicyManagerWrapper;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NavigationBarController;
-import com.android.systemui.statusbar.NotificationRemoteInputManager;
-import com.android.systemui.statusbar.phone.AutoHideController;
 import com.android.systemui.statusbar.phone.ConfigurationControllerImpl;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.DataSaverController;
@@ -162,16 +159,6 @@
 
     @Singleton
     @Provides
-    public AutoHideController provideAutoHideController(Context context,
-            @Main Handler mainHandler,
-            NotificationRemoteInputManager notificationRemoteInputManager,
-            IWindowManager iWindowManager) {
-        return new AutoHideController(context, mainHandler, notificationRemoteInputManager,
-                iWindowManager);
-    }
-
-    @Singleton
-    @Provides
     public ActivityManagerWrapper provideActivityManagerWrapper() {
         return ActivityManagerWrapper.getInstance();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
index 5de88e1..413a522 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
@@ -24,17 +24,19 @@
 import com.android.systemui.accessibility.SystemActions;
 import com.android.systemui.accessibility.WindowMagnification;
 import com.android.systemui.biometrics.AuthController;
+import com.android.systemui.bubbles.dagger.BubbleModule;
 import com.android.systemui.globalactions.GlobalActionsComponent;
 import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.keyguard.dagger.KeyguardModule;
 import com.android.systemui.pip.PipUI;
 import com.android.systemui.power.PowerUI;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsModule;
 import com.android.systemui.shortcut.ShortcutKeyDispatcher;
 import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.statusbar.dagger.StatusBarModule;
 import com.android.systemui.statusbar.notification.InstantAppNotifier;
 import com.android.systemui.statusbar.phone.StatusBar;
-import com.android.systemui.statusbar.phone.StatusBarModule;
 import com.android.systemui.statusbar.tv.TvStatusBar;
 import com.android.systemui.theme.ThemeOverlayController;
 import com.android.systemui.toast.ToastUI;
@@ -49,7 +51,8 @@
 /**
  * SystemUI objects that are injectable should go here.
  */
-@Module(includes = {RecentsModule.class, StatusBarModule.class})
+@Module(includes = {RecentsModule.class, StatusBarModule.class, BubbleModule.class,
+        KeyguardModule.class})
 public abstract class SystemUIBinder {
     /** Inject into AuthController. */
     @Binds
@@ -142,7 +145,7 @@
     @ClassKey(StatusBar.class)
     public abstract SystemUI bindsStatusBar(StatusBar sysui);
 
-   /** Inject into SystemActions. */
+    /** Inject into SystemActions. */
     @Binds
     @IntoMap
     @ClassKey(SystemActions.class)
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 91aeb22..030b504 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -35,10 +35,8 @@
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationShadeWindowBlurController;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
 import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
-import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
 import com.android.systemui.statusbar.notification.people.PeopleHubModule;
 import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent;
 import com.android.systemui.statusbar.notification.row.dagger.NotificationRowComponent;
@@ -69,7 +67,6 @@
             AssistModule.class,
             ConcurrencyModule.class,
             LogModule.class,
-            NotificationsModule.class,
             PeopleHubModule.class,
         },
         subcomponents = {StatusBarComponent.class,
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index d298b99..9203e6d 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -64,12 +64,12 @@
 import android.util.FeatureFlagUtils;
 import android.util.Log;
 import android.view.ContextThemeWrapper;
+import android.view.IWindowManager;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
 import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
@@ -88,13 +88,13 @@
 import com.android.internal.util.ScreenshotHelper;
 import com.android.internal.view.RotationPolicy;
 import com.android.internal.widget.LockPatternUtils;
-import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.MultiListLayout;
 import com.android.systemui.MultiListLayout.MultiListAdapter;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.controls.ui.ControlsUiController;
+import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
@@ -110,6 +110,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.Executor;
 
 import javax.inject.Inject;
 
@@ -155,6 +156,7 @@
     private final BroadcastDispatcher mBroadcastDispatcher;
     private final ContentResolver mContentResolver;
     private final Resources mResources;
+    private final ConfigurationController mConfigurationController;
     private final UserManager mUserManager;
     private final TrustManager mTrustManager;
     private final IActivityManager mIActivityManager;
@@ -186,6 +188,8 @@
     private final NotificationShadeWindowController mNotificationShadeWindowController;
     private GlobalActionsPanelPlugin mPanelPlugin;
     private ControlsUiController mControlsUiController;
+    private final IWindowManager mIWindowManager;
+    private final Executor mBackgroundExecutor;
 
     /**
      * @param context everything needs a context :(
@@ -204,7 +208,8 @@
             BlurUtils blurUtils, SysuiColorExtractor colorExtractor,
             IStatusBarService statusBarService,
             NotificationShadeWindowController notificationShadeWindowController,
-            ControlsUiController controlsUiController) {
+            ControlsUiController controlsUiController, IWindowManager iWindowManager,
+            @Background Executor backgroundExecutor) {
         mContext = new ContextThemeWrapper(context, com.android.systemui.R.style.qs_theme);
         mWindowManagerFuncs = windowManagerFuncs;
         mAudioManager = audioManager;
@@ -215,6 +220,7 @@
         mBroadcastDispatcher = broadcastDispatcher;
         mContentResolver = contentResolver;
         mResources = resources;
+        mConfigurationController = configurationController;
         mUserManager = userManager;
         mTrustManager = trustManager;
         mIActivityManager = iActivityManager;
@@ -225,6 +231,8 @@
         mStatusBarService = statusBarService;
         mNotificationShadeWindowController = notificationShadeWindowController;
         mControlsUiController = controlsUiController;
+        mIWindowManager = iWindowManager;
+        mBackgroundExecutor = backgroundExecutor;
 
         // receive broadcasts
         IntentFilter filter = new IntentFilter();
@@ -249,7 +257,7 @@
         mScreenshotHelper = new ScreenshotHelper(context);
         mScreenRecordHelper = new ScreenRecordHelper(context);
 
-        configurationController.addCallback(this);
+        mConfigurationController.addCallback(this);
 
         mActivityStarter = activityStarter;
         keyguardStateController.addCallback(new KeyguardStateController.Callback() {
@@ -335,45 +343,7 @@
         } else {
             mSilentModeAction = new SilentModeTriStateAction(mAudioManager, mHandler);
         }
-        mAirplaneModeOn = new ToggleAction(
-                R.drawable.ic_lock_airplane_mode,
-                R.drawable.ic_lock_airplane_mode_off,
-                R.string.global_actions_toggle_airplane_mode,
-                R.string.global_actions_airplane_mode_on_status,
-                R.string.global_actions_airplane_mode_off_status) {
-
-            void onToggle(boolean on) {
-                if (mHasTelephony && TelephonyProperties.in_ecm_mode().orElse(false)) {
-                    mIsWaitingForEcmExit = true;
-                    // Launch ECM exit dialog
-                    Intent ecmDialogIntent =
-                            new Intent(TelephonyManager.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null);
-                    ecmDialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                    mContext.startActivity(ecmDialogIntent);
-                } else {
-                    changeAirplaneModeSystemSetting(on);
-                }
-            }
-
-            @Override
-            protected void changeStateFromPress(boolean buttonOn) {
-                if (!mHasTelephony) return;
-
-                // In ECM mode airplane state cannot be changed
-                if (!TelephonyProperties.in_ecm_mode().orElse(false)) {
-                    mState = buttonOn ? State.TurningOn : State.TurningOff;
-                    mAirplaneState = mState;
-                }
-            }
-
-            public boolean showDuringKeyguard() {
-                return true;
-            }
-
-            public boolean showBeforeProvisioning() {
-                return false;
-            }
-        };
+        mAirplaneModeOn = new AirplaneModeAction();
         onAirplaneModeChanged();
 
         mItems = new ArrayList<Action>();
@@ -495,7 +465,7 @@
     }
 
     public void destroy() {
-        Dependency.get(ConfigurationController.class).removeCallback(this);
+        mConfigurationController.removeCallback(this);
     }
 
     private final class PowerAction extends SinglePressAction implements LongPressAction {
@@ -537,7 +507,7 @@
 
         @Override
         public boolean shouldBeSeparated() {
-            return !shouldShowControls();
+            return true;
         }
 
         @Override
@@ -836,14 +806,12 @@
 
             @Override
             public void onPress() {
-                new LockPatternUtils(mContext)
-                        .requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN,
-                                UserHandle.USER_ALL);
+                mLockPatternUtils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN,
+                        UserHandle.USER_ALL);
                 try {
-                    WindowManagerGlobal.getWindowManagerService().lockNow(null);
+                    mIWindowManager.lockNow(null);
                     // Lock profiles (if any) on the background thread.
-                    final Handler bgHandler = new Handler(Dependency.get(Dependency.BG_LOOPER));
-                    bgHandler.post(() -> lockProfiles());
+                    mBackgroundExecutor.execute(() -> lockProfiles());
                 } catch (RemoteException e) {
                     Log.e(TAG, "Error while trying to lock device.", e);
                 }
@@ -1333,6 +1301,48 @@
         }
     }
 
+    private class AirplaneModeAction extends ToggleAction {
+        AirplaneModeAction() {
+            super(
+                R.drawable.ic_lock_airplane_mode,
+                R.drawable.ic_lock_airplane_mode_off,
+                R.string.global_actions_toggle_airplane_mode,
+                R.string.global_actions_airplane_mode_on_status,
+                R.string.global_actions_airplane_mode_off_status);
+        }
+        void onToggle(boolean on) {
+            if (mHasTelephony && TelephonyProperties.in_ecm_mode().orElse(false)) {
+                mIsWaitingForEcmExit = true;
+                // Launch ECM exit dialog
+                Intent ecmDialogIntent =
+                        new Intent(TelephonyManager.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null);
+                ecmDialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                mContext.startActivity(ecmDialogIntent);
+            } else {
+                changeAirplaneModeSystemSetting(on);
+            }
+        }
+
+        @Override
+        protected void changeStateFromPress(boolean buttonOn) {
+            if (!mHasTelephony) return;
+
+            // In ECM mode airplane state cannot be changed
+            if (!TelephonyProperties.in_ecm_mode().orElse(false)) {
+                mState = buttonOn ? State.TurningOn : State.TurningOff;
+                mAirplaneState = mState;
+            }
+        }
+
+        public boolean showDuringKeyguard() {
+            return true;
+        }
+
+        public boolean showBeforeProvisioning() {
+            return false;
+        }
+    }
+
     private class SilentModeToggleAction extends ToggleAction {
         public SilentModeToggleAction() {
             super(R.drawable.ic_audio_vol_mute,
@@ -1555,6 +1565,7 @@
 
         private ControlsUiController mControlsUiController;
         private ViewGroup mControlsView;
+        private ViewGroup mContainerView;
 
         ActionsDialog(Context context, MyAdapter adapter,
                 GlobalActionsPanelPlugin.PanelViewController plugin, BlurUtils blurUtils,
@@ -1672,6 +1683,14 @@
                 mScrimAlpha = ScrimController.BUSY_SCRIM_ALPHA;
             }
             getWindow().setBackgroundDrawable(mBackgroundDrawable);
+
+            if (mControlsView != null) {
+                mContainerView = findViewById(com.android.systemui.R.id.global_actions_container);
+                mContainerView.setOnTouchListener((v, e) -> {
+                    dismiss();
+                    return true;
+                });
+            }
         }
 
         private void fixNavBarClipping() {
@@ -1894,14 +1913,6 @@
         return isPanelDebugModeEnabled(context);
     }
 
-
-    /**
-     * Determines whether the Global Actions menu should use a separated view for emergency actions.
-     */
-    private static boolean shouldUseSeparatedView() {
-        return true;
-    }
-
     private boolean shouldShowControls() {
         return !mKeyguardManager.isDeviceLocked()
                 && mControlsUiController.getAvailable();
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsFlatLayout.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsFlatLayout.java
index 6749f1d..f102561 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsFlatLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsFlatLayout.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,164 +23,62 @@
 import android.content.Context;
 import android.util.AttributeSet;
 import android.view.View;
-import android.view.ViewGroup;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.HardwareBgDrawable;
+import com.android.systemui.R;
 
 /**
- * Single row implementation of the button layout created by the global actions dialog.
+ * Flat, single-row implementation of the button layout created by the global actions dialog.
  */
 public class GlobalActionsFlatLayout extends GlobalActionsLayout {
+    private static final int MAX_ITEMS = 4;
     public GlobalActionsFlatLayout(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
 
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        mBackgroundsSet = true;
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-
-        // backgrounds set only once, the first time onMeasure is called after inflation
-        // if (getListView() != null && !mBackgroundsSet) {
-        //     setBackgrounds();
-        //     mBackgroundsSet = true;
-        // }
-    }
-
     @VisibleForTesting
-    protected void setupListView() {
-        ListGridLayout listView = getListView();
-        listView.setExpectedCount(Math.min(2, mAdapter.countListItems()));
-        listView.setReverseSublists(shouldReverseSublists());
-        listView.setReverseItems(shouldReverseListItems());
-        listView.setSwapRowsAndColumns(shouldSwapRowsAndColumns());
+    protected boolean shouldReverseListItems() {
+        int rotation = getCurrentRotation();
+        if (rotation == ROTATION_NONE) {
+            return false;
+        }
+        if (getCurrentLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
+            return rotation == ROTATION_LANDSCAPE;
+        }
+        return rotation == ROTATION_SEASCAPE;
     }
 
     @Override
-    public void onUpdateList() {
-        setupListView();
-        super.onUpdateList();
-        updateSeparatedItemSize();
-    }
-
-    /**
-     * If the separated view contains only one item, expand the bounds of that item to take up the
-     * entire view, so that the whole thing is touch-able.
-     */
-    @VisibleForTesting
-    protected void updateSeparatedItemSize() {
-        ViewGroup separated = getSeparatedView();
-        if (separated.getChildCount() == 0) {
-            return;
-        }
-        View firstChild = separated.getChildAt(0);
-        ViewGroup.LayoutParams childParams = firstChild.getLayoutParams();
-
-        if (separated.getChildCount() == 1) {
-            childParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
-            childParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
-        } else {
-            childParams.width = ViewGroup.LayoutParams.WRAP_CONTENT;
-            childParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
-        }
-    }
-
-    @Override
-    protected ListGridLayout getListView() {
-        return (ListGridLayout) super.getListView();
-    }
-
-    @Override
-    protected void removeAllListViews() {
-        ListGridLayout list = getListView();
-        if (list != null) {
-            list.removeAllItems();
-        }
+    protected HardwareBgDrawable getBackgroundDrawable(int backgroundColor) {
+        return null;
     }
 
     @Override
     protected void addToListView(View v, boolean reverse) {
-        ListGridLayout list = getListView();
-        if (list != null) {
-            list.addItem(v);
+        // only add items to the list view if we haven't hit our max yet
+        if (getListView().getChildCount() < MAX_ITEMS) {
+            super.addToListView(v, reverse);
         }
     }
 
-    @Override
-    public void removeAllItems() {
-        ViewGroup separatedList = getSeparatedView();
-        ListGridLayout list = getListView();
-        if (separatedList != null) {
-            separatedList.removeAllViews();
-        }
-        if (list != null) {
-            list.removeAllItems();
-        }
-    }
-
-    /**
-     * Determines whether the ListGridLayout should fill sublists in the reverse order.
-     * Used to account for sublist ordering changing between landscape and seascape views.
-     */
     @VisibleForTesting
-    protected boolean shouldReverseSublists() {
-        if (getCurrentRotation() == ROTATION_SEASCAPE) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Determines whether the ListGridLayout should fill rows first instead of columns.
-     * Used to account for vertical/horizontal changes due to landscape or seascape rotations.
-     */
-    @VisibleForTesting
-    protected boolean shouldSwapRowsAndColumns() {
-        if (getCurrentRotation() == ROTATION_NONE) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    protected boolean shouldReverseListItems() {
-        int rotation = getCurrentRotation();
-        boolean reverse = false; // should we add items to parents in the reverse order?
-        if (rotation == ROTATION_NONE
-                || rotation == ROTATION_SEASCAPE) {
-            reverse = !reverse; // if we're in portrait or seascape, reverse items
-        }
-        if (getCurrentLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
-            reverse = !reverse; // if we're in an RTL language, reverse items (again)
-        }
-        return reverse;
+    protected float getGridItemSize() {
+        return getContext().getResources().getDimension(R.dimen.global_actions_grid_item_height);
     }
 
     @VisibleForTesting
     protected float getAnimationDistance() {
-        int rows = getListView().getRowCount();
-        float gridItemSize = getContext().getResources().getDimension(
-                com.android.systemui.R.dimen.global_actions_grid_item_height);
-        return rows * gridItemSize / 2;
+        return getGridItemSize() / 2;
     }
 
     @Override
     public float getAnimationOffsetX() {
-        switch (getCurrentRotation()) {
-            case ROTATION_LANDSCAPE:
-                return getAnimationDistance();
-            case ROTATION_SEASCAPE:
-                return -getAnimationDistance();
-            default: // Portrait
-                return 0;
-        }
+        return 0;
     }
 
     @Override
     public float getAnimationOffsetY() {
-        if (getCurrentRotation() == ROTATION_NONE) {
-            return getAnimationDistance();
-        }
-        return 0;
+        return -getAnimationDistance();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsLayout.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsLayout.java
index f755a93..183ee45 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsLayout.java
@@ -42,16 +42,30 @@
     }
 
     private void setBackgrounds() {
-        int gridBackgroundColor = getResources().getColor(
+        ViewGroup listView = getListView();
+        int listBgColor = getResources().getColor(
                 R.color.global_actions_grid_background, null);
-        int separatedBackgroundColor = getResources().getColor(
-                R.color.global_actions_separated_background, null);
-        HardwareBgDrawable listBackground  = new HardwareBgDrawable(true, true, getContext());
-        HardwareBgDrawable separatedBackground = new HardwareBgDrawable(true, true, getContext());
-        listBackground.setTint(gridBackgroundColor);
-        separatedBackground.setTint(separatedBackgroundColor);
-        getListView().setBackground(listBackground);
-        getSeparatedView().setBackground(separatedBackground);
+        HardwareBgDrawable listBackground = getBackgroundDrawable(listBgColor);
+        if (listBackground != null) {
+            listView.setBackground(listBackground);
+        }
+
+        ViewGroup separatedView = getSeparatedView();
+
+        if (separatedView != null) {
+            int separatedBgColor = getResources().getColor(
+                    R.color.global_actions_separated_background, null);
+            HardwareBgDrawable separatedBackground = getBackgroundDrawable(separatedBgColor);
+            if (separatedBackground != null) {
+                getSeparatedView().setBackground(separatedBackground);
+            }
+        }
+    }
+
+    protected HardwareBgDrawable getBackgroundDrawable(int backgroundColor) {
+        HardwareBgDrawable background = new HardwareBgDrawable(true, true, getContext());
+        background.setTint(backgroundColor);
+        return background;
     }
 
     @Override
@@ -74,10 +88,16 @@
     }
 
     protected void addToSeparatedView(View v, boolean reverse) {
-        if (reverse) {
-            getSeparatedView().addView(v, 0);
+        ViewGroup separated = getSeparatedView();
+        if (separated != null) {
+            if (reverse) {
+                separated.addView(v, 0);
+            } else {
+                separated.addView(v);
+            }
         } else {
-            getSeparatedView().addView(v);
+            // if no separated view exists, just use the list view
+            addToListView(v, reverse);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 83a6d75..b1db7df 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -86,6 +86,7 @@
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.UiBackground;
+import com.android.systemui.keyguard.dagger.KeyguardModule;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.statusbar.phone.BiometricUnlockController;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
@@ -100,9 +101,6 @@
 import java.util.ArrayList;
 import java.util.concurrent.Executor;
 
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
 import dagger.Lazy;
 
 /**
@@ -146,7 +144,6 @@
  * directly to the keyguard UI is posted to a {@link android.os.Handler} to ensure it is taken on the UI
  * thread of the keyguard.
  */
-@Singleton
 public class KeyguardViewMediator extends SystemUI {
     private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000;
     private static final long KEYGUARD_DONE_PENDING_TIMEOUT_MS = 3000;
@@ -688,7 +685,9 @@
         }
     };
 
-    @Inject
+    /**
+     * Injected constructor. See {@link KeyguardModule}.
+     */
     public KeyguardViewMediator(
             Context context,
             FalsingManager falsingManager,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
new file mode 100644
index 0000000..2c023ca
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyguard.dagger;
+
+import android.content.Context;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.dagger.qualifiers.UiBackground;
+import com.android.systemui.keyguard.DismissCallbackRegistry;
+import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
+import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+
+import java.util.concurrent.Executor;
+
+import javax.inject.Singleton;
+
+import dagger.Lazy;
+import dagger.Module;
+import dagger.Provides;
+
+/**
+ * Dagger Module providing {@link StatusBar}.
+ */
+@Module
+public class KeyguardModule {
+    /**
+     * Provides our instance of KeyguardViewMediator which is considered optional.
+     */
+    @Provides
+    @Singleton
+    public static KeyguardViewMediator newKeyguardViewMediator(
+            Context context,
+            FalsingManager falsingManager,
+            LockPatternUtils lockPatternUtils,
+            BroadcastDispatcher broadcastDispatcher,
+            NotificationShadeWindowController notificationShadeWindowController,
+            Lazy<StatusBarKeyguardViewManager> statusBarKeyguardViewManagerLazy,
+            DismissCallbackRegistry dismissCallbackRegistry,
+            @UiBackground Executor uiBgExecutor) {
+        return new KeyguardViewMediator(
+                context,
+                falsingManager,
+                lockPatternUtils,
+                broadcastDispatcher,
+                notificationShadeWindowController,
+                statusBarKeyguardViewManagerLazy,
+                dismissCallbackRegistry,
+                uiBgExecutor);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/model/SysUiState.java b/packages/SystemUI/src/com/android/systemui/model/SysUiState.java
index 029ab43..a827f59 100644
--- a/packages/SystemUI/src/com/android/systemui/model/SysUiState.java
+++ b/packages/SystemUI/src/com/android/systemui/model/SysUiState.java
@@ -19,6 +19,7 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 
 import android.annotation.NonNull;
+import android.util.Log;
 
 import com.android.systemui.Dumpable;
 import com.android.systemui.shared.system.QuickStepContract;
@@ -37,6 +38,9 @@
 @Singleton
 public class SysUiState implements Dumpable {
 
+    private static final String TAG = SysUiState.class.getSimpleName();
+    public static final boolean DEBUG = true;
+
     private @QuickStepContract.SystemUiStateFlags int mFlags;
     private final List<SysUiStateCallback> mCallbacks = new ArrayList<>();
     private int mFlagsToSet = 0;
@@ -76,6 +80,7 @@
     private void updateFlags(int displayId) {
         if (displayId != DEFAULT_DISPLAY) {
             // Ignore non-default displays for now
+            Log.w(TAG, "Ignoring flag update for display: " + displayId, new Throwable());
             return;
         }
 
@@ -87,6 +92,9 @@
 
     /** Notify all those who are registered that the state has changed. */
     private void notifyAndSetSystemUiStateChanged(int newFlags, int oldFlags) {
+        if (DEBUG) {
+            Log.d(TAG, "SysUiState changed: old=" + oldFlags + " new=" + newFlags);
+        }
         if (newFlags != oldFlags) {
             mCallbacks.forEach(callback -> callback.onSystemUiStateChanged(newFlags));
             mFlags = newFlags;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index d4af154..8cd70cf 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -61,9 +61,9 @@
 import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
 import com.android.systemui.qs.QSDetail.Callback;
 import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.phone.PhoneStatusBarView;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager;
+import com.android.systemui.statusbar.phone.StatusBarWindowView;
 import com.android.systemui.statusbar.phone.StatusIconContainer;
 import com.android.systemui.statusbar.policy.Clock;
 import com.android.systemui.statusbar.policy.DateView;
@@ -146,6 +146,7 @@
         }
     };
     private boolean mHasTopCutout = false;
+    private int mRoundedCornerPadding = 0;
 
     @Inject
     public QuickStatusBarHeader(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
@@ -325,6 +326,9 @@
         Resources resources = mContext.getResources();
         updateMinimumHeight();
 
+        mRoundedCornerPadding = resources.getDimensionPixelSize(
+                R.dimen.rounded_corner_content_padding);
+
         // Update height for a few views, especially due to landscape mode restricting space.
         mHeaderTextContainerView.getLayoutParams().height =
                 resources.getDimensionPixelSize(R.dimen.qs_header_tooltip_height);
@@ -432,16 +436,23 @@
     @Override
     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
         DisplayCutout cutout = insets.getDisplayCutout();
-        Pair<Integer, Integer> padding = PhoneStatusBarView.cornerCutoutMargins(
-                cutout, getDisplay());
-        if (padding == null) {
-            mSystemIconsView.setPaddingRelative(
-                    getResources().getDimensionPixelSize(R.dimen.status_bar_padding_start), 0,
-                    getResources().getDimensionPixelSize(R.dimen.status_bar_padding_end), 0);
-        } else {
-            mSystemIconsView.setPadding(padding.first, 0, padding.second, 0);
 
-        }
+        // Handle padding of QuickStatusBarHeader
+        Pair<Integer, Integer> cornerCutoutPadding = StatusBarWindowView.cornerCutoutMargins(
+                cutout, getDisplay());
+        Pair<Integer, Integer> padding =
+                StatusBarWindowView.paddingNeededForCutoutAndRoundedCorner(
+                        cutout, cornerCutoutPadding, mRoundedCornerPadding);
+        setPadding(padding.first, 0, padding.second, getPaddingBottom());
+
+        // Handle padding of SystemIconsView
+        final int waterfallTopInset = cutout == null ? 0 : cutout.getWaterfallInsets().top;
+        mSystemIconsView.setPaddingRelative(
+                getResources().getDimensionPixelSize(R.dimen.status_bar_padding_start),
+                waterfallTopInset,
+                getResources().getDimensionPixelSize(R.dimen.status_bar_padding_end),
+                0);
+
         return super.onApplyWindowInsets(insets);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
index 88a30a1..84891ec 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
@@ -31,20 +31,26 @@
 /**
  * Quick settings tile for screen recording
  */
-public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> {
+public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState>
+        implements RecordingController.RecordingStateChangeCallback {
     private static final String TAG = "ScreenRecordTile";
     private RecordingController mController;
     private long mMillisUntilFinished = 0;
+    private Callback mCallback = new Callback();
 
     @Inject
     public ScreenRecordTile(QSHost host, RecordingController controller) {
         super(host);
         mController = controller;
+        mController.observe(this, mCallback);
     }
 
     @Override
     public BooleanState newTileState() {
-        return new BooleanState();
+        BooleanState state = new BooleanState();
+        state.label = mContext.getString(R.string.quick_settings_screen_record_label);
+        state.handlesLongClick = false;
+        return state;
     }
 
     @Override
@@ -59,24 +65,13 @@
         refreshState();
     }
 
-    /**
-     * Refresh tile state
-     * @param millisUntilFinished Time until countdown completes, or 0 if not counting down
-     */
-    public void refreshState(long millisUntilFinished) {
-        mMillisUntilFinished = millisUntilFinished;
-        refreshState();
-    }
-
     @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
         boolean isStarting = mController.isStarting();
         boolean isRecording = mController.isRecording();
 
-        state.label = mContext.getString(R.string.quick_settings_screen_record_label);
         state.value = isRecording || isStarting;
         state.state = (isRecording || isStarting) ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
-        state.handlesLongClick = false;
 
         if (isRecording) {
             state.icon = ResourceIcon.get(R.drawable.ic_qs_screenrecord);
@@ -125,4 +120,22 @@
         Log.d(TAG, "Stopping recording from tile");
         mController.stopRecording();
     }
+
+    private final class Callback implements RecordingController.RecordingStateChangeCallback {
+        @Override
+        public void onCountdown(long millisUntilFinished) {
+            mMillisUntilFinished = millisUntilFinished;
+            refreshState();
+        }
+
+        @Override
+        public void onRecordingStart() {
+            refreshState();
+        }
+
+        @Override
+        public void onRecordingEnd() {
+            refreshState();
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 9f64b39..34cad51 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -380,6 +380,14 @@
                     taskId, mHandler, null);
         }
 
+        @Override
+        public void setSplitScreenMinimized(boolean minimized) {
+            Divider divider = mDividerOptional.get();
+            if (divider != null) {
+                divider.setMinimized(minimized);
+            }
+        }
+
         private boolean verifyCaller(String reason) {
             final int callerId = Binder.getCallingUserHandle().getIdentifier();
             if (callerId != mCurrentBoundedUserId) {
@@ -410,6 +418,9 @@
     private final ServiceConnection mOverviewServiceConnection = new ServiceConnection() {
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
+            if (SysUiState.DEBUG) {
+                Log.d(TAG_OPS, "Overview proxy service connected");
+            }
             mConnectionBackoffAttempts = 0;
             mHandler.removeCallbacks(mDeferredConnectionCallback);
             try {
@@ -562,6 +573,10 @@
                 mNavBarController.getDefaultNavigationBarFragment();
         final NavigationBarView navBarView =
                 mNavBarController.getNavigationBarView(mContext.getDisplayId());
+        if (SysUiState.DEBUG) {
+            Log.d(TAG_OPS, "Updating sysui state flags: navBarFragment=" + navBarFragment
+                    + " navBarView=" + navBarView);
+        }
 
         if (navBarFragment != null) {
             navBarFragment.updateSystemUiStateFlags(-1);
@@ -576,6 +591,10 @@
     }
 
     private void notifySystemUiStateFlags(int flags) {
+        if (SysUiState.DEBUG) {
+            Log.d(TAG_OPS, "Notifying sysui state change to overview service: proxy="
+                    + mOverviewProxy + " flags=" + flags);
+        }
         try {
             if (mOverviewProxy != null) {
                 mOverviewProxy.onSystemUiStateChanged(flags);
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
index 188501e..6ad9c40 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
@@ -24,6 +24,9 @@
 import android.util.Log;
 
 import com.android.systemui.qs.tiles.ScreenRecordTile;
+import com.android.systemui.statusbar.policy.CallbackController;
+
+import java.util.ArrayList;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
@@ -32,7 +35,8 @@
  * Helper class to initiate a screen recording
  */
 @Singleton
-public class RecordingController {
+public class RecordingController
+        implements CallbackController<RecordingController.RecordingStateChangeCallback> {
     private static final String TAG = "RecordingController";
     private static final String SYSUI_PACKAGE = "com.android.systemui";
     private static final String SYSUI_SCREENRECORD_LAUNCHER =
@@ -41,10 +45,11 @@
     private final Context mContext;
     private boolean mIsStarting;
     private boolean mIsRecording;
-    private ScreenRecordTile mTileToUpdate;
     private PendingIntent mStopIntent;
     private CountDownTimer mCountDownTimer = null;
 
+    private ArrayList<RecordingStateChangeCallback> mListeners = new ArrayList<>();
+
     /**
      * Create a new RecordingController
      * @param context Context for the controller
@@ -63,10 +68,7 @@
         final Intent intent = new Intent();
         intent.setComponent(launcherComponent);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        intent.putExtra("com.android.systemui.screenrecord.EXTRA_SETTINGS_ONLY", true);
         mContext.startActivity(intent);
-
-        mTileToUpdate = tileToUpdate;
     }
 
     /**
@@ -82,16 +84,21 @@
         mCountDownTimer = new CountDownTimer(ms, 1000) {
             @Override
             public void onTick(long millisUntilFinished) {
-                refreshTile(millisUntilFinished);
+                for (RecordingStateChangeCallback cb : mListeners) {
+                    cb.onCountdown(millisUntilFinished);
+                }
             }
 
             @Override
             public void onFinish() {
                 mIsStarting = false;
                 mIsRecording = true;
-                refreshTile();
+                for (RecordingStateChangeCallback cb : mListeners) {
+                    cb.onRecordingEnd();
+                }
                 try {
                     startIntent.send();
+                    Log.d(TAG, "sent start intent");
                 } catch (PendingIntent.CanceledException e) {
                     Log.e(TAG, "Pending intent was cancelled: " + e.getMessage());
                 }
@@ -101,18 +108,6 @@
         mCountDownTimer.start();
     }
 
-    private void refreshTile() {
-        refreshTile(0);
-    }
-
-    private void refreshTile(long millisUntilFinished) {
-        if (mTileToUpdate != null) {
-            mTileToUpdate.refreshState(millisUntilFinished);
-        } else {
-            Log.e(TAG, "No tile to refresh");
-        }
-    }
-
     /**
      * Cancel a countdown in progress. This will not stop the recording if it already started.
      */
@@ -123,7 +118,10 @@
             Log.e(TAG, "Timer was null");
         }
         mIsStarting = false;
-        refreshTile();
+
+        for (RecordingStateChangeCallback cb : mListeners) {
+            cb.onRecordingEnd();
+        }
     }
 
     /**
@@ -152,7 +150,10 @@
         } catch (PendingIntent.CanceledException e) {
             Log.e(TAG, "Error stopping: " + e.getMessage());
         }
-        refreshTile();
+
+        for (RecordingStateChangeCallback cb : mListeners) {
+            cb.onRecordingEnd();
+        }
     }
 
     /**
@@ -161,6 +162,44 @@
      */
     public void updateState(boolean isRecording) {
         mIsRecording = isRecording;
-        refreshTile();
+        for (RecordingStateChangeCallback cb : mListeners) {
+            if (isRecording) {
+                cb.onRecordingStart();
+            } else {
+                cb.onRecordingEnd();
+            }
+        }
+    }
+
+    @Override
+    public void addCallback(RecordingStateChangeCallback listener) {
+        mListeners.add(listener);
+    }
+
+    @Override
+    public void removeCallback(RecordingStateChangeCallback listener) {
+        mListeners.remove(listener);
+    }
+
+    /**
+     * A callback for changes in the screen recording state
+     */
+    public interface RecordingStateChangeCallback {
+        /**
+         * Called when a countdown to recording has updated
+         *
+         * @param millisUntilFinished Time in ms remaining in the countdown
+         */
+        default void onCountdown(long millisUntilFinished) {}
+
+        /**
+         * Called when a screen recording has started
+         */
+        default void onRecordingStart() {}
+
+        /**
+         * Called when a screen recording has ended
+         */
+        default void onRecordingEnd() {}
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 197fe21..9e1e347 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -27,7 +27,6 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.app.ActivityManager;
@@ -58,6 +57,7 @@
 import android.provider.DeviceConfig;
 import android.util.DisplayMetrics;
 import android.util.Log;
+import android.util.MathUtils;
 import android.util.Slog;
 import android.view.Display;
 import android.view.LayoutInflater;
@@ -68,6 +68,7 @@
 import android.view.ViewOutlineProvider;
 import android.view.ViewTreeObserver;
 import android.view.WindowManager;
+import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.widget.FrameLayout;
 import android.widget.HorizontalScrollView;
@@ -136,13 +137,11 @@
 
     private static final String TAG = "GlobalScreenshot";
 
-    private static final int SCREENSHOT_FLASH_TO_PEAK_DURATION = 130;
-    private static final int SCREENSHOT_DROP_IN_DURATION = 430;
-    private static final int SCREENSHOT_DROP_OUT_DELAY = 500;
-    private static final int SCREENSHOT_DROP_OUT_DURATION = 430;
-    private static final int SCREENSHOT_DROP_OUT_SCALE_DURATION = 370;
-    private static final float BACKGROUND_ALPHA = 0.5f;
-    private static final float SCREENSHOT_DROP_IN_MIN_SCALE = 0.725f;
+    private static final long SCREENSHOT_FLASH_IN_DURATION_MS = 133;
+    private static final long SCREENSHOT_FLASH_OUT_DURATION_MS = 217;
+    private static final long SCREENSHOT_TO_CORNER_X_DURATION_MS = 234;
+    private static final long SCREENSHOT_TO_CORNER_Y_DURATION_MS = 500;
+    private static final long SCREENSHOT_TO_CORNER_SCALE_DURATION_MS = 234;
     private static final float ROUNDED_CORNER_RADIUS = .05f;
     private static final long SCREENSHOT_CORNER_TIMEOUT_MILLIS = 6000;
     private static final int MESSAGE_CORNER_TIMEOUT = 2;
@@ -166,18 +165,21 @@
     private final FrameLayout mDismissButton;
 
     private Bitmap mScreenBitmap;
-    private AnimatorSet mScreenshotAnimation;
+    private Animator mScreenshotAnimation;
 
     private float mScreenshotOffsetXPx;
     private float mScreenshotOffsetYPx;
     private float mScreenshotHeightPx;
-    private float mCornerScale;
     private float mDismissButtonSize;
+    private float mCornerSizeX;
 
     private AsyncTask<Void, Void, Void> mSaveInBgTask;
 
     private MediaActionSound mCameraSound;
 
+    // standard material ease
+    private final Interpolator mFastOutSlowIn;
+
     private final Handler mScreenshotHandler = new Handler(Looper.getMainLooper()) {
         @Override
         public void handleMessage(Message msg) {
@@ -227,6 +229,8 @@
         mScreenshotLayout.setFocusable(true);
         mScreenshotSelectorView.setFocusable(true);
         mScreenshotSelectorView.setFocusableInTouchMode(true);
+        mScreenshotView.setPivotX(0);
+        mScreenshotView.setPivotY(0);
 
         // Setup the window that we are going to use
         mWindowLayoutParams = new WindowManager.LayoutParams(
@@ -250,10 +254,12 @@
         mScreenshotOffsetYPx = resources.getDimensionPixelSize(R.dimen.screenshot_offset_y);
         mScreenshotHeightPx =
                 resources.getDimensionPixelSize(R.dimen.screenshot_action_container_offset_y);
-        mCornerScale = resources.getDimensionPixelSize(R.dimen.global_screenshot_x_scale)
-                / (float) mDisplayMetrics.widthPixels;
         mDismissButtonSize = resources.getDimensionPixelSize(
                 R.dimen.screenshot_dismiss_button_tappable_size);
+        mCornerSizeX = resources.getDimensionPixelSize(R.dimen.global_screenshot_x_scale);
+
+        mFastOutSlowIn =
+                AnimationUtils.loadInterpolator(mContext, android.R.interpolator.fast_out_slow_in);
 
         // Setup the Camera shutter sound
         mCameraSound = new MediaActionSound();
@@ -305,7 +311,9 @@
         int width = crop.width();
         int height = crop.height();
 
-        takeScreenshot(SurfaceControl.screenshot(crop, width, height, rot), finisher, null);
+        Rect screenRect = new Rect(0, 0, mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels);
+
+        takeScreenshot(SurfaceControl.screenshot(crop, width, height, rot), finisher, screenRect);
     }
 
     private void takeScreenshot(Bitmap screenshot, Consumer<Uri> finisher, Rect screenRect) {
@@ -325,7 +333,7 @@
         mScreenshotLayout.getViewTreeObserver().addOnComputeInternalInsetsListener(this);
 
         // Start the post-screenshot animation
-        startAnimation(finisher, mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels,
+        startAnimation(finisher, screenRect.width(), screenRect.height(),
                 screenRect);
     }
 
@@ -406,7 +414,6 @@
         mScreenshotLayout.getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
 
         // Clear any references to the bitmap
-        mScreenBitmap = null;
         mScreenshotView.setImageBitmap(null);
         mActionsContainer.setVisibility(View.GONE);
         mBackgroundView.setVisibility(View.GONE);
@@ -430,21 +437,8 @@
 
         // Add the view for the animation
         mScreenshotView.setImageBitmap(mScreenBitmap);
-        mScreenshotLayout.requestFocus();
 
-        // Setup the animation with the screenshot just taken
-        if (mScreenshotAnimation != null) {
-            if (mScreenshotAnimation.isStarted()) {
-                mScreenshotAnimation.end();
-            }
-            mScreenshotAnimation.removeAllListeners();
-        }
-
-        ValueAnimator screenshotDropInAnim = screenRect != null ? createRectAnimation(screenRect)
-                : createScreenshotDropInAnimation();
-        ValueAnimator screenshotToCornerAnimation = createScreenshotToCornerAnimation(w, h);
-        mScreenshotAnimation = new AnimatorSet();
-        mScreenshotAnimation.playSequentially(screenshotDropInAnim, screenshotToCornerAnimation);
+        mScreenshotAnimation = createScreenshotDropInAnimation(w, h, screenRect);
 
         saveScreenshotInWorkerThread(finisher, new ActionsReadyListener() {
             @Override
@@ -487,147 +481,64 @@
         });
     }
 
-    private ValueAnimator createRectAnimation(Rect rect) {
-        mScreenshotView.setAdjustViewBounds(true);
-        mScreenshotView.setMaxHeight(rect.height());
-        mScreenshotView.setMaxWidth(rect.width());
+    private AnimatorSet createScreenshotDropInAnimation(int width, int height, Rect bounds) {
+        float cornerScale = mCornerSizeX / (float) width;
 
-        final float flashPeakDurationPct = ((float) (SCREENSHOT_FLASH_TO_PEAK_DURATION)
-                / SCREENSHOT_DROP_IN_DURATION);
-        final float flashDurationPct = 2f * flashPeakDurationPct;
-        final Interpolator scaleInterpolator = x -> {
-            // We start scaling when the flash is at it's peak
-            if (x < flashPeakDurationPct) {
-                return 0;
+        AnimatorSet dropInAnimation = new AnimatorSet();
+        ValueAnimator flashInAnimator = ValueAnimator.ofFloat(0, 1);
+        flashInAnimator.setDuration(SCREENSHOT_FLASH_IN_DURATION_MS);
+        flashInAnimator.setInterpolator(mFastOutSlowIn);
+        flashInAnimator.addUpdateListener(animation ->
+                mScreenshotFlash.setAlpha((float) animation.getAnimatedValue()));
+
+        ValueAnimator flashOutAnimator = ValueAnimator.ofFloat(1, 0);
+        flashOutAnimator.setDuration(SCREENSHOT_FLASH_OUT_DURATION_MS);
+        flashOutAnimator.setInterpolator(mFastOutSlowIn);
+        flashOutAnimator.addUpdateListener(animation ->
+                mScreenshotFlash.setAlpha((float) animation.getAnimatedValue()));
+
+        final PointF startPos = new PointF((float) bounds.left, (float) bounds.top);
+        final PointF finalPos = new PointF(mScreenshotOffsetXPx,
+                mDisplayMetrics.heightPixels - mScreenshotOffsetYPx - height * cornerScale);
+
+        ValueAnimator toCorner = ValueAnimator.ofFloat(0, 1);
+        toCorner.setDuration(SCREENSHOT_TO_CORNER_Y_DURATION_MS);
+        float xPositionPct =
+                SCREENSHOT_TO_CORNER_X_DURATION_MS / (float) SCREENSHOT_TO_CORNER_Y_DURATION_MS;
+        float scalePct =
+                SCREENSHOT_TO_CORNER_SCALE_DURATION_MS / (float) SCREENSHOT_TO_CORNER_Y_DURATION_MS;
+        toCorner.addUpdateListener(animation -> {
+            float t = animation.getAnimatedFraction();
+            if (t < scalePct) {
+                float scale = MathUtils.lerp(
+                        1, cornerScale, mFastOutSlowIn.getInterpolation(t / scalePct));
+                mScreenshotView.setScaleX(scale);
+                mScreenshotView.setScaleY(scale);
             }
-            return (x - flashDurationPct) / (1f - flashDurationPct);
-        };
 
-        ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
-        anim.setDuration(SCREENSHOT_DROP_IN_DURATION);
-        anim.addListener(new AnimatorListenerAdapter() {
+            if (t < xPositionPct) {
+                mScreenshotView.setX(MathUtils.lerp(
+                        startPos.x, finalPos.x, mFastOutSlowIn.getInterpolation(t / xPositionPct)));
+            }
+            mScreenshotView.setY(MathUtils.lerp(
+                    startPos.y, finalPos.y, mFastOutSlowIn.getInterpolation(t)));
+        });
+
+        toCorner.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationStart(Animator animation) {
-                mBackgroundView.setAlpha(0f);
-                mBackgroundView.setVisibility(View.VISIBLE);
-                mScreenshotView.setAlpha(0f);
-                mScreenshotView.setElevation(0f);
-                mScreenshotView.setTranslationX(0f);
-                mScreenshotView.setTranslationY(0f);
-                mScreenshotView.setScaleX(1f);
-                mScreenshotView.setScaleY(1f);
+                super.onAnimationStart(animation);
                 mScreenshotView.setVisibility(View.VISIBLE);
             }
         });
-        anim.addUpdateListener(animation -> {
-            float t = (Float) animation.getAnimatedValue();
-            mBackgroundView.setAlpha(scaleInterpolator.getInterpolation(t) * BACKGROUND_ALPHA);
-            mScreenshotView.setAlpha(t);
-        });
-        return anim;
-    }
 
-    private ValueAnimator createScreenshotDropInAnimation() {
-        final float flashPeakDurationPct = ((float) (SCREENSHOT_FLASH_TO_PEAK_DURATION)
-                / SCREENSHOT_DROP_IN_DURATION);
-        final float flashDurationPct = 2f * flashPeakDurationPct;
-        final Interpolator flashAlphaInterpolator = new Interpolator() {
-            @Override
-            public float getInterpolation(float x) {
-                // Flash the flash view in and out quickly
-                if (x <= flashDurationPct) {
-                    return (float) Math.sin(Math.PI * (x / flashDurationPct));
-                }
-                return 0;
-            }
-        };
-        final Interpolator scaleInterpolator = new Interpolator() {
-            @Override
-            public float getInterpolation(float x) {
-                // We start scaling when the flash is at it's peak
-                if (x < flashPeakDurationPct) {
-                    return 0;
-                }
-                return (x - flashDurationPct) / (1f - flashDurationPct);
-            }
-        };
+        mScreenshotFlash.setAlpha(0f);
+        mScreenshotFlash.setVisibility(View.VISIBLE);
 
-        ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
-        anim.setDuration(SCREENSHOT_DROP_IN_DURATION);
-        anim.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationStart(Animator animation) {
-                mBackgroundView.setAlpha(0f);
-                mBackgroundView.setVisibility(View.VISIBLE);
-                mScreenshotView.setAlpha(0f);
-                mScreenshotView.setTranslationX(0f);
-                mScreenshotView.setTranslationY(0f);
-                mScreenshotView.setScaleX(1);
-                mScreenshotView.setScaleY(1);
-                mScreenshotView.setVisibility(View.VISIBLE);
-                mScreenshotFlash.setAlpha(0f);
-                mScreenshotFlash.setVisibility(View.VISIBLE);
-            }
+        dropInAnimation.play(flashOutAnimator).after(flashInAnimator);
+        dropInAnimation.play(flashOutAnimator).with(toCorner);
 
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                mScreenshotFlash.setVisibility(View.GONE);
-            }
-        });
-        anim.addUpdateListener(new AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                float t = (Float) animation.getAnimatedValue();
-                float scaleT = 1 - (scaleInterpolator.getInterpolation(t)
-                        * (1 - SCREENSHOT_DROP_IN_MIN_SCALE));
-                mBackgroundView.setAlpha(scaleInterpolator.getInterpolation(t) * BACKGROUND_ALPHA);
-                mScreenshotView.setAlpha(t);
-                mScreenshotView.setScaleX(scaleT);
-                mScreenshotView.setScaleY(scaleT);
-                mScreenshotFlash.setAlpha(flashAlphaInterpolator.getInterpolation(t));
-            }
-        });
-        return anim;
-    }
-
-    private ValueAnimator createScreenshotToCornerAnimation(int w, int h) {
-        ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
-        anim.setStartDelay(SCREENSHOT_DROP_OUT_DELAY);
-
-        final float scaleDurationPct =
-                (float) SCREENSHOT_DROP_OUT_SCALE_DURATION / SCREENSHOT_DROP_OUT_DURATION;
-        final Interpolator scaleInterpolator = new Interpolator() {
-            @Override
-            public float getInterpolation(float x) {
-                if (x < scaleDurationPct) {
-                    // Decelerate, and scale the input accordingly
-                    return (float) (1f - Math.pow(1f - (x / scaleDurationPct), 2f));
-                }
-                return 1f;
-            }
-        };
-
-        // Determine the bounds of how to scale
-        float halfScreenWidth = w / 2f;
-        float halfScreenHeight = h / 2f;
-        final PointF finalPos = new PointF(
-                -halfScreenWidth + mCornerScale * halfScreenWidth + mScreenshotOffsetXPx,
-                halfScreenHeight - mCornerScale * halfScreenHeight - mScreenshotOffsetYPx);
-
-        // Animate the screenshot to the bottom left corner
-        anim.setDuration(SCREENSHOT_DROP_OUT_DURATION);
-        anim.addUpdateListener(animation -> {
-            float t = (Float) animation.getAnimatedValue();
-            float scaleT = (SCREENSHOT_DROP_IN_MIN_SCALE)
-                    - scaleInterpolator.getInterpolation(t)
-                    * (SCREENSHOT_DROP_IN_MIN_SCALE - mCornerScale);
-            mBackgroundView.setAlpha((1f - t) * BACKGROUND_ALPHA);
-            mScreenshotView.setScaleX(scaleT);
-            mScreenshotView.setScaleY(scaleT);
-            mScreenshotView.setTranslationX(t * finalPos.x);
-            mScreenshotView.setTranslationY(t * finalPos.y);
-        });
-        anim.addListener(new AnimatorListenerAdapter() {
+        dropInAnimation.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
                 super.onAnimationEnd(animation);
@@ -638,7 +549,8 @@
                 mDismissButton.setVisibility(View.VISIBLE);
             }
         });
-        return anim;
+
+        return dropInAnimation;
     }
 
     private ValueAnimator createScreenshotActionsShadeAnimation(
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
index 92236ae..7de70f5 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
@@ -219,11 +219,6 @@
             mParams.mActionsReadyListener.onActionsReady(null, null, null);
         }
 
-        // Recycle the bitmap data
-        if (image != null) {
-            image.recycle();
-        }
-
         return null;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
index 5ae0954..4f20492 100644
--- a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
@@ -22,10 +22,8 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.os.RemoteException;
-import android.util.Log;
 import android.view.IWindowManager;
 import android.view.KeyEvent;
-import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 
 import com.android.internal.policy.DividerSnapAlgorithm;
@@ -94,29 +92,24 @@
     }
 
     private void handleDockKey(long shortcutCode) {
-        try {
-            int dockSide = mWindowManagerService.getDockedStackSide();
-            if (dockSide == WindowManager.DOCKED_INVALID) {
-                // Split the screen
-                mRecents.splitPrimaryTask((shortcutCode == SC_DOCK_LEFT)
-                        ? SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT
-                        : SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT, null, -1);
-            } else {
-                // If there is already a docked window, we respond by resizing the docking pane.
-                DividerView dividerView = mDivider.getView();
-                DividerSnapAlgorithm snapAlgorithm = dividerView.getSnapAlgorithm();
-                int dividerPosition = dividerView.getCurrentPosition();
-                DividerSnapAlgorithm.SnapTarget currentTarget =
-                        snapAlgorithm.calculateNonDismissingSnapTarget(dividerPosition);
-                DividerSnapAlgorithm.SnapTarget target = (shortcutCode == SC_DOCK_LEFT)
-                        ? snapAlgorithm.getPreviousTarget(currentTarget)
-                        : snapAlgorithm.getNextTarget(currentTarget);
-                dividerView.startDragging(true /* animate */, false /* touching */);
-                dividerView.stopDragging(target.position, 0f, false /* avoidDismissStart */,
-                        true /* logMetrics */);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "handleDockKey() failed.");
+        if (mDivider == null || !mDivider.inSplitMode()) {
+            // Split the screen
+            mRecents.splitPrimaryTask((shortcutCode == SC_DOCK_LEFT)
+                    ? SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT
+                    : SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT, null, -1);
+        } else {
+            // If there is already a docked window, we respond by resizing the docking pane.
+            DividerView dividerView = mDivider.getView();
+            DividerSnapAlgorithm snapAlgorithm = dividerView.getSnapAlgorithm();
+            int dividerPosition = dividerView.getCurrentPosition();
+            DividerSnapAlgorithm.SnapTarget currentTarget =
+                    snapAlgorithm.calculateNonDismissingSnapTarget(dividerPosition);
+            DividerSnapAlgorithm.SnapTarget target = (shortcutCode == SC_DOCK_LEFT)
+                    ? snapAlgorithm.getPreviousTarget(currentTarget)
+                    : snapAlgorithm.getNextTarget(currentTarget);
+            dividerView.startDragging(true /* animate */, false /* touching */);
+            dividerView.stopDragging(target.position, 0f, false /* avoidDismissStart */,
+                    true /* logMetrics */);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
index 90cc0e57..ba9eb4a 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
@@ -17,69 +17,281 @@
 package com.android.systemui.stackdivider;
 
 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.Display.DEFAULT_DISPLAY;
 
+import android.app.ActivityTaskManager;
 import android.content.Context;
 import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.os.Handler;
 import android.os.RemoteException;
+import android.provider.Settings;
 import android.util.Log;
-import android.view.IDockedStackListener;
+import android.util.Slog;
+import android.view.IWindowContainer;
 import android.view.LayoutInflater;
+import android.view.SurfaceControl;
+import android.view.SurfaceSession;
 import android.view.View;
-import android.view.WindowManagerGlobal;
+import android.view.WindowContainerTransaction;
 
+import com.android.internal.policy.DividerSnapAlgorithm;
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
 import com.android.systemui.recents.Recents;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.wm.DisplayChangeController;
+import com.android.systemui.wm.DisplayController;
+import com.android.systemui.wm.DisplayImeController;
+import com.android.systemui.wm.DisplayLayout;
+import com.android.systemui.wm.SystemWindows;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
 import java.util.Optional;
+import java.util.function.Consumer;
+
+import javax.inject.Singleton;
 
 import dagger.Lazy;
 
 /**
  * Controls the docked stack divider.
  */
-public class Divider extends SystemUI implements DividerView.DividerCallbacks {
+@Singleton
+public class Divider extends SystemUI implements DividerView.DividerCallbacks,
+        DisplayController.OnDisplaysChangedListener {
     private static final String TAG = "Divider";
+
+    static final boolean DEBUG = true;
+
+    static final int DEFAULT_APP_TRANSITION_DURATION = 336;
+
     private final Optional<Lazy<Recents>> mRecentsOptionalLazy;
 
     private DividerWindowManager mWindowManager;
     private DividerView mView;
     private final DividerState mDividerState = new DividerState();
-    private DockDividerVisibilityListener mDockDividerVisibilityListener;
     private boolean mVisible = false;
     private boolean mMinimized = false;
     private boolean mAdjustedForIme = false;
     private boolean mHomeStackResizable = false;
     private ForcedResizableInfoActivityController mForcedResizableController;
+    private SystemWindows mSystemWindows;
+    final SurfaceSession mSurfaceSession = new SurfaceSession();
+    private DisplayController mDisplayController;
+    private DisplayImeController mImeController;
 
-    public Divider(Context context, Optional<Lazy<Recents>> recentsOptionalLazy) {
+    // Keeps track of real-time split geometry including snap positions and ime adjustments
+    private SplitDisplayLayout mSplitLayout;
+
+    // Transient: this contains the layout calculated for a new rotation requested by WM. This is
+    // kept around so that we can wait for a matching configuration change and then use the exact
+    // layout that we sent back to WM.
+    private SplitDisplayLayout mRotateSplitLayout;
+
+    private Handler mHandler;
+    private KeyguardStateController mKeyguardStateController;
+
+    private final ArrayList<WeakReference<Consumer<Boolean>>> mDockedStackExistsListeners =
+            new ArrayList<>();
+
+    private SplitScreenTaskOrganizer mSplits = new SplitScreenTaskOrganizer(this);
+
+    private DisplayChangeController.OnDisplayChangingListener mRotationController =
+            (display, fromRotation, toRotation, t) -> {
+                DisplayLayout displayLayout =
+                        new DisplayLayout(mDisplayController.getDisplayLayout(display));
+                SplitDisplayLayout sdl = new SplitDisplayLayout(mContext, displayLayout, mSplits);
+                sdl.rotateTo(toRotation);
+                mRotateSplitLayout = sdl;
+                int position = mMinimized ? mView.mSnapTargetBeforeMinimized.position
+                        : mView.getCurrentPosition();
+                DividerSnapAlgorithm snap = sdl.getSnapAlgorithm();
+                final DividerSnapAlgorithm.SnapTarget target =
+                        snap.calculateNonDismissingSnapTarget(position);
+                sdl.resizeSplits(target.position, t);
+
+                if (inSplitMode()) {
+                    WindowManagerProxy.applyHomeTasksMinimized(sdl, mSplits.mSecondary.token, t);
+                }
+            };
+
+    private IWindowContainer mLastImeTarget = null;
+    private boolean mShouldAdjustForIme = false;
+
+    private DisplayImeController.ImePositionProcessor mImePositionProcessor =
+            new DisplayImeController.ImePositionProcessor() {
+                private int mStartTop = 0;
+                private int mFinalTop = 0;
+                @Override
+                public void onImeStartPositioning(int displayId, int imeTop, int finalImeTop,
+                        boolean showing, SurfaceControl.Transaction t) {
+                    mStartTop = imeTop;
+                    mFinalTop = finalImeTop;
+                    if (showing) {
+                        try {
+                            mLastImeTarget = ActivityTaskManager.getTaskOrganizerController()
+                                    .getImeTarget(displayId);
+                            mShouldAdjustForIme = !mSplitLayout.mDisplayLayout.isLandscape()
+                                    && (mLastImeTarget.asBinder()
+                                    == mSplits.mSecondary.token.asBinder());
+                        } catch (RemoteException e) {
+                            Slog.w(TAG, "Failed to get IME target", e);
+                        }
+                    }
+                    if (!mShouldAdjustForIme) {
+                        setAdjustedForIme(false);
+                        return;
+                    }
+                    mView.setAdjustedForIme(showing, showing
+                            ? DisplayImeController.ANIMATION_DURATION_SHOW_MS
+                            : DisplayImeController.ANIMATION_DURATION_HIDE_MS);
+                    // Reposition the server's secondary split position so that it evaluates
+                    // insets properly.
+                    WindowContainerTransaction wct = new WindowContainerTransaction();
+                    if (showing) {
+                        mSplitLayout.updateAdjustedBounds(finalImeTop, imeTop, finalImeTop);
+                        wct.setBounds(mSplits.mSecondary.token, mSplitLayout.mAdjustedSecondary);
+                    } else {
+                        wct.setBounds(mSplits.mSecondary.token, mSplitLayout.mSecondary);
+                    }
+                    try {
+                        ActivityTaskManager.getTaskOrganizerController()
+                                .applyContainerTransaction(wct, null /* organizer */);
+                    } catch (RemoteException e) {
+                    }
+                    setAdjustedForIme(showing);
+                }
+
+                @Override
+                public void onImePositionChanged(int displayId, int imeTop,
+                        SurfaceControl.Transaction t) {
+                    if (!mShouldAdjustForIme) {
+                        return;
+                    }
+                    mSplitLayout.updateAdjustedBounds(imeTop, mStartTop, mFinalTop);
+                    mView.resizeSplitSurfaces(t, mSplitLayout.mAdjustedPrimary,
+                            mSplitLayout.mAdjustedSecondary);
+                    final boolean showing = mFinalTop < mStartTop;
+                    final float progress = ((float) (imeTop - mStartTop)) / (mFinalTop - mStartTop);
+                    final float fraction = showing ? progress : 1.f - progress;
+                    mView.setResizeDimLayer(t, true /* primary */, fraction * 0.3f);
+                }
+
+                @Override
+                public void onImeEndPositioning(int displayId, int imeTop,
+                        boolean showing, SurfaceControl.Transaction t) {
+                    if (!mShouldAdjustForIme) {
+                        return;
+                    }
+                    mSplitLayout.updateAdjustedBounds(imeTop, mStartTop, mFinalTop);
+                    mView.resizeSplitSurfaces(t, mSplitLayout.mAdjustedPrimary,
+                            mSplitLayout.mAdjustedSecondary);
+                    mView.setResizeDimLayer(t, true /* primary */, showing ? 0.3f : 0.f);
+                }
+            };
+
+    public Divider(Context context, Optional<Lazy<Recents>> recentsOptionalLazy,
+            DisplayController displayController, SystemWindows systemWindows,
+            DisplayImeController imeController, Handler handler,
+            KeyguardStateController keyguardStateController) {
         super(context);
+        mDisplayController = displayController;
+        mSystemWindows = systemWindows;
+        mImeController = imeController;
+        mHandler = handler;
+        mKeyguardStateController = keyguardStateController;
         mRecentsOptionalLazy = recentsOptionalLazy;
+        mForcedResizableController = new ForcedResizableInfoActivityController(context, this);
     }
 
     @Override
     public void start() {
-        mWindowManager = new DividerWindowManager(mContext);
-        update(mContext.getResources().getConfiguration());
-        mDockDividerVisibilityListener = new DockDividerVisibilityListener();
-        try {
-            WindowManagerGlobal.getWindowManagerService().registerDockedStackListener(
-                    mDockDividerVisibilityListener);
-        } catch (Exception e) {
-            Log.e(TAG, "Failed to register docked stack listener", e);
-        }
-        mForcedResizableController = new ForcedResizableInfoActivityController(mContext);
+        mWindowManager = new DividerWindowManager(mSystemWindows);
+        mDisplayController.addDisplayWindowListener(this);
+        // Hide the divider when keyguard is showing. Even though keyguard/statusbar is above
+        // everything, it is actually transparent except for notifications, so we still need to
+        // hide any surfaces that are below it.
+        // TODO(b/148906453): Figure out keyguard dismiss animation for divider view.
+        mKeyguardStateController.addCallback(new KeyguardStateController.Callback() {
+            @Override
+            public void onUnlockedChanged() {
+
+            }
+
+            @Override
+            public void onKeyguardShowingChanged() {
+                if (!inSplitMode() || mView == null || mView.getViewRootImpl() == null
+                        || mView.getViewRootImpl().getSurfaceControl() == null) {
+                    return;
+                }
+                mView.setHidden(mKeyguardStateController.isShowing());
+            }
+
+            @Override
+            public void onKeyguardFadingAwayChanged() {
+
+            }
+        });
+        // Don't initialize the divider or anything until we get the default display.
     }
 
     @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
+    public void onDisplayAdded(int displayId) {
+        if (displayId != DEFAULT_DISPLAY) {
+            return;
+        }
+        mSplitLayout = new SplitDisplayLayout(mDisplayController.getDisplayContext(displayId),
+                mDisplayController.getDisplayLayout(displayId), mSplits);
+        mImeController.addPositionProcessor(mImePositionProcessor);
+        mDisplayController.addDisplayChangingController(mRotationController);
+        try {
+            mSplits.init(ActivityTaskManager.getTaskOrganizerController(), mSurfaceSession);
+            // Set starting tile bounds based on middle target
+            final WindowContainerTransaction tct = new WindowContainerTransaction();
+            int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position;
+            mSplitLayout.resizeSplits(midPos, tct);
+            ActivityTaskManager.getTaskOrganizerController().applyContainerTransaction(tct,
+                    null /* organizer */);
+        } catch (Exception e) {
+            Slog.e(TAG, "Failed to register docked stack listener", e);
+        }
+        update(mDisplayController.getDisplayContext(displayId).getResources().getConfiguration());
+    }
+
+    @Override
+    public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {
+        if (displayId != DEFAULT_DISPLAY) {
+            return;
+        }
+        mSplitLayout = new SplitDisplayLayout(mDisplayController.getDisplayContext(displayId),
+                mDisplayController.getDisplayLayout(displayId), mSplits);
+        if (mRotateSplitLayout == null) {
+            int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position;
+            final WindowContainerTransaction tct = new WindowContainerTransaction();
+            mSplitLayout.resizeSplits(midPos, tct);
+            try {
+                ActivityTaskManager.getTaskOrganizerController().applyContainerTransaction(tct,
+                        null /* organizer */);
+            } catch (RemoteException e) {
+            }
+        } else if (mRotateSplitLayout != null
+                && mSplitLayout.mDisplayLayout.rotation()
+                        == mRotateSplitLayout.mDisplayLayout.rotation()) {
+            mSplitLayout.mPrimary = new Rect(mRotateSplitLayout.mPrimary);
+            mSplitLayout.mSecondary = new Rect(mRotateSplitLayout.mSecondary);
+            mRotateSplitLayout = null;
+        }
         update(newConfig);
     }
 
+    Handler getHandler() {
+        return mHandler;
+    }
+
     public DividerView getView() {
         return mView;
     }
@@ -92,18 +304,25 @@
         return mHomeStackResizable;
     }
 
+    /** {@code true} if this is visible */
+    public boolean inSplitMode() {
+        return mView != null && mView.getVisibility() == View.VISIBLE;
+    }
+
     private void addDivider(Configuration configuration) {
+        Context dctx = mDisplayController.getDisplayContext(mContext.getDisplayId());
         mView = (DividerView)
-                LayoutInflater.from(mContext).inflate(R.layout.docked_stack_divider, null);
-        mView.injectDependencies(mWindowManager, mDividerState, this);
+                LayoutInflater.from(dctx).inflate(R.layout.docked_stack_divider, null);
+        DisplayLayout displayLayout = mDisplayController.getDisplayLayout(mContext.getDisplayId());
+        mView.injectDependencies(mWindowManager, mDividerState, this, mSplits, mSplitLayout);
         mView.setVisibility(mVisible ? View.VISIBLE : View.INVISIBLE);
         mView.setMinimizedDockStack(mMinimized, mHomeStackResizable);
-        final int size = mContext.getResources().getDimensionPixelSize(
+        final int size = dctx.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.docked_stack_divider_thickness);
         final boolean landscape = configuration.orientation == ORIENTATION_LANDSCAPE;
-        final int width = landscape ? size : MATCH_PARENT;
-        final int height = landscape ? MATCH_PARENT : size;
-        mWindowManager.add(mView, width, height);
+        final int width = landscape ? size : displayLayout.width();
+        final int height = landscape ? displayLayout.height() : size;
+        mWindowManager.add(mView, width, height, mContext.getDisplayId());
     }
 
     private void removeDivider() {
@@ -116,65 +335,86 @@
     private void update(Configuration configuration) {
         removeDivider();
         addDivider(configuration);
-        if (mMinimized) {
+        if (mMinimized && mView != null) {
             mView.setMinimizedDockStack(true, mHomeStackResizable);
             updateTouchable();
         }
     }
 
-    private void updateVisibility(final boolean visible) {
-        mView.post(new Runnable() {
-            @Override
-            public void run() {
-                if (mVisible != visible) {
-                    mVisible = visible;
-                    mView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
+    void updateVisibility(final boolean visible) {
+        if (mVisible != visible) {
+            mVisible = visible;
+            mView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
 
-                    // Update state because animations won't finish.
-                    mView.setMinimizedDockStack(mMinimized, mHomeStackResizable);
-                }
+            if (visible) {
+                mView.enterSplitMode(mHomeStackResizable);
+                // Update state because animations won't finish.
+                mView.setMinimizedDockStack(mMinimized, mHomeStackResizable);
+            } else {
+                mView.exitSplitMode();
+                // un-minimize so that next entry triggers minimize anim.
+                mView.setMinimizedDockStack(false /* minimized */, mHomeStackResizable);
             }
-        });
+            // Notify existence listeners
+            synchronized (mDockedStackExistsListeners) {
+                mDockedStackExistsListeners.removeIf(wf -> {
+                    Consumer<Boolean> l = wf.get();
+                    if (l != null) l.accept(visible);
+                    return l == null;
+                });
+            }
+        }
+    }
+
+    private void setHomeStackResizable(boolean resizable) {
+        if (mHomeStackResizable == resizable) {
+            return;
+        }
+        mHomeStackResizable = resizable;
+        if (!inSplitMode()) {
+            return;
+        }
+        WindowManagerProxy.applyHomeTasksMinimized(mSplitLayout, mSplits.mSecondary.token);
     }
 
     private void updateMinimizedDockedStack(final boolean minimized, final long animDuration,
             final boolean isHomeStackResizable) {
-        mView.post(new Runnable() {
-            @Override
-            public void run() {
-                mHomeStackResizable = isHomeStackResizable;
-                if (mMinimized != minimized) {
-                    mMinimized = minimized;
-                    updateTouchable();
-                    if (animDuration > 0) {
-                        mView.setMinimizedDockStack(minimized, animDuration, isHomeStackResizable);
-                    } else {
-                        mView.setMinimizedDockStack(minimized, isHomeStackResizable);
-                    }
-                }
+        setHomeStackResizable(isHomeStackResizable);
+        if (animDuration > 0) {
+            mView.setMinimizedDockStack(minimized, animDuration, isHomeStackResizable);
+        } else {
+            mView.setMinimizedDockStack(minimized, isHomeStackResizable);
+        }
+        updateTouchable();
+    }
+
+    /** Switch to minimized state if appropriate */
+    public void setMinimized(final boolean minimized) {
+        mHandler.post(() -> {
+            if (!inSplitMode()) {
+                return;
             }
+            if (mMinimized == minimized) {
+                return;
+            }
+            mMinimized = minimized;
+            mView.setMinimizedDockStack(minimized, getAnimDuration(), mHomeStackResizable);
+            updateTouchable();
         });
     }
 
-    private void notifyDockedStackExistsChanged(final boolean exists) {
-        mView.post(new Runnable() {
-            @Override
-            public void run() {
-                mForcedResizableController.notifyDockedStackExistsChanged(exists);
-            }
-        });
+    void setAdjustedForIme(boolean adjustedForIme) {
+        if (mAdjustedForIme == adjustedForIme) {
+            return;
+        }
+        mAdjustedForIme = adjustedForIme;
+        updateTouchable();
     }
 
     private void updateTouchable() {
         mWindowManager.setTouchable((mHomeStackResizable || !mMinimized) && !mAdjustedForIme);
     }
 
-    public void onRecentsActivityStarting() {
-        if (mView != null) {
-            mView.onRecentsActivityStarting();
-        }
-    }
-
     /**
      * Workaround for b/62528361, at the time recents has drawn, it may happen before a
      * configuration change to the Divider, and internally, the event will be posted to the
@@ -206,6 +446,9 @@
     }
 
     public void onAppTransitionFinished() {
+        if (mView == null) {
+            return;
+        }
         mForcedResizableController.onAppTransitionFinished();
     }
 
@@ -231,46 +474,66 @@
         pw.print("  mAdjustedForIme="); pw.println(mAdjustedForIme);
     }
 
-    class DockDividerVisibilityListener extends IDockedStackListener.Stub {
+    long getAnimDuration() {
+        float transitionScale = Settings.Global.getFloat(mContext.getContentResolver(),
+                Settings.Global.TRANSITION_ANIMATION_SCALE,
+                mContext.getResources().getFloat(
+                        com.android.internal.R.dimen
+                                .config_appTransitionAnimationDurationScaleDefault));
+        final long transitionDuration = DEFAULT_APP_TRANSITION_DURATION;
+        return (long) (transitionDuration * transitionScale);
+    }
 
-        @Override
-        public void onDividerVisibilityChanged(boolean visible) throws RemoteException {
-            updateVisibility(visible);
+    /** Register a listener that gets called whenever the existence of the divider changes */
+    public void registerInSplitScreenListener(Consumer<Boolean> listener) {
+        listener.accept(inSplitMode());
+        synchronized (mDockedStackExistsListeners) {
+            mDockedStackExistsListeners.add(new WeakReference<>(listener));
         }
+    }
 
-        @Override
-        public void onDockedStackExistsChanged(boolean exists) throws RemoteException {
-            notifyDockedStackExistsChanged(exists);
+    void startEnterSplit() {
+        // Set resizable directly here because applyEnterSplit already resizes home stack.
+        mHomeStackResizable = WindowManagerProxy.applyEnterSplit(mSplits, mSplitLayout);
+    }
+
+    void ensureMinimizedSplit() {
+        final boolean wasMinimized = mMinimized;
+        mMinimized = true;
+        setHomeStackResizable(mSplits.mSecondary.isResizable());
+        if (!inSplitMode()) {
+            // Wasn't in split-mode yet, so enter now.
+            if (DEBUG) {
+                Log.d(TAG, " entering split mode with minimized=true");
+            }
+            updateVisibility(true /* visible */);
+        } else if (!wasMinimized) {
+            if (DEBUG) {
+                Log.d(TAG, " in split mode, but minimizing ");
+            }
+            // Was already in split-mode, update just minimized state.
+            updateMinimizedDockedStack(mMinimized, getAnimDuration(),
+                    mHomeStackResizable);
         }
+    }
 
-        @Override
-        public void onDockedStackMinimizedChanged(boolean minimized, long animDuration,
-                boolean isHomeStackResizable) throws RemoteException {
-            mHomeStackResizable = isHomeStackResizable;
-            updateMinimizedDockedStack(minimized, animDuration, isHomeStackResizable);
+    void ensureNormalSplit() {
+        if (!inSplitMode()) {
+            // Wasn't in split-mode, so enter now.
+            if (DEBUG) {
+                Log.d(TAG, " enter split mode unminimized ");
+            }
+            mMinimized = false;
+            updateVisibility(true /* visible */);
         }
-
-        @Override
-        public void onAdjustedForImeChanged(boolean adjustedForIme, long animDuration)
-                throws RemoteException {
-            mView.post(() -> {
-                if (mAdjustedForIme != adjustedForIme) {
-                    mAdjustedForIme = adjustedForIme;
-                    updateTouchable();
-                    if (!mMinimized) {
-                        if (animDuration > 0) {
-                            mView.setAdjustedForIme(adjustedForIme, animDuration);
-                        } else {
-                            mView.setAdjustedForIme(adjustedForIme);
-                        }
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void onDockSideChanged(final int newDockSide) throws RemoteException {
-            mView.post(() -> mView.notifyDockSideChanged(newDockSide));
+        if (mMinimized) {
+            // Was in minimized state, so leave that.
+            if (DEBUG) {
+                Log.d(TAG, " in split mode already, but unminimizing ");
+            }
+            mMinimized = false;
+            updateMinimizedDockedStack(mMinimized, getAnimDuration(),
+                    mHomeStackResizable);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerModule.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerModule.java
index 49f4d5e..f3b2553 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerModule.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerModule.java
@@ -17,8 +17,14 @@
 package com.android.systemui.stackdivider;
 
 import android.content.Context;
+import android.os.Handler;
 
+import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.recents.Recents;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.wm.DisplayController;
+import com.android.systemui.wm.DisplayImeController;
+import com.android.systemui.wm.SystemWindows;
 
 import java.util.Optional;
 
@@ -35,7 +41,11 @@
 public class DividerModule {
     @Singleton
     @Provides
-    static Divider provideDivider(Context context, Optional<Lazy<Recents>> recentsOptionalLazy) {
-        return new Divider(context, recentsOptionalLazy);
+    static Divider provideDivider(Context context, Optional<Lazy<Recents>> recentsOptionalLazy,
+            DisplayController displayController, SystemWindows systemWindows,
+            DisplayImeController imeController, @Main Handler handler,
+            KeyguardStateController keyguardStateController) {
+        return new Divider(context, recentsOptionalLazy, displayController, systemWindows,
+                imeController, handler, keyguardStateController);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 9fe6e84..fdd04b9 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -16,12 +16,8 @@
 
 package com.android.systemui.stackdivider;
 
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.view.PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW;
 import static android.view.PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW;
-import static android.view.WindowManager.DOCKED_LEFT;
 import static android.view.WindowManager.DOCKED_RIGHT;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
 
@@ -40,10 +36,11 @@
 import android.util.AttributeSet;
 import android.view.Choreographer;
 import android.view.Display;
-import android.view.DisplayInfo;
 import android.view.InsetsState;
 import android.view.MotionEvent;
 import android.view.PointerIcon;
+import android.view.SurfaceControl;
+import android.view.SurfaceControl.Transaction;
 import android.view.VelocityTracker;
 import android.view.View;
 import android.view.View.OnTouchListener;
@@ -75,6 +72,7 @@
  */
 public class DividerView extends FrameLayout implements OnTouchListener,
         OnComputeInternalInsetsListener {
+    private static final String TAG = "DividerView";
 
     public interface DividerCallbacks {
         void onDraggingStart();
@@ -123,14 +121,11 @@
     private int mTouchSlop;
     private boolean mBackgroundLifted;
     private boolean mIsInMinimizeInteraction;
-    private SnapTarget mSnapTargetBeforeMinimized;
+    SnapTarget mSnapTargetBeforeMinimized;
 
     private int mDividerInsets;
     private final Display mDefaultDisplay;
-    private int mDisplayWidth;
-    private int mDisplayHeight;
-    private int mDisplayRotation;
-    private int mDividerWindowWidth;
+
     private int mDividerSize;
     private int mTouchElevation;
     private int mLongPressEntraceAnimDuration;
@@ -147,8 +142,7 @@
     private DividerWindowManager mWindowManager;
     private VelocityTracker mVelocityTracker;
     private FlingAnimationUtils mFlingAnimationUtils;
-    private DividerSnapAlgorithm mSnapAlgorithm;
-    private DividerSnapAlgorithm mMinimizedSnapAlgorithm;
+    private SplitDisplayLayout mSplitLayout;
     private DividerCallbacks mCallback;
     private final Rect mStableInsets = new Rect();
 
@@ -163,6 +157,10 @@
     private DividerState mState;
     private final SurfaceFlingerVsyncChoreographer mSfChoreographer;
 
+    private SplitScreenTaskOrganizer mTiles;
+    boolean mFirstLayout = true;
+    int mDividerPositionX;
+    int mDividerPositionY;
 
     // The view is removed or in the process of been removed from the system.
     private boolean mRemoved;
@@ -172,7 +170,7 @@
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case MSG_RESIZE_STACK:
-                    resizeStack(msg.arg1, msg.arg2, (SnapTarget) msg.obj);
+                    resizeStackSurfaces(msg.arg1, msg.arg2, (SnapTarget) msg.obj);
                     break;
                 default:
                     super.handleMessage(msg);
@@ -228,16 +226,17 @@
         public boolean performAccessibilityAction(View host, int action, Bundle args) {
             int currentPosition = getCurrentPosition();
             SnapTarget nextTarget = null;
+            DividerSnapAlgorithm snapAlgorithm = mSplitLayout.getSnapAlgorithm();
             if (action == R.id.action_move_tl_full) {
-                nextTarget = mSnapAlgorithm.getDismissEndTarget();
+                nextTarget = snapAlgorithm.getDismissEndTarget();
             } else if (action == R.id.action_move_tl_70) {
-                nextTarget = mSnapAlgorithm.getLastSplitTarget();
+                nextTarget = snapAlgorithm.getLastSplitTarget();
             } else if (action == R.id.action_move_tl_50) {
-                nextTarget = mSnapAlgorithm.getMiddleTarget();
+                nextTarget = snapAlgorithm.getMiddleTarget();
             } else if (action == R.id.action_move_tl_30) {
-                nextTarget = mSnapAlgorithm.getFirstSplitTarget();
+                nextTarget = snapAlgorithm.getFirstSplitTarget();
             } else if (action == R.id.action_move_rb_full) {
-                nextTarget = mSnapAlgorithm.getDismissStartTarget();
+                nextTarget = snapAlgorithm.getDismissStartTarget();
             }
             if (nextTarget != null) {
                 startDragging(true /* animate */, false /* touching */);
@@ -284,11 +283,11 @@
         mBackground = findViewById(R.id.docked_divider_background);
         mMinimizedShadow = findViewById(R.id.minimized_dock_shadow);
         mHandle.setOnTouchListener(this);
-        mDividerWindowWidth = getResources().getDimensionPixelSize(
+        final int dividerWindowWidth = getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.docked_stack_divider_thickness);
         mDividerInsets = getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.docked_stack_divider_insets);
-        mDividerSize = mDividerWindowWidth - 2 * mDividerInsets;
+        mDividerSize = dividerWindowWidth - 2 * mDividerInsets;
         mTouchElevation = getResources().getDimensionPixelSize(
                 R.dimen.docked_stack_divider_lift_elevation);
         mLongPressEntraceAnimDuration = getResources().getInteger(
@@ -296,7 +295,6 @@
         mGrowRecents = getResources().getBoolean(R.bool.recents_grow_in_multiwindow);
         mTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
         mFlingAnimationUtils = new FlingAnimationUtils(getResources().getDisplayMetrics(), 0.3f);
-        updateDisplayInfo();
         boolean landscape = getResources().getConfiguration().orientation
                 == Configuration.ORIENTATION_LANDSCAPE;
         mHandle.setPointerIcon(PointerIcon.getSystemIcon(getContext(),
@@ -314,6 +312,7 @@
                 && !mIsInMinimizeInteraction) {
             saveSnapTargetBeforeMinimized(mSnapTargetBeforeMinimized);
         }
+        mFirstLayout = true;
     }
 
     void onDividerRemoved() {
@@ -341,17 +340,17 @@
                 || mStableInsets.bottom != insets.getStableInsetBottom()) {
             mStableInsets.set(insets.getStableInsetLeft(), insets.getStableInsetTop(),
                     insets.getStableInsetRight(), insets.getStableInsetBottom());
-            if (mSnapAlgorithm != null || mMinimizedSnapAlgorithm != null) {
-                mSnapAlgorithm = null;
-                mMinimizedSnapAlgorithm = null;
-                initializeSnapAlgorithm();
-            }
         }
         return super.onApplyWindowInsets(insets);
     }
 
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        if (mFirstLayout) {
+            // Wait for first layout so that the ViewRootImpl surface has been created.
+            initializeSurfaceState();
+            mFirstLayout = false;
+        }
         super.onLayout(changed, left, top, right, bottom);
         int minimizeLeft = 0;
         int minimizeTop = 0;
@@ -372,19 +371,16 @@
     }
 
     public void injectDependencies(DividerWindowManager windowManager, DividerState dividerState,
-            DividerCallbacks callback) {
+            DividerCallbacks callback, SplitScreenTaskOrganizer tiles, SplitDisplayLayout sdl) {
         mWindowManager = windowManager;
         mState = dividerState;
         mCallback = callback;
-
-        // Set the previous position ratio before minimized state after attaching this divider
-        if (mStableInsets.isEmpty()) {
-            WindowManagerWrapper.getInstance().getStableInsets(mStableInsets);
-        }
+        mTiles = tiles;
+        mSplitLayout = sdl;
 
         if (mState.mRatioPositionBeforeMinimized == 0) {
             // Set the middle target as the initial state
-            mSnapTargetBeforeMinimized = mSnapAlgorithm.getMiddleTarget();
+            mSnapTargetBeforeMinimized = mSplitLayout.getSnapAlgorithm().getMiddleTarget();
         } else {
             repositionSnapTargetBeforeMinimized();
         }
@@ -411,18 +407,34 @@
         return mOtherTaskRect;
     }
 
+    private boolean inSplitMode() {
+        return getVisibility() == VISIBLE;
+    }
+
+    /** Unlike setVisible, this directly hides the surface without changing view visibility. */
+    void setHidden(boolean hidden) {
+        post(() -> {
+            if (!isViewSurfaceValid()) {
+                return;
+            }
+            Transaction t = mTiles.getTransaction();
+            if (hidden) {
+                t.hide(getViewRootImpl().getSurfaceControl());
+            } else {
+                t.show(getViewRootImpl().getSurfaceControl());
+            }
+            t.apply();
+            mTiles.releaseTransaction(t);
+        });
+    }
+
     public boolean startDragging(boolean animate, boolean touching) {
         cancelFlingAnimation();
         if (touching) {
             mHandle.setTouching(true, animate);
         }
-        mDockSide = mWindowManagerProxy.getDockSide();
+        mDockSide = mSplitLayout.getPrimarySplitSide();
 
-        // Update snap algorithm if rotation has occurred
-        if (mDisplayRotation != mDefaultDisplay.getRotation()) {
-            updateDisplayInfo();
-        }
-        initializeSnapAlgorithm();
         mWindowManagerProxy.setResizing(true);
         if (touching) {
             mWindowManager.setSlippery(false);
@@ -431,7 +443,7 @@
         if (mCallback != null) {
             mCallback.onDraggingStart();
         }
-        return mDockSide != WindowManager.DOCKED_INVALID;
+        return inSplitMode();
     }
 
     public void stopDragging(int position, float velocity, boolean avoidDismissStart,
@@ -467,38 +479,22 @@
     }
 
     private void updateDockSide() {
-        mDockSide = mWindowManagerProxy.getDockSide();
+        mDockSide = mSplitLayout.getPrimarySplitSide();
         mMinimizedShadow.setDockSide(mDockSide);
     }
 
-    private void initializeSnapAlgorithm() {
-        if (mSnapAlgorithm == null) {
-            mSnapAlgorithm = new DividerSnapAlgorithm(getContext().getResources(), mDisplayWidth,
-                    mDisplayHeight, mDividerSize, isHorizontalDivision(), mStableInsets, mDockSide);
-            if (mSnapTargetBeforeMinimized != null && mSnapTargetBeforeMinimized.isMiddleTarget) {
-                mSnapTargetBeforeMinimized = mSnapAlgorithm.getMiddleTarget();
-            }
-        }
-        if (mMinimizedSnapAlgorithm == null) {
-            mMinimizedSnapAlgorithm = new DividerSnapAlgorithm(getContext().getResources(),
-                    mDisplayWidth, mDisplayHeight, mDividerSize, isHorizontalDivision(),
-                    mStableInsets, mDockSide, mDockedStackMinimized && mHomeStackResizable);
-        }
-    }
-
     public DividerSnapAlgorithm getSnapAlgorithm() {
-        initializeSnapAlgorithm();
-        return mDockedStackMinimized && mHomeStackResizable ? mMinimizedSnapAlgorithm :
-                mSnapAlgorithm;
+        return mDockedStackMinimized
+                && mHomeStackResizable ? mSplitLayout.getMinimizedSnapAlgorithm()
+                        : mSplitLayout.getSnapAlgorithm();
     }
 
     public int getCurrentPosition() {
-        getLocationOnScreen(mTempInt2);
-        if (isHorizontalDivision()) {
-            return mTempInt2[1] + mDividerInsets;
-        } else {
-            return mTempInt2[0] + mDividerInsets;
-        }
+        return isHorizontalDivision() ? mDividerPositionY : mDividerPositionX;
+    }
+
+    public boolean isMinimized() {
+        return mDockedStackMinimized;
     }
 
     @Override
@@ -557,25 +553,25 @@
     }
 
     private void logResizeEvent(SnapTarget snapTarget) {
-        if (snapTarget == mSnapAlgorithm.getDismissStartTarget()) {
+        if (snapTarget == mSplitLayout.getSnapAlgorithm().getDismissStartTarget()) {
             MetricsLogger.action(
                     mContext, MetricsEvent.ACTION_WINDOW_UNDOCK_MAX, dockSideTopLeft(mDockSide)
                             ? LOG_VALUE_UNDOCK_MAX_OTHER
                             : LOG_VALUE_UNDOCK_MAX_DOCKED);
-        } else if (snapTarget == mSnapAlgorithm.getDismissEndTarget()) {
+        } else if (snapTarget == mSplitLayout.getSnapAlgorithm().getDismissEndTarget()) {
             MetricsLogger.action(
                     mContext, MetricsEvent.ACTION_WINDOW_UNDOCK_MAX, dockSideBottomRight(mDockSide)
                             ? LOG_VALUE_UNDOCK_MAX_OTHER
                             : LOG_VALUE_UNDOCK_MAX_DOCKED);
-        } else if (snapTarget == mSnapAlgorithm.getMiddleTarget()) {
+        } else if (snapTarget == mSplitLayout.getSnapAlgorithm().getMiddleTarget()) {
             MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_RESIZE,
                     LOG_VALUE_RESIZE_50_50);
-        } else if (snapTarget == mSnapAlgorithm.getFirstSplitTarget()) {
+        } else if (snapTarget == mSplitLayout.getSnapAlgorithm().getFirstSplitTarget()) {
             MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_RESIZE,
                     dockSideTopLeft(mDockSide)
                             ? LOG_VALUE_RESIZE_DOCKED_SMALLER
                             : LOG_VALUE_RESIZE_DOCKED_LARGER);
-        } else if (snapTarget == mSnapAlgorithm.getLastSplitTarget()) {
+        } else if (snapTarget == mSplitLayout.getSnapAlgorithm().getLastSplitTarget()) {
             MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_RESIZE,
                     dockSideTopLeft(mDockSide)
                             ? LOG_VALUE_RESIZE_DOCKED_LARGER
@@ -625,12 +621,16 @@
                         : snapTarget.taskPosition,
                 snapTarget));
         Runnable endAction = () -> {
-            commitSnapFlags(snapTarget);
+            boolean dismissed = commitSnapFlags(snapTarget);
             mWindowManagerProxy.setResizing(false);
             updateDockSide();
             mCurrentAnimator = null;
             mEntranceAnimationRunning = false;
             mExitAnimationRunning = false;
+            if (!dismissed) {
+                WindowManagerProxy.applyResizeSplits((mIsInMinimizeInteraction
+                        ? mSnapTargetBeforeMinimized : snapTarget).position, mSplitLayout);
+            }
             if (mCallback != null) {
                 mCallback.onDraggingEnd();
             }
@@ -642,12 +642,13 @@
                 // position isn't negative.
                 final SnapTarget saveTarget;
                 if (snapTarget.position < 0) {
-                    saveTarget = mSnapAlgorithm.getMiddleTarget();
+                    saveTarget = mSplitLayout.getSnapAlgorithm().getMiddleTarget();
                 } else {
                     saveTarget = snapTarget;
                 }
-                if (saveTarget.position != mSnapAlgorithm.getDismissEndTarget().position
-                        && saveTarget.position != mSnapAlgorithm.getDismissStartTarget().position) {
+                final DividerSnapAlgorithm snapAlgo = mSplitLayout.getSnapAlgorithm();
+                if (saveTarget.position != snapAlgo.getDismissEndTarget().position
+                        && saveTarget.position != snapAlgo.getDismissStartTarget().position) {
                     saveSnapTargetBeforeMinimized(saveTarget);
                 }
             }
@@ -701,11 +702,11 @@
         }
     }
 
-    private void commitSnapFlags(SnapTarget target) {
+    private boolean commitSnapFlags(SnapTarget target) {
         if (target.flag == SnapTarget.FLAG_NONE) {
-            return;
+            return false;
         }
-        boolean dismissOrMaximize;
+        final boolean dismissOrMaximize;
         if (target.flag == SnapTarget.FLAG_DISMISS_START) {
             dismissOrMaximize = mDockSide == WindowManager.DOCKED_LEFT
                     || mDockSide == WindowManager.DOCKED_TOP;
@@ -713,12 +714,13 @@
             dismissOrMaximize = mDockSide == WindowManager.DOCKED_RIGHT
                     || mDockSide == WindowManager.DOCKED_BOTTOM;
         }
-        if (dismissOrMaximize) {
-            mWindowManagerProxy.dismissDockedStack();
-        } else {
-            mWindowManagerProxy.maximizeDockedStack();
-        }
-        mWindowManagerProxy.setResizeDimLayer(false, WINDOWING_MODE_UNDEFINED, 0f);
+        mWindowManagerProxy.dismissOrMaximizeDocked(mTiles, dismissOrMaximize);
+        Transaction t = mTiles.getTransaction();
+        setResizeDimLayer(t, true /* primary */, 0f);
+        setResizeDimLayer(t, false /* primary */, 0f);
+        t.apply();
+        mTiles.releaseTransaction(t);
+        return true;
     }
 
     private void liftBackground() {
@@ -765,6 +767,28 @@
         mBackgroundLifted = false;
     }
 
+    private void initializeSurfaceState() {
+        int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position;
+        // Recalculate the split-layout's internal tile bounds
+        mSplitLayout.resizeSplits(midPos);
+        Transaction t = mTiles.getTransaction();
+        if (mDockedStackMinimized) {
+            int position = mSplitLayout.getMinimizedSnapAlgorithm().getMiddleTarget().position;
+            calculateBoundsForPosition(position, mDockSide, mDockedRect);
+            calculateBoundsForPosition(position, DockedDividerUtils.invertDockSide(mDockSide),
+                    mOtherRect);
+            mDividerPositionX = mDividerPositionY = position;
+            resizeSplitSurfaces(t, mDockedRect, mSplitLayout.mPrimary,
+                    mOtherRect, mSplitLayout.mSecondary);
+        } else {
+            resizeSplitSurfaces(t, mSplitLayout.mPrimary, null,
+                    mSplitLayout.mSecondary, null);
+        }
+        setResizeDimLayer(t, true /* primary */, 0.f /* alpha */);
+        setResizeDimLayer(t, false /* secondary */, 0.f /* alpha */);
+        t.apply();
+        mTiles.releaseTransaction(t);
+    }
 
     public void setMinimizedDockStack(boolean minimized, boolean isHomeStackResizable) {
         mHomeStackResizable = isHomeStackResizable;
@@ -789,15 +813,11 @@
             mDockedStackMinimized = minimized;
         } else if (mDockedStackMinimized != minimized) {
             mDockedStackMinimized = minimized;
-            if (mDisplayRotation != mDefaultDisplay.getRotation()) {
+            if (mSplitLayout.mDisplayLayout.rotation() != mDefaultDisplay.getRotation()) {
                 // Splitscreen to minimize is about to starts after rotating landscape to seascape,
                 // update insets, display info and snap algorithm targets
                 WindowManagerWrapper.getInstance().getStableInsets(mStableInsets);
                 repositionSnapTargetBeforeMinimized();
-                updateDisplayInfo();
-            } else {
-                mMinimizedSnapAlgorithm = null;
-                initializeSnapAlgorithm();
             }
             if (mIsInMinimizeInteraction != minimized || mCurrentAnimator != null) {
                 cancelFlingAnimation();
@@ -805,15 +825,51 @@
                     // Relayout to recalculate the divider shadow when minimizing
                     requestLayout();
                     mIsInMinimizeInteraction = true;
-                    resizeStack(mMinimizedSnapAlgorithm.getMiddleTarget());
+                    resizeStackSurfaces(mSplitLayout.getMinimizedSnapAlgorithm().getMiddleTarget());
                 } else {
-                    resizeStack(mSnapTargetBeforeMinimized);
+                    resizeStackSurfaces(mSnapTargetBeforeMinimized);
                     mIsInMinimizeInteraction = false;
                 }
             }
         }
     }
 
+    void enterSplitMode(boolean isHomeStackResizable) {
+        post(() -> {
+            if (!isViewSurfaceValid()) {
+                return;
+            }
+            Transaction t = mTiles.getTransaction();
+            t.show(getViewRootImpl().getSurfaceControl()).apply();
+            mTiles.releaseTransaction(t);
+        });
+        if (isHomeStackResizable) {
+            SnapTarget miniMid = mSplitLayout.getMinimizedSnapAlgorithm().getMiddleTarget();
+            if (mDockedStackMinimized) {
+                mDividerPositionY = mDividerPositionX = miniMid.position;
+            }
+        }
+    }
+
+    private boolean isViewSurfaceValid() {
+        return getViewRootImpl() != null && getViewRootImpl().getSurfaceControl() != null
+                && getViewRootImpl().getSurfaceControl().isValid();
+    }
+
+    void exitSplitMode() {
+        // Reset tile bounds
+        post(() -> {
+            if (!isViewSurfaceValid()) {
+                return;
+            }
+            Transaction t = mTiles.getTransaction();
+            t.hide(getViewRootImpl().getSurfaceControl()).apply();
+            mTiles.releaseTransaction(t);
+        });
+        int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position;
+        WindowManagerProxy.applyResizeSplits(midPos, mSplitLayout);
+    }
+
     public void setMinimizedDockStack(boolean minimized, long animDuration,
             boolean isHomeStackResizable) {
         mHomeStackResizable = isHomeStackResizable;
@@ -844,14 +900,12 @@
             mDockedStackMinimized = minimized;
         } else if (mDockedStackMinimized != minimized) {
             mIsInMinimizeInteraction = true;
-            mMinimizedSnapAlgorithm = null;
             mDockedStackMinimized = minimized;
-            initializeSnapAlgorithm();
             stopDragging(minimized
                             ? mSnapTargetBeforeMinimized.position
                             : getCurrentPosition(),
                     minimized
-                            ? mMinimizedSnapAlgorithm.getMiddleTarget()
+                            ? mSplitLayout.getMinimizedSnapAlgorithm().getMiddleTarget()
                             : mSnapTargetBeforeMinimized,
                     animDuration, Interpolators.FAST_OUT_SLOW_IN, 0);
             setAdjustedForIme(false, animDuration);
@@ -865,18 +919,6 @@
                 .start();
     }
 
-    public void setAdjustedForIme(boolean adjustedForIme) {
-        updateDockSide();
-        mHandle.setAlpha(adjustedForIme ? 0f : 1f);
-        if (!adjustedForIme) {
-            resetBackground();
-        } else if (mDockSide == WindowManager.DOCKED_TOP) {
-            mBackground.setPivotY(0);
-            mBackground.setScaleY(ADJUSTED_FOR_IME_SCALE);
-        }
-        mAdjustedForIme = adjustedForIme;
-    }
-
     public void setAdjustedForIme(boolean adjustedForIme, long animDuration) {
         updateDockSide();
         mHandle.animate()
@@ -902,7 +944,8 @@
     private void saveSnapTargetBeforeMinimized(SnapTarget target) {
         mSnapTargetBeforeMinimized = target;
         mState.mRatioPositionBeforeMinimized = (float) target.position /
-                (isHorizontalDivision() ? mDisplayHeight : mDisplayWidth);
+                (isHorizontalDivision() ? mSplitLayout.mDisplayLayout.height()
+                        : mSplitLayout.mDisplayLayout.width());
     }
 
     private void resetBackground() {
@@ -916,51 +959,17 @@
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
-        updateDisplayInfo();
-    }
-
-    public void notifyDockSideChanged(int newDockSide) {
-        int oldDockSide = mDockSide;
-        mDockSide = newDockSide;
-        mMinimizedShadow.setDockSide(mDockSide);
-        requestLayout();
-
-        // Update the snap position to the new docked side with correct insets
-        WindowManagerWrapper.getInstance().getStableInsets(mStableInsets);
-        mMinimizedSnapAlgorithm = null;
-        initializeSnapAlgorithm();
-
-        if (oldDockSide == DOCKED_LEFT && mDockSide == DOCKED_RIGHT
-                || oldDockSide == DOCKED_RIGHT && mDockSide == DOCKED_LEFT) {
-            repositionSnapTargetBeforeMinimized();
-        }
-
-        // Landscape to seascape rotation requires minimized to resize docked app correctly
-        if (mHomeStackResizable && mDockedStackMinimized) {
-            resizeStack(mMinimizedSnapAlgorithm.getMiddleTarget());
-        }
     }
 
     private void repositionSnapTargetBeforeMinimized() {
         int position = (int) (mState.mRatioPositionBeforeMinimized *
-                (isHorizontalDivision() ? mDisplayHeight : mDisplayWidth));
-        mSnapAlgorithm = null;
-        initializeSnapAlgorithm();
+                (isHorizontalDivision() ? mSplitLayout.mDisplayLayout.height()
+                        : mSplitLayout.mDisplayLayout.width()));
 
         // Set the snap target before minimized but do not save until divider is attached and not
         // minimized because it does not know its minimized state yet.
-        mSnapTargetBeforeMinimized = mSnapAlgorithm.calculateNonDismissingSnapTarget(position);
-    }
-
-    private void updateDisplayInfo() {
-        mDisplayRotation = mDefaultDisplay.getRotation();
-        final DisplayInfo info = new DisplayInfo();
-        mDefaultDisplay.getDisplayInfo(info);
-        mDisplayWidth = info.logicalWidth;
-        mDisplayHeight = info.logicalHeight;
-        mSnapAlgorithm = null;
-        mMinimizedSnapAlgorithm = null;
-        initializeSnapAlgorithm();
+        mSnapTargetBeforeMinimized =
+                mSplitLayout.getSnapAlgorithm().calculateNonDismissingSnapTarget(position);
     }
 
     private int calculatePosition(int touchX, int touchY) {
@@ -994,8 +1003,9 @@
     }
 
     public void calculateBoundsForPosition(int position, int dockSide, Rect outRect) {
-        DockedDividerUtils.calculateBoundsForPosition(position, dockSide, outRect, mDisplayWidth,
-                mDisplayHeight, mDividerSize);
+        DockedDividerUtils.calculateBoundsForPosition(position, dockSide, outRect,
+                mSplitLayout.mDisplayLayout.width(), mSplitLayout.mDisplayLayout.height(),
+                mDividerSize);
     }
 
     public void resizeStackDelayed(int position, int taskPosition, SnapTarget taskSnapTarget) {
@@ -1005,16 +1015,61 @@
         mSfChoreographer.scheduleAtSfVsync(mHandler, message);
     }
 
-    private void resizeStack(SnapTarget taskSnapTarget) {
-        resizeStack(taskSnapTarget.position, taskSnapTarget.position, taskSnapTarget);
+    private void resizeStackSurfaces(SnapTarget taskSnapTarget) {
+        resizeStackSurfaces(taskSnapTarget.position, taskSnapTarget.position, taskSnapTarget);
     }
 
-    public void resizeStack(int position, int taskPosition, SnapTarget taskSnapTarget) {
+    void resizeSplitSurfaces(Transaction t, Rect dockedRect, Rect otherRect) {
+        post(() -> resizeSplitSurfaces(t, dockedRect, null, otherRect, null));
+    }
+
+    private void resizeSplitSurfaces(Transaction t, Rect dockedRect, Rect dockedTaskRect,
+            Rect otherRect, Rect otherTaskRect) {
+        dockedTaskRect = dockedTaskRect == null ? dockedRect : dockedTaskRect;
+        otherTaskRect = otherTaskRect == null ? otherRect : otherTaskRect;
+
+        mDividerPositionX = dockedRect.right;
+        mDividerPositionY = dockedRect.bottom;
+
+        t.setPosition(mTiles.mPrimarySurface, dockedTaskRect.left, dockedTaskRect.top);
+        Rect crop = new Rect(dockedRect);
+        crop.offsetTo(-Math.min(dockedTaskRect.left - dockedRect.left, 0),
+                -Math.min(dockedTaskRect.top - dockedRect.top, 0));
+        t.setWindowCrop(mTiles.mPrimarySurface, crop);
+        t.setPosition(mTiles.mSecondarySurface, otherTaskRect.left, otherTaskRect.top);
+        crop.set(otherRect);
+        crop.offsetTo(-(otherTaskRect.left - otherRect.left),
+                -(otherTaskRect.top - otherRect.top));
+        t.setWindowCrop(mTiles.mSecondarySurface, crop);
+        SurfaceControl dividerCtrl = getViewRootImpl() != null
+                ? getViewRootImpl().getSurfaceControl() : null;
+        if (dividerCtrl != null && dividerCtrl.isValid()) {
+            if (isHorizontalDivision()) {
+                t.setPosition(dividerCtrl, 0, mDividerPositionY - mDividerInsets);
+            } else {
+                t.setPosition(dividerCtrl, mDividerPositionX - mDividerInsets, 0);
+            }
+        }
+    }
+
+    void setResizeDimLayer(Transaction t, boolean primary, float alpha) {
+        SurfaceControl dim = primary ? mTiles.mPrimaryDim : mTiles.mSecondaryDim;
+        if (alpha <= 0.f) {
+            t.hide(dim);
+        } else {
+            t.setAlpha(dim, alpha);
+            t.show(dim);
+        }
+    }
+
+    void resizeStackSurfaces(int position, int taskPosition, SnapTarget taskSnapTarget) {
         if (mRemoved) {
             // This divider view has been removed so shouldn't have any additional influence.
             return;
         }
         calculateBoundsForPosition(position, mDockSide, mDockedRect);
+        calculateBoundsForPosition(position, DockedDividerUtils.invertDockSide(mDockSide),
+                mOtherRect);
 
         if (mDockedRect.equals(mLastResizeRect) && !mEntranceAnimationRunning) {
             return;
@@ -1025,6 +1080,7 @@
             mBackground.invalidate();
         }
 
+        Transaction t = mTiles.getTransaction();
         mLastResizeRect.set(mDockedRect);
         if (mHomeStackResizable && mIsInMinimizeInteraction) {
             calculateBoundsForPosition(mSnapTargetBeforeMinimized.position, mDockSide,
@@ -1037,8 +1093,10 @@
                 mDockedTaskRect.offset(Math.max(position, mStableInsets.left - mDividerSize)
                         - mDockedTaskRect.left + mDividerSize, 0);
             }
-            mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, mDockedTaskRect,
-                    mOtherTaskRect, null);
+            resizeSplitSurfaces(t, mDockedRect, mDockedTaskRect, mOtherRect,
+                    mOtherTaskRect);
+            t.apply();
+            mTiles.releaseTransaction(t);
             return;
         }
 
@@ -1052,8 +1110,7 @@
             }
             calculateBoundsForPosition(taskPosition, DockedDividerUtils.invertDockSide(mDockSide),
                     mOtherTaskRect);
-            mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, null,
-                    mOtherTaskRect, null);
+            resizeSplitSurfaces(t, mDockedRect, mDockedTaskRect, mOtherRect, mOtherTaskRect);
         } else if (mExitAnimationRunning && taskPosition != TASK_POSITION_SAME) {
             calculateBoundsForPosition(taskPosition, mDockSide, mDockedTaskRect);
             mDockedInsetRect.set(mDockedTaskRect);
@@ -1066,8 +1123,7 @@
             if (mDockSide == DOCKED_RIGHT) {
                 mDockedTaskRect.offset(position - mStableInsets.left + mDividerSize, 0);
             }
-            mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, mDockedInsetRect,
-                    mOtherTaskRect, mOtherInsetRect);
+            resizeSplitSurfaces(t, mDockedRect, mDockedTaskRect, mOtherRect, mOtherTaskRect);
         } else if (taskPosition != TASK_POSITION_SAME) {
             calculateBoundsForPosition(position, DockedDividerUtils.invertDockSide(mDockSide),
                     mOtherRect);
@@ -1078,7 +1134,8 @@
                     restrictDismissingTaskPosition(taskPosition, dockSideInverted, taskSnapTarget);
             calculateBoundsForPosition(taskPositionDocked, mDockSide, mDockedTaskRect);
             calculateBoundsForPosition(taskPositionOther, dockSideInverted, mOtherTaskRect);
-            mTmpRect.set(0, 0, mDisplayWidth, mDisplayHeight);
+            mTmpRect.set(0, 0, mSplitLayout.mDisplayLayout.width(),
+                    mSplitLayout.mDisplayLayout.height());
             alignTopLeft(mDockedRect, mDockedTaskRect);
             alignTopLeft(mOtherRect, mOtherTaskRect);
             mDockedInsetRect.set(mDockedTaskRect);
@@ -1094,15 +1151,15 @@
                     taskPositionDocked);
             applyDismissingParallax(mOtherTaskRect, dockSideInverted, taskSnapTarget, position,
                     taskPositionOther);
-            mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, mDockedInsetRect,
-                    mOtherTaskRect, mOtherInsetRect);
+            resizeSplitSurfaces(t, mDockedRect, mDockedTaskRect, mOtherRect, mOtherTaskRect);
         } else {
-            mWindowManagerProxy.resizeDockedStack(mDockedRect, null, null, null, null);
+            resizeSplitSurfaces(t, mDockedRect, null, mOtherRect, null);
         }
         SnapTarget closestDismissTarget = getSnapAlgorithm().getClosestDismissTarget(position);
         float dimFraction = getDimFraction(position, closestDismissTarget);
-        mWindowManagerProxy.setResizeDimLayer(dimFraction != 0f,
-                getWindowingModeForDismissTarget(closestDismissTarget), dimFraction);
+        setResizeDimLayer(t, isDismissTargetPrimary(closestDismissTarget), dimFraction);
+        t.apply();
+        mTiles.releaseTransaction(t);
     }
 
     private void applyExitAnimationParallax(Rect taskRect, int position) {
@@ -1156,10 +1213,12 @@
     private int restrictDismissingTaskPosition(int taskPosition, int dockSide,
             SnapTarget snapTarget) {
         if (snapTarget.flag == SnapTarget.FLAG_DISMISS_START && dockSideTopLeft(dockSide)) {
-            return Math.max(mSnapAlgorithm.getFirstSplitTarget().position, mStartPosition);
+            return Math.max(mSplitLayout.getSnapAlgorithm().getFirstSplitTarget().position,
+                    mStartPosition);
         } else if (snapTarget.flag == SnapTarget.FLAG_DISMISS_END
                 && dockSideBottomRight(dockSide)) {
-            return Math.min(mSnapAlgorithm.getLastSplitTarget().position, mStartPosition);
+            return Math.min(mSplitLayout.getSnapAlgorithm().getLastSplitTarget().position,
+                    mStartPosition);
         } else {
             return taskPosition;
         }
@@ -1171,19 +1230,19 @@
     private void applyDismissingParallax(Rect taskRect, int dockSide, SnapTarget snapTarget,
             int position, int taskPosition) {
         float fraction = Math.min(1, Math.max(0,
-                mSnapAlgorithm.calculateDismissingFraction(position)));
+                mSplitLayout.getSnapAlgorithm().calculateDismissingFraction(position)));
         SnapTarget dismissTarget = null;
         SnapTarget splitTarget = null;
         int start = 0;
-        if (position <= mSnapAlgorithm.getLastSplitTarget().position
+        if (position <= mSplitLayout.getSnapAlgorithm().getLastSplitTarget().position
                 && dockSideTopLeft(dockSide)) {
-            dismissTarget = mSnapAlgorithm.getDismissStartTarget();
-            splitTarget = mSnapAlgorithm.getFirstSplitTarget();
+            dismissTarget = mSplitLayout.getSnapAlgorithm().getDismissStartTarget();
+            splitTarget = mSplitLayout.getSnapAlgorithm().getFirstSplitTarget();
             start = taskPosition;
-        } else if (position >= mSnapAlgorithm.getLastSplitTarget().position
+        } else if (position >= mSplitLayout.getSnapAlgorithm().getLastSplitTarget().position
                 && dockSideBottomRight(dockSide)) {
-            dismissTarget = mSnapAlgorithm.getDismissEndTarget();
-            splitTarget = mSnapAlgorithm.getLastSplitTarget();
+            dismissTarget = mSplitLayout.getSnapAlgorithm().getDismissEndTarget();
+            splitTarget = mSplitLayout.getSnapAlgorithm().getLastSplitTarget();
             start = splitTarget.position;
         }
         if (dismissTarget != null && fraction > 0f
@@ -1236,14 +1295,10 @@
         }
     }
 
-    private int getWindowingModeForDismissTarget(SnapTarget dismissTarget) {
-        if ((dismissTarget.flag == SnapTarget.FLAG_DISMISS_START && dockSideTopLeft(mDockSide))
+    private boolean isDismissTargetPrimary(SnapTarget dismissTarget) {
+        return (dismissTarget.flag == SnapTarget.FLAG_DISMISS_START && dockSideTopLeft(mDockSide))
                 || (dismissTarget.flag == SnapTarget.FLAG_DISMISS_END
-                        && dockSideBottomRight(mDockSide))) {
-            return WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-        } else {
-            return WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
-        }
+                        && dockSideBottomRight(mDockSide));
     }
 
     /**
@@ -1297,7 +1352,7 @@
     }
 
     void onDockedFirstAnimationFrame() {
-        saveSnapTargetBeforeMinimized(mSnapAlgorithm.getMiddleTarget());
+        saveSnapTargetBeforeMinimized(mSplitLayout.getSnapAlgorithm().getMiddleTarget());
     }
 
     void onDockedTopTask() {
@@ -1307,8 +1362,9 @@
         updateDockSide();
         mEntranceAnimationRunning = true;
 
-        resizeStack(calculatePositionForInsetBounds(), mSnapAlgorithm.getMiddleTarget().position,
-                mSnapAlgorithm.getMiddleTarget());
+        resizeStackSurfaces(calculatePositionForInsetBounds(),
+                mSplitLayout.getSnapAlgorithm().getMiddleTarget().position,
+                mSplitLayout.getSnapAlgorithm().getMiddleTarget());
     }
 
     void onRecentsDrawn() {
@@ -1337,13 +1393,12 @@
     }
 
     void onUndockingTask() {
-        int dockSide = mWindowManagerProxy.getDockSide();
-        if (dockSide != WindowManager.DOCKED_INVALID && (mHomeStackResizable
-                || !mDockedStackMinimized)) {
+        int dockSide = mSplitLayout.getPrimarySplitSide();
+        if (inSplitMode() && (mHomeStackResizable || !mDockedStackMinimized)) {
             startDragging(false /* animate */, false /* touching */);
             SnapTarget target = dockSideTopLeft(dockSide)
-                    ? mSnapAlgorithm.getDismissEndTarget()
-                    : mSnapAlgorithm.getDismissStartTarget();
+                    ? mSplitLayout.getSnapAlgorithm().getDismissEndTarget()
+                    : mSplitLayout.getSnapAlgorithm().getDismissStartTarget();
 
             // Don't start immediately - give a little bit time to settle the drag resize change.
             mExitAnimationRunning = true;
@@ -1354,8 +1409,7 @@
     }
 
     private int calculatePositionForInsetBounds() {
-        mTmpRect.set(0, 0, mDisplayWidth, mDisplayHeight);
-        mTmpRect.inset(mStableInsets);
+        mSplitLayout.mDisplayLayout.getStableBounds(mTmpRect);
         return DockedDividerUtils.calculatePositionForBounds(mTmpRect, mDockSide, mDividerSize);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java
index 2486d653..bd843b0 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java
@@ -26,12 +26,13 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
 
-import android.content.Context;
 import android.graphics.PixelFormat;
 import android.os.Binder;
 import android.view.View;
 import android.view.WindowManager;
 
+import com.android.systemui.wm.SystemWindows;
+
 /**
  * Manages the window parameters of the docked stack divider.
  */
@@ -39,15 +40,16 @@
 
     private static final String WINDOW_TITLE = "DockedStackDivider";
 
-    private final WindowManager mWindowManager;
+    private final SystemWindows mSystemWindows;
     private WindowManager.LayoutParams mLp;
     private View mView;
 
-    public DividerWindowManager(Context ctx) {
-        mWindowManager = ctx.getSystemService(WindowManager.class);
+    public DividerWindowManager(SystemWindows systemWindows) {
+        mSystemWindows = systemWindows;
     }
 
-    public void add(View view, int width, int height) {
+    /** Add a divider view */
+    public void add(View view, int width, int height, int displayId) {
         mLp = new WindowManager.LayoutParams(
                 width, height, TYPE_DOCK_DIVIDER,
                 FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL
@@ -60,13 +62,13 @@
         view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
-        mWindowManager.addView(view, mLp);
+        mSystemWindows.addView(view, mLp, displayId, TYPE_DOCK_DIVIDER);
         mView = view;
     }
 
     public void remove() {
         if (mView != null) {
-            mWindowManager.removeView(mView);
+            mSystemWindows.removeView(mView);
         }
         mView = null;
     }
@@ -81,7 +83,7 @@
             changed = true;
         }
         if (changed) {
-            mWindowManager.updateViewLayout(mView, mLp);
+            mSystemWindows.updateViewLayout(mView, mLp);
         }
     }
 
@@ -95,7 +97,7 @@
             changed = true;
         }
         if (changed) {
-            mWindowManager.updateViewLayout(mView, mLp);
+            mSystemWindows.updateViewLayout(mView, mLp);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
index c6ac309..db7996e 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
@@ -31,6 +31,8 @@
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.TaskStackChangeListener;
 
+import java.util.function.Consumer;
+
 /**
  * Controller that decides when to show the {@link ForcedResizableInfoActivity}.
  */
@@ -52,6 +54,12 @@
         }
     };
 
+    private final Consumer<Boolean> mDockedStackExistsListener = exists -> {
+        if (!exists) {
+            mPackagesShownInSession.clear();
+        }
+    };
+
     /** Record of force resized task that's pending to be handled. */
     private class PendingTaskRecord {
         int taskId;
@@ -67,7 +75,7 @@
         }
     }
 
-    public ForcedResizableInfoActivityController(Context context) {
+    public ForcedResizableInfoActivityController(Context context, Divider divider) {
         mContext = context;
         ActivityManagerWrapper.getInstance().registerTaskStackListener(
                 new TaskStackChangeListener() {
@@ -87,12 +95,7 @@
                         activityLaunchOnSecondaryDisplayFailed();
                     }
                 });
-    }
-
-    public void notifyDockedStackExistsChanged(boolean exists) {
-        if (!exists) {
-            mPackagesShownInSession.clear();
-        }
+        divider.registerInSplitScreenListener(mDockedStackExistsListener);
     }
 
     public void onAppTransitionFinished() {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitDisplayLayout.java b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitDisplayLayout.java
new file mode 100644
index 0000000..b19f560
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitDisplayLayout.java
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.stackdivider;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.view.WindowManager.DOCKED_BOTTOM;
+import static android.view.WindowManager.DOCKED_INVALID;
+import static android.view.WindowManager.DOCKED_LEFT;
+import static android.view.WindowManager.DOCKED_RIGHT;
+import static android.view.WindowManager.DOCKED_TOP;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.Rect;
+import android.util.TypedValue;
+import android.view.WindowContainerTransaction;
+
+import com.android.internal.policy.DividerSnapAlgorithm;
+import com.android.internal.policy.DockedDividerUtils;
+import com.android.systemui.wm.DisplayLayout;
+
+/**
+ * Handles split-screen related internal display layout. In general, this represents the
+ * WM-facing understanding of the splits.
+ */
+public class SplitDisplayLayout {
+    /** Minimum size of an adjusted stack bounds relative to original stack bounds. Used to
+     * restrict IME adjustment so that a min portion of top stack remains visible.*/
+    private static final float ADJUSTED_STACK_FRACTION_MIN = 0.3f;
+
+    private static final int DIVIDER_WIDTH_INACTIVE_DP = 4;
+
+    SplitScreenTaskOrganizer mTiles;
+    DisplayLayout mDisplayLayout;
+    Context mContext;
+
+    // Lazy stuff
+    boolean mResourcesValid = false;
+    int mDividerSize;
+    int mDividerSizeInactive;
+    private DividerSnapAlgorithm mSnapAlgorithm = null;
+    private DividerSnapAlgorithm mMinimizedSnapAlgorithm = null;
+    Rect mPrimary = null;
+    Rect mSecondary = null;
+    Rect mAdjustedPrimary = null;
+    Rect mAdjustedSecondary = null;
+
+    public SplitDisplayLayout(Context ctx, DisplayLayout dl, SplitScreenTaskOrganizer taskTiles) {
+        mTiles = taskTiles;
+        mDisplayLayout = dl;
+        mContext = ctx;
+    }
+
+    void rotateTo(int newRotation) {
+        mDisplayLayout.rotateTo(mContext.getResources(), newRotation);
+        final Configuration config = new Configuration();
+        config.unset();
+        config.orientation = mDisplayLayout.getOrientation();
+        Rect tmpRect = new Rect(0, 0, mDisplayLayout.width(), mDisplayLayout.height());
+        tmpRect.inset(mDisplayLayout.nonDecorInsets());
+        config.windowConfiguration.setAppBounds(tmpRect);
+        tmpRect.set(0, 0, mDisplayLayout.width(), mDisplayLayout.height());
+        tmpRect.inset(mDisplayLayout.stableInsets());
+        config.screenWidthDp = (int) (tmpRect.width() / mDisplayLayout.density());
+        config.screenHeightDp = (int) (tmpRect.height() / mDisplayLayout.density());
+        mContext = mContext.createConfigurationContext(config);
+        mSnapAlgorithm = null;
+        mMinimizedSnapAlgorithm = null;
+        mResourcesValid = false;
+    }
+
+    private void updateResources() {
+        if (mResourcesValid) {
+            return;
+        }
+        mResourcesValid = true;
+        Resources res = mContext.getResources();
+        mDividerSize = DockedDividerUtils.getDividerSize(res,
+                DockedDividerUtils.getDividerInsets(res));
+        mDividerSizeInactive = (int) TypedValue.applyDimension(
+                TypedValue.COMPLEX_UNIT_DIP, DIVIDER_WIDTH_INACTIVE_DP, res.getDisplayMetrics());
+    }
+
+    int getPrimarySplitSide() {
+        return mDisplayLayout.isLandscape() ? DOCKED_LEFT : DOCKED_TOP;
+    }
+
+    boolean isMinimized() {
+        return mTiles.mSecondary.topActivityType == ACTIVITY_TYPE_HOME
+                || mTiles.mSecondary.topActivityType == ACTIVITY_TYPE_RECENTS;
+    }
+
+    DividerSnapAlgorithm getSnapAlgorithm() {
+        if (mSnapAlgorithm == null) {
+            updateResources();
+            boolean isHorizontalDivision = !mDisplayLayout.isLandscape();
+            mSnapAlgorithm = new DividerSnapAlgorithm(mContext.getResources(),
+                    mDisplayLayout.width(), mDisplayLayout.height(), mDividerSize,
+                    isHorizontalDivision, mDisplayLayout.stableInsets(), getPrimarySplitSide());
+        }
+        return mSnapAlgorithm;
+    }
+
+    DividerSnapAlgorithm getMinimizedSnapAlgorithm() {
+        if (mMinimizedSnapAlgorithm == null) {
+            updateResources();
+            boolean isHorizontalDivision = !mDisplayLayout.isLandscape();
+            mMinimizedSnapAlgorithm = new DividerSnapAlgorithm(mContext.getResources(),
+                    mDisplayLayout.width(), mDisplayLayout.height(), mDividerSize,
+                    isHorizontalDivision, mDisplayLayout.stableInsets(), getPrimarySplitSide(),
+                    true /* isMinimized */);
+        }
+        return mMinimizedSnapAlgorithm;
+    }
+
+    void resizeSplits(int position) {
+        mPrimary = mPrimary == null ? new Rect() : mPrimary;
+        mSecondary = mSecondary == null ? new Rect() : mSecondary;
+        calcSplitBounds(position, mPrimary, mSecondary);
+    }
+
+    void resizeSplits(int position, WindowContainerTransaction t) {
+        resizeSplits(position);
+        t.setBounds(mTiles.mPrimary.token, mPrimary);
+        t.setBounds(mTiles.mSecondary.token, mSecondary);
+
+        t.setSmallestScreenWidthDp(mTiles.mPrimary.token,
+                getSmallestWidthDpForBounds(mContext, mDisplayLayout, mPrimary));
+        t.setSmallestScreenWidthDp(mTiles.mSecondary.token,
+                getSmallestWidthDpForBounds(mContext, mDisplayLayout, mSecondary));
+    }
+
+    void calcSplitBounds(int position, @NonNull Rect outPrimary, @NonNull Rect outSecondary) {
+        int dockSide = getPrimarySplitSide();
+        DockedDividerUtils.calculateBoundsForPosition(position, dockSide, outPrimary,
+                mDisplayLayout.width(), mDisplayLayout.height(), mDividerSize);
+
+        DockedDividerUtils.calculateBoundsForPosition(position,
+                DockedDividerUtils.invertDockSide(dockSide), outSecondary, mDisplayLayout.width(),
+                mDisplayLayout.height(), mDividerSize);
+    }
+
+    Rect calcMinimizedHomeStackBounds() {
+        DividerSnapAlgorithm.SnapTarget miniMid = getMinimizedSnapAlgorithm().getMiddleTarget();
+        Rect homeBounds = new Rect();
+        DockedDividerUtils.calculateBoundsForPosition(miniMid.position,
+                DockedDividerUtils.invertDockSide(getPrimarySplitSide()), homeBounds,
+                mDisplayLayout.width(), mDisplayLayout.height(), mDividerSize);
+        return homeBounds;
+    }
+
+    /**
+     * Updates the adjustment depending on it's current state.
+     */
+    void updateAdjustedBounds(int currImeTop, int startTop, int finalTop) {
+        updateAdjustedBounds(mDisplayLayout, currImeTop, startTop, finalTop, mDividerSize,
+                mDividerSizeInactive, mPrimary, mSecondary);
+    }
+
+    /**
+     * Updates the adjustment depending on it's current state.
+     */
+    private void updateAdjustedBounds(DisplayLayout dl, int currImeTop, int startTop, int finalTop,
+            int dividerWidth, int dividerWidthInactive, Rect primaryBounds, Rect secondaryBounds) {
+        adjustForIME(dl, currImeTop, startTop, finalTop, dividerWidth, dividerWidthInactive,
+                primaryBounds, secondaryBounds);
+    }
+
+    /** Assumes top/bottom split. Splits are not adjusted for left/right splits. */
+    private void adjustForIME(DisplayLayout dl, int currImeTop, int startTop, int finalTop,
+            int dividerWidth, int dividerWidthInactive, Rect primaryBounds, Rect secondaryBounds) {
+        if (mAdjustedPrimary == null) {
+            mAdjustedPrimary = new Rect();
+            mAdjustedSecondary = new Rect();
+        }
+
+        final Rect displayStableRect = new Rect();
+        dl.getStableBounds(displayStableRect);
+
+        final boolean showing = finalTop < startTop;
+        final float progress = ((float) (currImeTop - startTop)) / (finalTop - startTop);
+        final float dividerSquish = showing ? progress : 1.f - progress;
+        final int currDividerWidth =
+                (int) (dividerWidthInactive * dividerSquish + dividerWidth * (1.f - dividerSquish));
+
+        final int minTopStackBottom = displayStableRect.top
+                + (int) ((mPrimary.bottom - displayStableRect.top) * ADJUSTED_STACK_FRACTION_MIN);
+        final int minImeTop = minTopStackBottom + currDividerWidth;
+
+        // Calculate an offset which shifts the stacks up by the height of the IME, but still
+        // leaves at least 30% of the top stack visible.
+        final int yOffset = Math.max(0, dl.height() - Math.max(currImeTop, minImeTop));
+
+        // TOP
+        // Reduce the offset by an additional small amount to squish the divider bar.
+        mAdjustedPrimary.set(primaryBounds);
+        mAdjustedPrimary.offset(0, -yOffset + (dividerWidth - currDividerWidth));
+
+        // BOTTOM
+        mAdjustedSecondary.set(secondaryBounds);
+        mAdjustedSecondary.offset(0, -yOffset);
+    }
+
+    static int getSmallestWidthDpForBounds(@NonNull Context context, DisplayLayout dl,
+            Rect bounds) {
+        int dividerSize = DockedDividerUtils.getDividerSize(context.getResources(),
+                DockedDividerUtils.getDividerInsets(context.getResources()));
+
+        int minWidth = Integer.MAX_VALUE;
+
+        // Go through all screen orientations and find the orientation in which the task has the
+        // smallest width.
+        Rect tmpRect = new Rect();
+        Rect rotatedDisplayRect = new Rect();
+        Rect displayRect = new Rect(0, 0, dl.width(), dl.height());
+
+        DisplayLayout tmpDL = new DisplayLayout();
+        for (int rotation = 0; rotation < 4; rotation++) {
+            tmpDL.set(dl);
+            tmpDL.rotateTo(context.getResources(), rotation);
+            DividerSnapAlgorithm snap = initSnapAlgorithmForRotation(context, tmpDL, dividerSize);
+
+            tmpRect.set(bounds);
+            DisplayLayout.rotateBounds(tmpRect, displayRect, rotation - dl.rotation());
+            rotatedDisplayRect.set(0, 0, tmpDL.width(), tmpDL.height());
+            final int dockSide = getPrimarySplitSide(tmpRect, rotatedDisplayRect,
+                    tmpDL.getOrientation());
+            final int position = DockedDividerUtils.calculatePositionForBounds(tmpRect, dockSide,
+                    dividerSize);
+
+            final int snappedPosition =
+                    snap.calculateNonDismissingSnapTarget(position).position;
+            DockedDividerUtils.calculateBoundsForPosition(snappedPosition, dockSide, tmpRect,
+                    tmpDL.width(), tmpDL.height(), dividerSize);
+            Rect insettedDisplay = new Rect(rotatedDisplayRect);
+            insettedDisplay.inset(tmpDL.stableInsets());
+            tmpRect.intersect(insettedDisplay);
+            minWidth = Math.min(tmpRect.width(), minWidth);
+        }
+        return (int) (minWidth / dl.density());
+    }
+
+    static DividerSnapAlgorithm initSnapAlgorithmForRotation(Context context, DisplayLayout dl,
+            int dividerSize) {
+        final Configuration config = new Configuration();
+        config.unset();
+        config.orientation = dl.getOrientation();
+        Rect tmpRect = new Rect(0, 0, dl.width(), dl.height());
+        tmpRect.inset(dl.nonDecorInsets());
+        config.windowConfiguration.setAppBounds(tmpRect);
+        tmpRect.set(0, 0, dl.width(), dl.height());
+        tmpRect.inset(dl.stableInsets());
+        config.screenWidthDp = (int) (tmpRect.width() / dl.density());
+        config.screenHeightDp = (int) (tmpRect.height() / dl.density());
+        final Context rotationContext = context.createConfigurationContext(config);
+        return new DividerSnapAlgorithm(
+                rotationContext.getResources(), dl.width(), dl.height(), dividerSize,
+                config.orientation == ORIENTATION_PORTRAIT, dl.stableInsets());
+    }
+
+    /**
+     * Get the current primary-split side. Determined by its location of {@param bounds} within
+     * {@param displayRect} but if both are the same, it will try to dock to each side and determine
+     * if allowed in its respected {@param orientation}.
+     *
+     * @param bounds bounds of the primary split task to get which side is docked
+     * @param displayRect bounds of the display that contains the primary split task
+     * @param orientation the origination of device
+     * @return current primary-split side
+     */
+    static int getPrimarySplitSide(Rect bounds, Rect displayRect, int orientation) {
+        if (orientation == ORIENTATION_PORTRAIT) {
+            // Portrait mode, docked either at the top or the bottom.
+            final int diff = (displayRect.bottom - bounds.bottom) - (bounds.top - displayRect.top);
+            if (diff < 0) {
+                return DOCKED_BOTTOM;
+            } else {
+                // Top is default
+                return DOCKED_TOP;
+            }
+        } else if (orientation == ORIENTATION_LANDSCAPE) {
+            // Landscape mode, docked either on the left or on the right.
+            final int diff = (displayRect.right - bounds.right) - (bounds.left - displayRect.left);
+            if (diff < 0) {
+                return DOCKED_RIGHT;
+            }
+            return DOCKED_LEFT;
+        }
+        return DOCKED_INVALID;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
new file mode 100644
index 0000000..0a54d2f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.stackdivider;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import android.app.ActivityManager.RunningTaskInfo;
+import android.app.ITaskOrganizerController;
+import android.app.WindowConfiguration;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.Pools;
+import android.view.Display;
+import android.view.ITaskOrganizer;
+import android.view.IWindowContainer;
+import android.view.SurfaceControl;
+import android.view.SurfaceSession;
+
+class SplitScreenTaskOrganizer extends ITaskOrganizer.Stub {
+    private static final String TAG = "SplitScreenTaskOrganizer";
+    private static final boolean DEBUG = Divider.DEBUG;
+
+    RunningTaskInfo mPrimary;
+    RunningTaskInfo mSecondary;
+    SurfaceControl mPrimarySurface;
+    SurfaceControl mSecondarySurface;
+    SurfaceControl mPrimaryDim;
+    SurfaceControl mSecondaryDim;
+    final Divider mDivider;
+
+    private final Pools.SynchronizedPool<SurfaceControl.Transaction> mTransactionPool =
+            new Pools.SynchronizedPool<>(4);
+
+    SplitScreenTaskOrganizer(Divider divider) {
+        mDivider = divider;
+    }
+
+    void init(ITaskOrganizerController organizerController, SurfaceSession session)
+            throws RemoteException {
+        organizerController.registerTaskOrganizer(this, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+        organizerController.registerTaskOrganizer(this, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
+        mPrimary = organizerController.createRootTask(Display.DEFAULT_DISPLAY,
+                WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+        mSecondary = organizerController.createRootTask(Display.DEFAULT_DISPLAY,
+                WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
+        mPrimarySurface = mPrimary.token.getLeash();
+        mSecondarySurface = mSecondary.token.getLeash();
+
+        // Initialize dim surfaces:
+        mPrimaryDim = new SurfaceControl.Builder(session).setParent(mPrimarySurface)
+                .setColorLayer().setName("Primary Divider Dim").build();
+        mSecondaryDim = new SurfaceControl.Builder(session).setParent(mSecondarySurface)
+                .setColorLayer().setName("Secondary Divider Dim").build();
+        SurfaceControl.Transaction t = getTransaction();
+        t.setLayer(mPrimaryDim, Integer.MAX_VALUE);
+        t.setColor(mPrimaryDim, new float[]{0f, 0f, 0f});
+        t.setLayer(mSecondaryDim, Integer.MAX_VALUE);
+        t.setColor(mSecondaryDim, new float[]{0f, 0f, 0f});
+        t.apply();
+        releaseTransaction(t);
+    }
+
+    SurfaceControl.Transaction getTransaction() {
+        SurfaceControl.Transaction t = mTransactionPool.acquire();
+        if (t == null) {
+            return new SurfaceControl.Transaction();
+        }
+        return t;
+    }
+
+    void releaseTransaction(SurfaceControl.Transaction t) {
+        mTransactionPool.release(t);
+    }
+
+    @Override
+    public void taskAppeared(RunningTaskInfo taskInfo) {
+    }
+
+    @Override
+    public void taskVanished(IWindowContainer container) {
+    }
+
+    @Override
+    public void transactionReady(int id, SurfaceControl.Transaction t) {
+    }
+
+    @Override
+    public void onTaskInfoChanged(RunningTaskInfo taskInfo) {
+        if (taskInfo.displayId != DEFAULT_DISPLAY) {
+            return;
+        }
+        mDivider.getHandler().post(() -> handleTaskInfoChanged(taskInfo));
+    }
+
+    /**
+     * This is effectively a finite state machine which moves between the various split-screen
+     * presentations based on the contents of the split regions.
+     */
+    private void handleTaskInfoChanged(RunningTaskInfo info) {
+        final boolean primaryWasEmpty = mPrimary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
+        final boolean secondaryWasEmpty = mSecondary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
+        if (info.token.asBinder() == mPrimary.token.asBinder()) {
+            mPrimary = info;
+        } else if (info.token.asBinder() == mSecondary.token.asBinder()) {
+            mSecondary = info;
+        }
+        final boolean primaryIsEmpty = mPrimary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
+        final boolean secondaryIsEmpty = mSecondary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
+        if (DEBUG) {
+            Log.d(TAG, "onTaskInfoChanged " + mPrimary + "  " + mSecondary);
+        }
+        if (primaryIsEmpty || secondaryIsEmpty) {
+            // At-least one of the splits is empty which means we are currently transitioning
+            // into or out-of split-screen mode.
+            if (DEBUG) {
+                Log.d(TAG, " at-least one split empty " + mPrimary.topActivityType
+                        + "  " + mSecondary.topActivityType);
+            }
+            if (mDivider.inSplitMode()) {
+                // Was in split-mode, which means we are leaving split, so continue that.
+                // This happens when the stack in the primary-split is dismissed.
+                if (DEBUG) {
+                    Log.d(TAG, "    was in split, so this means leave it "
+                            + mPrimary.topActivityType + "  " + mSecondary.topActivityType);
+                }
+                WindowManagerProxy.applyDismissSplit(this, true /* dismissOrMaximize */);
+                mDivider.updateVisibility(false /* visible */);
+            } else if (!primaryIsEmpty && primaryWasEmpty && secondaryWasEmpty) {
+                // Wasn't in split-mode (both were empty), but now that the primary split is
+                // populated, we should fully enter split by moving everything else into secondary.
+                // This just tells window-manager to reparent things, the UI will respond
+                // when it gets new task info for the secondary split.
+                if (DEBUG) {
+                    Log.d(TAG, "   was not in split, but primary is populated, so enter it");
+                }
+                mDivider.startEnterSplit();
+            }
+        } else if (mSecondary.topActivityType == ACTIVITY_TYPE_HOME
+                || mSecondary.topActivityType == ACTIVITY_TYPE_RECENTS) {
+            // Both splits are populated but the secondary split has a home/recents stack on top,
+            // so enter minimized mode.
+            mDivider.ensureMinimizedSplit();
+        } else {
+            // Both splits are populated by normal activities, so make sure we aren't minimized.
+            mDivider.ensureNormalSplit();
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
index 228aab5..7685733 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
@@ -16,16 +16,25 @@
 
 package com.android.systemui.stackdivider;
 
-import static android.view.WindowManager.DOCKED_INVALID;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.Display.DEFAULT_DISPLAY;
 
+import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
 import android.graphics.Rect;
 import android.os.RemoteException;
 import android.util.Log;
+import android.view.Display;
+import android.view.IWindowContainer;
+import android.view.WindowContainerTransaction;
 import android.view.WindowManagerGlobal;
 
 import com.android.internal.annotations.GuardedBy;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
@@ -35,88 +44,20 @@
 public class WindowManagerProxy {
 
     private static final String TAG = "WindowManagerProxy";
+    private static final int[] HOME_AND_RECENTS = {ACTIVITY_TYPE_HOME, ACTIVITY_TYPE_RECENTS};
 
     private static final WindowManagerProxy sInstance = new WindowManagerProxy();
 
     @GuardedBy("mDockedRect")
     private final Rect mDockedRect = new Rect();
-    private final Rect mTempDockedTaskRect = new Rect();
-    private final Rect mTempDockedInsetRect = new Rect();
-    private final Rect mTempOtherTaskRect = new Rect();
-    private final Rect mTempOtherInsetRect = new Rect();
 
     private final Rect mTmpRect1 = new Rect();
-    private final Rect mTmpRect2 = new Rect();
-    private final Rect mTmpRect3 = new Rect();
-    private final Rect mTmpRect4 = new Rect();
-    private final Rect mTmpRect5 = new Rect();
 
     @GuardedBy("mDockedRect")
     private final Rect mTouchableRegion = new Rect();
 
-    private boolean mDimLayerVisible;
-    private int mDimLayerTargetWindowingMode;
-    private float mDimLayerAlpha;
-
     private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
 
-    private final Runnable mResizeRunnable = new Runnable() {
-        @Override
-        public void run() {
-            synchronized (mDockedRect) {
-                mTmpRect1.set(mDockedRect);
-                mTmpRect2.set(mTempDockedTaskRect);
-                mTmpRect3.set(mTempDockedInsetRect);
-                mTmpRect4.set(mTempOtherTaskRect);
-                mTmpRect5.set(mTempOtherInsetRect);
-            }
-            try {
-                ActivityTaskManager.getService()
-                        .resizeDockedStack(mTmpRect1,
-                                mTmpRect2.isEmpty() ? null : mTmpRect2,
-                                mTmpRect3.isEmpty() ? null : mTmpRect3,
-                                mTmpRect4.isEmpty() ? null : mTmpRect4,
-                                mTmpRect5.isEmpty() ? null : mTmpRect5);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Failed to resize stack: " + e);
-            }
-        }
-    };
-
-    private final Runnable mDismissRunnable = new Runnable() {
-        @Override
-        public void run() {
-            try {
-                ActivityTaskManager.getService().dismissSplitScreenMode(false /* onTop */);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Failed to remove stack: " + e);
-            }
-        }
-    };
-
-    private final Runnable mMaximizeRunnable = new Runnable() {
-        @Override
-        public void run() {
-            try {
-                ActivityTaskManager.getService().dismissSplitScreenMode(true /* onTop */);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Failed to resize stack: " + e);
-            }
-        }
-    };
-
-    private final Runnable mDimLayerRunnable = new Runnable() {
-        @Override
-        public void run() {
-            try {
-                WindowManagerGlobal.getWindowManagerService().setResizeDimLayer(mDimLayerVisible,
-                        mDimLayerTargetWindowingMode, mDimLayerAlpha);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Failed to resize stack: " + e);
-            }
-        }
-    };
-
     private final Runnable mSetTouchableRegionRunnable = new Runnable() {
         @Override
         public void run() {
@@ -139,40 +80,9 @@
         return sInstance;
     }
 
-    public void resizeDockedStack(Rect docked, Rect tempDockedTaskRect, Rect tempDockedInsetRect,
-            Rect tempOtherTaskRect, Rect tempOtherInsetRect) {
-        synchronized (mDockedRect) {
-            mDockedRect.set(docked);
-            if (tempDockedTaskRect != null) {
-                mTempDockedTaskRect.set(tempDockedTaskRect);
-            } else {
-                mTempDockedTaskRect.setEmpty();
-            }
-            if (tempDockedInsetRect != null) {
-                mTempDockedInsetRect.set(tempDockedInsetRect);
-            } else {
-                mTempDockedInsetRect.setEmpty();
-            }
-            if (tempOtherTaskRect != null) {
-                mTempOtherTaskRect.set(tempOtherTaskRect);
-            } else {
-                mTempOtherTaskRect.setEmpty();
-            }
-            if (tempOtherInsetRect != null) {
-                mTempOtherInsetRect.set(tempOtherInsetRect);
-            } else {
-                mTempOtherInsetRect.setEmpty();
-            }
-        }
-        mExecutor.execute(mResizeRunnable);
-    }
-
-    public void dismissDockedStack() {
-        mExecutor.execute(mDismissRunnable);
-    }
-
-    public void maximizeDockedStack() {
-        mExecutor.execute(mMaximizeRunnable);
+    void dismissOrMaximizeDocked(
+            final SplitScreenTaskOrganizer tiles, final boolean dismissOrMaximize) {
+        mExecutor.execute(() -> applyDismissSplit(tiles, dismissOrMaximize));
     }
 
     public void setResizing(final boolean resizing) {
@@ -188,26 +98,204 @@
         });
     }
 
-    public int getDockSide() {
-        try {
-            return WindowManagerGlobal.getWindowManagerService().getDockedStackSide();
-        } catch (RemoteException e) {
-            Log.w(TAG, "Failed to get dock side: " + e);
-        }
-        return DOCKED_INVALID;
-    }
-
-    public void setResizeDimLayer(boolean visible, int targetWindowingMode, float alpha) {
-        mDimLayerVisible = visible;
-        mDimLayerTargetWindowingMode = targetWindowingMode;
-        mDimLayerAlpha = alpha;
-        mExecutor.execute(mDimLayerRunnable);
-    }
-
+    /** Sets a touch region */
     public void setTouchRegion(Rect region) {
         synchronized (mDockedRect) {
             mTouchableRegion.set(region);
         }
         mExecutor.execute(mSetTouchableRegionRunnable);
     }
+
+    static void applyResizeSplits(int position, SplitDisplayLayout splitLayout) {
+        WindowContainerTransaction t = new WindowContainerTransaction();
+        splitLayout.resizeSplits(position, t);
+        try {
+            ActivityTaskManager.getTaskOrganizerController().applyContainerTransaction(t,
+                    null /* organizer */);
+        } catch (RemoteException e) {
+        }
+    }
+
+    private static boolean getHomeAndRecentsTasks(List<IWindowContainer> out,
+            IWindowContainer parent) {
+        boolean resizable = false;
+        try {
+            List<ActivityManager.RunningTaskInfo> rootTasks = parent == null
+                    ? ActivityTaskManager.getTaskOrganizerController().getRootTasks(
+                            Display.DEFAULT_DISPLAY, HOME_AND_RECENTS)
+                    : ActivityTaskManager.getTaskOrganizerController().getChildTasks(parent,
+                            HOME_AND_RECENTS);
+            for (int i = 0, n = rootTasks.size(); i < n; ++i) {
+                final ActivityManager.RunningTaskInfo ti = rootTasks.get(i);
+                out.add(ti.token);
+                if (ti.topActivityType == ACTIVITY_TYPE_HOME) {
+                    resizable = ti.isResizable();
+                }
+            }
+        } catch (RemoteException e) {
+        }
+        return resizable;
+    }
+
+    static void applyHomeTasksMinimized(SplitDisplayLayout layout, IWindowContainer parent) {
+        applyHomeTasksMinimized(layout, parent, null /* transaction */);
+    }
+
+    /**
+     * Assign a fixed override-bounds to home tasks that reflect their geometry while the primary
+     * split is minimized. This actually "sticks out" of the secondary split area, but when in
+     * minimized mode, the secondary split gets a 'negative' crop to expose it.
+     */
+    static boolean applyHomeTasksMinimized(SplitDisplayLayout layout, IWindowContainer parent,
+            WindowContainerTransaction t) {
+        // Resize the home/recents stacks to the larger minimized-state size
+        final Rect homeBounds;
+        final ArrayList<IWindowContainer> homeStacks = new ArrayList<>();
+        boolean isHomeResizable = getHomeAndRecentsTasks(homeStacks, parent);
+        if (isHomeResizable) {
+            homeBounds = layout.calcMinimizedHomeStackBounds();
+        } else {
+            homeBounds = new Rect(0, 0, layout.mDisplayLayout.width(),
+                    layout.mDisplayLayout.height());
+        }
+        WindowContainerTransaction wct = t != null ? t : new WindowContainerTransaction();
+        for (int i = homeStacks.size() - 1; i >= 0; --i) {
+            wct.setBounds(homeStacks.get(i), homeBounds);
+        }
+        if (t != null) {
+            return isHomeResizable;
+        }
+        try {
+            ActivityTaskManager.getTaskOrganizerController().applyContainerTransaction(wct,
+                    null /* organizer */);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to resize home stacks ", e);
+        }
+        return isHomeResizable;
+    }
+
+    /**
+     * Finishes entering split-screen by reparenting all FULLSCREEN tasks into the secondary split.
+     * This assumes there is already something in the primary split since that is usually what
+     * triggers a call to this. In the same transaction, this overrides the home task bounds via
+     * {@link #applyHomeTasksMinimized}.
+     *
+     * @return whether the home stack is resizable
+     */
+    static boolean applyEnterSplit(SplitScreenTaskOrganizer tiles, SplitDisplayLayout layout) {
+        try {
+            // Set launchtile first so that any stack created after
+            // getAllStackInfos and before reparent (even if unlikely) are placed
+            // correctly.
+            ActivityTaskManager.getTaskOrganizerController().setLaunchRoot(
+                    DEFAULT_DISPLAY, tiles.mSecondary.token);
+            List<ActivityManager.RunningTaskInfo> rootTasks =
+                    ActivityTaskManager.getTaskOrganizerController().getRootTasks(DEFAULT_DISPLAY,
+                            null /* activityTypes */);
+            WindowContainerTransaction wct = new WindowContainerTransaction();
+            if (rootTasks.isEmpty()) {
+                return false;
+            }
+            for (int i = rootTasks.size() - 1; i >= 0; --i) {
+                if (rootTasks.get(i).configuration.windowConfiguration.getWindowingMode()
+                        != WINDOWING_MODE_FULLSCREEN) {
+                    continue;
+                }
+                wct.reparent(rootTasks.get(i).token, tiles.mSecondary.token,
+                        true /* onTop */);
+            }
+            boolean isHomeResizable = applyHomeTasksMinimized(layout, null /* parent */, wct);
+            ActivityTaskManager.getTaskOrganizerController()
+                    .applyContainerTransaction(wct, null /* organizer */);
+            return isHomeResizable;
+        } catch (RemoteException e) {
+            Log.w(TAG, "Error moving fullscreen tasks to secondary split: " + e);
+        }
+        return false;
+    }
+
+    private static boolean isHomeOrRecentTask(ActivityManager.RunningTaskInfo ti) {
+        final int atype = ti.configuration.windowConfiguration.getActivityType();
+        return atype == ACTIVITY_TYPE_HOME || atype == ACTIVITY_TYPE_RECENTS;
+    }
+
+    /**
+     * Reparents all tile members back to their display and resets home task override bounds.
+     * @param dismissOrMaximize When {@code true} this resolves the split by closing the primary
+     *                          split (thus resulting in the top of the secondary split becoming
+     *                          fullscreen. {@code false} resolves the other way.
+     */
+    static void applyDismissSplit(SplitScreenTaskOrganizer tiles, boolean dismissOrMaximize) {
+        try {
+            // Set launch root first so that any task created after getChildContainers and
+            // before reparent (pretty unlikely) are put into fullscreen.
+            ActivityTaskManager.getTaskOrganizerController().setLaunchRoot(Display.DEFAULT_DISPLAY,
+                    null);
+            // TODO(task-org): Once task-org is more complete, consider using Appeared/Vanished
+            //                 plus specific APIs to clean this up.
+            List<ActivityManager.RunningTaskInfo> primaryChildren =
+                    ActivityTaskManager.getTaskOrganizerController().getChildTasks(
+                            tiles.mPrimary.token, null /* activityTypes */);
+            List<ActivityManager.RunningTaskInfo> secondaryChildren =
+                    ActivityTaskManager.getTaskOrganizerController().getChildTasks(
+                            tiles.mSecondary.token, null /* activityTypes */);
+            // In some cases (eg. non-resizable is launched), system-server will leave split-screen.
+            // as a result, the above will not capture any tasks; yet, we need to clean-up the
+            // home task bounds.
+            List<ActivityManager.RunningTaskInfo> freeHomeAndRecents =
+                    ActivityTaskManager.getTaskOrganizerController().getRootTasks(
+                            Display.DEFAULT_DISPLAY, HOME_AND_RECENTS);
+            if (primaryChildren.isEmpty() && secondaryChildren.isEmpty()
+                    && freeHomeAndRecents.isEmpty()) {
+                return;
+            }
+            WindowContainerTransaction wct = new WindowContainerTransaction();
+            if (dismissOrMaximize) {
+                // Dismissing, so move all primary split tasks first
+                for (int i = primaryChildren.size() - 1; i >= 0; --i) {
+                    wct.reparent(primaryChildren.get(i).token, null /* parent */,
+                            true /* onTop */);
+                }
+                // Don't need to worry about home tasks because they are already in the "proper"
+                // order within the secondary split.
+                for (int i = secondaryChildren.size() - 1; i >= 0; --i) {
+                    final ActivityManager.RunningTaskInfo ti = secondaryChildren.get(i);
+                    wct.reparent(ti.token, null /* parent */, true /* onTop */);
+                    if (isHomeOrRecentTask(ti)) {
+                        wct.setBounds(ti.token, null);
+                    }
+                }
+            } else {
+                // Maximize, so move non-home secondary split first
+                for (int i = secondaryChildren.size() - 1; i >= 0; --i) {
+                    if (isHomeOrRecentTask(secondaryChildren.get(i))) {
+                        continue;
+                    }
+                    wct.reparent(secondaryChildren.get(i).token, null /* parent */,
+                            true /* onTop */);
+                }
+                // Find and place home tasks in-between. This simulates the fact that there was
+                // nothing behind the primary split's tasks.
+                for (int i = secondaryChildren.size() - 1; i >= 0; --i) {
+                    final ActivityManager.RunningTaskInfo ti = secondaryChildren.get(i);
+                    if (isHomeOrRecentTask(ti)) {
+                        wct.reparent(ti.token, null /* parent */, true /* onTop */);
+                        // reset bounds too
+                        wct.setBounds(ti.token, null);
+                    }
+                }
+                for (int i = primaryChildren.size() - 1; i >= 0; --i) {
+                    wct.reparent(primaryChildren.get(i).token, null /* parent */,
+                            true /* onTop */);
+                }
+            }
+            for (int i = freeHomeAndRecents.size() - 1; i >= 0; --i) {
+                wct.setBounds(freeHomeAndRecents.get(i).token, null);
+            }
+            ActivityTaskManager.getTaskOrganizerController().applyContainerTransaction(wct,
+                    null /* organizer */);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to remove stack: " + e);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
index 4d6764e..b43fe73 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
@@ -31,20 +31,17 @@
 import android.util.Log;
 
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.statusbar.dagger.StatusBarModule;
 import com.android.systemui.statusbar.phone.NotificationListenerWithPlugins;
 
 import java.util.ArrayList;
 import java.util.List;
 
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
 /**
  * This class handles listening to notification updates and passing them along to
  * NotificationPresenter to be displayed to the user.
  */
 @SuppressLint("OverrideAbstract")
-@Singleton
 public class NotificationListener extends NotificationListenerWithPlugins {
     private static final String TAG = "NotificationListener";
 
@@ -54,7 +51,9 @@
     private final List<NotificationHandler> mNotificationHandlers = new ArrayList<>();
     private final ArrayList<NotificationSettingsListener> mSettingsListeners = new ArrayList<>();
 
-    @Inject
+    /**
+     * Injected constructor. See {@link StatusBarModule}.
+     */
     public NotificationListener(
             Context context,
             NotificationManager notificationManager,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index a457266..d0af106 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -53,6 +53,7 @@
 import com.android.systemui.Interpolators;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.dagger.StatusBarModule;
 import com.android.systemui.statusbar.notification.NotificationEntryListener;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -73,16 +74,12 @@
 import java.util.List;
 import java.util.Set;
 
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
 import dagger.Lazy;
 
 /**
  * Handles tasks and state related to media notifications. For example, there is a 'current' media
  * notification, which this class keeps track of.
  */
-@Singleton
 public class NotificationMediaManager implements Dumpable {
     private static final String TAG = "NotificationMediaManager";
     public static final boolean DEBUG_MEDIA = false;
@@ -101,11 +98,10 @@
         PAUSED_MEDIA_STATES.add(PlaybackState.STATE_ERROR);
     }
 
-
     private final NotificationEntryManager mEntryManager;
 
     @Nullable
-    private Lazy<NotificationShadeWindowController> mStatusBarWindowController;
+    private Lazy<NotificationShadeWindowController> mNotificationShadeWindowController;
 
     @Nullable
     private BiometricUnlockController mBiometricUnlockController;
@@ -176,11 +172,13 @@
         }
     };
 
-    @Inject
+    /**
+     * Injected constructor. See {@link StatusBarModule}.
+     */
     public NotificationMediaManager(
             Context context,
             Lazy<StatusBar> statusBarLazy,
-            Lazy<NotificationShadeWindowController> statusBarWindowController,
+            Lazy<NotificationShadeWindowController> notificationShadeWindowController,
             NotificationEntryManager notificationEntryManager,
             MediaArtworkProcessor mediaArtworkProcessor,
             KeyguardBypassController keyguardBypassController) {
@@ -194,7 +192,7 @@
                 Context.MEDIA_SESSION_SERVICE);
         // TODO: use KeyguardStateController#isOccluded to remove this dependency
         mStatusBarLazy = statusBarLazy;
-        mStatusBarWindowController = statusBarWindowController;
+        mNotificationShadeWindowController = notificationShadeWindowController;
         mEntryManager = notificationEntryManager;
         notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
             @Override
@@ -525,7 +523,8 @@
             }
         }
 
-        NotificationShadeWindowController windowController = mStatusBarWindowController.get();
+        NotificationShadeWindowController windowController =
+                mNotificationShadeWindowController.get();
         boolean hideBecauseOccluded = mStatusBarLazy.get().isOccluded();
 
         final boolean hasArtwork = artworkDrawable != null;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index f3783c8..ebc2fa6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -54,6 +54,7 @@
 import com.android.systemui.R;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.dagger.StatusBarModule;
 import com.android.systemui.statusbar.notification.NotificationEntryListener;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -70,9 +71,6 @@
 import java.util.Objects;
 import java.util.Set;
 
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
 import dagger.Lazy;
 
 /**
@@ -81,7 +79,6 @@
  * interaction, keeping track of notifications to remove when NotificationPresenter is collapsed,
  * and handling clicks on remote views.
  */
-@Singleton
 public class NotificationRemoteInputManager implements Dumpable {
     public static final boolean ENABLE_REMOTE_INPUT =
             SystemProperties.getBoolean("debug.enable_remote_input", true);
@@ -257,7 +254,9 @@
         }
     };
 
-    @Inject
+    /**
+     * Injected constructor. See {@link StatusBarModule}.
+     */
     public NotificationRemoteInputManager(
             Context context,
             NotificationLockscreenUserManager lockscreenUserManager,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index 37f9f88..7e70c20 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -29,6 +29,7 @@
 import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.dagger.StatusBarModule;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
@@ -46,9 +47,6 @@
 import java.util.List;
 import java.util.Stack;
 
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
 /**
  * NotificationViewHierarchyManager manages updating the view hierarchy of notification views based
  * on their group structure. For example, if a notification becomes bundled with another,
@@ -56,7 +54,6 @@
  * tell NotificationListContainer which notifications to display, and inform it of changes to those
  * notifications that might affect their display.
  */
-@Singleton
 public class NotificationViewHierarchyManager implements DynamicPrivacyController.Listener {
     private static final String TAG = "NotificationViewHierarchyManager";
 
@@ -94,8 +91,12 @@
     // the problem.
     private boolean mIsHandleDynamicPrivacyChangeScheduled;
 
-    @Inject
-    public NotificationViewHierarchyManager(Context context, @Main Handler mainHandler,
+    /**
+     * Injected constructor. See {@link StatusBarModule}.
+     */
+    public NotificationViewHierarchyManager(
+            Context context,
+            @Main Handler mainHandler,
             NotificationLockscreenUserManager notificationLockscreenUserManager,
             NotificationGroupManager groupManager,
             VisualStabilityManager visualStabilityManager,
@@ -104,8 +105,7 @@
             KeyguardBypassController bypassController,
             BubbleController bubbleController,
             DynamicPrivacyController privacyController,
-            ForegroundServiceSectionController fgsSectionController
-    ) {
+            ForegroundServiceSectionController fgsSectionController) {
         mContext = context;
         mHandler = mainHandler;
         mLockscreenUserManager = notificationLockscreenUserManager;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ScreenRecordDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/ScreenRecordDrawable.java
new file mode 100644
index 0000000..44ef6b4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ScreenRecordDrawable.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.DrawableWrapper;
+import android.util.AttributeSet;
+
+import com.android.systemui.R;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+/**
+ * The screen record drawable draws a colored background and either a countdown or circle to
+ * indicate that the screen is being recorded.
+ */
+public class ScreenRecordDrawable extends DrawableWrapper {
+    private Drawable mFillDrawable;
+    private int mHorizontalPadding;
+    private int mLevel;
+    private float mTextSize;
+    private float mIconRadius;
+    private Paint mPaint;
+
+    /** No-arg constructor used by drawable inflation. */
+    public ScreenRecordDrawable() {
+        super(null);
+    }
+
+    @Override
+    public void inflate(@NonNull Resources r, @NonNull XmlPullParser parser,
+            @NonNull AttributeSet attrs, @Nullable Resources.Theme theme)
+            throws XmlPullParserException, IOException {
+        super.inflate(r, parser, attrs, theme);
+        setDrawable(r.getDrawable(R.drawable.ic_screen_record_background, theme).mutate());
+        mFillDrawable = r.getDrawable(R.drawable.ic_screen_record_background, theme).mutate();
+        mHorizontalPadding = r.getDimensionPixelSize(R.dimen.status_bar_horizontal_padding);
+
+        mTextSize = r.getDimensionPixelSize(R.dimen.screenrecord_status_text_size);
+        mIconRadius = r.getDimensionPixelSize(R.dimen.screenrecord_status_icon_radius);
+        mLevel = attrs.getAttributeIntValue(null, "level", 0);
+
+        mPaint = new Paint();
+        mPaint.setTextAlign(Paint.Align.CENTER);
+        mPaint.setColor(Color.WHITE);
+        mPaint.setTextSize(mTextSize);
+        mPaint.setFakeBoldText(true);
+    }
+
+    @Override
+    public boolean canApplyTheme() {
+        return mFillDrawable.canApplyTheme() || super.canApplyTheme();
+    }
+
+    @Override
+    public void applyTheme(Resources.Theme t) {
+        super.applyTheme(t);
+        mFillDrawable.applyTheme(t);
+    }
+
+    @Override
+    protected void onBoundsChange(Rect bounds) {
+        super.onBoundsChange(bounds);
+        mFillDrawable.setBounds(bounds);
+    }
+
+    @Override
+    public boolean onLayoutDirectionChanged(int layoutDirection) {
+        mFillDrawable.setLayoutDirection(layoutDirection);
+        return super.onLayoutDirectionChanged(layoutDirection);
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        super.draw(canvas);
+        mFillDrawable.draw(canvas);
+
+        Rect b = mFillDrawable.getBounds();
+        if (mLevel > 0) {
+            String val = String.valueOf(mLevel);
+            Rect textBounds = new Rect();
+            mPaint.getTextBounds(val, 0, val.length(), textBounds);
+            float yOffset = textBounds.height() / 4; // half, and half again since it's centered
+            canvas.drawText(val, b.centerX(), b.centerY() + yOffset, mPaint);
+        } else {
+            canvas.drawCircle(b.centerX(), b.centerY() - mIconRadius / 2, mIconRadius, mPaint);
+        }
+    }
+
+    @Override
+    public boolean getPadding(Rect padding) {
+        padding.left += mHorizontalPadding;
+        padding.right += mHorizontalPadding;
+        padding.top = 0;
+        padding.bottom = 0;
+        android.util.Log.d("ScreenRecordDrawable", "set zero top/bottom pad");
+        return true;
+    }
+
+    @Override
+    public void setAlpha(int alpha) {
+        super.setAlpha(alpha);
+        mFillDrawable.setAlpha(alpha);
+    }
+
+    @Override
+    public boolean setVisible(boolean visible, boolean restart) {
+        mFillDrawable.setVisible(visible, restart);
+        return super.setVisible(visible, restart);
+    }
+
+    @Override
+    public Drawable mutate() {
+        mFillDrawable.mutate();
+        return super.mutate();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java b/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java
index 40f8e39..bb96f42 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java
@@ -21,27 +21,26 @@
 
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.statusbar.NotificationVisibility;
+import com.android.systemui.statusbar.dagger.StatusBarModule;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 
 import java.util.Set;
 
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
 /**
  * Handles when smart replies are added to a notification
  * and clicked upon.
  */
-@Singleton
 public class SmartReplyController {
     private final IStatusBarService mBarService;
     private final NotificationEntryManager mEntryManager;
     private Set<String> mSendingKeys = new ArraySet<>();
     private Callback mCallback;
 
-    @Inject
+    /**
+     * Injected constructor. See {@link StatusBarModule}.
+     */
     public SmartReplyController(NotificationEntryManager entryManager,
             IStatusBarService statusBarService) {
         mBarService = statusBarService;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarDependenciesModule.java
deleted file mode 100644
index 493482a..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarDependenciesModule.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar;
-
-import android.content.Context;
-
-import com.android.systemui.statusbar.notification.row.NotificationRowModule;
-import com.android.systemui.recents.OverviewProxyService;
-import com.android.systemui.tracing.ProtoTracer;
-
-import javax.inject.Singleton;
-
-import dagger.Module;
-import dagger.Provides;
-
-/**
- * Dagger Module providing common dependencies of StatusBar.
- */
-@Module(includes = {NotificationRowModule.class})
-public class StatusBarDependenciesModule {
-    /**
-     * Provides our instance of CommandQueue which is considered optional.
-     */
-    @Provides
-    @Singleton
-    public CommandQueue provideCommandQueue(Context context, ProtoTracer protoTracer) {
-        return new CommandQueue(context, protoTracer);
-    }
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java
new file mode 100644
index 0000000..0b37c22
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.dagger;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.Handler;
+
+import com.android.internal.statusbar.IStatusBarService;
+import com.android.systemui.bubbles.BubbleController;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.MediaArtworkProcessor;
+import com.android.systemui.statusbar.NotificationListener;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.NotificationViewHierarchyManager;
+import com.android.systemui.statusbar.SmartReplyController;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.VisualStabilityManager;
+import com.android.systemui.statusbar.notification.stack.ForegroundServiceSectionController;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
+import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.policy.RemoteInputUriController;
+import com.android.systemui.tracing.ProtoTracer;
+
+import javax.inject.Singleton;
+
+import dagger.Lazy;
+import dagger.Module;
+import dagger.Provides;
+
+/**
+ * This module provides instances needed to construct {@link StatusBar}. These are moved to this
+ * separate from {@link StatusBarModule} module so that components that wish to build their own
+ * version of StatusBar can include just dependencies, without injecting StatusBar itself.
+ */
+@Module
+public interface StatusBarDependenciesModule {
+    /** */
+    @Singleton
+    @Provides
+    static NotificationRemoteInputManager provideNotificationRemoteInputManager(
+            Context context,
+            NotificationLockscreenUserManager lockscreenUserManager,
+            SmartReplyController smartReplyController,
+            NotificationEntryManager notificationEntryManager,
+            Lazy<StatusBar> statusBarLazy,
+            StatusBarStateController statusBarStateController,
+            Handler mainHandler,
+            RemoteInputUriController remoteInputUriController) {
+        return new NotificationRemoteInputManager(
+                context,
+                lockscreenUserManager,
+                smartReplyController,
+                notificationEntryManager,
+                statusBarLazy,
+                statusBarStateController,
+                mainHandler,
+                remoteInputUriController);
+    }
+
+    /** */
+    @Singleton
+    @Provides
+    static NotificationMediaManager provideNotificationMediaManager(
+            Context context,
+            Lazy<StatusBar> statusBarLazy,
+            Lazy<NotificationShadeWindowController> notificationShadeWindowController,
+            NotificationEntryManager notificationEntryManager,
+            MediaArtworkProcessor mediaArtworkProcessor,
+            KeyguardBypassController keyguardBypassController) {
+        return new NotificationMediaManager(
+                context,
+                statusBarLazy,
+                notificationShadeWindowController,
+                notificationEntryManager,
+                mediaArtworkProcessor,
+                keyguardBypassController);
+    }
+
+    /** */
+    @Singleton
+    @Provides
+    static NotificationListener provideNotificationListener(
+            Context context,
+            NotificationManager notificationManager,
+            @Main Handler mainHandler) {
+        return new NotificationListener(
+                context, notificationManager, mainHandler);
+    }
+
+    /** */
+    @Singleton
+    @Provides
+    static SmartReplyController provideSmartReplyController(
+            NotificationEntryManager entryManager, IStatusBarService statusBarService) {
+        return new SmartReplyController(entryManager, statusBarService);
+    }
+
+    /** */
+    @Singleton
+    @Provides
+    static NotificationViewHierarchyManager provideNotificationViewHierarchyManager(
+            Context context,
+            @Main Handler mainHandler,
+            NotificationLockscreenUserManager notificationLockscreenUserManager,
+            NotificationGroupManager groupManager,
+            VisualStabilityManager visualStabilityManager,
+            StatusBarStateController statusBarStateController,
+            NotificationEntryManager notificationEntryManager,
+            KeyguardBypassController bypassController,
+            BubbleController bubbleController,
+            DynamicPrivacyController privacyController,
+            ForegroundServiceSectionController fgsSectionController) {
+        return new NotificationViewHierarchyManager(
+                context,
+                mainHandler,
+                notificationLockscreenUserManager,
+                groupManager,
+                visualStabilityManager,
+                statusBarStateController,
+                notificationEntryManager,
+                bypassController,
+                bubbleController,
+                privacyController,
+                fgsSectionController);
+    }
+
+    /**
+     * Provides our instance of CommandQueue which is considered optional.
+     */
+    @Provides
+    @Singleton
+    static CommandQueue provideCommandQueue(Context context, ProtoTracer protoTracer) {
+        return new CommandQueue(context, protoTracer);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarModule.java
new file mode 100644
index 0000000..ad5ef20
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarModule.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.dagger;
+
+import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
+import com.android.systemui.statusbar.notification.row.NotificationRowModule;
+import com.android.systemui.statusbar.phone.dagger.StatusBarPhoneModule;
+
+import dagger.Module;
+
+/** */
+@Module(includes = {StatusBarPhoneModule.class, StatusBarDependenciesModule.class,
+        NotificationsModule.class, NotificationRowModule.class})
+public interface StatusBarModule {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
index 93f5805..55a20fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
@@ -51,10 +51,10 @@
 import com.android.internal.messages.nano.SystemMessageProto;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.systemui.Dependency;
-import com.android.systemui.DockedStackExistsListener;
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
 import com.android.systemui.dagger.qualifiers.UiBackground;
+import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.NotificationChannels;
@@ -80,11 +80,13 @@
     private final CommandQueue mCommandQueue;
     private boolean mDockedStackExists;
     private KeyguardStateController mKeyguardStateController;
+    private final Divider mDivider;
 
     @Inject
     public InstantAppNotifier(Context context, CommandQueue commandQueue,
-            @UiBackground Executor uiBgExecutor) {
+            @UiBackground Executor uiBgExecutor, Divider divider) {
         super(context);
+        mDivider = divider;
         mCommandQueue = commandQueue;
         mUiBgExecutor = uiBgExecutor;
     }
@@ -103,7 +105,7 @@
         mCommandQueue.addCallback(this);
         mKeyguardStateController.addCallback(this);
 
-        DockedStackExistsListener.register(
+        mDivider.registerInSplitScreenListener(
                 exists -> {
                     mDockedStackExists = exists;
                     updateForegroundInstantApps();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java
index d0e238a..72a7e11 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java
@@ -28,13 +28,10 @@
 import com.android.systemui.statusbar.NotificationListener;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
 /** Handles heads-up and pulsing behavior driven by notification changes. */
-@Singleton
 public class NotificationAlertingManager {
 
     private static final String TAG = "NotifAlertManager";
@@ -47,7 +44,9 @@
 
     private HeadsUpManager mHeadsUpManager;
 
-    @Inject
+    /**
+     * Injected constructor. See {@link NotificationsModule}.
+     */
     public NotificationAlertingManager(
             NotificationEntryManager notificationEntryManager,
             NotificationRemoteInputManager remoteInputManager,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index b0bf813..4f55e02 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -47,6 +47,7 @@
 import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
+import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
@@ -64,9 +65,6 @@
 import java.util.Map;
 import java.util.Set;
 
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
 import dagger.Lazy;
 
 /**
@@ -94,7 +92,6 @@
  * aware of
  * @see #getActiveNotificationsForCurrentUser() to see every notification that the current user owns
  */
-@Singleton
 public class NotificationEntryManager implements
         CommonNotifCollection,
         Dumpable,
@@ -181,7 +178,9 @@
         }
     }
 
-    @Inject
+    /**
+     * Injected constructor. See {@link NotificationsModule}.
+     */
     public NotificationEntryManager(
             NotificationEntryManagerLogger logger,
             NotificationGroupManager groupManager,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
index 99718ab..616c110 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
@@ -26,6 +26,7 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
 
@@ -33,14 +34,10 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
 /**
  * A manager that ensures that notifications are visually stable. It will suppress reorderings
  * and reorder at the right time when they are out of view.
  */
-@Singleton
 public class VisualStabilityManager implements OnHeadsUpChangedListener, Dumpable {
 
     private static final long TEMPORARY_REORDERING_ALLOWED_DURATION = 1000;
@@ -60,7 +57,9 @@
     private ArraySet<View> mAddedChildren = new ArraySet<>();
     private boolean mPulsing;
 
-    @Inject
+    /**
+     * Injected constructor. See {@link NotificationsModule}.
+     */
     public VisualStabilityManager(
             NotificationEntryManager notificationEntryManager, @Main Handler handler) {
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index 39f4dfa..8f8f742 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -17,15 +17,39 @@
 package com.android.systemui.statusbar.notification.dagger;
 
 import android.content.Context;
+import android.os.Handler;
+import android.view.accessibility.AccessibilityManager;
 
+import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.dagger.qualifiers.UiBackground;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.FeatureFlags;
+import com.android.systemui.statusbar.NotificationListener;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.notification.ForegroundServiceDismissalFeatureController;
+import com.android.systemui.statusbar.notification.NotificationAlertingManager;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.NotificationEntryManagerLogger;
+import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
+import com.android.systemui.statusbar.notification.VisualStabilityManager;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
+import com.android.systemui.statusbar.notification.collection.NotificationRankingManager;
+import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
+import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
 import com.android.systemui.statusbar.notification.init.NotificationsController;
 import com.android.systemui.statusbar.notification.init.NotificationsControllerImpl;
 import com.android.systemui.statusbar.notification.init.NotificationsControllerStub;
+import com.android.systemui.statusbar.notification.logging.NotificationLogger;
+import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
+import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
+import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.util.leak.LeakDetector;
+
+import java.util.concurrent.Executor;
 
 import javax.inject.Singleton;
 
@@ -33,9 +57,111 @@
 import dagger.Module;
 import dagger.Provides;
 
-/** Module for classes related to the notifications data pipeline */
+/**
+ * Dagger Module for classes found within the com.android.systemui.statusbar.notification package.
+ */
 @Module
-public class NotificationsModule {
+public interface NotificationsModule {
+    /** Provides an instance of {@link NotificationEntryManager} */
+    @Singleton
+    @Provides
+    static NotificationEntryManager provideNotificationEntryManager(
+            NotificationEntryManagerLogger logger,
+            NotificationGroupManager groupManager,
+            NotificationRankingManager rankingManager,
+            NotificationEntryManager.KeyguardEnvironment keyguardEnvironment,
+            FeatureFlags featureFlags,
+            Lazy<NotificationRowBinder> notificationRowBinderLazy,
+            Lazy<NotificationRemoteInputManager> notificationRemoteInputManagerLazy,
+            LeakDetector leakDetector,
+            ForegroundServiceDismissalFeatureController fgsFeatureController) {
+        return new NotificationEntryManager(
+                logger,
+                groupManager,
+                rankingManager,
+                keyguardEnvironment,
+                featureFlags,
+                notificationRowBinderLazy,
+                notificationRemoteInputManagerLazy,
+                leakDetector,
+                fgsFeatureController);
+    }
+
+    /** Provides an instance of {@link NotificationGutsManager} */
+    @Singleton
+    @Provides
+    static NotificationGutsManager provideNotificationGutsManager(
+            Context context,
+            VisualStabilityManager visualStabilityManager,
+            Lazy<StatusBar> statusBarLazy,
+            @Main Handler mainHandler,
+            AccessibilityManager accessibilityManager,
+            HighPriorityProvider highPriorityProvider) {
+        return new NotificationGutsManager(
+                context,
+                visualStabilityManager,
+                statusBarLazy,
+                mainHandler,
+                accessibilityManager,
+                highPriorityProvider);
+    }
+
+    /** Provides an instance of {@link VisualStabilityManager} */
+    @Singleton
+    @Provides
+    static VisualStabilityManager provideVisualStabilityManager(
+            NotificationEntryManager notificationEntryManager, Handler handler) {
+        return new VisualStabilityManager(notificationEntryManager, handler);
+    }
+
+    /** Provides an instance of {@link NotificationAlertingManager} */
+    @Singleton
+    @Provides
+    static NotificationAlertingManager provideNotificationAlertingManager(
+            NotificationEntryManager notificationEntryManager,
+            NotificationRemoteInputManager remoteInputManager,
+            VisualStabilityManager visualStabilityManager,
+            StatusBarStateController statusBarStateController,
+            NotificationInterruptionStateProvider notificationInterruptionStateProvider,
+            NotificationListener notificationListener) {
+        return new NotificationAlertingManager(
+                notificationEntryManager,
+                remoteInputManager,
+                visualStabilityManager,
+                statusBarStateController,
+                notificationInterruptionStateProvider,
+                notificationListener);
+    }
+
+    /** Provides an instance of {@link NotificationLogger} */
+    @Singleton
+    @Provides
+    static NotificationLogger provideNotificationLogger(
+            NotificationListener notificationListener,
+            @UiBackground Executor uiBgExecutor,
+            NotificationEntryManager entryManager,
+            StatusBarStateController statusBarStateController,
+            NotificationLogger.ExpansionStateLogger expansionStateLogger) {
+        return new NotificationLogger(
+                notificationListener,
+                uiBgExecutor,
+                entryManager,
+                statusBarStateController,
+                expansionStateLogger);
+    }
+
+    /** Provides an instance of {@link NotificationBlockingHelperManager} */
+    @Singleton
+    @Provides
+    static NotificationBlockingHelperManager provideNotificationBlockingHelperManager(
+            Context context,
+            NotificationGutsManager notificationGutsManager,
+            NotificationEntryManager notificationEntryManager,
+            MetricsLogger metricsLogger) {
+        return new NotificationBlockingHelperManager(
+                context, notificationGutsManager, notificationEntryManager, metricsLogger);
+    }
+
     /** Initializes the notification data pipeline (can be disabled via config). */
     @Singleton
     @Provides
@@ -55,7 +181,7 @@
      */
     @Provides
     @Singleton
-    public CommonNotifCollection provideCommonNotifCollection(
+    static CommonNotifCollection provideCommonNotifCollection(
             FeatureFlags featureFlags,
             Lazy<NotifPipeline> pipeline,
             NotificationEntryManager entryManager) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
index 89e5f55..becb758 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
@@ -39,6 +39,7 @@
 import com.android.systemui.statusbar.notification.NotificationEntryListener;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
 import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -50,13 +51,11 @@
 import java.util.concurrent.Executor;
 
 import javax.inject.Inject;
-import javax.inject.Singleton;
 
 /**
  * Handles notification logging, in particular, logging which notifications are visible and which
  * are not.
  */
-@Singleton
 public class NotificationLogger implements StateListener {
     private static final String TAG = "NotificationLogger";
 
@@ -192,7 +191,9 @@
         }
     }
 
-    @Inject
+    /**
+     * Injected constructor. See {@link NotificationsModule}.
+     */
     public NotificationLogger(NotificationListener notificationListener,
             @UiBackground Executor uiBgExecutor,
             NotificationEntryManager entryManager,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManager.java
index 7b758aa..9212325 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManager.java
@@ -16,8 +16,7 @@
 
 package com.android.systemui.statusbar.notification.row;
 
-import static android.service.notification.NotificationListenerService.Ranking
-        .USER_SENTIMENT_NEGATIVE;
+import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
 
 import android.content.Context;
 import android.metrics.LogMaker;
@@ -27,29 +26,28 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.Dependency;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
 import com.android.systemui.statusbar.notification.logging.NotificationCounters;
 
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
 /**
  * Manager for the notification blocking helper - tracks and helps create the blocking helper
  * affordance.
  */
-@Singleton
 public class NotificationBlockingHelperManager {
     /** Enables debug logging and always makes the blocking helper show up after a dismiss. */
     private static final boolean DEBUG = false;
     private static final String TAG = "BlockingHelper";
 
     private final Context mContext;
+    private final NotificationGutsManager mNotificationGutsManager;
+    private final NotificationEntryManager mNotificationEntryManager;
+    private final MetricsLogger mMetricsLogger;
     /** Row that the blocking helper will be shown in (via {@link NotificationGuts}. */
     private ExpandableNotificationRow mBlockingHelperRow;
     private Set<String> mNonBlockablePkgs;
@@ -60,11 +58,18 @@
      */
     private boolean mIsShadeExpanded;
 
-    private MetricsLogger mMetricsLogger = new MetricsLogger();
-
-    @Inject
-    public NotificationBlockingHelperManager(Context context) {
+    /**
+     * Injected constructor. See {@link NotificationsModule}.
+     */
+    public NotificationBlockingHelperManager(
+            Context context,
+            NotificationGutsManager notificationGutsManager,
+            NotificationEntryManager notificationEntryManager,
+            MetricsLogger metricsLogger) {
         mContext = context;
+        mNotificationGutsManager = notificationGutsManager;
+        mNotificationEntryManager = notificationEntryManager;
+        mMetricsLogger = metricsLogger;
         mNonBlockablePkgs = new HashSet<>();
         Collections.addAll(mNonBlockablePkgs, mContext.getResources().getStringArray(
                 com.android.internal.R.array.config_nonBlockableNotificationPackages));
@@ -99,7 +104,6 @@
             if (DEBUG) {
                 Log.d(TAG, "Manager.perhapsShowBlockingHelper: Showing new blocking helper");
             }
-            NotificationGutsManager manager = Dependency.get(NotificationGutsManager.class);
 
             // Enable blocking helper on the row before moving forward so everything in the guts is
             // correctly prepped.
@@ -113,10 +117,10 @@
 
             // We don't care about the touch origin (x, y) since we're opening guts without any
             // explicit user interaction.
-            manager.openGuts(mBlockingHelperRow, 0, 0, menuRow.getLongpressMenuItem(mContext));
+            mNotificationGutsManager.openGuts(
+                    mBlockingHelperRow, 0, 0, menuRow.getLongpressMenuItem(mContext));
 
-            Dependency.get(MetricsLogger.class)
-                    .count(NotificationCounters.BLOCKING_HELPER_SHOWN, 1);
+            mMetricsLogger.count(NotificationCounters.BLOCKING_HELPER_SHOWN, 1);
             return true;
         }
         return false;
@@ -139,8 +143,7 @@
 
             mBlockingHelperRow.setBlockingHelperShowing(false);
             if (mBlockingHelperRow.isAttachedToWindow()) {
-                Dependency.get(NotificationEntryManager.class).updateNotifications(
-                        "dismissCurrentBlockingHelper");
+                mNotificationEntryManager.updateNotifications("dismissCurrentBlockingHelper");
             }
             mBlockingHelperRow = null;
             return true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
index 566da65..e3ca283 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
@@ -33,7 +33,6 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.widget.ImageMessageConsumer;
-import com.android.systemui.Dependency;
 import com.android.systemui.statusbar.InflationTask;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.SmartReplyController;
@@ -53,6 +52,8 @@
 import javax.inject.Inject;
 import javax.inject.Singleton;
 
+import dagger.Lazy;
+
 /**
  * {@link NotificationContentInflater} binds content to a {@link ExpandableNotificationRow} by
  * asynchronously building the content's {@link RemoteViews} and applying it to the row.
@@ -66,13 +67,19 @@
     private boolean mInflateSynchronously = false;
     private final NotificationRemoteInputManager mRemoteInputManager;
     private final NotifRemoteViewCache mRemoteViewCache;
+    private final Lazy<SmartReplyConstants> mSmartReplyConstants;
+    private final Lazy<SmartReplyController> mSmartReplyController;
 
     @Inject
     NotificationContentInflater(
             NotifRemoteViewCache remoteViewCache,
-            NotificationRemoteInputManager remoteInputManager) {
+            NotificationRemoteInputManager remoteInputManager,
+            Lazy<SmartReplyConstants> smartReplyConstants,
+            Lazy<SmartReplyController> smartReplyController) {
         mRemoteViewCache = remoteViewCache;
         mRemoteInputManager = remoteInputManager;
+        mSmartReplyConstants = smartReplyConstants;
+        mSmartReplyController = smartReplyController;
     }
 
     @Override
@@ -104,6 +111,8 @@
                 contentToBind,
                 mRemoteViewCache,
                 entry,
+                mSmartReplyConstants.get(),
+                mSmartReplyController.get(),
                 row,
                 bindParams.isLowPriority,
                 bindParams.isChildInGroup,
@@ -136,6 +145,7 @@
                 packageContext);
         result = inflateSmartReplyViews(result, reInflateFlags, entry,
                 row.getContext(), packageContext, row.getHeadsUpManager(),
+                mSmartReplyConstants.get(), mSmartReplyController.get(),
                 row.getExistingSmartRepliesAndActions());
 
         apply(
@@ -204,9 +214,8 @@
     private static InflationProgress inflateSmartReplyViews(InflationProgress result,
             @InflationFlag int reInflateFlags, NotificationEntry entry, Context context,
             Context packageContext, HeadsUpManager headsUpManager,
+            SmartReplyConstants smartReplyConstants, SmartReplyController smartReplyController,
             SmartRepliesAndActions previousSmartRepliesAndActions) {
-        SmartReplyConstants smartReplyConstants = Dependency.get(SmartReplyConstants.class);
-        SmartReplyController smartReplyController = Dependency.get(SmartReplyController.class);
         if ((reInflateFlags & FLAG_CONTENT_VIEW_EXPANDED) != 0 && result.newExpandedView != null) {
             result.expandedInflatedSmartReplies =
                     InflatedSmartReplies.inflate(
@@ -643,6 +652,8 @@
         private final boolean mUsesIncreasedHeadsUpHeight;
         private final @InflationFlag int mReInflateFlags;
         private final NotifRemoteViewCache mRemoteViewCache;
+        private final SmartReplyConstants mSmartReplyConstants;
+        private final SmartReplyController mSmartReplyController;
         private ExpandableNotificationRow mRow;
         private Exception mError;
         private RemoteViews.OnClickHandler mRemoteViewClickHandler;
@@ -653,6 +664,8 @@
                 @InflationFlag int reInflateFlags,
                 NotifRemoteViewCache cache,
                 NotificationEntry entry,
+                SmartReplyConstants smartReplyConstants,
+                SmartReplyController smartReplyController,
                 ExpandableNotificationRow row,
                 boolean isLowPriority,
                 boolean isChildInGroup,
@@ -662,6 +675,8 @@
                 RemoteViews.OnClickHandler remoteViewClickHandler) {
             mEntry = entry;
             mRow = row;
+            mSmartReplyConstants = smartReplyConstants;
+            mSmartReplyController = smartReplyController;
             mInflateSynchronously = inflateSynchronously;
             mReInflateFlags = reInflateFlags;
             mRemoteViewCache = cache;
@@ -701,6 +716,7 @@
                         mUsesIncreasedHeadsUpHeight, packageContext);
                 return inflateSmartReplyViews(inflationProgress, mReInflateFlags, mEntry,
                         mRow.getContext(), packageContext, mRow.getHeadsUpManager(),
+                        mSmartReplyConstants, mSmartReplyController,
                         mRow.getExistingSmartRepliesAndActions());
             } catch (Exception e) {
                 mError = e;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
index a0af4ac..923c348 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
@@ -33,11 +33,9 @@
 import android.app.NotificationChannelGroup;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.LauncherApps;
 import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
 import android.content.pm.ShortcutInfo;
 import android.content.pm.ShortcutManager;
 import android.graphics.drawable.Icon;
@@ -61,6 +59,7 @@
 import android.widget.TextView;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.settingslib.notification.ConversationIconFactory;
 import com.android.settingslib.utils.ThreadUtils;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
@@ -87,6 +86,7 @@
     private PackageManager mPm;
     private VisualStabilityManager mVisualStabilityManager;
     private ShadeController mShadeController;
+    private ConversationIconFactory mIconFactory;
 
     private String mPackageName;
     private String mAppName;
@@ -186,6 +186,7 @@
             OnSettingsClickListener onSettingsClick,
             OnAppSettingsClickListener onAppSettingsClick,
             OnSnoozeClickListener onSnoozeClickListener,
+            ConversationIconFactory conversationIconFactory,
             boolean isDeviceProvisioned) {
         mSelectedAction = -1;
         mINotificationManager = iNotificationManager;
@@ -203,6 +204,7 @@
         mIsDeviceProvisioned = isDeviceProvisioned;
         mOnSnoozeClickListener = onSnoozeClickListener;
         mShadeController = Dependency.get(ShadeController.class);
+        mIconFactory = conversationIconFactory;
 
         mShortcutManager = shortcutManager;
         mLauncherApps = launcherApps;
@@ -320,8 +322,8 @@
     private void bindIcon() {
         ImageView image = findViewById(R.id.conversation_icon);
         if (mShortcutInfo != null) {
-            image.setImageDrawable(mLauncherApps.getShortcutBadgedIconDrawable(mShortcutInfo,
-                    mContext.getResources().getDisplayMetrics().densityDpi));
+            image.setImageBitmap(mIconFactory.getConversationBitmap(
+                    mShortcutInfo, mPackageName, mAppUid));
         } else {
             if (mSbn.getNotification().extras.getBoolean(EXTRA_IS_GROUP_CONVERSATION, false)) {
                 // TODO: maybe use a generic group icon, or a composite of recent senders
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 352abcf..c01f6c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -34,6 +34,7 @@
 import android.provider.Settings;
 import android.service.notification.StatusBarNotification;
 import android.util.ArraySet;
+import android.util.IconDrawableFactory;
 import android.util.Log;
 import android.view.HapticFeedbackConstants;
 import android.view.View;
@@ -42,8 +43,10 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
+import com.android.settingslib.notification.ConversationIconFactory;
 import com.android.systemui.Dependency;
 import com.android.systemui.Dumpable;
+import com.android.systemui.R;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -56,25 +59,21 @@
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
+import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
 import com.android.systemui.statusbar.notification.row.NotificationInfo.CheckSaveListener;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
-import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
 import dagger.Lazy;
 
 /**
  * Handles various NotificationGuts related tasks, such as binding guts to a row, opening and
  * closing guts, and keeping track of the currently exposed notification guts.
  */
-@Singleton
 public class NotificationGutsManager implements Dumpable, NotificationLifetimeExtender {
     private static final String TAG = "NotificationGutsManager";
 
@@ -111,7 +110,9 @@
     private final Handler mMainHandler;
     private Runnable mOpenRunnable;
 
-    @Inject
+    /**
+     * Injected constructor. See {@link NotificationsModule}.
+     */
     public NotificationGutsManager(Context context, VisualStabilityManager visualStabilityManager,
             Lazy<StatusBar> statusBarLazy, @Main Handler mainHandler,
             AccessibilityManager accessibilityManager,
@@ -388,6 +389,10 @@
                 notificationInfoView.closeControls(v, false);
             };
         }
+        ConversationIconFactory iconFactoryLoader = new ConversationIconFactory(mContext,
+                launcherApps, pmUser, IconDrawableFactory.newInstance(mContext),
+                mContext.getResources().getDimensionPixelSize(
+                        R.dimen.notification_guts_conversation_icon_size));
 
         notificationInfoView.bindNotification(
                 shortcutManager,
@@ -401,8 +406,8 @@
                 onSettingsClick,
                 onAppSettingsClick,
                 onSnoozeClickListener,
+                iconFactoryLoader,
                 mDeviceProvisionedController.isDeviceProvisioned());
-
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index b2b46d5..2eeda1f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -60,6 +60,7 @@
 import android.util.MathUtils;
 import android.util.Pair;
 import android.view.ContextThemeWrapper;
+import android.view.DisplayCutout;
 import android.view.InputDevice;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -524,6 +525,8 @@
     private float mLastSentExpandedHeight;
     private boolean mWillExpand;
 
+    private int mWaterfallTopInset;
+
     @Inject
     public NotificationStackScrollLayout(
             @Named(VIEW_CONTEXT) Context context,
@@ -1739,6 +1742,12 @@
     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
         mBottomInset = insets.getSystemWindowInsetBottom();
 
+        mWaterfallTopInset = 0;
+        final DisplayCutout cutout = insets.getDisplayCutout();
+        if (cutout != null) {
+            mWaterfallTopInset = cutout.getWaterfallInsets().top;
+        }
+
         if (ANCHOR_SCROLLING) {
             // TODO
         } else {
@@ -5335,7 +5344,9 @@
 
     @ShadeViewRefactor(RefactorComponent.COORDINATOR)
     public int getMinExpansionHeight() {
-        return mShelf.getIntrinsicHeight() - (mShelf.getIntrinsicHeight() - mStatusBarHeight) / 2;
+        return mShelf.getIntrinsicHeight()
+                - (mShelf.getIntrinsicHeight() - mStatusBarHeight + mWaterfallTopInset) / 2
+                + mWaterfallTopInset;
     }
 
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java
index 3165597..971f045 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java
@@ -25,8 +25,7 @@
 
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
-
-import javax.inject.Inject;
+import com.android.systemui.statusbar.phone.dagger.StatusBarPhoneModule;
 
 /** A controller to control all auto-hide things. */
 public class AutoHideController {
@@ -51,7 +50,9 @@
         }
     };
 
-    @Inject
+    /**
+     * Injected constructor. See {@link StatusBarPhoneModule}.
+     */
     public AutoHideController(Context context, @Main Handler handler,
             NotificationRemoteInputManager notificationRemoteInputManager,
             IWindowManager iWindowManager) {
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 b24942a..b46ca40 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -102,6 +102,9 @@
      */
     private int mCutoutSideNudge = 0;
 
+    private DisplayCutout mDisplayCutout;
+    private int mRoundedCornerPadding = 0;
+
     public KeyguardStatusBarView(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
@@ -159,9 +162,15 @@
                 getResources().getDimensionPixelSize(R.dimen.keyguard_carrier_text_margin));
         mCarrierLabel.setLayoutParams(lp);
 
-        lp = (MarginLayoutParams) getLayoutParams();
+        updateKeyguardStatusBarHeight();
+    }
+
+    private void updateKeyguardStatusBarHeight() {
+        final int waterfallTop =
+                mDisplayCutout == null ? 0 : mDisplayCutout.getWaterfallInsets().top;
+        MarginLayoutParams lp =  (MarginLayoutParams) getLayoutParams();
         lp.height =  getResources().getDimensionPixelSize(
-                R.dimen.status_bar_header_height_keyguard);
+                R.dimen.status_bar_header_height_keyguard) + waterfallTop;
         setLayoutParams(lp);
     }
 
@@ -175,6 +184,8 @@
                 R.dimen.display_cutout_margin_consumption);
         mShowPercentAvailable = getContext().getResources().getBoolean(
                 com.android.internal.R.bool.config_battery_percentage_setting_available);
+        mRoundedCornerPadding = res.getDimensionPixelSize(
+                R.dimen.rounded_corner_content_padding);
     }
 
     private void updateVisibilities() {
@@ -225,23 +236,26 @@
     }
 
     private boolean updateLayoutConsideringCutout() {
-        DisplayCutout dc = getRootWindowInsets().getDisplayCutout();
+        mDisplayCutout = getRootWindowInsets().getDisplayCutout();
+        updateKeyguardStatusBarHeight();
+
         Pair<Integer, Integer> cornerCutoutMargins =
-                PhoneStatusBarView.cornerCutoutMargins(dc, getDisplay());
-        updateCornerCutoutPadding(cornerCutoutMargins);
-        if (dc == null || cornerCutoutMargins != null) {
+                StatusBarWindowView.cornerCutoutMargins(mDisplayCutout, getDisplay());
+        updatePadding(cornerCutoutMargins);
+        if (mDisplayCutout == null || cornerCutoutMargins != null) {
             return updateLayoutParamsNoCutout();
         } else {
-            return updateLayoutParamsForCutout(dc);
+            return updateLayoutParamsForCutout();
         }
     }
 
-    private void updateCornerCutoutPadding(Pair<Integer, Integer> cornerCutoutMargins) {
-        if (cornerCutoutMargins != null) {
-            setPadding(cornerCutoutMargins.first, 0, cornerCutoutMargins.second, 0);
-        } else {
-            setPadding(0, 0, 0, 0);
-        }
+    private void updatePadding(Pair<Integer, Integer> cornerCutoutMargins) {
+        final int waterfallTop =
+                mDisplayCutout == null ? 0 : mDisplayCutout.getWaterfallInsets().top;
+        Pair<Integer, Integer> padding =
+                StatusBarWindowView.paddingNeededForCutoutAndRoundedCorner(
+                        mDisplayCutout, cornerCutoutMargins, mRoundedCornerPadding);
+        setPadding(padding.first, waterfallTop, padding.second, 0);
     }
 
     private boolean updateLayoutParamsNoCutout() {
@@ -268,7 +282,7 @@
         return true;
     }
 
-    private boolean updateLayoutParamsForCutout(DisplayCutout dc) {
+    private boolean updateLayoutParamsForCutout() {
         if (mLayoutState == LAYOUT_CUTOUT) {
             return false;
         }
@@ -279,7 +293,7 @@
         }
 
         Rect bounds = new Rect();
-        boundsFromDirection(dc, Gravity.TOP, bounds);
+        boundsFromDirection(mDisplayCutout, Gravity.TOP, bounds);
 
         mCutoutSpace.setVisibility(View.VISIBLE);
         RelativeLayout.LayoutParams lp = (LayoutParams) mCutoutSpace.getLayoutParams();
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 ba9ba6c..84aecd4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -63,7 +63,6 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.Dependency;
-import com.android.systemui.DockedStackExistsListener;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.assist.AssistHandleViewController;
@@ -75,6 +74,7 @@
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.shared.system.WindowManagerWrapper;
+import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NavigationBarController;
 import com.android.systemui.statusbar.policy.DeadZone;
@@ -770,7 +770,14 @@
 
     public void updatePanelSystemUiStateFlags() {
         int displayId = mContext.getDisplayId();
+        if (SysUiState.DEBUG) {
+            Log.d(TAG, "Updating panel sysui state flags: panelView=" + mPanelView);
+        }
         if (mPanelView != null) {
+            if (SysUiState.DEBUG) {
+                Log.d(TAG, "Updating panel sysui state flags: fullyExpanded="
+                        + mPanelView.isFullyExpanded() + " inQs=" + mPanelView.isInSettings());
+            }
             mSysUiFlagContainer.setFlag(SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED,
                     mPanelView.isFullyExpanded() && !mPanelView.isInSettings())
                     .setFlag(SYSUI_STATE_QUICK_SETTINGS_EXPANDED,
@@ -862,7 +869,8 @@
 
         getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
 
-        DockedStackExistsListener.register(mDockedListener);
+        Divider divider = Dependency.get(Divider.class);
+        divider.registerInSplitScreenListener(mDockedListener);
         updateOrientationViews();
         reloadNavIcons();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
index 826af66..67e7f23 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
@@ -73,7 +73,7 @@
 public class NavigationModeController implements Dumpable {
 
     private static final String TAG = NavigationModeController.class.getSimpleName();
-    private static final boolean DEBUG = false;
+    private static final boolean DEBUG = true;
 
     public interface ModeChangedListener {
         void onNavigationModeChanged(int mode);
@@ -248,8 +248,7 @@
                     Secure.NAVIGATION_MODE, String.valueOf(mode));
         });
         if (DEBUG) {
-            Log.e(TAG, "updateCurrentInteractionMode: mode=" + mMode
-                    + " contextUser=" + mCurrentUserContext.getUserId());
+            Log.e(TAG, "updateCurrentInteractionMode: mode=" + mMode);
             dumpAssetPaths(mCurrentUserContext);
         }
 
@@ -293,6 +292,7 @@
                     0 /* flags */, UserHandle.of(userId));
         } catch (PackageManager.NameNotFoundException e) {
             // Never happens for the sysui package
+            Log.e(TAG, "Failed to create package context", e);
             return null;
         }
     }
@@ -404,11 +404,17 @@
             defaultOverlays = "failed_to_fetch";
         }
         pw.println("  defaultOverlays=" + defaultOverlays);
+        pw.println("  restoreGesturalNavMode:");
+        for (int i = 0; i < mRestoreGesturalNavBarMode.size(); i++) {
+            pw.println("    userId=" + mRestoreGesturalNavBarMode.keyAt(i)
+                    + " shouldRestore=" + mRestoreGesturalNavBarMode.valueAt(i));
+        }
         dumpAssetPaths(mCurrentUserContext);
     }
 
     private void dumpAssetPaths(Context context) {
-        Log.d(TAG, "assetPaths=");
+        Log.d(TAG, "  contextUser=" + mCurrentUserContext.getUserId());
+        Log.d(TAG, "  assetPaths=");
         ApkAssets[] assets = context.getResources().getAssets().getApkAssets();
         for (ApkAssets a : assets) {
             Log.d(TAG, "    " + a.getAssetPath());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java
index bdca9a4..d709e02 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java
@@ -36,21 +36,18 @@
 import com.android.systemui.statusbar.notification.row.RowContentBindStage;
 import com.android.systemui.statusbar.phone.NotificationGroupManager.NotificationGroup;
 import com.android.systemui.statusbar.phone.NotificationGroupManager.OnGroupChangeListener;
+import com.android.systemui.statusbar.phone.dagger.StatusBarPhoneModule;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
 
 import java.util.ArrayList;
 import java.util.Objects;
 
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
 /**
  * A helper class dealing with the alert interactions between {@link NotificationGroupManager} and
  * {@link HeadsUpManager}. In particular, this class deals with keeping
  * the correct notification in a group alerting based off the group suppression.
  */
-@Singleton
 public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedListener,
         StateListener {
 
@@ -76,7 +73,9 @@
 
     private boolean mIsDozing;
 
-    @Inject
+    /**
+     * Injected constructor. See {@link StatusBarPhoneModule}.
+     */
     public NotificationGroupAlertTransferHelper(RowContentBindStage bindStage) {
         Dependency.get(StatusBarStateController.class).addCallback(this);
         mRowContentBindStage = bindStage;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java
index 7650a3a..bc80a1a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java
@@ -88,33 +88,11 @@
             boolean paddingChanged = insets.top != getPaddingTop()
                     || insets.bottom != getPaddingBottom();
 
-            int rightCutout = 0;
-            int leftCutout = 0;
-            DisplayCutout displayCutout = getRootWindowInsets().getDisplayCutout();
-            if (displayCutout != null) {
-                leftCutout = displayCutout.getSafeInsetLeft();
-                rightCutout = displayCutout.getSafeInsetRight();
-            }
-
-            int targetLeft = Math.max(insets.left, leftCutout);
-            int targetRight = Math.max(insets.right, rightCutout);
-
-            // Super-special right inset handling, because scrims and backdrop need to ignore it.
-            if (targetRight != mRightInset || targetLeft != mLeftInset) {
-                mRightInset = targetRight;
-                mLeftInset = targetLeft;
-                applyMargins();
-            }
             // Drop top inset, and pass through bottom inset.
             if (paddingChanged) {
                 setPadding(0, 0, 0, 0);
             }
         } else {
-            if (mRightInset != 0 || mLeftInset != 0) {
-                mRightInset = 0;
-                mLeftInset = 0;
-                applyMargins();
-            }
             boolean changed = getPaddingLeft() != 0
                     || getPaddingRight() != 0
                     || getPaddingTop() != 0
@@ -123,6 +101,17 @@
                 setPadding(0, 0, 0, 0);
             }
         }
+
+        mLeftInset = 0;
+        mRightInset = 0;
+        DisplayCutout displayCutout = getRootWindowInsets().getDisplayCutout();
+        if (displayCutout != null) {
+            mLeftInset = displayCutout.getSafeInsetLeft();
+            mRightInset = displayCutout.getSafeInsetRight();
+        }
+        mLeftInset = Math.max(insets.left, mLeftInset);
+        mRightInset = Math.max(insets.right, mRightInset);
+        applyMargins();
         return windowInsets;
     }
 
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 41d8968..260f94c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -43,6 +43,7 @@
 import com.android.systemui.dagger.qualifiers.UiBackground;
 import com.android.systemui.qs.tiles.DndTile;
 import com.android.systemui.qs.tiles.RotationLockTile;
+import com.android.systemui.screenrecord.RecordingController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.policy.BluetoothController;
 import com.android.systemui.statusbar.policy.CastController;
@@ -76,7 +77,8 @@
                 ZenModeController.Callback,
                 DeviceProvisionedListener,
                 KeyguardStateController.Callback,
-                LocationController.LocationChangeCallback {
+                LocationController.LocationChangeCallback,
+                RecordingController.RecordingStateChangeCallback {
     private static final String TAG = "PhoneStatusBarPolicy";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
@@ -98,6 +100,7 @@
     private final String mSlotMicrophone;
     private final String mSlotCamera;
     private final String mSlotSensorsOff;
+    private final String mSlotScreenRecord;
 
     private final Context mContext;
     private final Handler mHandler = new Handler();
@@ -116,6 +119,7 @@
     private final LocationController mLocationController;
     private final Executor mUiBgExecutor;
     private final SensorPrivacyController mSensorPrivacyController;
+    private final RecordingController mRecordingController;
 
     // Assume it's all good unless we hear otherwise.  We don't always seem
     // to get broadcasts that it *is* there.
@@ -149,6 +153,7 @@
         mKeyguardStateController = Dependency.get(KeyguardStateController.class);
         mLocationController = Dependency.get(LocationController.class);
         mSensorPrivacyController = Dependency.get(SensorPrivacyController.class);
+        mRecordingController = Dependency.get(RecordingController.class);
         mUiBgExecutor = uiBgExecutor;
 
         mSlotCast = context.getString(com.android.internal.R.string.status_bar_cast);
@@ -167,6 +172,8 @@
         mSlotMicrophone = context.getString(com.android.internal.R.string.status_bar_microphone);
         mSlotCamera = context.getString(com.android.internal.R.string.status_bar_camera);
         mSlotSensorsOff = context.getString(com.android.internal.R.string.status_bar_sensors_off);
+        mSlotScreenRecord = context.getString(
+                com.android.internal.R.string.status_bar_screen_record);
 
         // listen for broadcasts
         IntentFilter filter = new IntentFilter();
@@ -235,6 +242,10 @@
         mIconController.setIconVisibility(mSlotSensorsOff,
                 mSensorPrivacyController.isSensorPrivacyEnabled());
 
+        // screen record
+        mIconController.setIcon(mSlotScreenRecord, R.drawable.stat_sys_screen_record, null);
+        mIconController.setIconVisibility(mSlotScreenRecord, false);
+
         mRotationLockController.addCallback(this);
         mBluetooth.addCallback(this);
         mProvisionedController.addCallback(this);
@@ -246,6 +257,7 @@
         mKeyguardStateController.addCallback(this);
         mSensorPrivacyController.addCallback(mSensorPrivacyListener);
         mLocationController.addCallback(this);
+        mRecordingController.addCallback(this);
 
         commandQueue.addCallback(this);
     }
@@ -438,7 +450,7 @@
         }
         if (DEBUG) Log.v(TAG, "updateCast: isCasting: " + isCasting);
         mHandler.removeCallbacks(mRemoveCastIconRunnable);
-        if (isCasting) {
+        if (isCasting && !mRecordingController.isRecording()) { // screen record has its own icon
             mIconController.setIcon(mSlotCast, R.drawable.stat_sys_cast,
                     mContext.getString(R.string.accessibility_casting));
             mIconController.setIconVisibility(mSlotCast, true);
@@ -643,4 +655,40 @@
             mIconController.setIconVisibility(mSlotCast, false);
         }
     };
+
+    // Screen Recording
+    @Override
+    public void onCountdown(long millisUntilFinished) {
+        if (DEBUG) Log.d(TAG, "screenrecord: countdown " + millisUntilFinished);
+        int countdown = (int) Math.floorDiv(millisUntilFinished + 500, 1000);
+        int resourceId = R.drawable.stat_sys_screen_record;
+        switch (countdown) {
+            case 1:
+                resourceId = R.drawable.stat_sys_screen_record_1;
+                break;
+            case 2:
+                resourceId = R.drawable.stat_sys_screen_record_2;
+                break;
+            case 3:
+                resourceId = R.drawable.stat_sys_screen_record_3;
+                break;
+        }
+        mIconController.setIcon(mSlotScreenRecord, resourceId, null);
+        mIconController.setIconVisibility(mSlotScreenRecord, true);
+    }
+
+    @Override
+    public void onRecordingStart() {
+        if (DEBUG) Log.d(TAG, "screenrecord: showing icon");
+        mIconController.setIcon(mSlotScreenRecord,
+                R.drawable.stat_sys_screen_record, null);
+        mIconController.setIconVisibility(mSlotScreenRecord, true);
+    }
+
+    @Override
+    public void onRecordingEnd() {
+        // Ensure this is on the main thread, since it could be called during countdown
+        if (DEBUG) Log.d(TAG, "screenrecord: hiding icon");
+        mHandler.post(() -> mIconController.setIconVisibility(mSlotScreenRecord, false));
+    }
 }
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 f3b0a79..156a7e5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -23,12 +23,10 @@
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.Configuration;
-import android.graphics.Point;
 import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.util.EventLog;
 import android.util.Pair;
-import android.view.Display;
 import android.view.DisplayCutout;
 import android.view.Gravity;
 import android.view.MotionEvent;
@@ -36,7 +34,6 @@
 import android.view.ViewGroup;
 import android.view.WindowInsets;
 import android.view.accessibility.AccessibilityEvent;
-import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 
 import com.android.systemui.Dependency;
@@ -84,6 +81,8 @@
     private int mCutoutSideNudge = 0;
     private boolean mHeadsUpVisible;
 
+    private int mRoundedCornerPadding = 0;
+
     public PhoneStatusBarView(Context context, AttributeSet attrs) {
         super(context, attrs);
 
@@ -294,15 +293,25 @@
     public void updateResources() {
         mCutoutSideNudge = getResources().getDimensionPixelSize(
                 R.dimen.display_cutout_margin_consumption);
+        mRoundedCornerPadding = getResources().getDimensionPixelSize(
+                R.dimen.rounded_corner_content_padding);
 
+        updateStatusBarHeight();
+    }
+
+    private void updateStatusBarHeight() {
+        final int waterfallTopInset =
+                mDisplayCutout == null ? 0 : mDisplayCutout.getWaterfallInsets().top;
         ViewGroup.LayoutParams layoutParams = getLayoutParams();
-        layoutParams.height = getResources().getDimensionPixelSize(R.dimen.status_bar_height);
+        layoutParams.height =
+                getResources().getDimensionPixelSize(R.dimen.status_bar_height) - waterfallTopInset;
         setLayoutParams(layoutParams);
     }
 
     private void updateLayoutForCutout() {
-        Pair<Integer, Integer> cornerCutoutMargins = cornerCutoutMargins(mDisplayCutout,
-                getDisplay());
+        updateStatusBarHeight();
+        Pair<Integer, Integer> cornerCutoutMargins =
+                StatusBarWindowView.cornerCutoutMargins(mDisplayCutout, getDisplay());
         updateCutoutLocation(cornerCutoutMargins);
         updateSafeInsets(cornerCutoutMargins);
     }
@@ -337,47 +346,11 @@
         // Depending on our rotation, we may have to work around a cutout in the middle of the view,
         // or letterboxing from the right or left sides.
 
-        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
-        if (mDisplayCutout == null || mDisplayCutout.isEmpty()
-                || mLastOrientation != ORIENTATION_PORTRAIT || cornerCutoutMargins == null) {
-            lp.leftMargin = 0;
-            lp.rightMargin = 0;
-            return;
-        }
+        Pair<Integer, Integer> padding =
+                StatusBarWindowView.paddingNeededForCutoutAndRoundedCorner(
+                        mDisplayCutout, cornerCutoutMargins, mRoundedCornerPadding);
 
-        lp.leftMargin = Math.max(lp.leftMargin, cornerCutoutMargins.first);
-        lp.rightMargin = Math.max(lp.rightMargin, cornerCutoutMargins.second);
-
-        // If we're already inset enough (e.g. on the status bar side), we can have 0 margin
-        WindowInsets insets = getRootWindowInsets();
-        int leftInset = insets.getSystemWindowInsetLeft();
-        int rightInset = insets.getSystemWindowInsetRight();
-        if (lp.leftMargin <= leftInset) {
-            lp.leftMargin = 0;
-        }
-        if (lp.rightMargin <= rightInset) {
-            lp.rightMargin = 0;
-        }
-    }
-
-    public static Pair<Integer, Integer> cornerCutoutMargins(DisplayCutout cutout,
-            Display display) {
-        if (cutout == null) {
-            return null;
-        }
-        Point size = new Point();
-        display.getRealSize(size);
-
-        Rect bounds = new Rect();
-        boundsFromDirection(cutout, Gravity.TOP, bounds);
-
-        if (bounds.left <= 0) {
-            return new Pair<>(bounds.right, 0);
-        }
-        if (bounds.right >= size.x) {
-            return new Pair<>(0, size.x - bounds.left);
-        }
-        return null;
+        setPadding(padding.first, getPaddingTop(), padding.second, getPaddingBottom());
     }
 
     public void setHeadsUpVisible(boolean headsUpVisible) {
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 823adff..6298afe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -163,7 +163,6 @@
 import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.shared.system.WindowManagerWrapper;
 import com.android.systemui.stackdivider.Divider;
-import com.android.systemui.stackdivider.WindowManagerProxy;
 import com.android.systemui.statusbar.BackDropView;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.CrossFadeHelper;
@@ -199,6 +198,7 @@
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
+import com.android.systemui.statusbar.phone.dagger.StatusBarPhoneModule;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
 import com.android.systemui.statusbar.policy.BrightnessMirrorController;
@@ -597,7 +597,7 @@
      * Public constructor for StatusBar.
      *
      * StatusBar is considered optional, and therefore can not be marked as @Inject directly.
-     * Instead, an @Provide method is included.
+     * Instead, an @Provide method is included. See {@link StatusBarPhoneModule}.
      */
     @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
     public StatusBar(
@@ -1409,8 +1409,11 @@
         if (!mRecentsOptional.isPresent()) {
             return false;
         }
-        int dockSide = WindowManagerProxy.getInstance().getDockSide();
-        if (dockSide == WindowManager.DOCKED_INVALID) {
+        Divider divider = null;
+        if (mDividerOptional.isPresent()) {
+            divider = mDividerOptional.get();
+        }
+        if (divider == null || !divider.inSplitMode()) {
             final int navbarPos = WindowManagerWrapper.getInstance().getNavBarPosition(mDisplayId);
             if (navbarPos == NAV_BAR_POS_INVALID) {
                 return false;
@@ -1420,16 +1423,13 @@
                     : SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
             return mRecentsOptional.get().splitPrimaryTask(createMode, null, metricsDockAction);
         } else {
-            if (mDividerOptional.isPresent()) {
-                Divider divider = mDividerOptional.get();
-                if (divider.isMinimized() && !divider.isHomeStackResizable()) {
-                    // Undocking from the minimized state is not supported
-                    return false;
-                } else {
-                    divider.onUndockingTask();
-                    if (metricsUndockAction != -1) {
-                        mMetricsLogger.action(metricsUndockAction);
-                    }
+            if (divider.isMinimized() && !divider.isHomeStackResizable()) {
+                // Undocking from the minimized state is not supported
+                return false;
+            } else {
+                divider.onUndockingTask();
+                if (metricsUndockAction != -1) {
+                    mMetricsLogger.action(metricsUndockAction);
                 }
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index da5df6a..22bf513 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -16,8 +16,21 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static android.view.WindowInsets.Type.systemBars;
+
+import static com.android.systemui.ScreenDecorations.DisplayCutoutView.boundsFromDirection;
+
 import android.content.Context;
+import android.graphics.Insets;
+import android.graphics.Point;
+import android.graphics.Rect;
 import android.util.AttributeSet;
+import android.util.Pair;
+import android.view.Display;
+import android.view.DisplayCutout;
+import android.view.Gravity;
+import android.view.View;
+import android.view.WindowInsets;
 import android.widget.FrameLayout;
 
 /**
@@ -28,7 +41,118 @@
     public static final String TAG = "PhoneStatusBarWindowView";
     public static final boolean DEBUG = StatusBar.DEBUG;
 
+    private int mLeftInset = 0;
+    private int mRightInset = 0;
+    private int mTopInset = 0;
+
     public StatusBarWindowView(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
+
+    @Override
+    public WindowInsets onApplyWindowInsets(WindowInsets windowInsets) {
+        final Insets insets = windowInsets.getInsetsIgnoringVisibility(systemBars());
+        mLeftInset = 0;
+        mRightInset = 0;
+        mTopInset = 0;
+        DisplayCutout displayCutout = getRootWindowInsets().getDisplayCutout();
+        if (displayCutout != null) {
+            mTopInset = displayCutout.getWaterfallInsets().top;
+            mLeftInset = displayCutout.getSafeInsetLeft();
+            mRightInset = displayCutout.getSafeInsetRight();
+        }
+        mLeftInset = Math.max(insets.left, mLeftInset);
+        mRightInset = Math.max(insets.right, mRightInset);
+        applyMargins();
+        return windowInsets;
+    }
+
+    private void applyMargins() {
+        final int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            View child = getChildAt(i);
+            if (child.getLayoutParams() instanceof LayoutParams) {
+                LayoutParams lp = (LayoutParams) child.getLayoutParams();
+                if (lp.rightMargin != mRightInset || lp.leftMargin != mLeftInset
+                        || lp.topMargin != mTopInset) {
+                    lp.rightMargin = mRightInset;
+                    lp.leftMargin = mLeftInset;
+                    lp.topMargin = mTopInset;
+                    child.requestLayout();
+                }
+            }
+        }
+    }
+
+    /**
+     * Compute the padding needed for status bar related views, e.g., PhoneStatusBar,
+     * QuickStatusBarHeader and KeyguardStatusBarView).
+     *
+     * @param cutout
+     * @param cornerCutoutPadding
+     * @param roundedCornerContentPadding
+     * @return
+     */
+    public static Pair<Integer, Integer> paddingNeededForCutoutAndRoundedCorner(
+            DisplayCutout cutout, Pair<Integer, Integer> cornerCutoutPadding,
+            int roundedCornerContentPadding) {
+        if (cutout == null) {
+            return new Pair<>(roundedCornerContentPadding, roundedCornerContentPadding);
+        }
+
+        // compute the padding needed for corner cutout.
+        final int leftMargin = cutout.getSafeInsetLeft();
+        final int rightMargin = cutout.getSafeInsetRight();
+        int leftCornerCutoutPadding = 0;
+        int rightCornerCutoutPadding = 0;
+        if (cornerCutoutPadding != null) {
+            if (cornerCutoutPadding.first > leftMargin) {
+                leftCornerCutoutPadding = cornerCutoutPadding.first - leftMargin;
+            }
+            if (cornerCutoutPadding.second > rightMargin) {
+                rightCornerCutoutPadding = cornerCutoutPadding.second - rightMargin;
+            }
+        }
+
+        // compute the padding needed for rounded corner
+        int leftRoundedCornerPadding = 0;
+        int rightRoundedCornerPadding = 0;
+        if (roundedCornerContentPadding > leftMargin) {
+            leftRoundedCornerPadding = roundedCornerContentPadding - leftMargin;
+        }
+        if (roundedCornerContentPadding > rightMargin) {
+            rightRoundedCornerPadding = roundedCornerContentPadding - rightMargin;
+        }
+
+        return new Pair<>(
+                Math.max(leftCornerCutoutPadding, leftRoundedCornerPadding),
+                Math.max(rightCornerCutoutPadding, rightRoundedCornerPadding));
+    }
+
+    /**
+     * Compute the corner cutout margins
+     *
+     * @param cutout
+     * @param display
+     * @return
+     */
+    public static Pair<Integer, Integer> cornerCutoutMargins(DisplayCutout cutout,
+            Display display) {
+        if (cutout == null) {
+            return null;
+        }
+        Point size = new Point();
+        display.getRealSize(size);
+
+        Rect bounds = new Rect();
+        boundsFromDirection(cutout, Gravity.TOP, bounds);
+
+        if (bounds.left <= 0) {
+            return new Pair<>(bounds.right, 0);
+        }
+        if (bounds.right >= size.x) {
+            return new Pair<>(0, size.x - bounds.left);
+        }
+        return null;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneDependenciesModule.java
new file mode 100644
index 0000000..fcf698c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneDependenciesModule.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone.dagger;
+
+import android.content.Context;
+import android.os.Handler;
+import android.view.IWindowManager;
+
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.notification.row.RowContentBindStage;
+import com.android.systemui.statusbar.phone.AutoHideController;
+import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper;
+import com.android.systemui.statusbar.phone.StatusBar;
+
+import javax.inject.Singleton;
+
+import dagger.Module;
+import dagger.Provides;
+
+/**
+ * This module provides instances needed to construct {@link StatusBar}. These are moved to this
+ * separate from {@link StatusBarPhoneModule} module so that components that wish to build their own
+ * version of StatusBar can include just dependencies, without injecting StatusBar itself.
+ */
+@Module
+public interface StatusBarPhoneDependenciesModule {
+    /** */
+    @Singleton
+    @Provides
+    static AutoHideController newAutoHideController(Context context,
+            @Main Handler handler,
+            NotificationRemoteInputManager notificationRemoteInputManager,
+            IWindowManager iWindowManager) {
+        return new AutoHideController(context, handler, notificationRemoteInputManager,
+                iWindowManager);
+    }
+
+    /** */
+    @Singleton
+    @Provides
+    static NotificationGroupAlertTransferHelper provideNotificationGroupAlertTransferHelper(
+            RowContentBindStage bindStage) {
+        return new NotificationGroupAlertTransferHelper(bindStage);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
similarity index 87%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
index 15a0e08..26459a9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open 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.
  */
 
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.statusbar.phone.dagger;
 
 import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME;
 
@@ -52,7 +52,6 @@
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.NotificationViewHierarchyManager;
 import com.android.systemui.statusbar.PulseExpansionHandler;
-import com.android.systemui.statusbar.StatusBarDependenciesModule;
 import com.android.systemui.statusbar.SuperStatusBarViewFactory;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.VibratorHelper;
@@ -65,7 +64,27 @@
 import com.android.systemui.statusbar.notification.init.NotificationsController;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
-import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
+import com.android.systemui.statusbar.phone.AutoHideController;
+import com.android.systemui.statusbar.phone.BiometricUnlockController;
+import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.phone.DozeScrimController;
+import com.android.systemui.statusbar.phone.DozeServiceHost;
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
+import com.android.systemui.statusbar.phone.KeyguardLiftController;
+import com.android.systemui.statusbar.phone.LightBarController;
+import com.android.systemui.statusbar.phone.LightsOutNotifController;
+import com.android.systemui.statusbar.phone.LockscreenLockIconController;
+import com.android.systemui.statusbar.phone.LockscreenWallpaper;
+import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
+import com.android.systemui.statusbar.phone.ScrimController;
+import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.StatusBarIconController;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarter;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -91,8 +110,8 @@
 /**
  * Dagger Module providing {@link StatusBar}.
  */
-@Module(includes = {StatusBarDependenciesModule.class})
-public class StatusBarModule {
+@Module(includes = {StatusBarPhoneDependenciesModule.class})
+public interface StatusBarPhoneModule {
     /**
      * Provides our instance of StatusBar which is considered optional.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/util/FloatingContentCoordinator.kt b/packages/SystemUI/src/com/android/systemui/util/FloatingContentCoordinator.kt
index 70bcc21..0487ce6 100644
--- a/packages/SystemUI/src/com/android/systemui/util/FloatingContentCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/FloatingContentCoordinator.kt
@@ -98,6 +98,14 @@
     private val allContentBounds: MutableMap<FloatingContent, Rect> = HashMap()
 
     /**
+     * Whether we are currently resolving conflicts by asking content to move. If we are, we'll
+     * temporarily ignore calls to [onContentMoved] - those calls are from the content that is
+     * moving to new, conflict-free bounds, so we don't need to perform conflict detection
+     * calculations in response.
+     */
+    private var currentlyResolvingConflicts = false
+
+    /**
      * Makes the coordinator aware of a new piece of floating content, and moves any existing
      * content out of the way, if necessary.
      *
@@ -126,6 +134,13 @@
      */
     @JvmOverloads
     fun onContentMoved(content: FloatingContent) {
+
+        // Ignore calls when we are currently resolving conflicts, since those calls are from
+        // content that is moving to new, conflict-free bounds.
+        if (currentlyResolvingConflicts) {
+            return
+        }
+
         if (!allContentBounds.containsKey(content)) {
             Log.wtf(TAG, "Received onContentMoved call before onContentAdded! " +
                     "This should never happen.")
@@ -162,6 +177,8 @@
      * them to move out of the way.
      */
     private fun maybeMoveConflictingContent(fromContent: FloatingContent) {
+        currentlyResolvingConflicts = true
+
         val conflictingNewBounds = allContentBounds[fromContent]!!
         allContentBounds
                 // Filter to content that intersects with the new bounds. That's content that needs
@@ -182,6 +199,8 @@
                                             .minus(conflictingNewBounds)))
                     allContentBounds[content] = content.getFloatingBoundsOnScreen()
                 }
+
+        currentlyResolvingConflicts = false
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java b/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java
index 7dad05d..9227cf0 100644
--- a/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java
+++ b/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java
@@ -48,8 +48,8 @@
 public class DisplayImeController implements DisplayController.OnDisplaysChangedListener {
     private static final String TAG = "DisplayImeController";
 
-    static final int ANIMATION_DURATION_SHOW_MS = 275;
-    static final int ANIMATION_DURATION_HIDE_MS = 340;
+    public static final int ANIMATION_DURATION_SHOW_MS = 275;
+    public static final int ANIMATION_DURATION_HIDE_MS = 340;
     static final Interpolator INTERPOLATOR = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
     private static final int DIRECTION_NONE = 0;
     private static final int DIRECTION_SHOW = 1;
diff --git a/packages/SystemUI/src/com/android/systemui/wm/DisplayLayout.java b/packages/SystemUI/src/com/android/systemui/wm/DisplayLayout.java
index 64b0b66..4652abf 100644
--- a/packages/SystemUI/src/com/android/systemui/wm/DisplayLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/wm/DisplayLayout.java
@@ -35,6 +35,7 @@
 import android.graphics.Rect;
 import android.os.SystemProperties;
 import android.provider.Settings;
+import android.util.DisplayMetrics;
 import android.util.RotationUtils;
 import android.util.Size;
 import android.view.Display;
@@ -191,6 +192,11 @@
         return mDensityDpi;
     }
 
+    /** Get the density scale for the display. */
+    public float density() {
+        return mDensityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
+    }
+
     /** Get whether this layout is landscape. */
     public boolean isLandscape() {
         return mWidth > mHeight;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
index 5706bee..79188ce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
@@ -17,25 +17,18 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
 
 import static com.android.systemui.ScreenDecorations.rectsToRegion;
-import static com.android.systemui.tuner.TunablePadding.FLAG_END;
-import static com.android.systemui.tuner.TunablePadding.FLAG_START;
 
 import static org.hamcrest.Matchers.is;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertThat;
 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.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
-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.Fragment;
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.Handler;
@@ -43,21 +36,12 @@
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
 import android.view.Display;
-import android.view.View;
 import android.view.WindowManager;
 
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.R.dimen;
-import com.android.systemui.ScreenDecorations.TunablePaddingTagListener;
 import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.fragments.FragmentHostManager;
-import com.android.systemui.fragments.FragmentService;
-import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
-import com.android.systemui.statusbar.phone.StatusBar;
-import com.android.systemui.statusbar.phone.StatusBarWindowView;
-import com.android.systemui.tuner.TunablePadding;
-import com.android.systemui.tuner.TunablePadding.TunablePaddingService;
 import com.android.systemui.tuner.TunerService;
 
 import org.junit.Before;
@@ -68,8 +52,6 @@
 
 import java.util.Collections;
 
-import dagger.Lazy;
-
 @RunWithLooper
 @RunWith(AndroidTestingRunner.class)
 @SmallTest
@@ -77,19 +59,12 @@
 
     private TestableLooper mTestableLooper;
     private ScreenDecorations mScreenDecorations;
-    @Mock private StatusBar mStatusBar;
     private WindowManager mWindowManager;
-    private FragmentService mFragmentService;
-    private FragmentHostManager mFragmentHostManager;
-    private NotificationShadeWindowView mView;
-    private StatusBarWindowView mStatusBarWindowView;
-    private TunablePaddingService mTunablePaddingService;
     private Handler mMainHandler;
     @Mock
     private TunerService mTunerService;
     @Mock
     private BroadcastDispatcher mBroadcastDispatcher;
-    @Mock private Lazy<StatusBar> mStatusBarLazy;
 
     @Before
     public void setup() {
@@ -97,25 +72,14 @@
 
         mTestableLooper = TestableLooper.get(this);
         mMainHandler = new Handler(mTestableLooper.getLooper());
-        mTunablePaddingService = mDependency.injectMockDependency(TunablePaddingService.class);
-        mFragmentService = mDependency.injectMockDependency(FragmentService.class);
 
         mWindowManager = mock(WindowManager.class);
-        mView = spy(new NotificationShadeWindowView(mContext, null));
-        mStatusBarWindowView = spy(new StatusBarWindowView(mContext, null));
-        when(mStatusBarLazy.get()).thenReturn(mStatusBar);
-        when(mStatusBar.getNotificationShadeWindowView()).thenReturn(mView);
-        when(mStatusBar.getStatusBarWindow()).thenReturn(mStatusBarWindowView);
 
         Display display = mContext.getSystemService(WindowManager.class).getDefaultDisplay();
         when(mWindowManager.getDefaultDisplay()).thenReturn(display);
         mContext.addMockSystemService(WindowManager.class, mWindowManager);
 
-        mFragmentHostManager = mock(FragmentHostManager.class);
-        when(mFragmentService.getFragmentHostManager(any())).thenReturn(mFragmentHostManager);
-
-
-        mScreenDecorations = new ScreenDecorations(mContext, mStatusBarLazy, mMainHandler,
+        mScreenDecorations = new ScreenDecorations(mContext, mMainHandler,
                 mBroadcastDispatcher, mTunerService) {
             @Override
             public void start() {
@@ -159,8 +123,6 @@
         mScreenDecorations.start();
         // No views added.
         verify(mWindowManager, never()).addView(any(), any());
-        // No Fragments watched.
-        verify(mFragmentHostManager, never()).addTagListener(any(), any());
         // No Tuners tuned.
         verify(mTunerService, never()).addTunable(any(), any());
     }
@@ -178,12 +140,8 @@
         // Add 2 windows for rounded corners (top and bottom).
         verify(mWindowManager, times(2)).addView(any(), any());
 
-        // Add 2 tag listeners for each of the fragments that are needed.
-        verify(mFragmentHostManager, times(2)).addTagListener(any(), any());
         // One tunable.
         verify(mTunerService, times(1)).addTunable(any(), any());
-        // One TunablePadding.
-        verify(mTunablePaddingService, times(1)).add(any(), anyString(), anyInt(), anyInt());
     }
 
     @Test
@@ -227,29 +185,6 @@
     }
 
     @Test
-    public void testPaddingTagListener() {
-        TunablePaddingTagListener tagListener = new TunablePaddingTagListener(14, 5);
-        View v = mock(View.class);
-        View child = mock(View.class);
-        Fragment f = mock(Fragment.class);
-        TunablePadding padding = mock(TunablePadding.class);
-
-        when(mTunablePaddingService.add(any(), anyString(), anyInt(), anyInt()))
-                .thenReturn(padding);
-        when(f.getView()).thenReturn(v);
-        when(v.findViewById(5)).thenReturn(child);
-
-        // Trigger callback and verify we get a TunablePadding created.
-        tagListener.onFragmentViewCreated(null, f);
-        verify(mTunablePaddingService).add(eq(child), eq(ScreenDecorations.PADDING), eq(14),
-                eq(FLAG_START | FLAG_END));
-
-        // Call again and verify destroy is called.
-        tagListener.onFragmentViewCreated(null, f);
-        verify(padding).destroy();
-    }
-
-    @Test
     public void testUpdateRoundedCorners() {
         mContext.getOrCreateTestableResources().addOverride(
                 com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
index 7d47f6bd..fc79fcb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
@@ -44,7 +44,6 @@
 import android.app.IActivityManager;
 import android.app.Notification;
 import android.app.PendingIntent;
-import android.content.Context;
 import android.content.res.Resources;
 import android.hardware.face.FaceManager;
 import android.service.notification.ZenModeConfig;
@@ -859,42 +858,6 @@
         verify(mNotificationGroupManager, times(1)).onEntryRemoved(groupSummary.getEntry());
     }
 
-    static class TestableBubbleController extends BubbleController {
-        // Let's assume surfaces can be synchronized immediately.
-        TestableBubbleController(Context context,
-                NotificationShadeWindowController notificationShadeWindowController,
-                StatusBarStateController statusBarStateController,
-                ShadeController shadeController,
-                BubbleData data,
-                ConfigurationController configurationController,
-                NotificationInterruptionStateProvider interruptionStateProvider,
-                ZenModeController zenModeController,
-                NotificationLockscreenUserManager lockscreenUserManager,
-                NotificationGroupManager groupManager,
-                NotificationEntryManager entryManager,
-                NotifPipeline notifPipeline,
-                FeatureFlags featureFlags,
-                DumpController dumpController) {
-            super(context,
-                    notificationShadeWindowController, statusBarStateController, shadeController,
-                    data, Runnable::run, configurationController, interruptionStateProvider,
-                    zenModeController, lockscreenUserManager, groupManager, entryManager,
-                     notifPipeline, featureFlags, dumpController);
-            setInflateSynchronously(true);
-        }
-    }
-
-    static class TestableNotificationInterruptionStateProvider extends
-            NotificationInterruptionStateProvider {
-
-        TestableNotificationInterruptionStateProvider(Context context,
-                NotificationFilter filter, StatusBarStateController controller,
-                BatteryController batteryController) {
-            super(context, filter, controller, batteryController);
-            mUseHeadsUp = true;
-        }
-    }
-
     /**
      * Sets the bubble metadata flags for this entry. These ]flags are normally set by
      * NotificationManagerService when the notification is sent, however, these tests do not
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java
index 5a1bef9..24f8a7b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java
@@ -40,7 +40,6 @@
 import android.app.IActivityManager;
 import android.app.Notification;
 import android.app.PendingIntent;
-import android.content.Context;
 import android.content.res.Resources;
 import android.hardware.face.FaceManager;
 import android.service.notification.ZenModeConfig;
@@ -788,42 +787,6 @@
                 groupSummary.getEntry()));
     }
 
-    static class TestableBubbleController extends BubbleController {
-        // Let's assume surfaces can be synchronized immediately.
-        TestableBubbleController(Context context,
-                NotificationShadeWindowController notificationShadeWindowController,
-                StatusBarStateController statusBarStateController,
-                ShadeController shadeController,
-                BubbleData data,
-                ConfigurationController configurationController,
-                NotificationInterruptionStateProvider interruptionStateProvider,
-                ZenModeController zenModeController,
-                NotificationLockscreenUserManager lockscreenUserManager,
-                NotificationGroupManager groupManager,
-                NotificationEntryManager entryManager,
-                NotifPipeline notifPipeline,
-                FeatureFlags featureFlags,
-                DumpController dumpController) {
-            super(context,
-                    notificationShadeWindowController, statusBarStateController, shadeController,
-                    data, Runnable::run, configurationController, interruptionStateProvider,
-                    zenModeController, lockscreenUserManager, groupManager, entryManager,
-                    notifPipeline, featureFlags, dumpController);
-            setInflateSynchronously(true);
-        }
-    }
-
-    static class TestableNotificationInterruptionStateProvider extends
-            NotificationInterruptionStateProvider {
-
-        TestableNotificationInterruptionStateProvider(Context context,
-                NotificationFilter filter, StatusBarStateController controller,
-                BatteryController batteryController) {
-            super(context, filter, controller, batteryController);
-            mUseHeadsUp = true;
-        }
-    }
-
     /**
      * Sets the bubble metadata flags for this entry. These flags are normally set by
      * NotificationManagerService when the notification is sent, however, these tests do not
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableBubbleController.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableBubbleController.java
new file mode 100644
index 0000000..338abf5
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableBubbleController.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.bubbles;
+
+import android.content.Context;
+
+import com.android.systemui.DumpController;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.FeatureFlags;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
+import com.android.systemui.statusbar.notification.collection.NotifPipeline;
+import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
+import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.ZenModeController;
+
+/**
+ * Testable BubbleController subclass that immediately synchronizes surfaces.
+ */
+public class TestableBubbleController extends BubbleController {
+
+    // Let's assume surfaces can be synchronized immediately.
+    TestableBubbleController(Context context,
+            NotificationShadeWindowController notificationShadeWindowController,
+            StatusBarStateController statusBarStateController,
+            ShadeController shadeController,
+            BubbleData data,
+            ConfigurationController configurationController,
+            NotificationInterruptionStateProvider interruptionStateProvider,
+            ZenModeController zenModeController,
+            NotificationLockscreenUserManager lockscreenUserManager,
+            NotificationGroupManager groupManager,
+            NotificationEntryManager entryManager,
+            NotifPipeline notifPipeline,
+            FeatureFlags featureFlags,
+            DumpController dumpController) {
+        super(context,
+                notificationShadeWindowController, statusBarStateController, shadeController,
+                data, Runnable::run, configurationController, interruptionStateProvider,
+                zenModeController, lockscreenUserManager, groupManager, entryManager,
+                notifPipeline, featureFlags, dumpController);
+        setInflateSynchronously(true);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableNotificationInterruptionStateProvider.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableNotificationInterruptionStateProvider.java
new file mode 100644
index 0000000..5d192b2
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableNotificationInterruptionStateProvider.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.bubbles;
+
+import android.content.Context;
+
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.notification.NotificationFilter;
+import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
+import com.android.systemui.statusbar.policy.BatteryController;
+
+public class TestableNotificationInterruptionStateProvider
+        extends NotificationInterruptionStateProvider {
+
+    TestableNotificationInterruptionStateProvider(Context context,
+            NotificationFilter filter, StatusBarStateController controller,
+            BatteryController batteryController) {
+        super(context, filter, controller, batteryController);
+        mUseHeadsUp = true;
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index 5a0a495..f1fba79 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -282,6 +282,9 @@
                 .inflationCallback(any()))
                 .thenReturn(mExpandableNotificationRowComponentBuilder);
         when(mExpandableNotificationRowComponentBuilder
+                .rowContentBindStage(any()))
+                .thenReturn(mExpandableNotificationRowComponentBuilder);
+        when(mExpandableNotificationRowComponentBuilder
                 .onExpandClickListener(any()))
                 .thenReturn(mExpandableNotificationRowComponentBuilder);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java
index 1dfe7bc..a8c438a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java
@@ -28,6 +28,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
@@ -43,6 +44,7 @@
 import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
+import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
@@ -83,13 +85,12 @@
                 any(NotificationMenuRowPlugin.MenuItem.class)))
                 .thenReturn(true);
         when(mMenuRow.getLongpressMenuItem(any(Context.class))).thenReturn(mMenuItem);
-        mDependency.injectTestDependency(NotificationGutsManager.class, mGutsManager);
-        mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
         mDependency.injectMockDependency(BubbleController.class);
 
         mHelper = new NotificationTestHelper(mContext, mDependency);
 
-        mBlockingHelperManager = new NotificationBlockingHelperManager(mContext);
+        mBlockingHelperManager = new NotificationBlockingHelperManager(
+                mContext, mGutsManager, mEntryManager, mock(MetricsLogger.class));
         // By default, have the shade visible/expanded.
         mBlockingHelperManager.setNotificationShadeExpanded(1f);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
index 8a42e5f..149a95a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
@@ -50,10 +50,12 @@
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.SmartReplyController;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.BindParams;
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationCallback;
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
+import com.android.systemui.statusbar.policy.SmartReplyConstants;
 import com.android.systemui.tests.R;
 
 import org.junit.Assert;
@@ -92,9 +94,14 @@
         ExpandableNotificationRow row = new NotificationTestHelper(mContext, mDependency).createRow(
                 mBuilder.build());
         mRow = spy(row);
+
+        final SmartReplyConstants smartReplyConstants = mock(SmartReplyConstants.class);
+        final SmartReplyController smartReplyController = mock(SmartReplyController.class);
         mNotificationInflater = new NotificationContentInflater(
                 mCache,
-                mock(NotificationRemoteInputManager.class));
+                mock(NotificationRemoteInputManager.class),
+                () -> smartReplyConstants,
+                () -> smartReplyController);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
index e8de10f7..27b263f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
@@ -51,7 +51,8 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ShortcutInfo;
 import android.content.pm.ShortcutManager;
-import android.graphics.drawable.Drawable;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Icon;
 import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
@@ -60,12 +61,12 @@
 import android.testing.TestableLooper;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.widget.Button;
 import android.widget.ImageButton;
 import android.widget.ImageView;
 import android.widget.TextView;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.settingslib.notification.ConversationIconFactory;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
@@ -112,7 +113,8 @@
     private NotificationEntry mBubbleEntry;
     @Mock
     private ShortcutInfo mShortcutInfo;
-    private Drawable mImage;
+    @Mock
+    private Bitmap mImage;
 
     @Rule
     public MockitoRule mockito = MockitoJUnit.rule();
@@ -134,6 +136,8 @@
     private NotificationGuts mNotificationGuts;
     @Mock
     private ShadeController mShadeController;
+    @Mock
+    private ConversationIconFactory mIconFactory;
 
     @Before
     public void setUp() throws Exception {
@@ -176,9 +180,8 @@
         when(mShortcutInfo.getShortLabel()).thenReturn("Convo name");
         List<ShortcutInfo> shortcuts = Arrays.asList(mShortcutInfo);
         when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcuts);
-        mImage = mContext.getDrawable(R.drawable.ic_remove);
-        when(mLauncherApps.getShortcutBadgedIconDrawable(eq(mShortcutInfo),
-                anyInt())).thenReturn(mImage);
+        when(mIconFactory.getConversationBitmap(any(ShortcutInfo.class), anyString(), anyInt()))
+                .thenReturn(mImage);
 
         mNotificationChannel = new NotificationChannel(
                 TEST_CHANNEL, TEST_CHANNEL_NAME, IMPORTANCE_LOW);
@@ -224,9 +227,10 @@
                 null,
                 null,
                 null,
+                mIconFactory,
                 true);
         final ImageView view = mNotificationInfo.findViewById(R.id.conversation_icon);
-        assertEquals(mImage, view.getDrawable());
+        assertEquals(mImage, ((BitmapDrawable) view.getDrawable()).getBitmap());
     }
 
     @Test
@@ -244,6 +248,7 @@
                 null,
                 null,
                 null,
+                mIconFactory,
                 true);
         final TextView textView = mNotificationInfo.findViewById(R.id.pkg_name);
         assertTrue(textView.getText().toString().contains("App Name"));
@@ -290,6 +295,7 @@
                 null,
                 null,
                 null,
+                mIconFactory,
                 true);
         final TextView textView = mNotificationInfo.findViewById(R.id.group_name);
         assertTrue(textView.getText().toString().contains(group.getName()));
@@ -312,6 +318,7 @@
                 null,
                 null,
                 null,
+                mIconFactory,
                 true);
         final TextView textView = mNotificationInfo.findViewById(R.id.group_name);
         assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility());
@@ -333,6 +340,7 @@
                 null,
                 null,
                 null,
+                mIconFactory,
                 true);
         final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
         assertEquals(GONE, nameView.getVisibility());
@@ -361,6 +369,7 @@
                 null,
                 null,
                 null,
+                mIconFactory,
                 true);
         final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
         assertEquals(VISIBLE, nameView.getVisibility());
@@ -385,6 +394,7 @@
                 },
                 null,
                 null,
+                mIconFactory,
                 true);
 
         final View settingsButton = mNotificationInfo.findViewById(R.id.info);
@@ -407,6 +417,7 @@
                 null,
                 null,
                 null,
+                mIconFactory,
                 true);
         final View settingsButton = mNotificationInfo.findViewById(R.id.info);
         assertTrue(settingsButton.getVisibility() != View.VISIBLE);
@@ -430,6 +441,7 @@
                 },
                 null,
                 null,
+                mIconFactory,
                 false);
         final View settingsButton = mNotificationInfo.findViewById(R.id.info);
         assertTrue(settingsButton.getVisibility() != View.VISIBLE);
@@ -449,6 +461,7 @@
                 null,
                 null,
                 null,
+                mIconFactory,
                 true);
 
         View bubbleView = mNotificationInfo.findViewById(R.id.bubble);
@@ -469,6 +482,7 @@
                 null,
                 null,
                 null,
+                mIconFactory,
                 true);
 
         View bubbleView = mNotificationInfo.findViewById(R.id.bubble);
@@ -491,9 +505,9 @@
                 null,
                 null,
                 null,
+                mIconFactory,
                 true);
 
-
         // Promote it
         mNotificationInfo.findViewById(R.id.home).performClick();
         mTestableLooper.processAllMessages();
@@ -522,9 +536,9 @@
                 (View v, int hours) -> {
                     latch.countDown();
                 },
+                mIconFactory,
                 true);
 
-
         // Promote it
         mNotificationInfo.findViewById(R.id.snooze).performClick();
         mTestableLooper.processAllMessages();
@@ -551,6 +565,7 @@
                 null,
                 null,
                 null,
+                mIconFactory,
                 true);
 
         assertFalse(mBubbleEntry.isBubble());
@@ -583,6 +598,7 @@
                 null,
                 null,
                 null,
+                mIconFactory,
                 true);
 
         assertTrue(mBubbleEntry.isBubble());
@@ -613,6 +629,7 @@
                 null,
                 null,
                 null,
+                mIconFactory,
                 true);
 
         assertFalse(mBubbleEntry.isBubble());
@@ -641,9 +658,9 @@
                 null,
                 null,
                 null,
+                mIconFactory,
                 true);
 
-
         ImageButton fave = mNotificationInfo.findViewById(R.id.fave);
         assertEquals(mContext.getString(R.string.notification_conversation_unfavorite),
                 fave.getContentDescription().toString());
@@ -675,6 +692,7 @@
                 null,
                 null,
                 null,
+                mIconFactory,
                 true);
 
         ImageButton fave = mNotificationInfo.findViewById(R.id.fave);
@@ -708,6 +726,7 @@
                 null,
                 null,
                 null,
+                mIconFactory,
                 true);
 
         ImageButton mute = mNotificationInfo.findViewById(R.id.mute);
@@ -743,9 +762,9 @@
                 null,
                 null,
                 null,
+                mIconFactory,
                 true);
 
-
         ImageButton mute = mNotificationInfo.findViewById(R.id.mute);
         assertEquals(mContext.getString(R.string.notification_conversation_mute),
                 mute.getContentDescription().toString());
@@ -774,7 +793,9 @@
                 null,
                 null,
                 null,
+                mIconFactory,
                 true);
+
         verify(mMockINotificationManager, times(1)).createConversationNotificationChannelForPackage(
                 anyString(), anyInt(), anyString(), any(), eq(CONVERSATION_ID));
     }
@@ -794,7 +815,9 @@
                 null,
                 null,
                 null,
+                mIconFactory,
                 true);
+
         verify(mMockINotificationManager, never()).createConversationNotificationChannelForPackage(
                 anyString(), anyInt(), anyString(), any(), eq(CONVERSATION_ID));
     }
@@ -815,6 +838,7 @@
                 null,
                 null,
                 null,
+                mIconFactory,
                 true);
 
         mNotificationInfo.findViewById(R.id.mute).performClick();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index 7a1bd05..9a52ee8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -60,6 +60,7 @@
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
+import com.android.systemui.statusbar.policy.SmartReplyConstants;
 import com.android.systemui.tests.R;
 
 import org.mockito.ArgumentCaptor;
@@ -98,7 +99,6 @@
         dependency.injectMockDependency(NotificationMediaManager.class);
         dependency.injectMockDependency(BubbleController.class);
         dependency.injectMockDependency(NotificationShadeWindowController.class);
-        dependency.injectMockDependency(SmartReplyController.class);
         mStatusBarStateController = mock(StatusBarStateController.class);
         mGroupManager = new NotificationGroupManager(mStatusBarStateController);
         mHeadsUpManager = new HeadsUpManagerPhone(mContext, mStatusBarStateController,
@@ -106,10 +106,11 @@
         mHeadsUpManager.setUp(null, mGroupManager, null, null);
         mGroupManager.setHeadsUpManager(mHeadsUpManager);
 
-
         NotificationContentInflater contentBinder = new NotificationContentInflater(
                 mock(NotifRemoteViewCache.class),
-                mock(NotificationRemoteInputManager.class));
+                mock(NotificationRemoteInputManager.class),
+                () -> mock(SmartReplyConstants.class),
+                () -> mock(SmartReplyController.class));
         contentBinder.setInflateSynchronously(true);
         mBindStage = new RowContentBindStage(contentBinder,
                 mock(NotifInflationErrorManager.class),
diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp
index 4efe934..fa3926c 100644
--- a/packages/Tethering/Android.bp
+++ b/packages/Tethering/Android.bp
@@ -16,7 +16,8 @@
 
 java_defaults {
     name: "TetheringAndroidLibraryDefaults",
-    sdk_version: "system_current",
+    // TODO (b/146757305): change to module API once available
+    sdk_version: "core_platform",
     srcs: [
         "src/**/*.java",
         ":framework-tethering-shared-srcs",
@@ -35,6 +36,8 @@
     libs: [
         "framework-tethering",
         "unsupportedappusage",
+        "android_system_stubs_current",
+        "framework-res",
     ],
     plugins: ["java_api_finder"],
     manifest: "AndroidManifestBase.xml",
@@ -82,7 +85,8 @@
 // Common defaults for compiling the actual APK.
 java_defaults {
     name: "TetheringAppDefaults",
-    sdk_version: "system_current",
+    // TODO (b/146757305): change to module API once available
+    sdk_version: "core_platform",
     privileged: true,
     // Build system doesn't track transitive dependeicies for jni_libs, list all the dependencies
     // explicitly.
@@ -96,6 +100,8 @@
     ],
     libs: [
         "framework-tethering",
+        "android_system_stubs_current",
+        "framework-res",
     ],
     jarjar_rules: "jarjar-rules.txt",
     optimize: {
diff --git a/packages/Tethering/common/TetheringLib/Android.bp b/packages/Tethering/common/TetheringLib/Android.bp
index 8c4f733..cb0de7a 100644
--- a/packages/Tethering/common/TetheringLib/Android.bp
+++ b/packages/Tethering/common/TetheringLib/Android.bp
@@ -41,12 +41,12 @@
 
 java_library {
     name: "framework-tethering",
-    sdk_version: "system_current",
+    // TODO (b/146757305): change to module_app_current once available
+    sdk_version: "core_platform",
     srcs: [
         "src/android/net/TetheredClient.java",
         "src/android/net/TetheringManager.java",
         "src/android/net/TetheringConstants.java",
-        ":framework-tethering-annotations",
     ],
     static_libs: [
         "tethering-aidl-interfaces-java",
@@ -55,6 +55,7 @@
     installable: true,
 
     libs: [
+        "framework-annotations-lib",
         "android_system_stubs_current",
     ],
 
diff --git a/packages/Tethering/common/TetheringLib/jarjar-rules.txt b/packages/Tethering/common/TetheringLib/jarjar-rules.txt
index 1403bba..e459fad 100644
--- a/packages/Tethering/common/TetheringLib/jarjar-rules.txt
+++ b/packages/Tethering/common/TetheringLib/jarjar-rules.txt
@@ -1,2 +1 @@
-rule android.annotation.** com.android.networkstack.tethering.annotation.@1
-rule com.android.internal.annotations.** com.android.networkstack.tethering.annotation.@1
\ No newline at end of file
+# jarjar rules for the bootclasspath tethering framework library here
\ No newline at end of file
diff --git a/packages/Tethering/src/android/net/ip/IpServer.java b/packages/Tethering/src/android/net/ip/IpServer.java
index f39e7af..2653b6d 100644
--- a/packages/Tethering/src/android/net/ip/IpServer.java
+++ b/packages/Tethering/src/android/net/ip/IpServer.java
@@ -756,7 +756,7 @@
                 final IpPrefix ipv4Prefix = new IpPrefix(mIpv4Address.getAddress(),
                         mIpv4Address.getPrefixLength());
                 NetdUtils.tetherInterface(mNetd, mIfaceName, ipv4Prefix);
-            } catch (RemoteException | ServiceSpecificException e) {
+            } catch (RemoteException | ServiceSpecificException | IllegalStateException e) {
                 mLog.e("Error Tethering: " + e);
                 mLastError = TetheringManager.TETHER_ERROR_TETHER_IFACE_ERROR;
                 return;
diff --git a/packages/services/PacProcessor/jni/Android.bp b/packages/services/PacProcessor/jni/Android.bp
index 351e92c..0e7e101 100644
--- a/packages/services/PacProcessor/jni/Android.bp
+++ b/packages/services/PacProcessor/jni/Android.bp
@@ -37,8 +37,7 @@
         "-Wunused",
         "-Wunreachable-code",
     ],
-    // Re-enable when b/145990493 is fixed
-    // sanitize: {
-    //    cfi: true,
-    // },
+    sanitize: {
+       cfi: true,
+    },
 }
diff --git a/proto/src/system_messages.proto b/proto/src/system_messages.proto
index 63dd99e..eda3fb9 100644
--- a/proto/src/system_messages.proto
+++ b/proto/src/system_messages.proto
@@ -248,6 +248,10 @@
     // Package: android
     NOTE_LOCATION_CHANGED = 59;
 
+    // Notify user that a SIM is required to connect to Wifi network
+    // Package: android
+    NOTE_ID_WIFI_SIM_REQUIRED = 60;
+
     // ADD_NEW_IDS_ABOVE_THIS_LINE
     // Legacy IDs with arbitrary values appear below
     // Legacy IDs existed as stable non-conflicting constants prior to the O release
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 4474f60..872f0eb 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -119,6 +119,9 @@
     private final LocalLog mUiLatencyHistory;
     private final LocalLog mWtfHistory;
     private final FieldClassificationStrategy mFieldClassificationStrategy;
+
+    @GuardedBy("mLock")
+    @Nullable
     private RemoteInlineSuggestionRenderService mRemoteInlineSuggestionRenderService;
 
     /**
@@ -236,17 +239,8 @@
             sendStateToClients(/* resetClient= */ false);
         }
         updateRemoteAugmentedAutofillService();
+        updateRemoteInlineSuggestionRenderServiceLocked();
 
-        final ComponentName componentName = RemoteInlineSuggestionRenderService
-                .getServiceComponentName(getContext(), mUserId);
-        if (componentName != null) {
-            mRemoteInlineSuggestionRenderService = new RemoteInlineSuggestionRenderService(
-                    getContext(), componentName, InlineSuggestionRenderService.SERVICE_INTERFACE,
-                    mUserId, new InlineSuggestionRenderCallbacksImpl(),
-                    mMaster.isBindInstantServiceAllowed(), mMaster.verbose);
-        } else {
-            mRemoteInlineSuggestionRenderService = null;
-        }
         return enabledChanged;
     }
 
@@ -1644,7 +1638,29 @@
         return mFieldClassificationStrategy.getDefaultAlgorithm();
     }
 
-    RemoteInlineSuggestionRenderService getRemoteInlineSuggestionRenderService() {
+    private void updateRemoteInlineSuggestionRenderServiceLocked() {
+        if (mRemoteInlineSuggestionRenderService != null) {
+            if (sVerbose) {
+                Slog.v(TAG, "updateRemoteInlineSuggestionRenderService(): "
+                        + "destroying old remote service");
+            }
+            mRemoteInlineSuggestionRenderService = null;
+        }
+
+        mRemoteInlineSuggestionRenderService = getRemoteInlineSuggestionRenderServiceLocked();
+    }
+
+    RemoteInlineSuggestionRenderService getRemoteInlineSuggestionRenderServiceLocked() {
+        final ComponentName componentName = RemoteInlineSuggestionRenderService
+                .getServiceComponentName(getContext(), mUserId);
+
+        if (mRemoteInlineSuggestionRenderService == null) {
+            mRemoteInlineSuggestionRenderService = new RemoteInlineSuggestionRenderService(
+                    getContext(), componentName, InlineSuggestionRenderService.SERVICE_INTERFACE,
+                    mUserId, new InlineSuggestionRenderCallbacksImpl(),
+                    mMaster.isBindInstantServiceAllowed(), mMaster.verbose);
+        }
+
         return mRemoteInlineSuggestionRenderService;
     }
 
diff --git a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
index d93ac68..1eb7692 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
@@ -146,7 +146,8 @@
             @Nullable AutofillValue focusedValue,
             @Nullable InlineSuggestionsRequest inlineSuggestionsRequest,
             @Nullable IInlineSuggestionsResponseCallback inlineSuggestionsCallback,
-            @NonNull Runnable onErrorCallback) {
+            @NonNull Runnable onErrorCallback,
+            @NonNull RemoteInlineSuggestionRenderService remoteRenderService) {
         long requestTime = SystemClock.elapsedRealtime();
         AtomicReference<ICancellationSignal> cancellationRef = new AtomicReference<>();
 
@@ -168,7 +169,7 @@
                                     maybeRequestShowInlineSuggestions(sessionId,
                                             inlineSuggestionsRequest, inlineSuggestionsData,
                                             focusedId, inlineSuggestionsCallback, client,
-                                            onErrorCallback);
+                                            onErrorCallback, remoteRenderService);
                                     requestAutofill.complete(null);
                                 }
 
@@ -234,7 +235,8 @@
             @Nullable InlineSuggestionsRequest request, @Nullable Dataset[] inlineSuggestionsData,
             @NonNull AutofillId focusedId,
             @Nullable IInlineSuggestionsResponseCallback inlineSuggestionsCallback,
-            @NonNull IAutoFillManagerClient client, @NonNull Runnable onErrorCallback) {
+            @NonNull IAutoFillManagerClient client, @NonNull Runnable onErrorCallback,
+            @NonNull RemoteInlineSuggestionRenderService remoteRenderService) {
         if (ArrayUtils.isEmpty(inlineSuggestionsData) || inlineSuggestionsCallback == null
                 || request == null) {
             return;
@@ -254,7 +256,7 @@
                                 } catch (RemoteException e) {
                                     Slog.w(TAG, "Encounter exception autofilling the values");
                                 }
-                            }, onErrorCallback));
+                            }, onErrorCallback, remoteRenderService));
         } catch (RemoteException e) {
             Slog.w(TAG, "Exception sending inline suggestions response back to IME.");
         }
diff --git a/services/autofill/java/com/android/server/autofill/RemoteInlineSuggestionRenderService.java b/services/autofill/java/com/android/server/autofill/RemoteInlineSuggestionRenderService.java
index 31dc23f..5d5af53 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteInlineSuggestionRenderService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteInlineSuggestionRenderService.java
@@ -36,7 +36,10 @@
 
 import com.android.internal.infra.AbstractMultiplePendingRequestsRemoteService;
 
-final class RemoteInlineSuggestionRenderService extends
+/**
+ * Remote service to help connect to InlineSuggestionRenderService in ExtServices.
+ */
+public final class RemoteInlineSuggestionRenderService extends
         AbstractMultiplePendingRequestsRemoteService<RemoteInlineSuggestionRenderService,
                 IInlineSuggestionRenderService> {
 
@@ -81,9 +84,11 @@
      * Called by {@link Session} to generate a call to the
      * {@link RemoteInlineSuggestionRenderService} to request rendering a slice .
      */
-    void renderSuggestion(@NonNull IInlineSuggestionUiCallback callback,
-            @NonNull InlinePresentation presentation, int width, int height) {
-        scheduleAsyncRequest((s) -> s.renderSuggestion(callback, presentation, width, height));
+    public void renderSuggestion(@NonNull IInlineSuggestionUiCallback callback,
+            @NonNull InlinePresentation presentation, int width, int height,
+            @Nullable IBinder hostInputToken) {
+        scheduleAsyncRequest(
+                (s) -> s.renderSuggestion(callback, presentation, width, height, hostInputToken));
     }
 
     @Nullable
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 72029d1..697e5d7 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -1018,7 +1018,8 @@
 
     // FillServiceCallbacks
     @Override
-    public void authenticate(int requestId, int datasetIndex, IntentSender intent, Bundle extras) {
+    public void authenticate(int requestId, int datasetIndex, IntentSender intent, Bundle extras,
+            boolean authenticateInline) {
         if (sDebug) {
             Slog.d(TAG, "authenticate(): requestId=" + requestId + "; datasetIdx=" + datasetIndex
                     + "; intentSender=" + intent);
@@ -1042,7 +1043,7 @@
         final int authenticationId = AutofillManager.makeAuthenticationId(requestId, datasetIndex);
         mHandler.sendMessage(obtainMessage(
                 Session::startAuthentication,
-                this, authenticationId, intent, fillInIntent));
+                this, authenticationId, intent, fillInIntent, authenticateInline));
     }
 
     // VultureCallback
@@ -2623,8 +2624,6 @@
                 mService.getServicePackageName(), mComponentName,
                 serviceLabel, serviceIcon, this, id, mCompatMode);
 
-        mService.logDatasetShown(id, mClientState);
-
         synchronized (mLock) {
             if (mUiShownTime == 0) {
                 // Log first time UI is shown.
@@ -2656,10 +2655,6 @@
     private boolean requestShowInlineSuggestionsLocked(@NonNull FillResponse response,
             @Nullable String filterText) {
         final List<Dataset> datasets = response.getDatasets();
-        if (datasets == null) {
-            Log.w(TAG, "response returned null datasets");
-            return false;
-        }
 
         final InlineSuggestionSession.ImeResponse imeResponse =
                 mInlineSuggestionSession.waitAndGetImeResponse();
@@ -2671,13 +2666,12 @@
         final InlineSuggestionsRequest request = imeResponse.getRequest();
         InlineSuggestionsResponse inlineSuggestionsResponse =
                 InlineSuggestionFactory.createInlineSuggestionsResponse(request,
-                        response.getRequestId(),
-                        datasets.toArray(new Dataset[]{}), filterText, response.getInlineActions(),
-                        mCurrentViewId, mContext, this, () -> {
+                        response, filterText, response.getInlineActions(), mCurrentViewId, mContext,
+                        this, () -> {
                             synchronized (mLock) {
                                 requestHideFillUi(mCurrentViewId);
                             }
-                        });
+                        }, mService.getRemoteInlineSuggestionRenderServiceLocked());
         try {
             imeResponse.getCallback().onInlineSuggestionsResponse(inlineSuggestionsResponse);
         } catch (RemoteException e) {
@@ -2981,7 +2975,7 @@
                     synchronized (mLock) {
                         cancelAugmentedAutofillLocked();
                     }
-                });
+                }, mService.getRemoteInlineSuggestionRenderServiceLocked());
 
         if (mAugmentedAutofillDestroyer == null) {
             mAugmentedAutofillDestroyer = () -> remoteService.onDestroyAutofillWindowsRequest();
@@ -3160,7 +3154,8 @@
             }
             final int authenticationId = AutofillManager.makeAuthenticationId(requestId,
                     datasetIndex);
-            startAuthentication(authenticationId, dataset.getAuthentication(), fillInIntent);
+            startAuthentication(authenticationId, dataset.getAuthentication(), fillInIntent,
+                    /* authenticateInline= */false);
 
         }
     }
@@ -3184,10 +3179,11 @@
     }
 
     private void startAuthentication(int authenticationId, IntentSender intent,
-            Intent fillInIntent) {
+            Intent fillInIntent, boolean authenticateInline) {
         try {
             synchronized (mLock) {
-                mClient.authenticate(id, authenticationId, intent, fillInIntent);
+                mClient.authenticate(id, authenticationId, intent, fillInIntent,
+                        authenticateInline);
             }
         } catch (RemoteException e) {
             Slog.e(TAG, "Error launching auth intent", e);
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 26bb7c3..71c3c16 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -79,7 +79,7 @@
 
     public interface AutoFillUiCallback {
         void authenticate(int requestId, int datasetIndex, @NonNull IntentSender intent,
-                @Nullable Bundle extras);
+                @Nullable Bundle extras, boolean authenticateInline);
         void fill(int requestId, int datasetIndex, @NonNull Dataset dataset);
         void save();
         void cancelSave();
@@ -217,7 +217,8 @@
                     if (mCallback != null) {
                         mCallback.authenticate(response.getRequestId(),
                                 AutofillManager.AUTHENTICATION_ID_DATASET_ID_UNDEFINED,
-                                response.getAuthentication(), response.getClientState());
+                                response.getAuthentication(), response.getClientState(),
+                                /* authenticateInline= */ false);
                     }
                 }
 
diff --git a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java
index 5f6e47b..a8886fc 100644
--- a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java
+++ b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java
@@ -22,14 +22,17 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.os.IBinder;
 import android.os.RemoteException;
 import android.service.autofill.Dataset;
+import android.service.autofill.FillResponse;
+import android.service.autofill.IInlineSuggestionUiCallback;
 import android.service.autofill.InlinePresentation;
 import android.text.TextUtils;
 import android.util.Slog;
 import android.view.SurfaceControl;
-import android.view.View;
 import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillManager;
 import android.view.autofill.AutofillValue;
 import android.view.inline.InlinePresentationSpec;
 import android.view.inputmethod.InlineSuggestion;
@@ -40,11 +43,14 @@
 
 import com.android.internal.view.inline.IInlineContentCallback;
 import com.android.internal.view.inline.IInlineContentProvider;
+import com.android.server.LocalServices;
 import com.android.server.UiThread;
+import com.android.server.autofill.RemoteInlineSuggestionRenderService;
+import com.android.server.wm.WindowManagerInternal;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.function.BiFunction;
+import java.util.function.BiConsumer;
 import java.util.regex.Pattern;
 
 public final class InlineSuggestionFactory {
@@ -61,8 +67,42 @@
     }
 
     /**
-     * Creates an {@link InlineSuggestionsResponse} with the {@code datasets} provided by
-     * augmented autofill service.
+     * Creates an {@link InlineSuggestionsResponse} with the {@code datasets} provided by the
+     * autofill service, potentially filtering the datasets.
+     */
+    public static InlineSuggestionsResponse createInlineSuggestionsResponse(
+            @NonNull InlineSuggestionsRequest request, @NonNull FillResponse response,
+            @Nullable String filterText,
+            @Nullable List<InlinePresentation> inlineActions,
+            @NonNull AutofillId autofillId,
+            @NonNull Context context,
+            @NonNull AutoFillUI.AutoFillUiCallback client,
+            @NonNull Runnable onErrorCallback,
+            @Nullable RemoteInlineSuggestionRenderService remoteRenderService) {
+        if (sDebug) Slog.d(TAG, "createInlineSuggestionsResponse called");
+        final BiConsumer<Dataset, Integer> onClickFactory;
+        if (response.getAuthentication() != null) {
+            onClickFactory = (dataset, datasetIndex) -> client.authenticate(response.getRequestId(),
+                    datasetIndex, response.getAuthentication(), response.getClientState(),
+                    /* authenticateInline= */ true);
+        } else {
+            onClickFactory = (dataset, datasetIndex) ->
+                    client.fill(response.getRequestId(), datasetIndex, dataset);
+        }
+
+        final List<Dataset> datasetList = response.getDatasets();
+        final Dataset[] datasets = datasetList == null
+                ? null
+                : datasetList.toArray(new Dataset[]{});
+
+        return createInlineSuggestionsResponseInternal(/* isAugmented= */ false, request, response,
+                datasets, filterText, inlineActions, autofillId, context, onErrorCallback,
+                onClickFactory, remoteRenderService);
+    }
+
+    /**
+     * Creates an {@link InlineSuggestionsResponse} with the {@code datasets} provided by augmented
+     * autofill service.
      */
     public static InlineSuggestionsResponse createAugmentedInlineSuggestionsResponse(
             @NonNull InlineSuggestionsRequest request,
@@ -70,44 +110,42 @@
             @NonNull AutofillId autofillId,
             @NonNull Context context,
             @NonNull InlineSuggestionUiCallback inlineSuggestionUiCallback,
-            @NonNull Runnable onErrorCallback) {
+            @NonNull Runnable onErrorCallback,
+            @Nullable RemoteInlineSuggestionRenderService remoteRenderService) {
         if (sDebug) Slog.d(TAG, "createAugmentedInlineSuggestionsResponse called");
         return createInlineSuggestionsResponseInternal(/* isAugmented= */ true, request,
-                datasets, /* filterText= */ null, /* inlineActions= */ null, autofillId, context,
-                onErrorCallback,
-                (dataset, filedIndex) -> (v -> inlineSuggestionUiCallback.autofill(dataset)));
-    }
-
-    /**
-     * Creates an {@link InlineSuggestionsResponse} with the {@code datasets} provided by the
-     * autofill service, potentially filtering the datasets.
-     */
-    public static InlineSuggestionsResponse createInlineSuggestionsResponse(
-            @NonNull InlineSuggestionsRequest request, int requestId,
-            @NonNull Dataset[] datasets,
-            @Nullable String filterText,
-            @Nullable List<InlinePresentation> inlineActions,
-            @NonNull AutofillId autofillId,
-            @NonNull Context context,
-            @NonNull AutoFillUI.AutoFillUiCallback client,
-            @NonNull Runnable onErrorCallback) {
-        if (sDebug) Slog.d(TAG, "createInlineSuggestionsResponse called");
-        return createInlineSuggestionsResponseInternal(/* isAugmented= */ false, request, datasets,
-                filterText, inlineActions, autofillId, context, onErrorCallback,
-                (dataset, filedIndex) -> (v -> client.fill(requestId, filedIndex, dataset)));
+                /* fillResponse= */ null, datasets, /* filterText= */ null,
+                /* inlineActions= */ null, autofillId, context, onErrorCallback,
+                (dataset, fieldIndex) ->
+                        inlineSuggestionUiCallback.autofill(dataset), remoteRenderService);
     }
 
     private static InlineSuggestionsResponse createInlineSuggestionsResponseInternal(
             boolean isAugmented, @NonNull InlineSuggestionsRequest request,
-            @NonNull Dataset[] datasets, @Nullable String filterText,
+            @Nullable FillResponse response, @Nullable Dataset[] datasets,
+            @Nullable String filterText,
             @Nullable List<InlinePresentation> inlineActions, @NonNull AutofillId autofillId,
             @NonNull Context context, @NonNull Runnable onErrorCallback,
-            @NonNull BiFunction<Dataset, Integer, View.OnClickListener> onClickListenerFactory) {
+            @NonNull BiConsumer<Dataset, Integer> onClickFactory,
+            @Nullable RemoteInlineSuggestionRenderService remoteRenderService) {
+
         final ArrayList<InlineSuggestion> inlineSuggestions = new ArrayList<>();
-        final InlineSuggestionUi inlineSuggestionUi = new InlineSuggestionUi(context,
-                onErrorCallback);
-        for (int i = 0; i < datasets.length; i++) {
-            final Dataset dataset = datasets[i];
+        if (response.getAuthentication() != null) {
+            InlineSuggestion inlineAuthSuggestion = createInlineAuthSuggestion(response,
+                    remoteRenderService, onClickFactory, onErrorCallback,
+                    request.getHostInputToken());
+            inlineSuggestions.add(inlineAuthSuggestion);
+
+            return new InlineSuggestionsResponse(inlineSuggestions);
+        }
+
+        if (datasets == null) {
+            Slog.w(TAG, "Datasets should not be null here");
+            return null;
+        }
+
+        for (int datasetIndex = 0; datasetIndex < datasets.length; datasetIndex++) {
+            final Dataset dataset = datasets[datasetIndex];
             final int fieldIndex = dataset.getFieldIds().indexOf(autofillId);
             if (fieldIndex < 0) {
                 Slog.w(TAG, "AutofillId=" + autofillId + " not found in dataset");
@@ -123,15 +161,17 @@
                 continue;
             }
             InlineSuggestion inlineSuggestion = createInlineSuggestion(isAugmented, dataset,
-                    fieldIndex, mergedInlinePresentation(request, i, inlinePresentation),
-                    inlineSuggestionUi, onClickListenerFactory);
+                    fieldIndex, mergedInlinePresentation(request, datasetIndex, inlinePresentation),
+                    onClickFactory, remoteRenderService, onErrorCallback,
+                    request.getHostInputToken());
+
             inlineSuggestions.add(inlineSuggestion);
         }
         if (inlineActions != null) {
             for (InlinePresentation inlinePresentation : inlineActions) {
                 final InlineSuggestion inlineAction = createInlineAction(isAugmented, context,
                         mergedInlinePresentation(request, 0, inlinePresentation),
-                        inlineSuggestionUi);
+                        remoteRenderService, onErrorCallback, request.getHostInputToken());
                 inlineSuggestions.add(inlineAction);
             }
         }
@@ -173,43 +213,59 @@
     private static InlineSuggestion createInlineAction(boolean isAugmented,
             @NonNull Context context,
             @NonNull InlinePresentation inlinePresentation,
-            @NonNull InlineSuggestionUi inlineSuggestionUi) {
+            @Nullable RemoteInlineSuggestionRenderService remoteRenderService,
+            @NonNull Runnable onErrorCallback, @Nullable IBinder hostInputToken) {
         // TODO(b/146453195): fill in the autofill hint properly.
         final InlineSuggestionInfo inlineSuggestionInfo = new InlineSuggestionInfo(
                 inlinePresentation.getInlinePresentationSpec(),
                 isAugmented ? InlineSuggestionInfo.SOURCE_PLATFORM
                         : InlineSuggestionInfo.SOURCE_AUTOFILL, new String[]{""},
                 InlineSuggestionInfo.TYPE_ACTION);
-        final View.OnClickListener onClickListener = v -> {
-            // TODO(b/148567875): Launch the intent provided through the slice. This
-            //  should be part of the UI renderer therefore will be moved to the support
-            //  library.
+        final Runnable onClickAction = () -> {
             Toast.makeText(context, "icon clicked", Toast.LENGTH_SHORT).show();
         };
         return new InlineSuggestion(inlineSuggestionInfo,
-                createInlineContentProvider(inlinePresentation, inlineSuggestionUi,
-                        onClickListener));
+                createInlineContentProvider(inlinePresentation, onClickAction, onErrorCallback,
+                        remoteRenderService, hostInputToken));
     }
 
     private static InlineSuggestion createInlineSuggestion(boolean isAugmented,
-            @NonNull Dataset dataset,
-            int fieldIndex, @NonNull InlinePresentation inlinePresentation,
-            @NonNull InlineSuggestionUi inlineSuggestionUi,
-            @NonNull BiFunction<Dataset, Integer, View.OnClickListener> onClickListenerFactory) {
+            @NonNull Dataset dataset, int datasetIndex,
+            @NonNull InlinePresentation inlinePresentation,
+            @NonNull BiConsumer<Dataset, Integer> onClickFactory,
+            @NonNull RemoteInlineSuggestionRenderService remoteRenderService,
+            @NonNull Runnable onErrorCallback, @Nullable IBinder hostInputToken) {
         // TODO(b/146453195): fill in the autofill hint properly.
         final InlineSuggestionInfo inlineSuggestionInfo = new InlineSuggestionInfo(
                 inlinePresentation.getInlinePresentationSpec(),
                 isAugmented ? InlineSuggestionInfo.SOURCE_PLATFORM
                         : InlineSuggestionInfo.SOURCE_AUTOFILL, new String[]{""},
                 InlineSuggestionInfo.TYPE_SUGGESTION);
-        final View.OnClickListener onClickListener = onClickListenerFactory.apply(dataset,
-                fieldIndex);
+
         final InlineSuggestion inlineSuggestion = new InlineSuggestion(inlineSuggestionInfo,
-                createInlineContentProvider(inlinePresentation, inlineSuggestionUi,
-                        onClickListener));
+                createInlineContentProvider(inlinePresentation,
+                        () -> onClickFactory.accept(dataset, datasetIndex), onErrorCallback,
+                        remoteRenderService, hostInputToken));
+
         return inlineSuggestion;
     }
 
+    private static InlineSuggestion createInlineAuthSuggestion(@NonNull FillResponse response,
+            @NonNull RemoteInlineSuggestionRenderService remoteRenderService,
+            @NonNull BiConsumer<Dataset, Integer> onClickFactory, @NonNull Runnable onErrorCallback,
+            @Nullable IBinder hostInputToken) {
+        final InlinePresentation inlinePresentation = response.getInlinePresentation();
+        final InlineSuggestionInfo inlineSuggestionInfo = new InlineSuggestionInfo(
+                inlinePresentation.getInlinePresentationSpec(),
+                InlineSuggestionInfo.SOURCE_AUTOFILL, null, InlineSuggestionInfo.TYPE_SUGGESTION);
+
+        return new InlineSuggestion(inlineSuggestionInfo,
+                createInlineContentProvider(inlinePresentation,
+                        () -> onClickFactory.accept(null,
+                                AutofillManager.AUTHENTICATION_ID_DATASET_ID_UNDEFINED),
+                        onErrorCallback, remoteRenderService, hostInputToken));
+    }
+
     /**
      * Returns an {@link InlinePresentation} with the style spec from the request/host, and
      * everything else from the provided {@code inlinePresentation}.
@@ -231,27 +287,64 @@
     }
 
     private static IInlineContentProvider.Stub createInlineContentProvider(
-            @NonNull InlinePresentation inlinePresentation,
-            @NonNull InlineSuggestionUi inlineSuggestionUi,
-            @Nullable View.OnClickListener onClickListener) {
+            @NonNull InlinePresentation inlinePresentation, @Nullable Runnable onClickAction,
+            @NonNull Runnable onErrorCallback,
+            @Nullable RemoteInlineSuggestionRenderService remoteRenderService,
+            @Nullable IBinder hostInputToken) {
         return new IInlineContentProvider.Stub() {
             @Override
-            public void provideContent(int width, int height,
-                    IInlineContentCallback callback) {
+            public void provideContent(int width, int height, IInlineContentCallback callback) {
                 UiThread.getHandler().post(() -> {
-                    SurfaceControl sc = inlineSuggestionUi.inflate(inlinePresentation, width,
-                            height,
-                            onClickListener);
-                    try {
-                        callback.onContent(sc);
-                    } catch (RemoteException e) {
-                        Slog.w(TAG, "Encounter exception calling back with inline content.");
+                    final IInlineSuggestionUiCallback uiCallback = createInlineSuggestionUiCallback(
+                            callback, onClickAction, onErrorCallback);
+
+                    if (remoteRenderService == null) {
+                        Slog.e(TAG, "RemoteInlineSuggestionRenderService is null");
+                        return;
                     }
+
+                    remoteRenderService.renderSuggestion(uiCallback, inlinePresentation,
+                            width, height, hostInputToken);
                 });
             }
         };
     }
 
+    private static IInlineSuggestionUiCallback.Stub createInlineSuggestionUiCallback(
+            @NonNull IInlineContentCallback callback, @NonNull Runnable onAutofillCallback,
+            @NonNull Runnable onErrorCallback) {
+        return new IInlineSuggestionUiCallback.Stub() {
+            @Override
+            public void onAutofill() throws RemoteException {
+                onAutofillCallback.run();
+            }
+
+            @Override
+            public void onContent(SurfaceControl surface)
+                    throws RemoteException {
+                callback.onContent(surface);
+            }
+
+            @Override
+            public void onError() throws RemoteException {
+                onErrorCallback.run();
+            }
+
+            @Override
+            public void onTransferTouchFocusToImeWindow(IBinder sourceInputToken, int displayId)
+                    throws RemoteException {
+                //TODO(b/149574510): Move logic to IMMS
+                final WindowManagerInternal windowManagerInternal = LocalServices.getService(
+                        WindowManagerInternal.class);
+                if (!windowManagerInternal.transferTouchFocusToImeWindow(sourceInputToken,
+                        displayId)) {
+                    Slog.e(TAG, "Cannot transfer touch focus from suggestion to IME");
+                    onErrorCallback.run();
+                }
+            }
+        };
+    }
+
     private InlineSuggestionFactory() {
     }
-}
+}
\ No newline at end of file
diff --git a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionUi.java b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionUi.java
deleted file mode 100644
index bf148a6..0000000
--- a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionUi.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.autofill.ui;
-
-import static android.app.slice.SliceItem.FORMAT_IMAGE;
-import static android.app.slice.SliceItem.FORMAT_TEXT;
-
-import android.annotation.MainThread;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.slice.Slice;
-import android.app.slice.SliceItem;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.PixelFormat;
-import android.graphics.drawable.Icon;
-import android.graphics.fonts.SystemFonts;
-import android.os.IBinder;
-import android.service.autofill.InlinePresentation;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.ContextThemeWrapper;
-import android.view.LayoutInflater;
-import android.view.SurfaceControl;
-import android.view.SurfaceControlViewHost;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.android.internal.R;
-
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * This is a temporary inline suggestion UI inflater which will be replaced by the ExtServices
- * implementation.
- *
- * TODO(b/146453086): remove this class once autofill ext service is implemented.
- *
- * @hide
- */
-public class InlineSuggestionUi {
-
-    private static final String TAG = "InlineSuggestionUi";
-
-    // The pattern to match the value can be obtained by calling {@code Resources#getResourceName
-    // (int)}. This name is a single string of the form "package:type/entry".
-    private static final Pattern RESOURCE_NAME_PATTERN = Pattern.compile("([^:]+):([^/]+)/(\\S+)");
-
-    private final @NonNull Context mContext;
-    private final @NonNull Runnable mOnErrorCallback;
-
-    InlineSuggestionUi(@NonNull Context context, @NonNull Runnable onErrorCallback) {
-        this.mContext = context;
-        mOnErrorCallback = onErrorCallback;
-    }
-
-    /**
-     * Returns a {@link SurfaceControl} with the inflated content embedded in it.
-     */
-    @MainThread
-    @Nullable
-    public SurfaceControl inflate(@NonNull InlinePresentation inlinePresentation, int width,
-            int height, @Nullable View.OnClickListener onClickListener) {
-        Log.d(TAG, "Inflating the inline suggestion UI");
-
-        //TODO(b/137800469): Pass in inputToken from IME.
-        final SurfaceControlViewHost wvr = new SurfaceControlViewHost(mContext,
-                mContext.getDisplay(), (IBinder) null);
-        final SurfaceControl sc = wvr.getSurfacePackage().getSurfaceControl();
-
-        Context contextThemeWrapper = getContextThemeWrapper(mContext,
-                inlinePresentation.getInlinePresentationSpec().getStyle());
-        if (contextThemeWrapper == null) {
-            contextThemeWrapper = getDefaultContextThemeWrapper(mContext);
-        }
-        final View suggestionView = renderSlice(inlinePresentation.getSlice(),
-                contextThemeWrapper);
-
-        final InlineSuggestionRoot suggestionRoot = new InlineSuggestionRoot(
-                mContext, mOnErrorCallback);
-        suggestionRoot.addView(suggestionView);
-        suggestionRoot.setOnClickListener(onClickListener);
-
-        WindowManager.LayoutParams lp =
-                new WindowManager.LayoutParams(width, height,
-                        WindowManager.LayoutParams.TYPE_APPLICATION, 0,
-                        PixelFormat.TRANSPARENT);
-        wvr.addView(suggestionRoot, lp);
-        return sc;
-    }
-
-    private static View renderSlice(Slice slice, Context context) {
-        final LayoutInflater inflater = LayoutInflater.from(context);
-        final ViewGroup suggestionView =
-                (ViewGroup) inflater.inflate(R.layout.autofill_inline_suggestion, null);
-
-        final ImageView startIconView =
-                suggestionView.findViewById(R.id.autofill_inline_suggestion_start_icon);
-        final TextView titleView =
-                suggestionView.findViewById(R.id.autofill_inline_suggestion_title);
-        final TextView subtitleView =
-                suggestionView.findViewById(R.id.autofill_inline_suggestion_subtitle);
-        final ImageView endIconView =
-                suggestionView.findViewById(R.id.autofill_inline_suggestion_end_icon);
-
-        boolean hasStartIcon = false;
-        boolean hasEndIcon = false;
-        boolean hasSubtitle = false;
-        final List<SliceItem> sliceItems = slice.getItems();
-        for (int i = 0; i < sliceItems.size(); i++) {
-            final SliceItem sliceItem = sliceItems.get(i);
-            if (sliceItem.getFormat().equals(FORMAT_IMAGE)) {
-                final Icon sliceIcon = sliceItem.getIcon();
-                if (i == 0) { // start icon
-                    startIconView.setImageIcon(sliceIcon);
-                    hasStartIcon = true;
-                } else { // end icon
-                    endIconView.setImageIcon(sliceIcon);
-                    hasEndIcon = true;
-                }
-            } else if (sliceItem.getFormat().equals(FORMAT_TEXT)) {
-                final List<String> sliceHints = sliceItem.getHints();
-                final String sliceText = sliceItem.getText().toString();
-                if (sliceHints.contains("inline_title")) { // title
-                    titleView.setText(sliceText);
-                } else { // subtitle
-                    subtitleView.setText(sliceText);
-                    hasSubtitle = true;
-                }
-            }
-        }
-        if (!hasStartIcon) {
-            startIconView.setVisibility(View.GONE);
-        }
-        if (!hasEndIcon) {
-            endIconView.setVisibility(View.GONE);
-        }
-        if (!hasSubtitle) {
-            subtitleView.setVisibility(View.GONE);
-        }
-
-        return suggestionView;
-    }
-
-    private Context getDefaultContextThemeWrapper(@NonNull Context context) {
-        Resources.Theme theme = context.getResources().newTheme();
-        theme.applyStyle(android.R.style.Theme_AutofillInlineSuggestion, true);
-        return new ContextThemeWrapper(context, theme);
-    }
-
-    /**
-     * Returns a context wrapping the theme in the provided {@code style}, or null if {@code
-     * style} doesn't pass validation.
-     */
-    @Nullable
-    private static Context getContextThemeWrapper(@NonNull Context context,
-            @Nullable String style) {
-        if (style == null) {
-            return null;
-        }
-        Matcher matcher = RESOURCE_NAME_PATTERN.matcher(style);
-        if (!matcher.matches()) {
-            Log.d(TAG, "Can not parse the style=" + style);
-            return null;
-        }
-        String packageName = matcher.group(1);
-        String type = matcher.group(2);
-        String entry = matcher.group(3);
-        if (TextUtils.isEmpty(packageName) || TextUtils.isEmpty(type) || TextUtils.isEmpty(entry)) {
-            Log.d(TAG, "Can not proceed with empty field values in the style=" + style);
-            return null;
-        }
-        Resources resources = null;
-        try {
-            resources = context.getPackageManager().getResourcesForApplication(
-                    packageName);
-        } catch (PackageManager.NameNotFoundException e) {
-            return null;
-        }
-        int resId = resources.getIdentifier(entry, type, packageName);
-        if (resId == Resources.ID_NULL) {
-            return null;
-        }
-        Resources.Theme theme = resources.newTheme();
-        theme.applyStyle(resId, true);
-        if (!validateBaseTheme(theme, resId)) {
-            Log.d(TAG, "Provided theme is not a child of Theme.InlineSuggestion, ignoring it.");
-            return null;
-        }
-        if (!validateFontFamilyForTextViewStyles(theme)) {
-            Log.d(TAG,
-                    "Provided theme specifies a font family that is not system font, ignoring it.");
-            return null;
-        }
-        return new ContextThemeWrapper(context, theme);
-    }
-
-    private static boolean validateFontFamilyForTextViewStyles(Resources.Theme theme) {
-        return validateFontFamily(theme, android.R.attr.autofillInlineSuggestionTitle)
-                && validateFontFamily(theme, android.R.attr.autofillInlineSuggestionSubtitle);
-    }
-
-    private static boolean validateFontFamily(Resources.Theme theme, int styleAttr) {
-        TypedArray ta = null;
-        try {
-            ta = theme.obtainStyledAttributes(null, new int[]{android.R.attr.fontFamily},
-                    styleAttr,
-                    0);
-            if (ta.getIndexCount() == 0) {
-                return true;
-            }
-            String fontFamily = ta.getString(ta.getIndex(0));
-            return SystemFonts.getRawSystemFallbackMap().containsKey(fontFamily);
-        } finally {
-            if (ta != null) {
-                ta.recycle();
-            }
-        }
-    }
-
-    private static boolean validateBaseTheme(Resources.Theme theme, int styleAttr) {
-        TypedArray ta = null;
-        try {
-            ta = theme.obtainStyledAttributes(null,
-                    new int[]{android.R.attr.isAutofillInlineSuggestionTheme}, styleAttr, 0);
-            if (ta.getIndexCount() == 0) {
-                return false;
-            }
-            return ta.getBoolean(ta.getIndex(0), false);
-        } finally {
-            if (ta != null) {
-                ta.recycle();
-            }
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 311a494..a4a42bc 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -69,6 +69,7 @@
 import android.util.FeatureFlagUtils;
 import android.util.Log;
 import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
@@ -196,6 +197,12 @@
                     + " due to " + getEnableDisableReasonString(mReason) + " by " + mPackageName;
         }
 
+        void dump(ProtoOutputStream proto) {
+            proto.write(BluetoothManagerServiceDumpProto.ActiveLog.TIMESTAMP_MS, mTimestamp);
+            proto.write(BluetoothManagerServiceDumpProto.ActiveLog.ENABLE, mEnable);
+            proto.write(BluetoothManagerServiceDumpProto.ActiveLog.PACKAGE_NAME, mPackageName);
+            proto.write(BluetoothManagerServiceDumpProto.ActiveLog.REASON, mReason);
+        }
     }
 
     private final LinkedList<ActiveLog> mActiveLogs = new LinkedList<>();
@@ -2408,56 +2415,56 @@
         if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) {
             return;
         }
+        if ((args.length > 0) && args[0].startsWith("--proto")) {
+            dumpProto(fd);
+            return;
+        }
         String errorMsg = null;
 
-        boolean protoOut = (args.length > 0) && args[0].startsWith("--proto");
+        writer.println("Bluetooth Status");
+        writer.println("  enabled: " + isEnabled());
+        writer.println("  state: " + BluetoothAdapter.nameForState(mState));
+        writer.println("  address: " + mAddress);
+        writer.println("  name: " + mName);
+        if (mEnable) {
+            long onDuration = SystemClock.elapsedRealtime() - mLastEnabledTime;
+            String onDurationString = String.format(Locale.US, "%02d:%02d:%02d.%03d",
+                    (int) (onDuration / (1000 * 60 * 60)),
+                    (int) ((onDuration / (1000 * 60)) % 60), (int) ((onDuration / 1000) % 60),
+                    (int) (onDuration % 1000));
+            writer.println("  time since enabled: " + onDurationString);
+        }
 
-        if (!protoOut) {
-            writer.println("Bluetooth Status");
-            writer.println("  enabled: " + isEnabled());
-            writer.println("  state: " + BluetoothAdapter.nameForState(mState));
-            writer.println("  address: " + mAddress);
-            writer.println("  name: " + mName);
-            if (mEnable) {
-                long onDuration = SystemClock.elapsedRealtime() - mLastEnabledTime;
-                String onDurationString = String.format(Locale.US, "%02d:%02d:%02d.%03d",
-                        (int) (onDuration / (1000 * 60 * 60)),
-                        (int) ((onDuration / (1000 * 60)) % 60), (int) ((onDuration / 1000) % 60),
-                        (int) (onDuration % 1000));
-                writer.println("  time since enabled: " + onDurationString);
+        if (mActiveLogs.size() == 0) {
+            writer.println("\nBluetooth never enabled!");
+        } else {
+            writer.println("\nEnable log:");
+            for (ActiveLog log : mActiveLogs) {
+                writer.println("  " + log);
             }
+        }
 
-            if (mActiveLogs.size() == 0) {
-                writer.println("\nBluetooth never enabled!");
-            } else {
-                writer.println("\nEnable log:");
-                for (ActiveLog log : mActiveLogs) {
-                    writer.println("  " + log);
-                }
-            }
+        writer.println(
+                "\nBluetooth crashed " + mCrashes + " time" + (mCrashes == 1 ? "" : "s"));
+        if (mCrashes == CRASH_LOG_MAX_SIZE) {
+            writer.println("(last " + CRASH_LOG_MAX_SIZE + ")");
+        }
+        for (Long time : mCrashTimestamps) {
+            writer.println("  " + timeToLog(time));
+        }
 
-            writer.println(
-                    "\nBluetooth crashed " + mCrashes + " time" + (mCrashes == 1 ? "" : "s"));
-            if (mCrashes == CRASH_LOG_MAX_SIZE) {
-                writer.println("(last " + CRASH_LOG_MAX_SIZE + ")");
-            }
-            for (Long time : mCrashTimestamps) {
-                writer.println("  " + timeToLog(time));
-            }
+        writer.println("\n" + mBleApps.size() + " BLE app" + (mBleApps.size() == 1 ? "" : "s")
+                + " registered");
+        for (ClientDeathRecipient app : mBleApps.values()) {
+            writer.println("  " + app.getPackageName());
+        }
 
-            writer.println("\n" + mBleApps.size() + " BLE app" + (mBleApps.size() == 1 ? "" : "s")
-                    + "registered");
-            for (ClientDeathRecipient app : mBleApps.values()) {
-                writer.println("  " + app.getPackageName());
-            }
-
-            writer.println("");
-            writer.flush();
-            if (args.length == 0) {
-                // Add arg to produce output
-                args = new String[1];
-                args[0] = "--print";
-            }
+        writer.println("");
+        writer.flush();
+        if (args.length == 0) {
+            // Add arg to produce output
+            args = new String[1];
+            args[0] = "--print";
         }
 
         if (mBluetoothBinder == null) {
@@ -2470,14 +2477,42 @@
             }
         }
         if (errorMsg != null) {
-            // Silently return if we are extracting metrics in Protobuf format
-            if (protoOut) {
-                return;
-            }
             writer.println(errorMsg);
         }
     }
 
+    private void dumpProto(FileDescriptor fd) {
+        final ProtoOutputStream proto = new ProtoOutputStream(fd);
+        proto.write(BluetoothManagerServiceDumpProto.ENABLED, isEnabled());
+        proto.write(BluetoothManagerServiceDumpProto.STATE, mState);
+        proto.write(BluetoothManagerServiceDumpProto.STATE_NAME,
+                BluetoothAdapter.nameForState(mState));
+        proto.write(BluetoothManagerServiceDumpProto.ADDRESS, mAddress);
+        proto.write(BluetoothManagerServiceDumpProto.NAME, mName);
+        if (mEnable) {
+            proto.write(BluetoothManagerServiceDumpProto.LAST_ENABLED_TIME_MS, mLastEnabledTime);
+        }
+        proto.write(BluetoothManagerServiceDumpProto.CURR_TIMESTAMP_MS,
+                SystemClock.elapsedRealtime());
+        for (ActiveLog log : mActiveLogs) {
+            long token = proto.start(BluetoothManagerServiceDumpProto.ACTIVE_LOGS);
+            log.dump(proto);
+            proto.end(token);
+        }
+        proto.write(BluetoothManagerServiceDumpProto.NUM_CRASHES, mCrashes);
+        proto.write(BluetoothManagerServiceDumpProto.CRASH_LOG_MAXED,
+                mCrashes == CRASH_LOG_MAX_SIZE);
+        for (Long time : mCrashTimestamps) {
+            proto.write(BluetoothManagerServiceDumpProto.CRASH_TIMESTAMPS_MS, time);
+        }
+        proto.write(BluetoothManagerServiceDumpProto.NUM_BLE_APPS, mBleApps.size());
+        for (ClientDeathRecipient app : mBleApps.values()) {
+            proto.write(BluetoothManagerServiceDumpProto.BLE_APP_PACKAGE_NAMES,
+                    app.getPackageName());
+        }
+        proto.flush();
+    }
+
     private static String getEnableDisableReasonString(int reason) {
         switch (reason) {
             case BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST:
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index b334b26..60a30d3 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -64,6 +64,7 @@
 import android.content.res.Configuration;
 import android.database.ContentObserver;
 import android.net.CaptivePortal;
+import android.net.CaptivePortalData;
 import android.net.ConnectionInfo;
 import android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
 import android.net.ConnectivityDiagnosticsManager.DataStallReport;
@@ -546,6 +547,14 @@
     public static final int EVENT_PROBE_STATUS_CHANGED = 46;
 
     /**
+     * Event for NetworkMonitor to inform ConnectivityService that captive portal data has changed.
+     * arg1 = unused
+     * arg2 = netId
+     * obj = captive portal data
+     */
+    private static final int EVENT_CAPPORT_DATA_CHANGED = 47;
+
+    /**
      * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
      * should be shown.
      */
@@ -2824,6 +2833,12 @@
                     updatePrivateDns(nai, (PrivateDnsConfig) msg.obj);
                     break;
                 }
+                case EVENT_CAPPORT_DATA_CHANGED: {
+                    final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
+                    if (nai == null) break;
+                    handleCaptivePortalDataUpdate(nai, (CaptivePortalData) msg.obj);
+                    break;
+                }
             }
             return true;
         }
@@ -2991,6 +3006,13 @@
         }
 
         @Override
+        public void notifyCaptivePortalDataChanged(CaptivePortalData data) {
+            mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
+                    EVENT_CAPPORT_DATA_CHANGED,
+                    0, mNetId, data));
+        }
+
+        @Override
         public void showProvisioningNotification(String action, String packageName) {
             final Intent intent = new Intent(action);
             intent.setPackage(packageName);
@@ -3118,6 +3140,13 @@
         handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
     }
 
+    private void handleCaptivePortalDataUpdate(@NonNull final NetworkAgentInfo nai,
+            @Nullable final CaptivePortalData data) {
+        nai.captivePortalData = data;
+        // CaptivePortalData will be merged into LinkProperties from NetworkAgentInfo
+        handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
+    }
+
     /**
      * Updates the linger state from the network requests inside the NAI.
      * @param nai the agent info to update
@@ -5838,6 +5867,10 @@
 
         updateWakeOnLan(newLp);
 
+        // Captive portal data is obtained from NetworkMonitor and stored in NetworkAgentInfo,
+        // it is not contained in LinkProperties sent from NetworkAgents so needs to be merged here.
+        newLp.setCaptivePortalData(networkAgent.captivePortalData);
+
         // TODO - move this check to cover the whole function
         if (!Objects.equals(newLp, oldLp)) {
             synchronized (networkAgent) {
@@ -6898,6 +6931,15 @@
             // worry about multiple different substates of CONNECTED.
             newInfo.setDetailedState(NetworkInfo.DetailedState.SUSPENDED, info.getReason(),
                     info.getExtraInfo());
+        } else if (!suspended && info.getDetailedState() == NetworkInfo.DetailedState.SUSPENDED) {
+            // SUSPENDED state is currently only overridden from CONNECTED state. In the case the
+            // network agent is created, then goes to suspended, then goes out of suspended without
+            // ever setting connected. Check if network agent is ever connected to update the state.
+            newInfo.setDetailedState(nai.everConnected
+                    ? NetworkInfo.DetailedState.CONNECTED
+                    : NetworkInfo.DetailedState.CONNECTING,
+                    info.getReason(),
+                    info.getExtraInfo());
         }
         newInfo.setRoaming(!nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_ROAMING));
         return newInfo;
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index b5b22f1..53dbb93 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -28,6 +28,10 @@
 import static android.app.AppOpsManager.OP_READ_EXTERNAL_STORAGE;
 import static android.app.AppOpsManager.OP_REQUEST_INSTALL_PACKAGES;
 import static android.app.AppOpsManager.OP_WRITE_EXTERNAL_STORAGE;
+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_UNINSTALLED_PACKAGES;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
 import static android.os.storage.OnObbStateChangeListener.ERROR_ALREADY_MOUNTED;
@@ -136,6 +140,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.IAppOpsCallback;
 import com.android.internal.app.IAppOpsService;
+import com.android.internal.content.PackageMonitor;
 import com.android.internal.os.AppFuseMount;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.os.FuseUnavailableMountException;
@@ -149,6 +154,7 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.server.SystemService.TargetUser;
 import com.android.server.pm.Installer;
 import com.android.server.storage.AppFuseBridge;
 import com.android.server.storage.StorageSessionController;
@@ -184,6 +190,7 @@
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -270,6 +277,11 @@
         public void onStopUser(int userHandle) {
             mStorageManagerService.onStopUser(userHandle);
         }
+
+        @Override
+        public void onStartUser(TargetUser user) {
+            mStorageManagerService.snapshotAndMonitorLegacyStorageAppOp(user.getUserHandle());
+        }
     }
 
     private static final boolean DEBUG_EVENTS = false;
@@ -578,6 +590,12 @@
 
     private final boolean mIsFuseEnabled;
 
+    @GuardedBy("mLock")
+    private final Set<Integer> mUidsWithLegacyExternalStorage = new ArraySet<>();
+    // Not guarded by lock, always used on the ActivityManager thread
+    private final Map<Integer, PackageMonitor> mPackageMonitorsForUser = new ArrayMap<>();
+
+
     class ObbState implements IBinder.DeathRecipient {
         public ObbState(String rawPath, String canonicalPath, int callingUid,
                 IObbActionListener token, int nonce, String volId) {
@@ -1145,6 +1163,10 @@
         } catch (Exception e) {
             Slog.wtf(TAG, e);
         }
+        PackageMonitor monitor = mPackageMonitorsForUser.remove(userId);
+        if (monitor != null) {
+            monitor.unregister();
+        }
     }
 
     private boolean supportsBlockCheckpoint() throws RemoteException {
@@ -1836,6 +1858,49 @@
         }
     }
 
+    private void updateLegacyStorageApps(String packageName, int uid, boolean hasLegacy) {
+        synchronized (mLock) {
+            if (hasLegacy) {
+                Slog.v(TAG, "Package " + packageName + " has legacy storage");
+                mUidsWithLegacyExternalStorage.add(uid);
+            } else {
+                // TODO(b/149391976): Handle shared user id. Check if there's any other
+                // installed app with legacy external storage before removing
+                Slog.v(TAG, "Package " + packageName + " does not have legacy storage");
+                mUidsWithLegacyExternalStorage.remove(uid);
+            }
+        }
+    }
+
+    private void snapshotAndMonitorLegacyStorageAppOp(UserHandle user) {
+        int userId = user.getIdentifier();
+
+        // TODO(b/149391976): Use mIAppOpsService.getPackagesForOps instead of iterating below
+        // It should improve performance but the AppOps method doesn't return any app here :(
+        // This operation currently takes about ~20ms on a freshly flashed device
+        for (ApplicationInfo ai : mPmInternal.getInstalledApplications(MATCH_DIRECT_BOOT_AWARE
+                        | MATCH_DIRECT_BOOT_UNAWARE | MATCH_UNINSTALLED_PACKAGES | MATCH_ANY_USER,
+                        userId, Process.myUid())) {
+            try {
+                boolean hasLegacy = mIAppOpsService.checkOperation(OP_LEGACY_STORAGE, ai.uid,
+                        ai.packageName) == MODE_ALLOWED;
+                updateLegacyStorageApps(ai.packageName, ai.uid, hasLegacy);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Failed to check legacy op for package " + ai.packageName, e);
+            }
+        }
+
+        PackageMonitor monitor = new PackageMonitor() {
+                @Override
+                public void onPackageRemoved(String packageName, int uid) {
+                    updateLegacyStorageApps(packageName, uid, false);
+                }
+            };
+        // TODO(b/149391976): Use different handler?
+        monitor.register(mContext, user, true, mHandler);
+        mPackageMonitorsForUser.put(userId, monitor);
+    }
+
     private static long getLastAccessTime(AppOpsManager manager,
             int uid, String packageName, int[] ops) {
         long maxTime = 0;
@@ -3975,7 +4040,7 @@
             if (mIsFuseEnabled && hasMtp) {
                 ApplicationInfo ai = mIPackageManager.getApplicationInfo(packageName,
                         0, UserHandle.getUserId(uid));
-                if (ai.isSignedWithPlatformKey()) {
+                if (ai != null && ai.isSignedWithPlatformKey()) {
                     // Platform processes hosting the MTP server should be able to write in Android/
                     return Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE;
                 }
@@ -4030,7 +4095,7 @@
             if (!hasLegacy && !mIsFuseEnabled) {
                 ApplicationInfo ai = mIPackageManager.getApplicationInfo(packageName,
                         0, UserHandle.getUserId(uid));
-                hasLegacy = ai.hasRequestedLegacyExternalStorage();
+                hasLegacy = (ai != null && ai.hasRequestedLegacyExternalStorage());
             }
 
             if (hasLegacy && hasWrite) {
@@ -4337,6 +4402,13 @@
             mHandler.obtainMessage(H_RESET).sendToTarget();
         }
 
+        @Override
+        public boolean hasLegacyExternalStorage(int uid) {
+            synchronized (mLock) {
+                return mUidsWithLegacyExternalStorage.contains(uid);
+            }
+        }
+
         public boolean hasExternalStorage(int uid, String packageName) {
             // No need to check for system uid. This avoids a deadlock between
             // PackageManagerService and AppOpsService.
@@ -4382,8 +4454,11 @@
                             // volumes, USB OTGs that are rarely mounted. The app will get the
                             // external_storage gid on next organic restart.
                             killAppForOpChange(code, uid, packageName);
-                            return;
                         }
+                        return;
+                    case OP_LEGACY_STORAGE:
+                        updateLegacyStorageApps(packageName, uid, mode == MODE_ALLOWED);
+                        return;
                 }
             }
 
diff --git a/services/core/java/com/android/server/SystemService.java b/services/core/java/com/android/server/SystemService.java
index e3c7325..aabe98b 100644
--- a/services/core/java/com/android/server/SystemService.java
+++ b/services/core/java/com/android/server/SystemService.java
@@ -168,6 +168,11 @@
         public int getUserIdentifier() {
             return mUserInfo.id;
         }
+
+        @Override
+        public String toString() {
+            return Integer.toString(getUserIdentifier());
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index ad550c5..1da07ef 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -7156,7 +7156,7 @@
                     } finally {
                         Binder.restoreCallingIdentity(ident);
                     }
-                } else if (dyingProc == cpr.proc) {
+                } else if (dyingProc == cpr.proc && dyingProc != null) {
                     // The old stable connection's client should be killed during proc cleaning up,
                     // so do not re-use the old ContentProviderRecord, otherwise the new clients
                     // could get killed unexpectedly.
@@ -8387,6 +8387,9 @@
 
     @Override
     public void setActivityController(IActivityController controller, boolean imAMonkey) {
+        if (controller != null) {
+            Binder.allowBlocking(controller.asBinder());
+        }
         mActivityTaskManager.setActivityController(controller, imAMonkey);
     }
 
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 88eb885..fb48db4 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -30,6 +30,7 @@
 import static android.os.Process.SHELL_UID;
 import static android.os.Process.SYSTEM_UID;
 
+import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__FRAMEWORK_LOCKED_BOOT_COMPLETED;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -92,8 +93,8 @@
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.logging.MetricsLogger;
 import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.FrameworkStatsLog;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
@@ -398,13 +399,14 @@
             // Do not report secondary users, runtime restarts or first boot/upgrade
             if (userId == UserHandle.USER_SYSTEM
                     && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
-                int uptimeSeconds = (int)(SystemClock.elapsedRealtime() / 1000);
-                MetricsLogger.histogram(mInjector.getContext(),
-                        "framework_locked_boot_completed", uptimeSeconds);
-                final int MAX_UPTIME_SECONDS = 120;
-                if (uptimeSeconds > MAX_UPTIME_SECONDS) {
+                final long elapsedTimeMs = SystemClock.elapsedRealtime();
+                FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
+                        BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__FRAMEWORK_LOCKED_BOOT_COMPLETED,
+                        elapsedTimeMs);
+                final long maxElapsedTimeMs = 120_000;
+                if (elapsedTimeMs > maxElapsedTimeMs) {
                     Slog.wtf("SystemServerTiming",
-                            "finishUserBoot took too long. uptimeSeconds=" + uptimeSeconds);
+                            "finishUserBoot took too long. elapsedTimeMs=" + elapsedTimeMs);
                 }
             }
 
@@ -618,9 +620,10 @@
         // Do not report secondary users, runtime restarts or first boot/upgrade
         if (userId == UserHandle.USER_SYSTEM
                 && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
-            int uptimeSeconds = (int) (SystemClock.elapsedRealtime() / 1000);
-            MetricsLogger.histogram(mInjector.getContext(), "framework_boot_completed",
-                    uptimeSeconds);
+            final long elapsedTimeMs = SystemClock.elapsedRealtime();
+            FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
+                    FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__FRAMEWORK_BOOT_COMPLETED,
+                    elapsedTimeMs);
         }
         final Intent bootIntent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
         bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 3ffe1be..5e1582c 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -34,6 +34,7 @@
 import static android.app.AppOpsManager.OP_COARSE_LOCATION;
 import static android.app.AppOpsManager.OP_FLAGS_ALL;
 import static android.app.AppOpsManager.OP_FLAG_SELF;
+import static android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXIED;
 import static android.app.AppOpsManager.OP_NONE;
 import static android.app.AppOpsManager.OP_PLAY_AUDIO;
 import static android.app.AppOpsManager.OP_RECORD_AUDIO;
@@ -52,10 +53,14 @@
 import static android.app.AppOpsManager.makeKey;
 import static android.app.AppOpsManager.modeToName;
 import static android.app.AppOpsManager.opToName;
+import static android.app.AppOpsManager.opToPublicName;
 import static android.app.AppOpsManager.resolveFirstUnrestrictedUidState;
 import static android.content.Intent.ACTION_PACKAGE_REMOVED;
 import static android.content.Intent.EXTRA_REPLACING;
 import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS;
+import static android.content.pm.PermissionInfo.PROTECTION_FLAG_APPOP;
+import static android.util.StatsLogInternal.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__RARELY_USED;
+import static android.util.StatsLogInternal.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__UNIFORM;
 
 import static com.android.server.appop.AppOpsService.ModeCallback.ALL_OPS;
 
@@ -78,6 +83,8 @@
 import android.app.AppOpsManagerInternal;
 import android.app.AppOpsManagerInternal.CheckOpsDelegate;
 import android.app.AsyncNotedAppOp;
+import android.app.RuntimeAppOpAccessMessage;
+import android.app.SyncNotedAppOp;
 import android.compat.Compatibility;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -86,6 +93,7 @@
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.PermissionInfo;
@@ -136,6 +144,7 @@
 import com.android.internal.app.IAppOpsCallback;
 import com.android.internal.app.IAppOpsNotedCallback;
 import com.android.internal.app.IAppOpsService;
+import com.android.internal.app.MessageSamplingConfig;
 import com.android.internal.os.Zygote;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
@@ -146,6 +155,7 @@
 import com.android.server.LocalServices;
 import com.android.server.LockGuard;
 import com.android.server.SystemServerInitThreadPool;
+import com.android.server.pm.PackageList;
 
 import libcore.util.EmptyArray;
 
@@ -162,6 +172,8 @@
 import java.io.PrintWriter;
 import java.nio.charset.StandardCharsets;
 import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -171,6 +183,8 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.function.Consumer;
 
 public class AppOpsService extends IAppOpsService.Stub {
     static final String TAG = "AppOps";
@@ -307,6 +321,34 @@
 
     private ActivityManagerInternal mActivityManagerInternal;
 
+    /** Package sampled for message collection in the current session */
+    @GuardedBy("this")
+    private String mSampledPackage = null;
+
+    /** Appop sampled for message collection in the current session */
+    @GuardedBy("this")
+    private int mSampledAppOpCode = OP_NONE;
+
+    /** Maximum distance for appop to be considered for message collection in the current session */
+    @GuardedBy("this")
+    private int mAcceptableLeftDistance = 0;
+
+    /** Number of messages collected for sampled package and appop in the current session */
+    @GuardedBy("this")
+    private float mMessagesCollectedCount;
+
+    /** List of rarely used packages priorities for message collection */
+    @GuardedBy("this")
+    private ArraySet<String> mRarelyUsedPackages = new ArraySet<>();
+
+    /** Sampling strategy used for current session */
+    @GuardedBy("this")
+    @AppOpsManager.SamplingStrategy
+    private int mSamplingStrategy;
+
+    /** Last runtime permission access message collected and ready for reporting */
+    @GuardedBy("this")
+    private RuntimeAppOpAccessMessage mCollectedRuntimePermissionMessage;
     /**
      * An unsynchronized pool of {@link OpEventProxyInfo} objects.
      */
@@ -1235,9 +1277,16 @@
             UserHandle.formatUid(sb, mWatchingUid);
             sb.append(" flags=0x");
             sb.append(Integer.toHexString(mFlags));
-            if (mWatchedOpCode != OP_NONE) {
-                sb.append(" op=");
-                sb.append(opToName(mWatchedOpCode));
+            switch (mWatchedOpCode) {
+                case OP_NONE:
+                    break;
+                case ALL_OPS:
+                    sb.append(" op=(all)");
+                    break;
+                default:
+                    sb.append(" op=");
+                    sb.append(opToName(mWatchedOpCode));
+                    break;
             }
             sb.append(" from uid=");
             UserHandle.formatUid(sb, mCallingUid);
@@ -1534,6 +1583,38 @@
             }
         }, packageSuspendFilter);
 
+        final IntentFilter packageAddedFilter = new IntentFilter();
+        packageAddedFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        packageAddedFilter.addDataScheme("package");
+        mContext.registerReceiver(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                final Uri data = intent.getData();
+
+                final String packageName = data.getSchemeSpecificPart();
+                PackageInfo pi = LocalServices.getService(
+                        PackageManagerInternal.class).getPackageInfo(packageName,
+                        PackageManager.GET_PERMISSIONS, Process.myUid(), mContext.getUserId());
+                if (isSamplingTarget(pi)) {
+                    synchronized (this) {
+                        mRarelyUsedPackages.add(packageName);
+                    }
+                }
+            }
+        }, packageAddedFilter);
+
+        List<String> packageNames = getPackageNamesForSampling();
+        synchronized (this) {
+            resamplePackageAndAppOpLocked(packageNames);
+        }
+
+        AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
+            @Override
+            public void run() {
+                initializeRarelyUsedPackagesList(new ArraySet<>(packageNames));
+            }
+        });
+
         PackageManagerInternal packageManagerInternal = LocalServices.getService(
                 PackageManagerInternal.class);
         packageManagerInternal.setExternalSourcesPolicy(
@@ -3029,6 +3110,9 @@
                         featureId, message, System.currentTimeMillis());
                 final boolean[] wasNoteForwarded = {false};
 
+                reportRuntimeAppOpAccessMessageAsyncLocked(uid, packageName, opCode, featureId,
+                        message);
+
                 if (callbacks != null) {
                     callbacks.broadcast((cb) -> {
                         try {
@@ -3365,7 +3449,8 @@
             return false;
         }
 
-        return permInfo.getProtection() == PROTECTION_DANGEROUS;
+        return permInfo.getProtection() == PROTECTION_DANGEROUS
+                || (permInfo.getProtectionFlags() & PROTECTION_FLAG_APPOP) != 0;
     }
 
     private void verifyIncomingUid(int uid) {
@@ -5492,6 +5577,227 @@
         mHistoricalRegistry.clearHistory();
     }
 
+    /**
+     * Report runtime access to AppOp together with message (including stack trace)
+     *
+     * @param packageName The package which reported the op
+     * @param notedAppOp contains code of op and featureId provided by developer
+     * @param message Message describing AppOp access (can be stack trace)
+     *
+     * @return Config for future sampling to reduce amount of reporting
+     */
+    @Override
+    public MessageSamplingConfig reportRuntimeAppOpAccessMessageAndGetConfig(
+            String packageName, SyncNotedAppOp notedAppOp, String message) {
+        int uid = Binder.getCallingUid();
+        Objects.requireNonNull(packageName);
+        synchronized (this) {
+            switchPackageIfRarelyUsedLocked(packageName);
+            if (!packageName.equals(mSampledPackage)) {
+                return new MessageSamplingConfig(OP_NONE, 0,
+                        Instant.now().plus(1, ChronoUnit.HOURS).toEpochMilli());
+            }
+
+            Objects.requireNonNull(notedAppOp);
+            Objects.requireNonNull(message);
+
+            reportRuntimeAppOpAccessMessageInternalLocked(uid, packageName,
+                    AppOpsManager.strOpToOp(notedAppOp.getOp()),
+                    notedAppOp.getFeatureId(), message);
+
+            return new MessageSamplingConfig(mSampledAppOpCode, mAcceptableLeftDistance,
+                    Instant.now().plus(1, ChronoUnit.HOURS).toEpochMilli());
+        }
+    }
+
+    /**
+     * Report runtime access to AppOp together with message (entry point for reporting
+     * asynchronous access)
+     * @param uid Uid of the package which reported the op
+     * @param packageName The package which reported the op
+     * @param opCode Code of AppOp
+     * @param featureId FeautreId of AppOp reported
+     * @param message Message describing AppOp access (can be stack trace)
+     */
+    private void reportRuntimeAppOpAccessMessageAsyncLocked(int uid,
+            @NonNull String packageName, int opCode, @Nullable String featureId,
+            @NonNull String message) {
+        switchPackageIfRarelyUsedLocked(packageName);
+        if (!Objects.equals(mSampledPackage, packageName)) {
+            return;
+        }
+        reportRuntimeAppOpAccessMessageInternalLocked(uid, packageName, opCode, featureId, message);
+    }
+
+    /**
+     * Decides whether reported message is within the range of watched AppOps and picks it for
+     * reporting uniformly at random across all received messages.
+     */
+    private void reportRuntimeAppOpAccessMessageInternalLocked(int uid,
+            @NonNull String packageName, int opCode, @Nullable String featureId,
+            @NonNull String message) {
+        int newLeftDistance = AppOpsManager.leftCircularDistance(opCode,
+                mSampledAppOpCode, _NUM_OP);
+
+        if (mAcceptableLeftDistance < newLeftDistance) {
+            return;
+        }
+
+        if (mAcceptableLeftDistance > newLeftDistance) {
+            mAcceptableLeftDistance = newLeftDistance;
+            mMessagesCollectedCount = 0.0f;
+        }
+
+        mMessagesCollectedCount += 1.0f;
+        if (ThreadLocalRandom.current().nextFloat() <= 1.0f / mMessagesCollectedCount) {
+            mCollectedRuntimePermissionMessage = new RuntimeAppOpAccessMessage(uid, opCode,
+                    packageName, featureId, message, mSamplingStrategy);
+        }
+        return;
+    }
+
+    /** Pulls current AppOps access report and resamples package and app op to watch */
+    @Override
+    public @Nullable RuntimeAppOpAccessMessage collectRuntimeAppOpAccessMessage() {
+        mContext.enforcePermission(android.Manifest.permission.GET_APP_OPS_STATS,
+                Binder.getCallingPid(), Binder.getCallingUid(), null);
+        RuntimeAppOpAccessMessage result;
+        List<String> packageNames = getPackageNamesForSampling();
+        synchronized (this) {
+            result = mCollectedRuntimePermissionMessage;
+            resamplePackageAndAppOpLocked(packageNames);
+        }
+        return result;
+    }
+
+    /**
+     * Checks if package is in the list of rarely used package and starts watching the new package
+     * to collect incoming message.
+     * @param packageName
+     */
+    private void switchPackageIfRarelyUsedLocked(@NonNull String packageName) {
+        if (mRarelyUsedPackages.contains(packageName)) {
+            mRarelyUsedPackages.remove(packageName);
+            if (ThreadLocalRandom.current().nextFloat() < 0.5f) {
+                mSamplingStrategy = RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__RARELY_USED;
+                resampleAppOpForPackageLocked(packageName);
+            }
+        }
+    }
+
+    /** Resamples package and appop to watch from the list provided. */
+    private void resamplePackageAndAppOpLocked(@NonNull List<String> packageNames) {
+        if (!packageNames.isEmpty()) {
+            mSamplingStrategy = RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__UNIFORM;
+            resampleAppOpForPackageLocked(packageNames.get(
+                    ThreadLocalRandom.current().nextInt(packageNames.size())));
+        }
+    }
+
+    /** Resamples appop for the chosen package and initializes sampling state */
+    private void resampleAppOpForPackageLocked(@NonNull String packageName) {
+        mMessagesCollectedCount = 0.0f;
+        mSampledAppOpCode = ThreadLocalRandom.current().nextInt(_NUM_OP);
+        mAcceptableLeftDistance = _NUM_OP;
+        mSampledPackage = packageName;
+        mCollectedRuntimePermissionMessage = null;
+    }
+
+    /**
+     * Creates list of rarely used packages - packages which were not used over last week or
+     * which declared but did not use permissions over last week.
+     *  */
+    private void initializeRarelyUsedPackagesList(@NonNull ArraySet<String> candidates) {
+        AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
+        List<String> runtimeAppOpsList = getRuntimeAppOpsList();
+        AppOpsManager.HistoricalOpsRequest histOpsRequest =
+                new AppOpsManager.HistoricalOpsRequest.Builder(
+                        Instant.now().minus(7, ChronoUnit.DAYS).toEpochMilli(),
+                        Long.MAX_VALUE).setOpNames(runtimeAppOpsList).setFlags(
+                        OP_FLAG_SELF | OP_FLAG_TRUSTED_PROXIED).build();
+        appOps.getHistoricalOps(histOpsRequest, AsyncTask.THREAD_POOL_EXECUTOR,
+                new Consumer<HistoricalOps>() {
+                    @Override
+                    public void accept(HistoricalOps histOps) {
+                        int uidCount = histOps.getUidCount();
+                        for (int uidIdx = 0; uidIdx < uidCount; uidIdx++) {
+                            final AppOpsManager.HistoricalUidOps uidOps = histOps.getUidOpsAt(
+                                    uidIdx);
+                            int pkgCount = uidOps.getPackageCount();
+                            for (int pkgIdx = 0; pkgIdx < pkgCount; pkgIdx++) {
+                                String packageName = uidOps.getPackageOpsAt(
+                                        pkgIdx).getPackageName();
+                                if (!candidates.contains(packageName)) {
+                                    continue;
+                                }
+                                AppOpsManager.HistoricalPackageOps packageOps =
+                                        uidOps.getPackageOpsAt(pkgIdx);
+                                if (packageOps.getOpCount() != 0) {
+                                    candidates.remove(packageName);
+                                }
+                            }
+                        }
+                        synchronized (this) {
+                            mRarelyUsedPackages = candidates;
+                        }
+                    }
+                });
+    }
+
+    /** List of app ops related to runtime permissions */
+    private List<String> getRuntimeAppOpsList() {
+        ArrayList<String> result = new ArrayList();
+        for (int i = 0; i < _NUM_OP; i++) {
+            if (shouldCollectNotes(i)) {
+                result.add(opToPublicName(i));
+            }
+        }
+        return result;
+    }
+
+    /** Returns list of packages to be used for package sampling */
+    private @NonNull List<String> getPackageNamesForSampling() {
+        List<String> packageNames = new ArrayList<>();
+        PackageManagerInternal packageManagerInternal = LocalServices.getService(
+                PackageManagerInternal.class);
+        PackageList packages = packageManagerInternal.getPackageList();
+        for (String packageName : packages.getPackageNames()) {
+            PackageInfo pkg = packageManagerInternal.getPackageInfo(packageName,
+                    PackageManager.GET_PERMISSIONS, Process.myUid(), mContext.getUserId());
+            if (isSamplingTarget(pkg)) {
+                packageNames.add(pkg.packageName);
+            }
+        }
+        return packageNames;
+    }
+
+    /** Checks whether package should be included in sampling pool */
+    private boolean isSamplingTarget(@Nullable PackageInfo pkg) {
+        if (pkg == null) {
+            return false;
+        }
+        if (pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.Q) {
+            return false;
+        }
+
+        String[] requestedPermissions = pkg.requestedPermissions;
+        if (requestedPermissions == null) {
+            return false;
+        }
+        for (String permission : requestedPermissions) {
+            PermissionInfo permissionInfo;
+            try {
+                permissionInfo = mContext.getPackageManager().getPermissionInfo(permission, 0);
+            } catch (PackageManager.NameNotFoundException ignored) {
+                continue;
+            }
+            if (permissionInfo.getProtection() == PROTECTION_DANGEROUS) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private void removeUidsForUserLocked(int userHandle) {
         for (int i = mUidStates.size() - 1; i >= 0; --i) {
             final int uid = mUidStates.keyAt(i);
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 67d7530..4be74b5 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -30,6 +30,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
 import android.app.AppGlobals;
@@ -158,6 +159,7 @@
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Objects;
 import java.util.Set;
@@ -1001,11 +1003,14 @@
         mDeviceBroker.onAudioServerDied();
 
         // Restore call state
-        if (AudioSystem.setPhoneState(mMode) ==  AudioSystem.AUDIO_STATUS_OK) {
-            mModeLogger.log(new AudioEventLogger.StringEvent(
-                "onAudioServerDied causes setPhoneState(" + AudioSystem.modeToString(mMode) + ")"));
+        synchronized (mDeviceBroker.mSetModeLock) {
+            if (AudioSystem.setPhoneState(mMode, getModeOwnerUid())
+                    ==  AudioSystem.AUDIO_STATUS_OK) {
+                mModeLogger.log(new AudioEventLogger.StringEvent(
+                        "onAudioServerDied causes setPhoneState(" + AudioSystem.modeToString(mMode)
+                        + ", uid=" + getModeOwnerUid() + ")"));
+            }
         }
-
         final int forSys;
         synchronized (mSettingsLock) {
             forSys = mCameraSoundForced ?
@@ -1072,6 +1077,15 @@
                             + AudioSystem.audioSystemErrorToString(status)
                             + " when connecting mixes for policy " + policy.toLogFriendlyString());
                     policy.release();
+                } else {
+                    final int deviceAffinitiesStatus = policy.setupDeviceAffinities();
+                    if (deviceAffinitiesStatus != AudioSystem.SUCCESS) {
+                        Log.e(TAG, "onAudioServerDied: error "
+                                + AudioSystem.audioSystemErrorToString(deviceAffinitiesStatus)
+                                + " when connecting device affinities for policy "
+                                + policy.toLogFriendlyString());
+                        policy.release();
+                    }
                 }
             }
         }
@@ -3425,14 +3439,30 @@
         return modeOwnerPid;
     }
 
+    /**
+     * Return the uid of the current audio mode owner
+     * @return 0 if nobody owns the mode
+     */
+    /*package*/ int getModeOwnerUid() {
+        int modeOwnerUid = 0;
+        try {
+            modeOwnerUid = mSetModeDeathHandlers.get(0).getUid();
+        } catch (Exception e) {
+            // nothing to do, modeOwnerUid is not modified
+        }
+        return modeOwnerUid;
+    }
+
     private class SetModeDeathHandler implements IBinder.DeathRecipient {
-        private IBinder mCb; // To be notified of client's death
-        private int mPid;
+        private final IBinder mCb; // To be notified of client's death
+        private final int mPid;
+        private final int mUid;
         private int mMode = AudioSystem.MODE_NORMAL; // Current mode set by this client
 
-        SetModeDeathHandler(IBinder cb, int pid) {
+        SetModeDeathHandler(IBinder cb, int pid, int uid) {
             mCb = cb;
             mPid = pid;
+            mUid = uid;
         }
 
         public void binderDied() {
@@ -3445,7 +3475,7 @@
                 if (index < 0) {
                     Log.w(TAG, "unregistered setMode() client died");
                 } else {
-                    newModeOwnerPid = setModeInt(AudioSystem.MODE_NORMAL, mCb, mPid, TAG);
+                    newModeOwnerPid = setModeInt(AudioSystem.MODE_NORMAL, mCb, mPid, mUid, TAG);
                 }
             }
             // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all
@@ -3470,6 +3500,10 @@
         public IBinder getBinder() {
             return mCb;
         }
+
+        public int getUid() {
+            return mUid;
+        }
     }
 
     /** @see AudioManager#setMode(int) */
@@ -3518,7 +3552,8 @@
                         + " without permission or being mode owner");
                 return;
             }
-            newModeOwnerPid = setModeInt(mode, cb, callingPid, callingPackage);
+            newModeOwnerPid = setModeInt(
+                mode, cb, callingPid, Binder.getCallingUid(), callingPackage);
         }
         // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all
         // SCO connections not started by the application changing the mode when pid changes
@@ -3530,9 +3565,11 @@
     // setModeInt() returns a valid PID if the audio mode was successfully set to
     // any mode other than NORMAL.
     @GuardedBy("mDeviceBroker.mSetModeLock")
-    private int setModeInt(int mode, IBinder cb, int pid, String caller) {
-        if (DEBUG_MODE) { Log.v(TAG, "setModeInt(mode=" + mode + ", pid=" + pid + ", caller="
-                + caller + ")"); }
+    private int setModeInt(int mode, IBinder cb, int pid, int uid, String caller) {
+        if (DEBUG_MODE) {
+            Log.v(TAG, "setModeInt(mode=" + mode + ", pid=" + pid
+                    + ", uid=" + uid + ", caller=" + caller + ")");
+        }
         int newModeOwnerPid = 0;
         if (cb == null) {
             Log.e(TAG, "setModeInt() called with null binder");
@@ -3569,7 +3606,7 @@
                 }
             } else {
                 if (hdlr == null) {
-                    hdlr = new SetModeDeathHandler(cb, pid);
+                    hdlr = new SetModeDeathHandler(cb, pid, uid);
                 }
                 // Register for client death notification
                 try {
@@ -3587,7 +3624,7 @@
 
             if (actualMode != mMode) {
                 final long identity = Binder.clearCallingIdentity();
-                status = AudioSystem.setPhoneState(actualMode);
+                status = AudioSystem.setPhoneState(actualMode, getModeOwnerUid());
                 Binder.restoreCallingIdentity(identity);
                 if (status == AudioSystem.AUDIO_STATUS_OK) {
                     if (DEBUG_MODE) { Log.v(TAG, " mode successfully set to " + actualMode); }
@@ -6634,7 +6671,7 @@
     static final int LOG_NB_EVENTS_DYN_POLICY = 10;
 
     final private AudioEventLogger mModeLogger = new AudioEventLogger(LOG_NB_EVENTS_PHONE_STATE,
-            "phone state (logged after successfull call to AudioSystem.setPhoneState(int))");
+            "phone state (logged after successful call to AudioSystem.setPhoneState(int, int))");
 
     // logs for wired + A2DP device connections:
     // - wired: logged before onSetWiredDeviceConnectionState() is executed
@@ -7872,22 +7909,16 @@
 
         int setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses) {
             final Integer Uid = new Integer(uid);
-            int res;
             if (mUidDeviceAffinities.remove(Uid) != null) {
-                final long identity = Binder.clearCallingIdentity();
-                res = AudioSystem.removeUidDeviceAffinities(uid);
-                Binder.restoreCallingIdentity(identity);
-                if (res != AudioSystem.SUCCESS) {
+                if (removeUidDeviceAffinitiesFromSystem(uid) != AudioSystem.SUCCESS) {
                     Log.e(TAG, "AudioSystem. removeUidDeviceAffinities(" + uid + ") failed, "
                             + " cannot call AudioSystem.setUidDeviceAffinities");
                     return AudioManager.ERROR;
                 }
             }
-            final long identity = Binder.clearCallingIdentity();
-            res = AudioSystem.setUidDeviceAffinities(uid, types, addresses);
-            Binder.restoreCallingIdentity(identity);
-            if (res == AudioSystem.SUCCESS) {
-                mUidDeviceAffinities.put(Uid, new AudioDeviceArray(types, addresses));
+            AudioDeviceArray deviceArray = new AudioDeviceArray(types, addresses);
+            if (setUidDeviceAffinitiesOnSystem(uid, deviceArray) == AudioSystem.SUCCESS) {
+                mUidDeviceAffinities.put(Uid, deviceArray);
                 return AudioManager.SUCCESS;
             }
             Log.e(TAG, "AudioSystem. setUidDeviceAffinities(" + uid + ") failed");
@@ -7896,10 +7927,7 @@
 
         int removeUidDeviceAffinities(int uid) {
             if (mUidDeviceAffinities.remove(new Integer(uid)) != null) {
-                final long identity = Binder.clearCallingIdentity();
-                final int res = AudioSystem.removeUidDeviceAffinities(uid);
-                Binder.restoreCallingIdentity(identity);
-                if (res == AudioSystem.SUCCESS) {
+                if (removeUidDeviceAffinitiesFromSystem(uid) == AudioSystem.SUCCESS) {
                     return AudioManager.SUCCESS;
                 }
             }
@@ -7907,26 +7935,41 @@
             return AudioManager.ERROR;
         }
 
+        @AudioSystem.AudioSystemError private int removeUidDeviceAffinitiesFromSystem(int uid) {
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                return AudioSystem.removeUidDeviceAffinities(uid);
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+
+        @AudioSystem.AudioSystemError private int setUidDeviceAffinitiesOnSystem(int uid,
+                AudioDeviceArray deviceArray) {
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                return AudioSystem.setUidDeviceAffinities(uid, deviceArray.mDeviceTypes,
+                        deviceArray.mDeviceAddresses);
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+
         int setUserIdDeviceAffinities(int userId,
                 @NonNull int[] types, @NonNull String[] addresses) {
             final Integer UserId = new Integer(userId);
-            int res;
             if (mUserIdDeviceAffinities.remove(UserId) != null) {
-                final long identity = Binder.clearCallingIdentity();
-                res = AudioSystem.removeUserIdDeviceAffinities(UserId);
-                Binder.restoreCallingIdentity(identity);
-                if (res != AudioSystem.SUCCESS) {
+                if (removeUserIdDeviceAffinitiesFromSystem(userId) != AudioSystem.SUCCESS) {
                     Log.e(TAG, "AudioSystem. removeUserIdDeviceAffinities("
                             + UserId + ") failed, "
                             + " cannot call AudioSystem.setUserIdDeviceAffinities");
                     return AudioManager.ERROR;
                 }
             }
-            final long identity = Binder.clearCallingIdentity();
-            res = AudioSystem.setUserIdDeviceAffinities(userId, types, addresses);
-            Binder.restoreCallingIdentity(identity);
-            if (res == AudioSystem.SUCCESS) {
-                mUserIdDeviceAffinities.put(UserId, new AudioDeviceArray(types, addresses));
+            AudioDeviceArray audioDeviceArray = new AudioDeviceArray(types, addresses);
+            if (setUserIdDeviceAffinitiesOnSystem(userId, audioDeviceArray)
+                    == AudioSystem.SUCCESS) {
+                mUserIdDeviceAffinities.put(UserId, audioDeviceArray);
                 return AudioManager.SUCCESS;
             }
             Log.e(TAG, "AudioSystem.setUserIdDeviceAffinities(" + userId + ") failed");
@@ -7935,10 +7978,7 @@
 
         int removeUserIdDeviceAffinities(int userId) {
             if (mUserIdDeviceAffinities.remove(new Integer(userId)) != null) {
-                final long identity = Binder.clearCallingIdentity();
-                final int res = AudioSystem.removeUserIdDeviceAffinities(userId);
-                Binder.restoreCallingIdentity(identity);
-                if (res == AudioSystem.SUCCESS) {
+                if (removeUserIdDeviceAffinitiesFromSystem(userId) == AudioSystem.SUCCESS) {
                     return AudioManager.SUCCESS;
                 }
             }
@@ -7946,9 +7986,76 @@
             return AudioManager.ERROR;
         }
 
+        @AudioSystem.AudioSystemError private int removeUserIdDeviceAffinitiesFromSystem(
+                @UserIdInt int userId) {
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                return AudioSystem.removeUserIdDeviceAffinities(userId);
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+
+        @AudioSystem.AudioSystemError private int setUserIdDeviceAffinitiesOnSystem(
+                @UserIdInt int userId, AudioDeviceArray deviceArray) {
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                return AudioSystem.setUserIdDeviceAffinities(userId, deviceArray.mDeviceTypes,
+                        deviceArray.mDeviceAddresses);
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+
+        @AudioSystem.AudioSystemError int setupDeviceAffinities() {
+            for (Map.Entry<Integer, AudioDeviceArray> uidEntry : mUidDeviceAffinities.entrySet()) {
+                int uidStatus = removeUidDeviceAffinitiesFromSystem(uidEntry.getKey());
+                if (uidStatus != AudioSystem.SUCCESS) {
+                    Log.e(TAG,
+                            "setupDeviceAffinities failed to remove device affinity for uid "
+                                    + uidEntry.getKey());
+                    return uidStatus;
+                }
+                uidStatus = setUidDeviceAffinitiesOnSystem(uidEntry.getKey(), uidEntry.getValue());
+                if (uidStatus != AudioSystem.SUCCESS) {
+                    Log.e(TAG,
+                            "setupDeviceAffinities failed to set device affinity for uid "
+                                    + uidEntry.getKey());
+                    return uidStatus;
+                }
+            }
+
+            for (Map.Entry<Integer, AudioDeviceArray> userIdEntry :
+                    mUserIdDeviceAffinities.entrySet()) {
+                int userIdStatus = removeUserIdDeviceAffinitiesFromSystem(userIdEntry.getKey());
+                if (userIdStatus != AudioSystem.SUCCESS) {
+                    Log.e(TAG,
+                            "setupDeviceAffinities failed to remove device affinity for userId "
+                                    + userIdEntry.getKey());
+                    return userIdStatus;
+                }
+                userIdStatus = setUserIdDeviceAffinitiesOnSystem(userIdEntry.getKey(),
+                                userIdEntry.getValue());
+                if (userIdStatus != AudioSystem.SUCCESS) {
+                    Log.e(TAG,
+                            "setupDeviceAffinities failed to set device affinity for userId "
+                                    + userIdEntry.getKey());
+                    return userIdStatus;
+                }
+            }
+            return AudioSystem.SUCCESS;
+        }
+
         /** @return human readable debug informations summarizing the state of the object. */
         public String toLogFriendlyString() {
             String textDump = super.toLogFriendlyString();
+            textDump += " Uid Device Affinities:\n";
+            String spacer = "     ";
+            textDump += logFriendlyAttributeDeviceArrayMap("Uid",
+                    mUidDeviceAffinities, spacer);
+            textDump += " UserId Device Affinities:\n";
+            textDump += logFriendlyAttributeDeviceArrayMap("UserId",
+                    mUserIdDeviceAffinities, spacer);
             textDump += " Proxy:\n";
             textDump += "   is focus policy= " + mIsFocusPolicy + "\n";
             if (mIsFocusPolicy) {
@@ -7959,6 +8066,24 @@
             textDump += "   media projection= " + mProjection + "\n";
             return textDump;
         }
+
+        private String logFriendlyAttributeDeviceArrayMap(String attribute,
+                Map<Integer, AudioDeviceArray> map, String spacer) {
+            final StringBuilder stringBuilder = new StringBuilder();
+            for (Map.Entry<Integer, AudioDeviceArray> mapEntry : map.entrySet()) {
+                stringBuilder.append(spacer).append(attribute).append(": ")
+                        .append(mapEntry.getKey()).append("\n");
+                AudioDeviceArray deviceArray = mapEntry.getValue();
+                String deviceSpacer = spacer + "   ";
+                for (int i = 0; i < deviceArray.mDeviceTypes.length; i++) {
+                    stringBuilder.append(deviceSpacer).append("Type: 0x")
+                            .append(Integer.toHexString(deviceArray.mDeviceTypes[i]))
+                            .append(" Address: ").append(deviceArray.mDeviceAddresses[i])
+                                    .append("\n");
+                }
+            }
+            return stringBuilder.toString();
+        }
     };
 
     //======================
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 592be2f..4612cfd 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -21,6 +21,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.net.CaptivePortalData;
 import android.net.IDnsResolver;
 import android.net.INetd;
 import android.net.INetworkMonitor;
@@ -167,6 +168,10 @@
     // Set to true when partial connectivity was detected.
     public boolean partialConnectivity;
 
+    // Captive portal info of the network, if any.
+    // Obtained by ConnectivityService and merged into NetworkAgent-provided information.
+    public CaptivePortalData captivePortalData;
+
     // Networks are lingered when they become unneeded as a result of their NetworkRequests being
     // satisfied by a higher-scoring network. so as to allow communication to wrap up before the
     // network is taken down.  This usually only happens to the default network. Lingering ends with
diff --git a/services/core/java/com/android/server/connectivity/NetworkRanker.java b/services/core/java/com/android/server/connectivity/NetworkRanker.java
index d0aabf95..1ae7dc5 100644
--- a/services/core/java/com/android/server/connectivity/NetworkRanker.java
+++ b/services/core/java/com/android/server/connectivity/NetworkRanker.java
@@ -20,6 +20,7 @@
 import android.annotation.Nullable;
 import android.net.NetworkRequest;
 
+import java.util.ArrayList;
 import java.util.Collection;
 
 /**
@@ -31,15 +32,15 @@
     /**
      * Find the best network satisfying this request among the list of passed networks.
      */
-    // Almost equivalent to Collections.max(nais), but allows returning null if no network
-    // satisfies the request.
     @Nullable
     public NetworkAgentInfo getBestNetwork(@NonNull final NetworkRequest request,
             @NonNull final Collection<NetworkAgentInfo> nais) {
+        final ArrayList<NetworkAgentInfo> candidates = new ArrayList<>(nais);
+        candidates.removeIf(nai -> !nai.satisfies(request));
+
         NetworkAgentInfo bestNetwork = null;
         int bestScore = Integer.MIN_VALUE;
-        for (final NetworkAgentInfo nai : nais) {
-            if (!nai.satisfies(request)) continue;
+        for (final NetworkAgentInfo nai : candidates) {
             if (nai.getCurrentScore() > bestScore) {
                 bestNetwork = nai;
                 bestScore = nai.getCurrentScore();
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 9140589..1ff8a94 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -121,7 +121,7 @@
  * The display manager service relies on a collection of {@link DisplayAdapter} components,
  * for discovering and configuring physical display devices attached to the system.
  * There are separate display adapters for each manner that devices are attached:
- * one display adapter for built-in local displays, one for simulated non-functional
+ * one display adapter for physical displays, one for simulated non-functional
  * displays when the system is headless, one for simulated overlay displays used for
  * development, one for wifi displays, etc.
  * </p><p>
@@ -231,7 +231,7 @@
     private int mGlobalDisplayState = Display.STATE_ON;
 
     // The overall display brightness.
-    // For now, this only applies to the built-in display but we may split it up eventually.
+    // For now, this only applies to the default display but we may split it up eventually.
     private float mGlobalDisplayBrightness;
 
     // Set to true when there are pending display changes that have yet to be applied
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 2b225e5..4ebbdda 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -35,7 +35,6 @@
 import android.view.DisplayAddress;
 import android.view.DisplayCutout;
 import android.view.DisplayEventReceiver;
-import android.view.Surface;
 import android.view.SurfaceControl;
 
 import com.android.internal.BrightnessSynchronizer;
@@ -53,7 +52,7 @@
 import java.util.Objects;
 
 /**
- * A display adapter for the local displays managed by Surface Flinger.
+ * A display adapter for the local displays managed by SurfaceFlinger.
  * <p>
  * Display adapters are guarded by the {@link DisplayManagerService.SyncRoot} lock.
  * </p>
@@ -129,10 +128,10 @@
             LocalDisplayDevice device = mDevices.get(physicalDisplayId);
             if (device == null) {
                 // Display was added.
-                final boolean isInternal = mDevices.size() == 0;
+                final boolean isDefaultDisplay = mDevices.size() == 0;
                 device = new LocalDisplayDevice(displayToken, physicalDisplayId, info,
                         configs, activeConfig, configSpecs, colorModes, activeColorMode,
-                        hdrCapabilities, isInternal);
+                        hdrCapabilities, isDefaultDisplay);
                 mDevices.put(physicalDisplayId, device);
                 sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
             } else if (device.updateDisplayProperties(configs, activeConfig,
@@ -175,7 +174,7 @@
         private final LogicalLight mBacklight;
         private final SparseArray<DisplayModeRecord> mSupportedModes = new SparseArray<>();
         private final ArrayList<Integer> mSupportedColorModes = new ArrayList<>();
-        private final boolean mIsInternal;
+        private final boolean mIsDefaultDisplay;
 
         private DisplayDeviceInfo mInfo;
         private boolean mHavePendingChanges;
@@ -207,15 +206,15 @@
                 SurfaceControl.DisplayInfo info, SurfaceControl.DisplayConfig[] configs,
                 int activeConfigId, SurfaceControl.DesiredDisplayConfigSpecs configSpecs,
                 int[] colorModes, int activeColorMode, Display.HdrCapabilities hdrCapabilities,
-                boolean isInternal) {
+                boolean isDefaultDisplay) {
             super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + physicalDisplayId);
             mPhysicalDisplayId = physicalDisplayId;
-            mIsInternal = isInternal;
+            mIsDefaultDisplay = isDefaultDisplay;
             mDisplayInfo = info;
             updateDisplayProperties(configs, activeConfigId, configSpecs, colorModes,
                     activeColorMode, hdrCapabilities);
             mSidekickInternal = LocalServices.getService(SidekickInternal.class);
-            if (mIsInternal) {
+            if (mIsDefaultDisplay) {
                 LightsManager lights = LocalServices.getService(LightsManager.class);
                 mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT);
             } else {
@@ -523,11 +522,10 @@
                 }
 
                 final Resources res = getOverlayContext().getResources();
-                if (mIsInternal) {
-                    mInfo.name = res.getString(
-                            com.android.internal.R.string.display_manager_built_in_display_name);
-                    mInfo.flags |= DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY
-                            | DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
+
+                if (mIsDefaultDisplay) {
+                    mInfo.flags |= DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY;
+
                     if (res.getBoolean(com.android.internal.R.bool.config_mainBuiltInDisplayIsRound)
                             || (Build.IS_EMULATOR
                             && SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false))) {
@@ -539,28 +537,7 @@
                     }
                     mInfo.displayCutout = DisplayCutout.fromResourcesRectApproximation(res,
                             mInfo.width, mInfo.height);
-                    mInfo.type = Display.TYPE_BUILT_IN;
-                    mInfo.touch = DisplayDeviceInfo.TOUCH_INTERNAL;
                 } else {
-                    mInfo.displayCutout = null;
-                    mInfo.type = Display.TYPE_HDMI;
-                    mInfo.flags |= DisplayDeviceInfo.FLAG_PRESENTATION;
-                    mInfo.name = getContext().getResources().getString(
-                            com.android.internal.R.string.display_manager_hdmi_display_name);
-                    mInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL;
-
-                    // For demonstration purposes, allow rotation of the external display.
-                    // In the future we might allow the user to configure this directly.
-                    if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
-                        mInfo.rotation = Surface.ROTATION_270;
-                    }
-
-                    // For demonstration purposes, allow rotation of the external display
-                    // to follow the built-in display.
-                    if (SystemProperties.getBoolean("persist.demo.hdmirotates", false)) {
-                        mInfo.flags |= DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
-                    }
-
                     if (!res.getBoolean(
                                 com.android.internal.R.bool.config_localDisplaysMirrorContent)) {
                         mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY;
@@ -570,6 +547,20 @@
                         mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE;
                     }
                 }
+
+                if (mDisplayInfo.isInternal) {
+                    mInfo.type = Display.TYPE_INTERNAL;
+                    mInfo.touch = DisplayDeviceInfo.TOUCH_INTERNAL;
+                    mInfo.flags |= DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
+                    mInfo.name = res.getString(
+                            com.android.internal.R.string.display_manager_built_in_display_name);
+                } else {
+                    mInfo.type = Display.TYPE_EXTERNAL;
+                    mInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL;
+                    mInfo.flags |= DisplayDeviceInfo.FLAG_PRESENTATION;
+                    mInfo.name = getContext().getResources().getString(
+                            com.android.internal.R.string.display_manager_hdmi_display_name);
+                }
             }
             return mInfo;
         }
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index 648e07a..ac3a653 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -395,7 +395,7 @@
     static final String PROPERTY_PREFERRED_ADDRESS_TV = "persist.sys.hdmi.addr.tv";
 
     // TODO(OEM): Set this to false to keep the playback device in sleep upon hotplug event.
-    //            True by default.
+    //            False by default.
     static final String PROPERTY_WAKE_ON_HOTPLUG = "ro.hdmi.wake_on_hotplug";
 
     /**
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index 0944324..5541b11 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -45,7 +45,7 @@
     private static final String TAG = "HdmiCecLocalDevicePlayback";
 
     private static final boolean WAKE_ON_HOTPLUG =
-            SystemProperties.getBoolean(Constants.PROPERTY_WAKE_ON_HOTPLUG, true);
+            SystemProperties.getBoolean(Constants.PROPERTY_WAKE_ON_HOTPLUG, false);
 
     private static final boolean SET_MENU_LANGUAGE =
             HdmiProperties.set_menu_language().orElse(false);
diff --git a/services/core/java/com/android/server/integrity/TEST_MAPPING b/services/core/java/com/android/server/integrity/TEST_MAPPING
index b45b4ea..ca7f396 100644
--- a/services/core/java/com/android/server/integrity/TEST_MAPPING
+++ b/services/core/java/com/android/server/integrity/TEST_MAPPING
@@ -5,12 +5,6 @@
       "options": [
         {
           "include-filter": "com.android.server.integrity."
-        },
-        {
-          "include-annotation": "android.platform.test.annotations.Presubmit"
-        },
-        {
-          "exclude-annotation": "androidx.test.filters.FlakyTest"
         }
       ]
     }
diff --git a/services/core/java/com/android/server/location/AbstractLocationProvider.java b/services/core/java/com/android/server/location/AbstractLocationProvider.java
index 997f21c..433ec43 100644
--- a/services/core/java/com/android/server/location/AbstractLocationProvider.java
+++ b/services/core/java/com/android/server/location/AbstractLocationProvider.java
@@ -16,6 +16,8 @@
 
 package com.android.server.location;
 
+import static com.android.internal.util.function.pooled.PooledLambda.obtainRunnable;
+
 import android.annotation.Nullable;
 import android.content.Context;
 import android.location.Location;
@@ -335,7 +337,8 @@
      */
     public final void setRequest(ProviderRequest request) {
         // all calls into the provider must be moved onto the provider thread to prevent deadlock
-        mExecutor.execute(() -> onSetRequest(request));
+        mExecutor.execute(obtainRunnable(AbstractLocationProvider::onSetRequest, this, request)
+                .recycleOnUse());
     }
 
     /**
@@ -348,7 +351,13 @@
      */
     public final void sendExtraCommand(int uid, int pid, String command, Bundle extras) {
         // all calls into the provider must be moved onto the provider thread to prevent deadlock
-        mExecutor.execute(() -> onExtraCommand(uid, pid, command, extras));
+
+        // the integer boxing done here likely cancels out any gains from removing lambda
+        // allocation, but since this an infrequently used api with no real performance needs, we
+        // we use pooled lambdas anyways for consistency.
+        mExecutor.execute(
+                obtainRunnable(AbstractLocationProvider::onExtraCommand, this, uid, pid, command,
+                        extras).recycleOnUse());
     }
 
     /**
@@ -361,7 +370,9 @@
      */
     public final void requestSetAllowed(boolean allowed) {
         // all calls into the provider must be moved onto the provider thread to prevent deadlock
-        mExecutor.execute(() -> onRequestSetAllowed(allowed));
+        mExecutor.execute(
+                obtainRunnable(AbstractLocationProvider::onRequestSetAllowed, this, allowed)
+                        .recycleOnUse());
     }
 
     /**
diff --git a/services/core/java/com/android/server/location/SettingsHelper.java b/services/core/java/com/android/server/location/SettingsHelper.java
index 370a3f7..5fe21bd 100644
--- a/services/core/java/com/android/server/location/SettingsHelper.java
+++ b/services/core/java/com/android/server/location/SettingsHelper.java
@@ -27,6 +27,9 @@
 import static android.provider.Settings.Secure.LOCATION_MODE;
 import static android.provider.Settings.Secure.LOCATION_MODE_OFF;
 
+import static com.android.server.LocationManagerService.D;
+import static com.android.server.LocationManagerService.TAG;
+
 import android.app.ActivityManager;
 import android.content.Context;
 import android.database.ContentObserver;
@@ -37,6 +40,7 @@
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.ArraySet;
+import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.IndentingPrintWriter;
@@ -423,6 +427,10 @@
 
         @Override
         public void onChange(boolean selfChange, Uri uri, int userId) {
+            if (D) {
+                Log.d(TAG, "location setting changed [u" + userId + "]: " + uri);
+            }
+
             for (UserSettingChangedListener listener : mListeners) {
                 listener.onSettingChanged(userId);
             }
diff --git a/services/core/java/com/android/server/location/UserInfoHelper.java b/services/core/java/com/android/server/location/UserInfoHelper.java
index a33e2da..28f3f47 100644
--- a/services/core/java/com/android/server/location/UserInfoHelper.java
+++ b/services/core/java/com/android/server/location/UserInfoHelper.java
@@ -18,6 +18,9 @@
 
 import static android.os.UserManager.DISALLOW_SHARE_LOCATION;
 
+import static com.android.server.LocationManagerService.D;
+import static com.android.server.LocationManagerService.TAG;
+
 import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
@@ -30,6 +33,7 @@
 import android.os.Build;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.ArrayUtils;
@@ -122,13 +126,13 @@
                     case Intent.ACTION_USER_STARTED:
                         userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
                         if (userId != UserHandle.USER_NULL) {
-                            onUserChanged(userId, UserListener.USER_STARTED);
+                            onUserStarted(userId);
                         }
                         break;
                     case Intent.ACTION_USER_STOPPED:
                         userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
                         if (userId != UserHandle.USER_NULL) {
-                            onUserChanged(userId, UserListener.USER_STOPPED);
+                            onUserStopped(userId);
                         }
                         break;
                     case Intent.ACTION_MANAGED_PROFILE_ADDED:
@@ -161,6 +165,10 @@
             return;
         }
 
+        if (D) {
+            Log.d(TAG, "current user switched from u" + mCurrentUserId + " to u" + newUserId);
+        }
+
         int oldUserId = mCurrentUserId;
         mCurrentUserId = newUserId;
 
@@ -168,6 +176,22 @@
         onUserChanged(newUserId, UserListener.USER_SWITCHED);
     }
 
+    private void onUserStarted(@UserIdInt int userId) {
+        if (D) {
+            Log.d(TAG, "u" + userId + " started");
+        }
+
+        onUserChanged(userId, UserListener.USER_STARTED);
+    }
+
+    private void onUserStopped(@UserIdInt int userId) {
+        if (D) {
+            Log.d(TAG, "u" + userId + " stopped");
+        }
+
+        onUserChanged(userId, UserListener.USER_STOPPED);
+    }
+
     private void onUserChanged(@UserIdInt int userId, @UserListener.UserChange int change) {
         for (UserListener listener : mListeners) {
             listener.onUserChanged(userId, change);
diff --git a/services/core/java/com/android/server/media/BluetoothRouteProvider.java b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
index 6474303..8379614 100644
--- a/services/core/java/com/android/server/media/BluetoothRouteProvider.java
+++ b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
@@ -29,7 +29,6 @@
 import android.content.IntentFilter;
 import android.media.AudioManager;
 import android.media.MediaRoute2Info;
-import android.text.TextUtils;
 import android.util.Slog;
 import android.util.SparseBooleanArray;
 
@@ -49,6 +48,8 @@
     @SuppressWarnings("WeakerAccess") /* synthetic access */
     final Map<String, BluetoothRouteInfo> mBluetoothRoutes = new HashMap<>();
     @SuppressWarnings("WeakerAccess") /* synthetic access */
+    BluetoothRouteInfo mSelectedRoute = null;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
     BluetoothA2dp mA2dpProfile;
     @SuppressWarnings("WeakerAccess") /* synthetic access */
     BluetoothHearingAid mHearingAidProfile;
@@ -62,8 +63,6 @@
     private final BroadcastReceiver mBroadcastReceiver = new BluetoothBroadcastReceiver();
     private final BluetoothProfileListener mProfileListener = new BluetoothProfileListener();
 
-    private BluetoothDevice mActiveDevice = null;
-
     static synchronized BluetoothRouteProvider getInstance(@NonNull Context context,
             @NonNull BluetoothRoutesUpdatedListener listener) {
         Objects.requireNonNull(context);
@@ -108,27 +107,21 @@
     }
 
     /**
-     * Clears the active device for all known profiles.
+     * Transfers to a given bluetooth route.
+     * The dedicated BT device with the route would be activated.
+     *
+     * @param routeId the id of the Bluetooth device. {@code null} denotes to clear the use of
+     *               BT routes.
      */
-    public void clearActiveDevices() {
-        BluetoothA2dp a2dpProfile = mA2dpProfile;
-        BluetoothHearingAid hearingAidProfile = mHearingAidProfile;
-        if (a2dpProfile != null) {
-            a2dpProfile.setActiveDevice(null);
+    public void transferTo(@Nullable String routeId) {
+        if (routeId == null) {
+            clearActiveDevices();
+            return;
         }
-        if (hearingAidProfile != null) {
-            hearingAidProfile.setActiveDevice(null);
-        }
-    }
 
-    /**
-     * Sets the active device.
-     * @param deviceId the id of the Bluetooth device
-     */
-    public void setActiveDevice(@NonNull String deviceId) {
-        BluetoothRouteInfo btRouteInfo = mBluetoothRoutes.get(deviceId);
+        BluetoothRouteInfo btRouteInfo = mBluetoothRoutes.get(routeId);
         if (btRouteInfo == null) {
-            Slog.w(TAG, "setActiveDevice: unknown device id=" + deviceId);
+            Slog.w(TAG, "setActiveDevice: unknown route id=" + routeId);
             return;
         }
         BluetoothA2dp a2dpProfile = mA2dpProfile;
@@ -144,6 +137,20 @@
         }
     }
 
+    /**
+     * Clears the active device for all known profiles.
+     */
+    private void clearActiveDevices() {
+        BluetoothA2dp a2dpProfile = mA2dpProfile;
+        BluetoothHearingAid hearingAidProfile = mHearingAidProfile;
+        if (a2dpProfile != null) {
+            a2dpProfile.setActiveDevice(null);
+        }
+        if (hearingAidProfile != null) {
+            hearingAidProfile.setActiveDevice(null);
+        }
+    }
+
     private void addEventReceiver(String action, BluetoothEventReceiver eventReceiver) {
         mEventReceiverMap.put(action, eventReceiver);
         mIntentFilter.addAction(action);
@@ -159,7 +166,8 @@
         }
     }
 
-    @NonNull List<MediaRoute2Info> getBluetoothRoutes() {
+    @NonNull
+    List<MediaRoute2Info> getAllBluetoothRoutes() {
         ArrayList<MediaRoute2Info> routes = new ArrayList<>();
         for (BluetoothRouteInfo btRoute : mBluetoothRoutes.values()) {
             routes.add(btRoute.route);
@@ -167,17 +175,14 @@
         return routes;
     }
 
-    @Nullable String getActiveDeviceAddress() {
-        BluetoothDevice device = mActiveDevice;
-        if (device == null) {
-            return null;
-        }
-        return device.getAddress();
+    @Nullable
+    String getSelectedRouteId() {
+        return mSelectedRoute == null ? null : mSelectedRoute.route.getId();
     }
 
     private void notifyBluetoothRoutesUpdated() {
         if (mListener != null) {
-            mListener.onBluetoothRoutesUpdated(getBluetoothRoutes());
+            mListener.onBluetoothRoutesUpdated(getAllBluetoothRoutes());
         }
     }
 
@@ -198,15 +203,10 @@
         return newBtRoute;
     }
 
-    private void setRouteConnectionStateForDevice(BluetoothDevice device,
+    private void setRouteConnectionState(@NonNull BluetoothRouteInfo btRoute,
             @MediaRoute2Info.ConnectionState int state) {
-        if (device == null) {
-            Slog.w(TAG, "setRouteConnectionStateForDevice: device shouldn't be null");
-            return;
-        }
-        BluetoothRouteInfo btRoute = mBluetoothRoutes.get(device.getAddress());
         if (btRoute == null) {
-            Slog.w(TAG, "setRouteConnectionStateForDevice: route shouldn't be null");
+            Slog.w(TAG, "setRouteConnectionState: route shouldn't be null");
             return;
         }
         if (btRoute.route.getConnectionState() == state) {
@@ -260,8 +260,8 @@
                     mBluetoothRoutes.put(device.getAddress(), btRoute);
                 }
                 if (activeDevices.contains(device)) {
-                    mActiveDevice = device;
-                    setRouteConnectionStateForDevice(device,
+                    mSelectedRoute = btRoute;
+                    setRouteConnectionState(mSelectedRoute,
                             MediaRoute2Info.CONNECTION_STATE_CONNECTED);
                 }
 
@@ -344,20 +344,18 @@
         public void onReceive(Context context, Intent intent, BluetoothDevice device) {
             switch (intent.getAction()) {
                 case BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED:
-                    String prevActiveDeviceAddress =
-                            (mActiveDevice == null) ? null : mActiveDevice.getAddress();
-                    String curActiveDeviceAddress =
-                            (device == null) ? null : device.getAddress();
-                    if (!TextUtils.equals(prevActiveDeviceAddress, curActiveDeviceAddress)) {
-                        if (mActiveDevice != null) {
-                            setRouteConnectionStateForDevice(mActiveDevice,
+                    if (mSelectedRoute == null
+                            || !mSelectedRoute.btDevice.equals(device)) {
+                        if (mSelectedRoute != null) {
+                            setRouteConnectionState(mSelectedRoute,
                                     MediaRoute2Info.CONNECTION_STATE_DISCONNECTED);
                         }
-                        if (device != null) {
-                            setRouteConnectionStateForDevice(device,
+                        mSelectedRoute = (device == null) ? null
+                                : mBluetoothRoutes.get(device.getAddress());
+                        if (mSelectedRoute != null) {
+                            setRouteConnectionState(mSelectedRoute,
                                     MediaRoute2Info.CONNECTION_STATE_CONNECTED);
                         }
-                        mActiveDevice = device;
                         notifyBluetoothRoutesUpdated();
                     }
                     break;
@@ -386,10 +384,8 @@
                     btRoute.connectedProfiles.delete(profile);
                     if (btRoute.connectedProfiles.size() == 0) {
                         mBluetoothRoutes.remove(device.getAddress());
-                        if (mActiveDevice != null
-                                && TextUtils.equals(mActiveDevice.getAddress(),
-                                device.getAddress())) {
-                            mActiveDevice = null;
+                        if (mSelectedRoute != null && mSelectedRoute.btDevice.equals(device)) {
+                            mSelectedRoute = null;
                         }
                         notifyBluetoothRoutesUpdated();
                     }
diff --git a/services/core/java/com/android/server/media/MediaRoute2Provider.java b/services/core/java/com/android/server/media/MediaRoute2Provider.java
index 3de5cf1..477122c 100644
--- a/services/core/java/com/android/server/media/MediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/MediaRoute2Provider.java
@@ -19,7 +19,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ComponentName;
-import android.content.Intent;
 import android.media.MediaRoute2ProviderInfo;
 import android.media.RouteDiscoveryPreference;
 import android.media.RoutingSessionInfo;
@@ -61,7 +60,6 @@
     public abstract void deselectRoute(String sessionId, String routeId);
     public abstract void transferToRoute(String sessionId, String routeId);
 
-    public abstract void sendControlRequest(String routeId, Intent request);
     public abstract void setRouteVolume(String routeId, int volume);
     public abstract void setSessionVolume(String sessionId, int volume);
 
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
index c1ea697..252855e 100644
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
@@ -123,14 +123,6 @@
     }
 
     @Override
-    public void sendControlRequest(String routeId, Intent request) {
-        if (mConnectionReady) {
-            mActiveConnection.sendControlRequest(routeId, request);
-            updateBinding();
-        }
-    }
-
-    @Override
     public void setRouteVolume(String routeId, int volume) {
         if (mConnectionReady) {
             mActiveConnection.setRouteVolume(routeId, volume);
@@ -508,14 +500,6 @@
             }
         }
 
-        public void sendControlRequest(String routeId, Intent request) {
-            try {
-                mProvider.notifyControlRequestSent(routeId, request);
-            } catch (RemoteException ex) {
-                Slog.e(TAG, "sendControlRequest: Failed to deliver request.", ex);
-            }
-        }
-
         public void setRouteVolume(String routeId, int volume) {
             try {
                 mProvider.setRouteVolume(routeId, volume);
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index 2096531..c5320b6 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -25,7 +25,6 @@
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.content.Context;
-import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.media.IMediaRouter2Client;
 import android.media.IMediaRouter2Manager;
@@ -288,22 +287,6 @@
         }
     }
 
-    public void sendControlRequest(@NonNull IMediaRouter2Client client,
-            @NonNull MediaRoute2Info route, @NonNull Intent request) {
-        Objects.requireNonNull(client, "client must not be null");
-        Objects.requireNonNull(route, "route must not be null");
-        Objects.requireNonNull(request, "request must not be null");
-
-        final long token = Binder.clearCallingIdentity();
-        try {
-            synchronized (mLock) {
-                sendControlRequestLocked(client, route, request);
-            }
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
     public void setDiscoveryRequest2(@NonNull IMediaRouter2Client client,
             @NonNull RouteDiscoveryPreference preference) {
         Objects.requireNonNull(client, "client must not be null");
@@ -605,18 +588,6 @@
         }
     }
 
-    private void sendControlRequestLocked(IMediaRouter2Client client, MediaRoute2Info route,
-            Intent request) {
-        final IBinder binder = client.asBinder();
-        Client2Record clientRecord = mAllClientRecords.get(binder);
-
-        if (clientRecord != null) {
-            clientRecord.mUserRecord.mHandler.sendMessage(
-                    obtainMessage(UserHandler::sendControlRequest,
-                            clientRecord.mUserRecord.mHandler, route, request));
-        }
-    }
-
     private void setRouteVolumeLocked(IMediaRouter2Client client, MediaRoute2Info route,
             int volume) {
         final IBinder binder = client.asBinder();
@@ -1446,13 +1417,6 @@
             }
         }
 
-        private void sendControlRequest(MediaRoute2Info route, Intent request) {
-            final MediaRoute2Provider provider = findProvider(route.getProviderId());
-            if (provider != null) {
-                provider.sendControlRequest(route.getOriginalId(), request);
-            }
-        }
-
         private void setRouteVolume(MediaRoute2Info route, int volume) {
             final MediaRoute2Provider provider = findProvider(route.getProviderId());
             if (provider != null) {
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index b38e47a..83cc894 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -498,13 +498,6 @@
 
     // Binder call
     @Override
-    public void sendControlRequest(IMediaRouter2Client client, MediaRoute2Info route,
-            Intent request) {
-        mService2.sendControlRequest(client, route, request);
-    }
-
-    // Binder call
-    @Override
     public void registerManager(IMediaRouter2Manager manager, String packageName) {
         final int uid = Binder.getCallingUid();
         if (!validatePackageName(uid, packageName)) {
diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
index ae11c70..777a8fe 100644
--- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
@@ -145,17 +145,12 @@
     @Override
     public void transferToRoute(String sessionId, String routeId) {
         if (TextUtils.equals(routeId, mDefaultRoute.getId())) {
-            mBtRouteProvider.clearActiveDevices();
+            mBtRouteProvider.transferTo(null);
         } else {
-            mBtRouteProvider.setActiveDevice(routeId);
+            mBtRouteProvider.transferTo(routeId);
         }
     }
 
-    //TODO: implement method
-    @Override
-    public void sendControlRequest(@NonNull String routeId, @NonNull Intent request) {
-    }
-
     @Override
     public void setRouteVolume(String routeId, int volume) {
         if (!TextUtils.equals(routeId, mSelectedRouteId)) {
@@ -196,7 +191,7 @@
     }
 
     private void initializeSessionInfo() {
-        mBluetoothRoutes = mBtRouteProvider.getBluetoothRoutes();
+        mBluetoothRoutes = mBtRouteProvider.getAllBluetoothRoutes();
 
         MediaRoute2ProviderInfo.Builder builder = new MediaRoute2ProviderInfo.Builder();
         builder.addRoute(mDefaultRoute);
@@ -251,7 +246,7 @@
         RoutingSessionInfo.Builder builder = new RoutingSessionInfo.Builder(
                 SYSTEM_SESSION_ID, "" /* clientPackageName */)
                 .setSystemSession(true);
-        String activeBtDeviceAddress = mBtRouteProvider.getActiveDeviceAddress();
+        String activeBtDeviceAddress = mBtRouteProvider.getSelectedRouteId();
         mSelectedRouteId = TextUtils.isEmpty(activeBtDeviceAddress) ? mDefaultRoute.getId()
                 : activeBtDeviceAddress;
         builder.addSelectedRoute(mSelectedRouteId);
@@ -311,7 +306,7 @@
                     AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, 0);
 
             if (newVolume != oldVolume) {
-                String activeBtDeviceAddress = mBtRouteProvider.getActiveDeviceAddress();
+                String activeBtDeviceAddress = mBtRouteProvider.getSelectedRouteId();
                 if (!TextUtils.isEmpty(activeBtDeviceAddress)) {
                     for (int i = mBluetoothRoutes.size() - 1; i >= 0; i--) {
                         MediaRoute2Info route = mBluetoothRoutes.get(i);
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
index b24a938..563dcf7 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
@@ -130,7 +130,7 @@
             Set<String> packageNames, int userId);
 
     /**
-     *  Notifies that any of the {@link AbstractNetworkStatsProvider} has reached its quota
+     *  Notifies that the specified {@link AbstractNetworkStatsProvider} has reached its quota
      *  which was set through {@link AbstractNetworkStatsProvider#setLimit(String, long)}.
      *
      * @param tag the human readable identifier of the custom network stats provider.
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index bb954ab..aacb46e9 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -4588,13 +4588,13 @@
                     final long quota = ((long) msg.arg1 << 32) | (msg.arg2 & 0xFFFFFFFFL);
                     removeInterfaceQuota(iface);
                     setInterfaceQuota(iface, quota);
-                    mNetworkStats.setStatsProviderLimit(iface, quota);
+                    mNetworkStats.setStatsProviderLimitAsync(iface, quota);
                     return true;
                 }
                 case MSG_REMOVE_INTERFACE_QUOTA: {
                     final String iface = (String) msg.obj;
                     removeInterfaceQuota(iface);
-                    mNetworkStats.setStatsProviderLimit(iface, QUOTA_UNLIMITED);
+                    mNetworkStats.setStatsProviderLimitAsync(iface, QUOTA_UNLIMITED);
                     return true;
                 }
                 case MSG_RESET_FIREWALL_RULES_BY_UID: {
diff --git a/services/core/java/com/android/server/net/NetworkStatsManagerInternal.java b/services/core/java/com/android/server/net/NetworkStatsManagerInternal.java
index 6d72cb5..0cb0bc2c 100644
--- a/services/core/java/com/android/server/net/NetworkStatsManagerInternal.java
+++ b/services/core/java/com/android/server/net/NetworkStatsManagerInternal.java
@@ -40,5 +40,5 @@
      * Set the quota limit to all registered custom network stats providers.
      * Note that invocation of any interface will be sent to all providers.
      */
-    public abstract void setStatsProviderLimit(@NonNull String iface, long quota);
+    public abstract void setStatsProviderLimitAsync(@NonNull String iface, long quota);
 }
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index bde9ee2..0662400 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -155,6 +155,8 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Collect and persist detailed network statistics, and provide this data to
@@ -255,7 +257,6 @@
     }
 
     private final Object mStatsLock = new Object();
-    private final Object mStatsProviderLock = new Object();
 
     /** Set of currently active ifaces. */
     @GuardedBy("mStatsLock")
@@ -280,8 +281,11 @@
     private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
             new DropBoxNonMonotonicObserver();
 
+    private static final int MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS = 100;
     private final RemoteCallbackList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList =
             new RemoteCallbackList<>();
+    /** Semaphore used to wait for stats provider to respond to request stats update. */
+    private final Semaphore mStatsProviderSem = new Semaphore(0, true);
 
     @GuardedBy("mStatsLock")
     private NetworkStatsRecorder mDevRecorder;
@@ -1337,6 +1341,25 @@
         final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0;
         final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
 
+        // Request asynchronous stats update from all providers for next poll. And wait a bit of
+        // time to allow providers report-in given that normally binder call should be fast.
+        // TODO: request with a valid token.
+        Trace.traceBegin(TRACE_TAG_NETWORK, "provider.requestStatsUpdate");
+        final int registeredCallbackCount = mStatsProviderCbList.getRegisteredCallbackCount();
+        mStatsProviderSem.drainPermits();
+        invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.requestStatsUpdate(0 /* unused */));
+        try {
+            mStatsProviderSem.tryAcquire(registeredCallbackCount,
+                    MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            // Strictly speaking it's possible a provider happened to deliver between the timeout
+            // and the log, and that doesn't matter too much as this is just a debug log.
+            Log.d(TAG, "requestStatsUpdate - providers responded "
+                    + mStatsProviderSem.availablePermits()
+                    + "/" + registeredCallbackCount + " : " + e);
+        }
+        Trace.traceEnd(TRACE_TAG_NETWORK);
+
         // TODO: consider marking "untrusted" times in historical stats
         final long currentTime = mClock.millis();
 
@@ -1374,10 +1397,6 @@
             performSampleLocked();
         }
 
-        // request asynchronous stats update from all providers for next poll.
-        // TODO: request with a valid token.
-        invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.requestStatsUpdate(0 /* unused */));
-
         // finally, dispatch updated event to any listeners
         final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
         updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
@@ -1501,8 +1520,8 @@
         }
 
         @Override
-        public void setStatsProviderLimit(@NonNull String iface, long quota) {
-            Slog.v(TAG, "setStatsProviderLimit(" + iface + "," + quota + ")");
+        public void setStatsProviderLimitAsync(@NonNull String iface, long quota) {
+            Slog.v(TAG, "setStatsProviderLimitAsync(" + iface + "," + quota + ")");
             invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.setLimit(iface, quota));
         }
     }
@@ -1783,9 +1802,9 @@
      * {@code unregister()} of the returned callback.
      *
      * @param tag a human readable identifier of the custom network stats provider.
-     * @param provider the binder interface of
-     *                 {@link android.net.netstats.provider.AbstractNetworkStatsProvider} that
-     *                 needs to be registered to the system.
+     * @param provider the {@link INetworkStatsProvider} binder corresponding to the
+     *                 {@link android.net.netstats.provider.AbstractNetworkStatsProvider} to be
+     *                 registered.
      *
      * @return a binder interface of
      *         {@link android.net.netstats.provider.NetworkStatsProviderCallback}, which can be
@@ -1798,7 +1817,8 @@
         Objects.requireNonNull(tag, "tag is null");
         try {
             NetworkStatsProviderCallbackImpl callback = new NetworkStatsProviderCallbackImpl(
-                            tag, provider, mAlertObserver, mStatsProviderCbList);
+                    tag, provider, mStatsProviderSem, mAlertObserver,
+                    mStatsProviderCbList);
             mStatsProviderCbList.register(callback);
             Log.d(TAG, "registerNetworkStatsProvider from " + callback.mTag + " uid/pid="
                     + getCallingUid() + "/" + getCallingPid());
@@ -1823,7 +1843,7 @@
 
     private void invokeForAllStatsProviderCallbacks(
             @NonNull ThrowingConsumer<NetworkStatsProviderCallbackImpl, RemoteException> task) {
-        synchronized (mStatsProviderCbList) {
+        synchronized (mStatsLock) {
             final int length = mStatsProviderCbList.beginBroadcast();
             try {
                 for (int i = 0; i < length; i++) {
@@ -1844,25 +1864,30 @@
     private static class NetworkStatsProviderCallbackImpl extends INetworkStatsProviderCallback.Stub
             implements IBinder.DeathRecipient {
         @NonNull final String mTag;
-        @NonNull private final Object mProviderStatsLock = new Object();
+
         @NonNull final INetworkStatsProvider mProvider;
+        @NonNull private final Semaphore mSemaphore;
         @NonNull final INetworkManagementEventObserver mAlertObserver;
         @NonNull final RemoteCallbackList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList;
 
+        @NonNull private final Object mProviderStatsLock = new Object();
+
         @GuardedBy("mProviderStatsLock")
-        // STATS_PER_IFACE and STATS_PER_UID
+        // Track STATS_PER_IFACE and STATS_PER_UID separately.
         private final NetworkStats mIfaceStats = new NetworkStats(0L, 0);
         @GuardedBy("mProviderStatsLock")
         private final NetworkStats mUidStats = new NetworkStats(0L, 0);
 
         NetworkStatsProviderCallbackImpl(
                 @NonNull String tag, @NonNull INetworkStatsProvider provider,
+                @NonNull Semaphore semaphore,
                 @NonNull INetworkManagementEventObserver alertObserver,
                 @NonNull RemoteCallbackList<NetworkStatsProviderCallbackImpl> cbList)
                 throws RemoteException {
             mTag = tag;
             mProvider = provider;
             mProvider.asBinder().linkToDeath(this, 0);
+            mSemaphore = semaphore;
             mAlertObserver = alertObserver;
             mStatsProviderCbList = cbList;
         }
@@ -1881,7 +1906,8 @@
                     default:
                         throw new IllegalArgumentException("Invalid type: " + how);
                 }
-                // Return a defensive copy instead of local reference.
+                // Callers might be able to mutate the returned object. Return a defensive copy
+                // instead of local reference.
                 return stats.clone();
             }
         }
@@ -1895,6 +1921,7 @@
                 if (ifaceStats != null) mIfaceStats.combineAllValues(ifaceStats);
                 if (uidStats != null) mUidStats.combineAllValues(uidStats);
             }
+            mSemaphore.release();
         }
 
         @Override
diff --git a/services/core/java/com/android/server/notification/NotificationHistoryProtoHelper.java b/services/core/java/com/android/server/notification/NotificationHistoryProtoHelper.java
index 2831d37..7ba993b 100644
--- a/services/core/java/com/android/server/notification/NotificationHistoryProtoHelper.java
+++ b/services/core/java/com/android/server/notification/NotificationHistoryProtoHelper.java
@@ -19,6 +19,7 @@
 import android.app.NotificationHistory.HistoricalNotification;
 import android.content.res.Resources;
 import android.graphics.drawable.Icon;
+import android.text.TextUtils;
 import android.util.Slog;
 import android.util.proto.ProtoInputStream;
 import android.util.proto.ProtoOutputStream;
@@ -141,6 +142,16 @@
                     loadIcon(parser, notification, pkg);
                     parser.end(iconToken);
                     break;
+                case (int) Notification.CONVERSATION_ID_INDEX:
+                    String conversationId =
+                            stringPool.get(parser.readInt(Notification.CONVERSATION_ID_INDEX) - 1);
+                    notification.setConversationId(conversationId);
+                    break;
+                case (int) Notification.CONVERSATION_ID:
+                    conversationId = parser.readString(Notification.CONVERSATION_ID);
+                    notification.setConversationId(conversationId);
+                    stringPool.add(conversationId);
+                    break;
                 case ProtoInputStream.NO_MORE_FIELDS:
                     return notification.build();
             }
@@ -271,6 +282,17 @@
                     + ") not found in string cache");
             proto.write(Notification.CHANNEL_ID, notification.getChannelId());
         }
+        if (!TextUtils.isEmpty(notification.getConversationId())) {
+            final int conversationIdIndex = Arrays.binarySearch(
+                    stringPool, notification.getConversationId());
+            if (conversationIdIndex >= 0) {
+                proto.write(Notification.CONVERSATION_ID_INDEX, conversationIdIndex + 1);
+            } else {
+                Slog.w(TAG, "notification conversation id (" + notification.getConversationId()
+                        + ") not found in string cache");
+                proto.write(Notification.CONVERSATION_ID, notification.getConversationId());
+            }
+        }
         proto.write(Notification.UID, notification.getUid());
         proto.write(Notification.USER_ID, notification.getUserId());
         proto.write(Notification.POSTED_TIME_MS, notification.getPostedTimeMs());
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index d0d0f5a..2e4a977 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -6243,6 +6243,7 @@
         private final int mRank;
         private final int mCount;
         private final ManagedServiceInfo mListener;
+        private final long mWhen;
 
         CancelNotificationRunnable(final int callingUid, final int callingPid,
                 final String pkg, final String tag, final int id,
@@ -6262,6 +6263,7 @@
             this.mRank = rank;
             this.mCount = count;
             this.mListener = listener;
+            this.mWhen = System.currentTimeMillis();
         }
 
         @Override
@@ -6273,13 +6275,28 @@
             }
 
             synchronized (mNotificationLock) {
-                // If the notification is currently enqueued, repost this runnable so it has a
-                // chance to notify listeners
-                if ((findNotificationByListLocked(mEnqueuedNotifications, mPkg, mTag, mId, mUserId))
-                        != null) {
+                // Check to see if there is a notification in the enqueued list that hasn't had a
+                // chance to post yet.
+                List<NotificationRecord> enqueued = findEnqueuedNotificationsForCriteria(
+                        mPkg, mTag, mId, mUserId);
+                boolean repost = false;
+                if (enqueued.size() > 0) {
+                    // Found something, let's see what it was
+                    repost = true;
+                    // If all enqueues happened before this cancel then wait for them to happen,
+                    // otherwise we should let this cancel through so the next enqueue happens
+                    for (NotificationRecord r : enqueued) {
+                        if (r.mUpdateTimeMs > mWhen) {
+                            // At least one enqueue was posted after the cancel, so we're invalid
+                            return;
+                        }
+                    }
+                }
+                if (repost) {
                     mHandler.post(this);
                     return;
                 }
+
                 // Look for the notification in the posted list, since we already checked enqueued.
                 NotificationRecord r =
                         findNotificationByListLocked(mNotificationList, mPkg, mTag, mId, mUserId);
@@ -6298,6 +6315,10 @@
                     if ((r.getNotification().flags & mMustNotHaveFlags) != 0) {
                         return;
                     }
+                    if (r.getUpdateTimeMs() > mWhen) {
+                        // In this case, a post must have slipped by when this runnable reposted
+                        return;
+                    }
 
                     // Bubbled children get to stick around if the summary was manually cancelled
                     // (user removed) from systemui.
@@ -8220,6 +8241,29 @@
         return null;
     }
 
+    /**
+     * There may be multiple records that match your criteria. For instance if there have been
+     * multiple notifications posted which are enqueued for the same pkg, tag, id, userId. This
+     * method will find all of them in the given list
+     * @return
+     */
+    @GuardedBy("mNotificationLock")
+    private List<NotificationRecord> findEnqueuedNotificationsForCriteria(
+            String pkg, String tag, int id, int userId) {
+        final ArrayList<NotificationRecord> records = new ArrayList<>();
+        final int n = mEnqueuedNotifications.size();
+        for (int i = 0; i < n; i++) {
+            NotificationRecord r = mEnqueuedNotifications.get(i);
+            if (notificationMatchesUserId(r, userId)
+                    && r.getSbn().getId() == id
+                    && TextUtils.equals(r.getSbn().getTag(), tag)
+                    && r.getSbn().getPackageName().equals(pkg)) {
+                records.add(r);
+            }
+        }
+        return records;
+    }
+
     @GuardedBy("mNotificationLock")
     int indexOfNotificationLocked(String key) {
         final int N = mNotificationList.size();
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 0ada58e..f92e1fc 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -906,6 +906,10 @@
         return (int) (now - mInterruptionTimeMs);
     }
 
+    public long getUpdateTimeMs() {
+        return mUpdateTimeMs;
+    }
+
     /**
      * Set the visibility of the notification.
      */
diff --git a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
index 96d3cc1..3939f26 100644
--- a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
+++ b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
@@ -68,7 +68,6 @@
 
     private Context mContext;
     private Injector mInjector;
-    private AppOpsManager mAppOpsManager;
 
     public CrossProfileAppsServiceImpl(Context context) {
         this(context, new InjectorImpl(context));
@@ -217,19 +216,27 @@
 
         mInjector.getActivityTaskManagerInternal().startActivityAsUser(caller, callingPackage,
                 callingFeatureId, launchIntent, /* options= */ null, userId);
+        logStartActivityByIntent(callingPackage);
+    }
+
+    private void logStartActivityByIntent(String packageName) {
+        DevicePolicyEventLogger
+                .createEvent(DevicePolicyEnums.START_ACTIVITY_BY_INTENT)
+                .setStrings(packageName)
+                .setBoolean(isCallingUserAManagedProfile())
+                .write();
     }
 
     @Override
     public boolean canRequestInteractAcrossProfiles(String callingPackage) {
         Objects.requireNonNull(callingPackage);
         verifyCallingPackage(callingPackage);
-        return canRequestInteractAcrossProfilesUnchecked(
-                callingPackage, mInjector.getCallingUserId());
+        return canRequestInteractAcrossProfilesUnchecked(callingPackage);
     }
 
-    private boolean canRequestInteractAcrossProfilesUnchecked(
-            String packageName, @UserIdInt int userId) {
-        List<UserHandle> targetUserProfiles = getTargetUserProfilesUnchecked(packageName, userId);
+    private boolean canRequestInteractAcrossProfilesUnchecked(String packageName) {
+        List<UserHandle> targetUserProfiles =
+                getTargetUserProfilesUnchecked(packageName, mInjector.getCallingUserId());
         if (targetUserProfiles.isEmpty()) {
             return false;
         }
@@ -256,12 +263,11 @@
         Objects.requireNonNull(callingPackage);
         verifyCallingPackage(callingPackage);
 
-        final List<UserHandle> targetUserProfiles = getTargetUserProfilesUnchecked(callingPackage,
-                mInjector.getCallingUserId());
+        final List<UserHandle> targetUserProfiles = getTargetUserProfilesUnchecked(
+                callingPackage, mInjector.getCallingUserId());
         if (targetUserProfiles.isEmpty()) {
             return false;
         }
-
         return hasInteractAcrossProfilesPermission(callingPackage);
     }
 
@@ -363,6 +369,12 @@
         });
     }
 
+    /**
+     * See {@link android.content.pm.CrossProfileApps#setInteractAcrossProfilesAppOp(String, int)}.
+     *
+     * <p>Logs metrics. Use {@link #setInteractAcrossProfilesAppOpUnchecked(String, int, boolean)}
+     * to avoid permission checks or to specify not to log metrics.
+     */
     @Override
     public void setInteractAcrossProfilesAppOp(String packageName, @Mode int newMode) {
         final int callingUid = mInjector.getCallingUid();
@@ -379,6 +391,11 @@
                     "MANAGE_APP_OPS_MODES or CONFIGURE_INTERACT_ACROSS_PROFILES is required to set"
                             + " the app-op for interacting across profiles.");
         }
+        setInteractAcrossProfilesAppOpUnchecked(packageName, newMode, /* logMetrics= */ true);
+    }
+
+    private void setInteractAcrossProfilesAppOpUnchecked(
+            String packageName, @Mode int newMode, boolean logMetrics) {
         if (newMode == AppOpsManager.MODE_ALLOWED
                 && !canConfigureInteractAcrossProfiles(packageName)) {
             // The user should not be prompted for apps that cannot request to interact across
@@ -394,7 +411,7 @@
             if (!isPackageInstalled(packageName, profileId)) {
                 continue;
             }
-            setInteractAcrossProfilesAppOpForUser(packageName, newMode, profileId);
+            setInteractAcrossProfilesAppOpForUser(packageName, newMode, profileId, logMetrics);
         }
     }
 
@@ -413,16 +430,16 @@
     }
 
     private void setInteractAcrossProfilesAppOpForUser(
-            String packageName, @Mode int newMode, @UserIdInt int userId) {
+            String packageName, @Mode int newMode, @UserIdInt int userId, boolean logMetrics) {
         try {
-            setInteractAcrossProfilesAppOpForUserOrThrow(packageName, newMode, userId);
+            setInteractAcrossProfilesAppOpForUserOrThrow(packageName, newMode, userId, logMetrics);
         } catch (PackageManager.NameNotFoundException e) {
             Slog.e(TAG, "Missing package " + packageName + " on user ID " + userId, e);
         }
     }
 
     private void setInteractAcrossProfilesAppOpForUserOrThrow(
-            String packageName, @Mode int newMode, @UserIdInt int userId)
+            String packageName, @Mode int newMode, @UserIdInt int userId, boolean logMetrics)
             throws PackageManager.NameNotFoundException {
         final int uid = mInjector.getPackageManager()
                 .getPackageUidAsUser(packageName, /* flags= */ 0, userId);
@@ -444,6 +461,28 @@
                     .setMode(OP_INTERACT_ACROSS_PROFILES, uid, packageName, newMode);
         }
         sendCanInteractAcrossProfilesChangedBroadcast(packageName, uid, UserHandle.of(userId));
+        maybeLogSetInteractAcrossProfilesAppOp(packageName, newMode, userId, logMetrics, uid);
+    }
+
+    private void maybeLogSetInteractAcrossProfilesAppOp(
+            String packageName,
+            @Mode int newMode,
+            @UserIdInt int userId,
+            boolean logMetrics,
+            int uid) {
+        if (!logMetrics) {
+            return;
+        }
+        if (userId != mInjector.getCallingUserId()) {
+            // Only log once per profile group by checking for the calling user ID.
+            return;
+        }
+        DevicePolicyEventLogger
+                .createEvent(DevicePolicyEnums.SET_INTERACT_ACROSS_PROFILES_APP_OP)
+                .setStrings(packageName)
+                .setInt(newMode)
+                .setBoolean(appDeclaresCrossProfileAttribute(uid))
+                .write();
     }
 
     /**
@@ -541,11 +580,13 @@
                 permission, uid, /* owningUid= */-1, /* exported= */ true);
     }
 
-    private AppOpsManager getAppOpsManager() {
-        if (mAppOpsManager == null) {
-            mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
-        }
-        return mAppOpsManager;
+    private boolean isCallingUserAManagedProfile() {
+        return isManagedProfile(mInjector.getCallingUserId());
+    }
+
+    private boolean isManagedProfile(@UserIdInt int userId) {
+        return mInjector.withCleanCallingIdentity(()
+                -> mContext.getSystemService(UserManager.class).isManagedProfile(userId));
     }
 
     private static class InjectorImpl implements Injector {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 064fd3f..ad70345 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -6698,6 +6698,9 @@
             // cross-profile app linking works only towards the parent.
             final int callingUid = Binder.getCallingUid();
             final UserInfo parent = getProfileParent(sourceUserId);
+            if (parent == null) {
+                return false;
+            }
             synchronized (mLock) {
                 int flags = updateFlagsForResolve(0, parent.id, callingUid,
                         false /*includeInstantApps*/);
@@ -14707,8 +14710,7 @@
         void handleVerificationFinished() {
             if (!mVerificationCompleted) {
                 mVerificationCompleted = true;
-                if (mIntegrityVerificationCompleted || mRet != INSTALL_SUCCEEDED) {
-                    mIntegrityVerificationCompleted = true;
+                if (mIntegrityVerificationCompleted) {
                     handleReturnCode();
                 }
                 // integrity verification still pending.
@@ -14718,8 +14720,7 @@
         void handleIntegrityVerificationFinished() {
             if (!mIntegrityVerificationCompleted) {
                 mIntegrityVerificationCompleted = true;
-                if (mVerificationCompleted || mRet != INSTALL_SUCCEEDED) {
-                    mVerificationCompleted = true;
+                if (mVerificationCompleted) {
                     handleReturnCode();
                 }
                 // verifier still pending
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 9395c97..a9035b2 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -578,7 +578,9 @@
 
     /** Returns true if standard APK Verity is enabled. */
     static boolean isApkVerityEnabled() {
-        return SystemProperties.getInt("ro.apk_verity.mode", FSVERITY_DISABLED) == FSVERITY_ENABLED;
+        return Build.VERSION.FIRST_SDK_INT >= Build.VERSION_CODES.R
+                || SystemProperties.getInt("ro.apk_verity.mode", FSVERITY_DISABLED)
+                        == FSVERITY_ENABLED;
     }
 
     static boolean isLegacyApkVerityEnabled() {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 832c9b7..d451152 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -5233,9 +5233,7 @@
                         List<RuntimePermissionsState.PermissionState> permissions =
                                 getPermissionsFromPermissionsState(
                                         packageSetting.getPermissionsState(), userId);
-                        if (permissions != null) {
-                            packagePermissions.put(packageName, permissions);
-                        }
+                        packagePermissions.put(packageName, permissions);
                     }
                 }
 
@@ -5248,9 +5246,7 @@
                     List<RuntimePermissionsState.PermissionState> permissions =
                             getPermissionsFromPermissionsState(
                                     sharedUserSetting.getPermissionsState(), userId);
-                    if (permissions != null) {
-                        sharedUserPermissions.put(sharedUserName, permissions);
-                    }
+                    sharedUserPermissions.put(sharedUserName, permissions);
                 }
 
                 runtimePermissions = new RuntimePermissionsState(version, fingerprint,
@@ -5260,15 +5256,11 @@
             mPersistence.write(runtimePermissions, UserHandle.of(userId));
         }
 
-        @Nullable
+        @NonNull
         private List<RuntimePermissionsState.PermissionState> getPermissionsFromPermissionsState(
                 @NonNull PermissionsState permissionsState, @UserIdInt int userId) {
             List<PermissionState> permissionStates = permissionsState.getRuntimePermissionStates(
                     userId);
-            if (permissionStates.isEmpty()) {
-                return null;
-            }
-
             List<RuntimePermissionsState.PermissionState> permissions =
                     new ArrayList<>();
             int permissionStatesSize = permissionStates.size();
@@ -5340,31 +5332,60 @@
             boolean defaultPermissionsGranted = Build.FINGERPRINT.equals(fingerprint);
             mDefaultPermissionsGranted.put(userId, defaultPermissionsGranted);
 
-            for (Map.Entry<String, List<RuntimePermissionsState.PermissionState>> entry
-                    : runtimePermissions.getPackagePermissions().entrySet()) {
-                String packageName = entry.getKey();
-                List<RuntimePermissionsState.PermissionState> permissions = entry.getValue();
+            boolean isUpgradeToR = getInternalVersion().sdkVersion < Build.VERSION_CODES.R;
 
-                PackageSetting packageSetting = mPackages.get(packageName);
-                if (packageSetting == null) {
-                    Slog.w(PackageManagerService.TAG, "Unknown package:" + packageName);
-                    continue;
+            Map<String, List<RuntimePermissionsState.PermissionState>> packagePermissions =
+                    runtimePermissions.getPackagePermissions();
+            int packagesSize = mPackages.size();
+            for (int i = 0; i < packagesSize; i++) {
+                String packageName = mPackages.keyAt(i);
+                PackageSetting packageSetting = mPackages.valueAt(i);
+
+                List<RuntimePermissionsState.PermissionState> permissions =
+                        packagePermissions.get(packageName);
+                if (permissions != null) {
+                    readPermissionsStateLpr(permissions, packageSetting.getPermissionsState(),
+                            userId);
+                } else if (packageSetting.sharedUser == null && !isUpgradeToR) {
+                    Slog.w(TAG, "Missing permission state for package: " + packageName);
+                    generateFallbackPermissionsStateLpr(
+                            packageSetting.pkg.getRequestedPermissions(),
+                            packageSetting.pkg.getTargetSdkVersion(),
+                            packageSetting.getPermissionsState(), userId);
                 }
-                readPermissionsStateLpr(permissions, packageSetting.getPermissionsState(), userId);
             }
 
-            for (Map.Entry<String, List<RuntimePermissionsState.PermissionState>> entry
-                    : runtimePermissions.getSharedUserPermissions().entrySet()) {
-                String sharedUserName = entry.getKey();
-                List<RuntimePermissionsState.PermissionState> permissions = entry.getValue();
+            Map<String, List<RuntimePermissionsState.PermissionState>> sharedUserPermissions =
+                    runtimePermissions.getSharedUserPermissions();
+            int sharedUsersSize = mSharedUsers.size();
+            for (int i = 0; i < sharedUsersSize; i++) {
+                String sharedUserName = mSharedUsers.keyAt(i);
+                SharedUserSetting sharedUserSetting = mSharedUsers.valueAt(i);
 
-                SharedUserSetting sharedUserSetting = mSharedUsers.get(sharedUserName);
-                if (sharedUserSetting == null) {
-                    Slog.w(PackageManagerService.TAG, "Unknown shared user:" + sharedUserName);
-                    continue;
+                List<RuntimePermissionsState.PermissionState> permissions =
+                        sharedUserPermissions.get(sharedUserName);
+                if (permissions != null) {
+                    readPermissionsStateLpr(permissions, sharedUserSetting.getPermissionsState(),
+                            userId);
+                } else if (!isUpgradeToR) {
+                    Slog.w(TAG, "Missing permission state for shared user: " + sharedUserName);
+                    ArraySet<String> requestedPermissions = new ArraySet<>();
+                    int targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
+                    int sharedUserPackagesSize = sharedUserSetting.packages.size();
+                    for (int packagesI = 0; packagesI < sharedUserPackagesSize; packagesI++) {
+                        PackageSetting packageSetting = sharedUserSetting.packages.valueAt(
+                                packagesI);
+                        if (packageSetting == null || packageSetting.pkg == null
+                                || !packageSetting.getInstalled(userId)) {
+                            continue;
+                        }
+                        AndroidPackage pkg = packageSetting.pkg;
+                        requestedPermissions.addAll(pkg.getRequestedPermissions());
+                        targetSdkVersion = Math.min(targetSdkVersion, pkg.getTargetSdkVersion());
+                    }
+                    generateFallbackPermissionsStateLpr(requestedPermissions, targetSdkVersion,
+                            sharedUserSetting.getPermissionsState(), userId);
                 }
-                readPermissionsStateLpr(permissions, sharedUserSetting.getPermissionsState(),
-                        userId);
             }
         }
 
@@ -5395,6 +5416,30 @@
             }
         }
 
+        private void generateFallbackPermissionsStateLpr(
+                @NonNull Collection<String> requestedPermissions, int targetSdkVersion,
+                @NonNull PermissionsState permissionsState, @UserIdInt int userId) {
+            for (String permissionName : requestedPermissions) {
+                BasePermission permission = mPermissions.getPermission(permissionName);
+                if (Objects.equals(permission.getSourcePackageName(), PLATFORM_PACKAGE_NAME)
+                        && permission.isRuntime() && !permission.isRemoved()) {
+                    if (permission.isHardOrSoftRestricted() || permission.isImmutablyRestricted()) {
+                        permissionsState.updatePermissionFlags(permission, userId,
+                                PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT,
+                                PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT);
+                    }
+                    if (targetSdkVersion < Build.VERSION_CODES.M) {
+                        permissionsState.updatePermissionFlags(permission, userId,
+                                PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
+                                        | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT,
+                                PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
+                                        | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT);
+                        permissionsState.grantRuntimePermission(permission, userId);
+                    }
+                }
+            }
+        }
+
         @GuardedBy("Settings.this.mLock")
         private void readLegacyStateForUserSyncLPr(int userId) {
             File permissionsFile = getUserRuntimePermissionsFile(userId);
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index a45a996..19e6062 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -45,7 +45,6 @@
 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAST_SYSTEM_WINDOW;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR;
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
@@ -2058,11 +2057,8 @@
 
     /** {@inheritDoc} */
     @Override
-    public int checkAddPermission(WindowManager.LayoutParams attrs, int[] outAppOp) {
-        final int type = attrs.type;
-        final boolean isRoundedCornerOverlay =
-                (attrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0;
-
+    public int checkAddPermission(int type, boolean isRoundedCornerOverlay, String packageName,
+            int[] outAppOp) {
         if (isRoundedCornerOverlay && mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW)
                 != PERMISSION_GRANTED) {
             return ADD_PERMISSION_DENIED;
@@ -2119,7 +2115,7 @@
         ApplicationInfo appInfo;
         try {
             appInfo = mPackageManager.getApplicationInfoAsUser(
-                            attrs.packageName,
+                            packageName,
                             0 /* flags */,
                             UserHandle.getUserId(callingUid));
         } catch (PackageManager.NameNotFoundException e) {
@@ -2139,7 +2135,7 @@
 
         // check if user has enabled this operation. SecurityException will be thrown if this app
         // has not been allowed by the user
-        final int mode = mAppOpsManager.noteOpNoThrow(outAppOp[0], callingUid, attrs.packageName);
+        final int mode = mAppOpsManager.noteOpNoThrow(outAppOp[0], callingUid, packageName);
         switch (mode) {
             case AppOpsManager.MODE_ALLOWED:
             case AppOpsManager.MODE_IGNORED:
diff --git a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
index a83c58d..740472e 100644
--- a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
+++ b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
@@ -35,14 +35,17 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.os.storage.StorageManagerInternal;
 import android.util.Log;
 
 import com.android.internal.compat.IPlatformCompat;
+import com.android.server.LocalServices;
 
 /**
  * The behavior of soft restricted permissions is different for each permission. This class collects
@@ -107,11 +110,16 @@
                 final boolean isWhiteListed;
                 boolean shouldApplyRestriction;
                 final boolean hasRequestedLegacyExternalStorage;
+                final boolean shouldPreserveLegacyExternalStorage;
                 final boolean hasWriteMediaStorageGrantedForUid;
                 final boolean isScopedStorageEnabled;
 
                 if (appInfo != null) {
                     PackageManager pm = context.getPackageManager();
+                    PackageManagerInternal pmInternal =
+                            LocalServices.getService(PackageManagerInternal.class);
+                    StorageManagerInternal smInternal =
+                            LocalServices.getService(StorageManagerInternal.class);
                     int flags = pm.getPermissionFlags(permission, appInfo.packageName, user);
                     isWhiteListed = (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
                     hasRequestedLegacyExternalStorage = hasUidRequestedLegacyExternalStorage(
@@ -123,12 +131,16 @@
                     isScopedStorageEnabled =
                             isChangeEnabledForUid(context, appInfo, user, ENABLE_SCOPED_STORAGE)
                             || isScopedStorageRequired;
+                    shouldPreserveLegacyExternalStorage = pmInternal.getPackage(
+                            appInfo.packageName).hasPreserveLegacyExternalStorage()
+                            && smInternal.hasLegacyExternalStorage(appInfo.uid);
                     shouldApplyRestriction = (flags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0
-                            || isScopedStorageRequired;
+                            || (isScopedStorageRequired && !shouldPreserveLegacyExternalStorage);
                 } else {
                     isWhiteListed = false;
                     shouldApplyRestriction = false;
                     hasRequestedLegacyExternalStorage = false;
+                    shouldPreserveLegacyExternalStorage = false;
                     hasWriteMediaStorageGrantedForUid = false;
                     isScopedStorageEnabled = false;
                 }
@@ -150,7 +162,8 @@
                     public boolean mayAllowExtraAppOp() {
                         return !shouldApplyRestriction
                                 && (hasRequestedLegacyExternalStorage
-                                        || hasWriteMediaStorageGrantedForUid);
+                                        || hasWriteMediaStorageGrantedForUid
+                                        || shouldPreserveLegacyExternalStorage);
                     }
                     @Override
                     public boolean mayDenyExtraAppOpIfGranted() {
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 39093ae..9d417c9 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -686,17 +686,25 @@
             WindowManagerFuncs windowManagerFuncs);
 
     /**
-     * Check permissions when adding a window.
+     * Check permissions when adding a window or a window token from
+     * {@link android.app.WindowContext}.
      *
-     * @param attrs The window's LayoutParams.
+     * @param type The window type
+     * @param isRoundedCornerOverlay {@code true} to indicate the adding window is
+     *                                           round corner overlay.
+     * @param packageName package name
      * @param outAppOp First element will be filled with the app op corresponding to
      *                 this window, or OP_NONE.
      *
      * @return {@link WindowManagerGlobal#ADD_OKAY} if the add can proceed;
      *      else an error code, usually
      *      {@link WindowManagerGlobal#ADD_PERMISSION_DENIED}, to abort the add.
+     *
+     * @see IWindowManager#addWindowTokenWithOptions(IBinder, int, int, Bundle, String)
+     * @see WindowManager.LayoutParams#PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY
      */
-    public int checkAddPermission(WindowManager.LayoutParams attrs, int[] outAppOp);
+    int checkAddPermission(int type, boolean isRoundedCornerOverlay, String packageName,
+            int[] outAppOp);
 
     /**
      * After the window manager has computed the current configuration based
diff --git a/services/core/java/com/android/server/security/FileIntegrityService.java b/services/core/java/com/android/server/security/FileIntegrityService.java
index e90c02a..8cf2d03 100644
--- a/services/core/java/com/android/server/security/FileIntegrityService.java
+++ b/services/core/java/com/android/server/security/FileIntegrityService.java
@@ -20,6 +20,7 @@
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.os.Build;
 import android.os.IBinder;
 import android.os.Process;
 import android.os.SystemProperties;
@@ -55,7 +56,8 @@
     private final IBinder mService = new IFileIntegrityService.Stub() {
         @Override
         public boolean isApkVeritySupported() {
-            return SystemProperties.getInt("ro.apk_verity.mode", 0) == 2;
+            return Build.VERSION.FIRST_SDK_INT >= Build.VERSION_CODES.R
+                    || SystemProperties.getInt("ro.apk_verity.mode", 0) == 2;
         }
 
         @Override
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerModule.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerModule.java
index 372c1f5..cd5e360 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerModule.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerModule.java
@@ -169,7 +169,7 @@
     }
 
     @Override
-    public synchronized  void serviceDied(long cookie) {
+    public synchronized void serviceDied(long cookie) {
         Log.w(TAG, String.format("Underlying HAL driver died."));
         for (Session session : mActiveSessions) {
             session.moduleDied();
@@ -248,44 +248,77 @@
         @Override
         public int loadModel(@NonNull SoundModel model) {
             Log.d(TAG, String.format("loadModel(model=%s)", model));
-            synchronized (SoundTriggerModule.this) {
-                checkValid();
-                if (mNumLoadedModels == mProperties.maxSoundModels) {
-                    throw new RecoverableException(Status.RESOURCE_CONTENTION,
-                            "Maximum number of models loaded.");
+
+            // We must do this outside the lock, to avoid possible deadlocks with the remote process
+            // that provides the audio sessions, which may also be calling into us.
+            SoundTriggerMiddlewareImpl.AudioSessionProvider.AudioSession audioSession =
+                    mAudioSessionProvider.acquireSession();
+
+            try {
+                synchronized (SoundTriggerModule.this) {
+                    checkValid();
+                    if (mNumLoadedModels == mProperties.maxSoundModels) {
+                        throw new RecoverableException(Status.RESOURCE_CONTENTION,
+                                "Maximum number of models loaded.");
+                    }
+                    Model loadedModel = new Model();
+                    int result = loadedModel.load(model, audioSession);
+                    ++mNumLoadedModels;
+                    return result;
                 }
-                Model loadedModel = new Model();
-                int result = loadedModel.load(model);
-                ++mNumLoadedModels;
-                return result;
+            } catch (Exception e) {
+                // We must do this outside the lock, to avoid possible deadlocks with the remote
+                // process that provides the audio sessions, which may also be calling into us.
+                mAudioSessionProvider.releaseSession(audioSession.mSessionHandle);
+                throw e;
             }
         }
 
         @Override
         public int loadPhraseModel(@NonNull PhraseSoundModel model) {
             Log.d(TAG, String.format("loadPhraseModel(model=%s)", model));
-            synchronized (SoundTriggerModule.this) {
-                checkValid();
-                if (mNumLoadedModels == mProperties.maxSoundModels) {
-                    throw new RecoverableException(Status.RESOURCE_CONTENTION,
-                            "Maximum number of models loaded.");
+
+            // We must do this outside the lock, to avoid possible deadlocks with the remote process
+            // that provides the audio sessions, which may also be calling into us.
+            SoundTriggerMiddlewareImpl.AudioSessionProvider.AudioSession audioSession =
+                    mAudioSessionProvider.acquireSession();
+
+            try {
+                synchronized (SoundTriggerModule.this) {
+                    checkValid();
+                    if (mNumLoadedModels == mProperties.maxSoundModels) {
+                        throw new RecoverableException(Status.RESOURCE_CONTENTION,
+                                "Maximum number of models loaded.");
+                    }
+                    Model loadedModel = new Model();
+                    int result = loadedModel.load(model, audioSession);
+                    ++mNumLoadedModels;
+                    Log.d(TAG, String.format("loadPhraseModel()->%d", result));
+                    return result;
                 }
-                Model loadedModel = new Model();
-                int result = loadedModel.load(model);
-                ++mNumLoadedModels;
-                Log.d(TAG, String.format("loadPhraseModel()->%d", result));
-                return result;
+            } catch (Exception e) {
+                // We must do this outside the lock, to avoid possible deadlocks with the remote
+                // process that provides the audio sessions, which may also be calling into us.
+                mAudioSessionProvider.releaseSession(audioSession.mSessionHandle);
+                throw e;
             }
         }
 
         @Override
         public void unloadModel(int modelHandle) {
             Log.d(TAG, String.format("unloadModel(handle=%d)", modelHandle));
+
+            int sessionId;
+
             synchronized (SoundTriggerModule.this) {
                 checkValid();
-                mLoadedModels.get(modelHandle).unload();
+                sessionId = mLoadedModels.get(modelHandle).unload();
                 --mNumLoadedModels;
             }
+
+            // We must do this outside the lock, to avoid possible deadlocks with the remote process
+            // that provides the audio sessions, which may also be calling into us.
+            mAudioSessionProvider.releaseSession(sessionId);
         }
 
         @Override
@@ -413,45 +446,40 @@
                 SoundTriggerModule.this.notifyAll();
             }
 
-            private int load(@NonNull SoundModel model) {
+            private int load(@NonNull SoundModel model,
+                    SoundTriggerMiddlewareImpl.AudioSessionProvider.AudioSession audioSession) {
                 mModelType = model.type;
+                mSession = audioSession;
                 ISoundTriggerHw.SoundModel hidlModel = ConversionUtil.aidl2hidlSoundModel(model);
 
-                mSession = mAudioSessionProvider.acquireSession();
-                try {
-                    mHandle = mHalService.loadSoundModel(hidlModel, this, 0);
-                } catch (Exception e) {
-                    mAudioSessionProvider.releaseSession(mSession.mSessionHandle);
-                    throw e;
-                }
-
+                mHandle = mHalService.loadSoundModel(hidlModel, this, 0);
                 setState(ModelState.LOADED);
                 mLoadedModels.put(mHandle, this);
                 return mHandle;
             }
 
-            private int load(@NonNull PhraseSoundModel model) {
+            private int load(@NonNull PhraseSoundModel model,
+                    SoundTriggerMiddlewareImpl.AudioSessionProvider.AudioSession audioSession) {
                 mModelType = model.common.type;
+                mSession = audioSession;
                 ISoundTriggerHw.PhraseSoundModel hidlModel =
                         ConversionUtil.aidl2hidlPhraseSoundModel(model);
 
-                mSession = mAudioSessionProvider.acquireSession();
-                try {
-                    mHandle = mHalService.loadPhraseSoundModel(hidlModel, this, 0);
-                } catch (Exception e) {
-                    mAudioSessionProvider.releaseSession(mSession.mSessionHandle);
-                    throw e;
-                }
+                mHandle = mHalService.loadPhraseSoundModel(hidlModel, this, 0);
 
                 setState(ModelState.LOADED);
                 mLoadedModels.put(mHandle, this);
                 return mHandle;
             }
 
-            private void unload() {
-                mAudioSessionProvider.releaseSession(mSession.mSessionHandle);
+            /**
+             * Unloads the model.
+             * @return The audio session handle.
+             */
+            private int unload() {
                 mHalService.unloadSoundModel(mHandle);
                 mLoadedModels.remove(mHandle);
+                return mSession.mSessionHandle;
             }
 
             private void startRecognition(@NonNull RecognitionConfig config) {
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index 0502d0b..68a7188 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -581,6 +581,9 @@
 
     /**
      * Notifies the tracker that all windows of the app have been drawn.
+     *
+     * @return Non-null info if the activity was pending to draw, otherwise it might have been set
+     *         to invisible (removed from active transition) or it was already drawn.
      */
     @Nullable
     TransitionInfoSnapshot notifyWindowsDrawn(@NonNull ActivityRecord r, long timestampNs) {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index e26dac6..b3b8159 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -2679,7 +2679,8 @@
         // DisplayContent#topRunningActivity().
         final ActivityRecord next = display.topRunningActivity();
         final boolean isLastStackOverEmptyHome =
-                next == null && stack.isFocusedStackOnDisplay() && display.getRootHomeTask() != null;
+                next == null && stack.isFocusedStackOnDisplay()
+                        && display.getOrCreateRootHomeTask() != null;
         if (isLastStackOverEmptyHome) {
             // Don't destroy activity immediately if this is the last activity on the display and
             // the display contains home stack. Although there is no next activity at the moment,
@@ -5201,11 +5202,17 @@
         }
         final TransitionInfoSnapshot info = mStackSupervisor
                 .getActivityMetricsLogger().notifyWindowsDrawn(this, timestampNs);
-        final int windowsDrawnDelayMs = info != null ? info.windowsDrawnDelayMs : INVALID_DELAY;
-        final @LaunchState int launchState = info != null ? info.getLaunchState() : -1;
-        mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
-                windowsDrawnDelayMs, launchState);
-        mStackSupervisor.stopWaitingForActivityVisible(this, windowsDrawnDelayMs);
+        final boolean validInfo = info != null;
+        final int windowsDrawnDelayMs = validInfo ? info.windowsDrawnDelayMs : INVALID_DELAY;
+        final @LaunchState int launchState = validInfo ? info.getLaunchState() : -1;
+        // The activity may have been requested to be invisible (another activity has been launched)
+        // so there is no valid info. But if it is the current top activity (e.g. sleeping), the
+        // invalid state is still reported to make sure the waiting result is notified.
+        if (validInfo || this == mDisplayContent.topRunningActivity()) {
+            mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
+                    windowsDrawnDelayMs, launchState);
+            mStackSupervisor.stopWaitingForActivityVisible(this, windowsDrawnDelayMs);
+        }
         finishLaunchTickingLocked();
         if (task != null) {
             task.hasBeenVisible = true;
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index ab8e975..3c39b39 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -111,6 +111,7 @@
 import static com.android.server.wm.TaskProto.ADJUST_IME_AMOUNT;
 import static com.android.server.wm.TaskProto.ANIMATING_BOUNDS;
 import static com.android.server.wm.TaskProto.BOUNDS;
+import static com.android.server.wm.TaskProto.CREATED_BY_ORGANIZER;
 import static com.android.server.wm.TaskProto.DEFER_REMOVAL;
 import static com.android.server.wm.TaskProto.DISPLAYED_BOUNDS;
 import static com.android.server.wm.TaskProto.DISPLAY_ID;
@@ -731,53 +732,14 @@
                         newBounds);
                 hasNewOverrideBounds = true;
             }
-
-            // Use override windowing mode to prevent extra bounds changes if inheriting the mode.
-            if (overrideWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
-                    || overrideWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) {
-                // If entering split screen or if something about the available split area changes,
-                // recalculate the split windows to match the new configuration.
-                if (rotationChanged || windowingModeChanged
-                        || prevDensity != getConfiguration().densityDpi
-                        || prevScreenW != getConfiguration().screenWidthDp
-                        || prevScreenH != getConfiguration().screenHeightDp) {
-                    calculateDockedBoundsForConfigChange(newParentConfig, newBounds);
-                    hasNewOverrideBounds = true;
-                }
-            }
         }
 
         if (windowingModeChanged) {
-            // Use override windowing mode to prevent extra bounds changes if inheriting the mode.
-            if (overrideWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
-                getStackDockedModeBounds(null /* dockedBounds */, null /* currentTempTaskBounds */,
-                        newBounds /* outStackBounds */, mTmpRect2 /* outTempTaskBounds */);
-                // immediately resize so docked bounds are available in onSplitScreenModeActivated
-                setTaskDisplayedBounds(null);
-                setTaskBounds(newBounds);
-                setBounds(newBounds);
-                newBounds.set(newBounds);
-            } else if (overrideWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) {
-                Rect dockedBounds = display.getRootSplitScreenPrimaryTask().getBounds();
-                final boolean isMinimizedDock =
-                        display.mDisplayContent.getDockedDividerController().isMinimizedDock();
-                if (isMinimizedDock) {
-                    Task topTask = display.getRootSplitScreenPrimaryTask().getTopMostTask();
-                    if (topTask != null) {
-                        dockedBounds = topTask.getBounds();
-                    }
-                }
-                getStackDockedModeBounds(dockedBounds, null /* currentTempTaskBounds */,
-                        newBounds /* outStackBounds */, mTmpRect2 /* outTempTaskBounds */);
-                hasNewOverrideBounds = true;
-            }
+            display.onStackWindowingModeChanged(this);
         }
         if (hasNewOverrideBounds) {
-            if (inSplitScreenPrimaryWindowingMode()) {
-                mStackSupervisor.resizeDockedStackLocked(new Rect(newBounds),
-                        null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
-                        null /* tempOtherTaskBounds */, null /* tempOtherTaskInsetBounds */,
-                        PRESERVE_WINDOWS, true /* deferResume */);
+            if (inSplitScreenWindowingMode()) {
+                setBounds(newBounds);
             } else if (overrideWindowingMode != WINDOWING_MODE_PINNED) {
                 // For pinned stack, resize is now part of the {@link WindowContainerTransaction}
                 resize(new Rect(newBounds), null /* tempTaskBounds */,
@@ -920,11 +882,7 @@
                 // warning toast about it.
                 mAtmService.getTaskChangeNotificationController()
                         .notifyActivityDismissingDockedStack();
-                final ActivityStack primarySplitStack = display.getRootSplitScreenPrimaryTask();
-                primarySplitStack.setWindowingModeInSurfaceTransaction(WINDOWING_MODE_UNDEFINED,
-                        false /* animate */, false /* showRecents */,
-                        false /* enteringSplitScreenMode */, true /* deferEnsuringVisibility */,
-                        primarySplitStack == this ? creating : false);
+                display.onSplitScreenModeDismissed();
             }
         }
 
@@ -1218,7 +1176,7 @@
                     display.getTopStackInWindowingMode(WINDOWING_MODE_FULLSCREEN);
             if (topFullScreenStack != null) {
                 final ActivityStack primarySplitScreenStack = display.getRootSplitScreenPrimaryTask();
-                if (display.getIndexOf(topFullScreenStack)
+                if (primarySplitScreenStack != null && display.getIndexOf(topFullScreenStack)
                         > display.getIndexOf(primarySplitScreenStack)) {
                     primarySplitScreenStack.moveToFront(reason + " splitScreenToTop");
                 }
@@ -3994,17 +3952,6 @@
                 ? ((WindowContainer) oldParent).getDisplayContent() : null;
         super.onParentChanged(newParent, oldParent);
 
-        if (display != null && inSplitScreenPrimaryWindowingMode()
-                // only do this for the base stack
-                && !newParent.inSplitScreenPrimaryWindowingMode()) {
-            // If we created a docked stack we want to resize it so it resizes all other stacks
-            // in the system.
-            getStackDockedModeBounds(null /* dockedBounds */, null /* currentTempTaskBounds */,
-                    mTmpRect /* outStackBounds */, mTmpRect2 /* outTempTaskBounds */);
-            mStackSupervisor.resizeDockedStackLocked(getRequestedOverrideBounds(), mTmpRect,
-                    mTmpRect2, null, null, PRESERVE_WINDOWS);
-        }
-
         // Resume next focusable stack after reparenting to another display if we aren't removing
         // the prevous display.
         if (oldDisplay != null && oldDisplay.isRemoving()) {
@@ -4950,6 +4897,12 @@
     }
 
     @Override
+    public SurfaceControl getParentSurfaceControl() {
+        // Tile is a "virtual" parent, so we need to intercept the parent surface here
+        return mTile != null ? mTile.getSurfaceControl() : super.getParentSurfaceControl();
+    }
+
+    @Override
     void removeImmediately() {
         // TODO(task-hierarchy): remove this override when tiles are in hierarchy
         if (mTile != null) {
@@ -5002,6 +4955,10 @@
         if (!matchParentBounds()) {
             final Rect bounds = getRequestedOverrideBounds();
             bounds.dumpDebug(proto, BOUNDS);
+        } else if (getStack().getTile() != null) {
+            // use tile's bounds here for cts.
+            final Rect bounds = getStack().getTile().getRequestedOverrideBounds();
+            bounds.dumpDebug(proto, BOUNDS);
         }
         getOverrideDisplayedBounds().dumpDebug(proto, DISPLAYED_BOUNDS);
         mAdjustedBounds.dumpDebug(proto, ADJUSTED_BOUNDS);
@@ -5021,6 +4978,8 @@
             proto.write(SURFACE_HEIGHT, mSurfaceControl.getHeight());
         }
 
+        proto.write(CREATED_BY_ORGANIZER, this instanceof TaskTile);
+
         proto.end(token);
     }
 }
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index a582f21..a2e8801 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -2447,7 +2447,9 @@
                 // split-screen in split-screen.
                 mService.getTaskChangeNotificationController()
                         .notifyActivityDismissingDockedStack();
-                moveTasksToFullscreenStackLocked(dockedStack, actualStack == dockedStack);
+                dockedStack.getDisplay().onSplitScreenModeDismissed();
+                dockedStack.getDisplay().ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS,
+                        true /* notifyClients */);
             }
             return;
         }
@@ -2809,7 +2811,7 @@
                 final DisplayContent display = task.getStack().getDisplay();
                 final ActivityStack topSecondaryStack =
                         display.getTopStackInWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
-                if (topSecondaryStack.isActivityTypeHome()) {
+                if (topSecondaryStack != null && topSecondaryStack.isActivityTypeHome()) {
                     // If the home activity is the top split-screen secondary stack, then the
                     // primary split-screen stack is in the minimized mode which means it can't
                     // receive input keys, so we should move the focused app to the home app so that
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 8ed798c..2a2ab4b 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1374,7 +1374,7 @@
                     break;
                 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
                     final ActivityStack homeStack =
-                            startedActivityStack.getDisplay().getRootHomeTask();
+                            startedActivityStack.getDisplay().getOrCreateRootHomeTask();
                     if (homeStack != null && homeStack.shouldBeVisible(null /* starting */)) {
                         mService.mWindowManager.showRecentApps();
                     }
@@ -1813,12 +1813,12 @@
      */
     private int deliverToCurrentTopIfNeeded(ActivityStack topStack) {
         final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
-        final boolean dontStart = top != null && mStartActivity.resultTo == null
+        final boolean dontStart = top != null
                 && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
                 && top.mUserId == mStartActivity.mUserId
                 && top.attachedToProcess()
                 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
-                || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK))
+                    || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK))
                 // This allows home activity to automatically launch on secondary display when
                 // display added, if home was the top activity on default display, instead of
                 // sending new intent to the home activity on default display.
@@ -2049,8 +2049,6 @@
                 && !isLaunchModeOneOf(LAUNCH_SINGLE_TASK, LAUNCH_SINGLE_INSTANCE)
                 && (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
 
-        sendNewTaskResultRequestIfNeeded();
-
         if ((mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && r.resultTo == null) {
             mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
         }
@@ -2232,6 +2230,8 @@
                 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
             }
         }
+
+        sendNewTaskResultRequestIfNeeded();
     }
 
     private void computeSourceStack() {
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 1859fae..f777e90 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -37,7 +37,6 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
@@ -229,6 +228,7 @@
 import android.view.IRecentsAnimationRunner;
 import android.view.RemoteAnimationAdapter;
 import android.view.RemoteAnimationDefinition;
+import android.view.WindowContainerTransaction;
 import android.view.WindowManager;
 
 import com.android.internal.R;
@@ -2269,6 +2269,9 @@
         synchronized (mGlobalLock) {
             final long ident = Binder.clearCallingIdentity();
             try {
+                if (WindowConfiguration.isSplitScreenWindowingMode(windowingMode)) {
+                    return setTaskWindowingModeSplitScreen(taskId, windowingMode, toTop);
+                }
                 final Task task = mRootWindowContainer.anyTaskForId(taskId,
                         MATCH_TASK_IN_STACKS_ONLY);
                 if (task == null) {
@@ -2286,10 +2289,16 @@
                 }
 
                 final ActivityStack stack = task.getStack();
+                // Convert some windowing-mode changes into root-task reparents for split-screen.
+                if (stack.getTile() != null) {
+                    stack.getDisplay().onSplitScreenModeDismissed();
+                }
                 if (toTop) {
                     stack.moveToFront("setTaskWindowingMode", task);
                 }
                 stack.setWindowingMode(windowingMode);
+                stack.getDisplay().ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS,
+                        true /* notifyClients */);
                 return true;
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -2719,36 +2728,8 @@
         synchronized (mGlobalLock) {
             final long ident = Binder.clearCallingIdentity();
             try {
-                if (isInLockTaskMode()) {
-                    Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: Is in lock task mode="
-                            + getLockTaskModeState());
-                    return false;
-                }
-
-                final Task task = mRootWindowContainer.anyTaskForId(taskId,
-                        MATCH_TASK_IN_STACKS_ONLY);
-                if (task == null) {
-                    Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
-                    return false;
-                }
-                if (!task.isActivityTypeStandardOrUndefined()) {
-                    throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
-                            + " non-standard task " + taskId + " to split-screen windowing mode");
-                }
-
-                if (DEBUG_STACK) Slog.d(TAG_STACK,
-                        "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
-                                + " to createMode=" + createMode + " toTop=" + toTop);
-                mWindowManager.setDockedStackCreateStateLocked(createMode, initialBounds);
-                final int windowingMode = task.getWindowingMode();
-                final ActivityStack stack = task.getStack();
-                if (toTop) {
-                    stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
-                }
-                stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
-                        false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */,
-                        false /* creating */);
-                return windowingMode != task.getWindowingMode();
+                return setTaskWindowingModeSplitScreen(taskId, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY,
+                        toTop);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -2756,6 +2737,49 @@
     }
 
     /**
+     * Moves the specified task into a split-screen tile.
+     */
+    private boolean setTaskWindowingModeSplitScreen(int taskId, int windowingMode, boolean toTop) {
+        if (!WindowConfiguration.isSplitScreenWindowingMode(windowingMode)) {
+            throw new IllegalArgumentException("Calling setTaskWindowingModeSplitScreen with non"
+                    + "split-screen mode: " + windowingMode);
+        }
+        if (isInLockTaskMode()) {
+            Slog.w(TAG, "setTaskWindowingModeSplitScreen: Is in lock task mode="
+                    + getLockTaskModeState());
+            return false;
+        }
+
+        final Task task = mRootWindowContainer.anyTaskForId(taskId,
+                MATCH_TASK_IN_STACKS_ONLY);
+        if (task == null) {
+            Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
+            return false;
+        }
+        if (!task.isActivityTypeStandardOrUndefined()) {
+            throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
+                    + " non-standard task " + taskId + " to split-screen windowing mode");
+        }
+
+        final int prevMode = task.getWindowingMode();
+        final ActivityStack stack = task.getStack();
+        TaskTile tile = null;
+        for (int i = stack.getDisplay().getStackCount() - 1; i >= 0; --i) {
+            tile = stack.getDisplay().getStackAt(i).asTile();
+            if (tile != null && tile.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
+                break;
+            }
+        }
+        if (tile == null) {
+            throw new IllegalStateException("Can't enter split without associated tile");
+        }
+        WindowContainerTransaction wct = new WindowContainerTransaction();
+        wct.reparent(stack.mRemoteToken, tile.mRemoteToken, toTop);
+        mTaskOrganizerController.applyContainerTransaction(wct, null);
+        return prevMode != task.getWindowingMode();
+    }
+
+    /**
      * Removes stacks in the input windowing modes from the system if they are of activity type
      * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
      */
@@ -3963,46 +3987,6 @@
     }
 
     /**
-     * Dismisses split-screen multi-window mode.
-     * @param toTop If true the current primary split-screen stack will be placed or left on top.
-     */
-    @Override
-    public void dismissSplitScreenMode(boolean toTop) {
-        enforceCallerIsRecentsOrHasPermission(
-                MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
-        final long ident = Binder.clearCallingIdentity();
-        try {
-            synchronized (mGlobalLock) {
-                final ActivityStack stack =
-                        mRootWindowContainer.getDefaultDisplay().getRootSplitScreenPrimaryTask();
-                if (stack == null) {
-                    Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
-                    return;
-                }
-
-                if (toTop) {
-                    // Caller wants the current split-screen primary stack to be the top stack after
-                    // it goes fullscreen, so move it to the front.
-                    stack.moveToFront("dismissSplitScreenMode");
-                } else {
-                    // In this case the current split-screen primary stack shouldn't be the top
-                    // stack after it goes fullscreen, so we move the focus to the top-most
-                    // split-screen secondary stack next to it.
-                    final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
-                            WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
-                    if (otherStack != null) {
-                        otherStack.moveToFront("dismissSplitScreenMode_other");
-                    }
-                }
-
-                stack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
-            }
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-
-    /**
      * Dismisses Pip
      * @param animate True if the dismissal should be animated.
      * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
@@ -5568,11 +5552,20 @@
         if (mLastResumedActivity != null && r.mUserId != mLastResumedActivity.mUserId) {
             mAmInternal.sendForegroundProfileChanged(r.mUserId);
         }
+        final Task prevTask = mLastResumedActivity != null ? mLastResumedActivity.getTask() : null;
+
         updateResumedAppTrace(r);
         mLastResumedActivity = r;
 
         r.getDisplay().setFocusedApp(r, true);
 
+        if (prevTask == null || task != prevTask) {
+            if (prevTask != null) {
+                mTaskChangeNotificationController.notifyTaskFocusChanged(prevTask.mTaskId, false);
+            }
+            mTaskChangeNotificationController.notifyTaskFocusChanged(task.mTaskId, true);
+        }
+
         applyUpdateLockStateLocked(r);
         applyUpdateVrModeLocked(r);
 
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index f72020e..3f4e791 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -713,7 +713,11 @@
 
         final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
         final boolean showWallpaper = wallpaperTarget != null
-                && (wallpaperTarget.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
+                && ((wallpaperTarget.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0
+                // Update task open transition to wallpaper transition when wallpaper is visible.
+                // (i.e.launching app info activity from recent tasks)
+                || ((transit == TRANSIT_TASK_OPEN || transit == TRANSIT_TASK_TO_FRONT)
+                && mWallpaperControllerLocked.isWallpaperVisible()));
         // If wallpaper is animating or wallpaperTarget doesn't have SHOW_WALLPAPER flag set,
         // don't consider upgrading to wallpaper transition.
         final WindowState oldWallpaper =
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 3b658c0..55a41ab 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -16,9 +16,7 @@
 
 package com.android.server.wm;
 
-import static android.app.ActivityTaskManager.INVALID_STACK_ID;
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
@@ -32,6 +30,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.app.WindowConfiguration.isSplitScreenWindowingMode;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -56,9 +55,6 @@
 import static android.view.View.GONE;
 import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
 import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
-import static android.view.WindowManager.DOCKED_BOTTOM;
-import static android.view.WindowManager.DOCKED_INVALID;
-import static android.view.WindowManager.DOCKED_TOP;
 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
@@ -84,9 +80,6 @@
 import static android.view.WindowManager.TRANSIT_TASK_OPEN;
 import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
 
-import static com.android.server.wm.DisplayContentProto.FOCUSED_ROOT_TASK_ID;
-import static com.android.server.wm.DisplayContentProto.RESUMED_ACTIVITY;
-import static com.android.server.wm.DisplayContentProto.SINGLE_TASK_INSTANCE;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
@@ -105,12 +98,15 @@
 import static com.android.server.wm.DisplayContentProto.DOCKED_STACK_DIVIDER_CONTROLLER;
 import static com.android.server.wm.DisplayContentProto.DPI;
 import static com.android.server.wm.DisplayContentProto.FOCUSED_APP;
+import static com.android.server.wm.DisplayContentProto.FOCUSED_ROOT_TASK_ID;
 import static com.android.server.wm.DisplayContentProto.ID;
 import static com.android.server.wm.DisplayContentProto.OPENING_APPS;
 import static com.android.server.wm.DisplayContentProto.OVERLAY_WINDOWS;
+import static com.android.server.wm.DisplayContentProto.RESUMED_ACTIVITY;
 import static com.android.server.wm.DisplayContentProto.ROOT_DISPLAY_AREA;
 import static com.android.server.wm.DisplayContentProto.ROTATION;
 import static com.android.server.wm.DisplayContentProto.SCREEN_ROTATION_ANIMATION;
+import static com.android.server.wm.DisplayContentProto.SINGLE_TASK_INSTANCE;
 import static com.android.server.wm.DisplayContentProto.TASKS;
 import static com.android.server.wm.DisplayContentProto.WINDOW_CONTAINER;
 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
@@ -1938,6 +1934,20 @@
         return mTaskContainers.getRootHomeTask();
     }
 
+    /**
+     * Returns the existing home stack or creates and returns a new one if it should exist for the
+     * display.
+     */
+    @Nullable
+    ActivityStack getOrCreateRootHomeTask() {
+        ActivityStack homeTask = getRootHomeTask();
+        if (homeTask == null && supportsSystemDecorations() && !isUntrustedVirtualDisplay()) {
+            homeTask = createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME,
+                    false /* onTop */);
+        }
+        return homeTask;
+    }
+
     /** @return The primary split-screen task, and {@code null} otherwise. */
     ActivityStack getRootSplitScreenPrimaryTask() {
         return mTaskContainers.getRootSplitScreenPrimaryTask();
@@ -2613,54 +2623,9 @@
 
     void adjustForImeIfNeeded() {
         final WindowState imeWin = mInputMethodWindow;
-        final boolean imeVisible = imeWin != null && imeWin.isVisibleLw() && imeWin.isDisplayedLw()
-                && !mDividerControllerLocked.isImeHideRequested();
-        final ActivityStack dockedStack = getRootSplitScreenPrimaryTask();
-        final boolean dockVisible = dockedStack != null;
-        final Task topDockedTask = dockVisible ? dockedStack.getTask((t) -> true): null;
-        final ActivityStack imeTargetStack = mWmService.getImeFocusStackLocked();
-        final int imeDockSide = (dockVisible && imeTargetStack != null) ?
-                imeTargetStack.getDockSide() : DOCKED_INVALID;
-        final boolean imeOnTop = (imeDockSide == DOCKED_TOP);
-        final boolean imeOnBottom = (imeDockSide == DOCKED_BOTTOM);
+        final boolean imeVisible = imeWin != null && imeWin.isVisibleLw()
+                && imeWin.isDisplayedLw();
         final int imeHeight = mDisplayFrames.getInputMethodWindowVisibleHeight();
-        final boolean imeHeightChanged = imeVisible &&
-                imeHeight != mDividerControllerLocked.getImeHeightAdjustedFor();
-
-        // This includes a case where the docked stack is unminimizing and IME is visible for the
-        // bottom side stack. The condition prevents adjusting the override task bounds for IME to
-        // the minimized docked stack bounds.
-        final boolean dockMinimized = mDividerControllerLocked.isMinimizedDock()
-                || (topDockedTask != null && imeOnBottom && !dockedStack.isAdjustedForIme()
-                && dockedStack.getBounds().height() < topDockedTask.getBounds().height());
-
-        // The divider could be adjusted for IME position, or be thinner than usual,
-        // or both. There are three possible cases:
-        // - If IME is visible, and focus is on top, divider is not moved for IME but thinner.
-        // - If IME is visible, and focus is on bottom, divider is moved for IME and thinner.
-        // - If IME is not visible, divider is not moved and is normal width.
-
-        if (imeVisible && dockVisible && (imeOnTop || imeOnBottom) && !dockMinimized) {
-            for (int i = mTaskContainers.getChildCount() - 1; i >= 0; --i) {
-                final ActivityStack stack = mTaskContainers.getChildAt(i);
-                final boolean isDockedOnBottom = stack.getDockSide() == DOCKED_BOTTOM;
-                if (stack.isVisible() && (imeOnBottom || isDockedOnBottom)
-                        && stack.inSplitScreenWindowingMode()) {
-                    stack.setAdjustedForIme(imeWin, imeOnBottom && imeHeightChanged);
-                } else {
-                    stack.resetAdjustedForIme(false);
-                }
-            }
-            mDividerControllerLocked.setAdjustedForIme(
-                    imeOnBottom /*ime*/, true /*divider*/, true /*animate*/, imeWin, imeHeight);
-        } else {
-            for (int i = mTaskContainers.getChildCount() - 1; i >= 0; --i) {
-                final ActivityStack stack = mTaskContainers.getChildAt(i);
-                stack.resetAdjustedForIme(!dockVisible);
-            }
-            mDividerControllerLocked.setAdjustedForIme(
-                    false /*ime*/, false /*divider*/, dockVisible /*animate*/, imeWin, imeHeight);
-        }
         mPinnedStackControllerLocked.setAdjustedForIme(imeVisible, imeHeight);
     }
 
@@ -3255,9 +3220,9 @@
             mWmService.mAtmInternal.onImeWindowSetOnDisplay(imePid,
                     mInputMethodWindow.getDisplayId());
         }
-        computeImeTarget(true /* updateImeTarget */);
         mInsetsStateController.getSourceProvider(ITYPE_IME).setWindow(win,
                 null /* frameProvider */, null /* imeFrameProvider */);
+        computeImeTarget(true /* updateImeTarget */);
     }
 
     /**
@@ -3440,8 +3405,6 @@
         mInputMethodTarget = target;
         mInputMethodTargetWaitingAnim = targetWaitingAnim;
         assignWindowLayers(false /* setLayoutNeeded */);
-        mInputMethodControlTarget = computeImeControlTarget();
-        mInsetsStateController.onImeControlTargetChanged(mInputMethodControlTarget);
         updateImeParent();
     }
 
@@ -3452,7 +3415,7 @@
      *
      * @see #getImeControlTarget()
      */
-    void updateImeControlTarget(WindowState target) {
+    void updateImeControlTarget(InsetsControlTarget target) {
         mInputMethodControlTarget = target;
         mInsetsStateController.onImeControlTargetChanged(mInputMethodControlTarget);
     }
@@ -3490,13 +3453,13 @@
      * Computes which control-target the IME should be attached to.
      */
     @VisibleForTesting
-    InsetsControlTarget computeImeControlTarget() {
+    InsetsControlTarget computeImeControlTarget(InsetsControlTarget appTarget) {
         if (!isImeAttachedToApp() && mRemoteInsetsControlTarget != null) {
             return mRemoteInsetsControlTarget;
         }
 
         // Otherwise, we just use the ime target
-        return mInputMethodTarget;
+        return appTarget;
     }
 
     void setLayoutNeeded() {
@@ -3817,6 +3780,10 @@
         }
         prepareSurfaces();
 
+        // This should be called after the insets have been dispatched to clients and we have
+        // committed finish drawing windows.
+        mInsetsStateController.getImeSourceProvider().checkShowImePostLayout();
+
         mLastHasContent = mTmpApplySurfaceChangesTransactionState.displayHasContent;
         mWmService.mDisplayManagerInternal.setDisplayProperties(mDisplayId,
                 mLastHasContent,
@@ -3880,7 +3847,7 @@
         }
     }
 
-    /** @returns the orientation of the display when it's rotation is ROTATION_0. */
+    /** @return the orientation of the display when it's rotation is ROTATION_0. */
     int getNaturalOrientation() {
         return mBaseDisplayWidth < mBaseDisplayHeight
                 ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
@@ -4255,9 +4222,6 @@
         }
 
         ActivityStack getRootHomeTask() {
-            if (mRootHomeTask == null && mDisplayId == DEFAULT_DISPLAY) {
-                Slog.e(TAG_WM, "getHomeStack: Returning null from this=" + this);
-            }
             return mRootHomeTask;
         }
 
@@ -4324,8 +4288,6 @@
                     }
                 } else {
                     mRootSplitScreenPrimaryTask = stack;
-                    mDisplayContent.onSplitScreenModeActivated();
-                    mDividerControllerLocked.notifyDockedStackExistsChanged(true);
                 }
             }
         }
@@ -4337,11 +4299,6 @@
                 mRootPinnedTask = null;
             } else if (stack == mRootSplitScreenPrimaryTask) {
                 mRootSplitScreenPrimaryTask = null;
-                mDisplayContent.onSplitScreenModeDismissed();
-                // Re-set the split-screen create mode whenever the split-screen stack is removed.
-                mWmService.setDockedStackCreateStateLocked(
-                        SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
-                mDividerControllerLocked.notifyDockedStackExistsChanged(false);
             }
         }
 
@@ -5757,6 +5714,33 @@
         return createStackUnchecked(windowingMode, activityType, stackId, onTop, info, intent);
     }
 
+    /** @return the tile to create the next stack in. */
+    private TaskTile updateLaunchTile(int windowingMode) {
+        if (!isSplitScreenWindowingMode(windowingMode)) {
+            // Only split-screen windowing modes interact with tiles.
+            return null;
+        }
+        for (int i = getStackCount() - 1; i >= 0; --i) {
+            final TaskTile t = getStackAt(i).asTile();
+            if (t == null || t.getRequestedOverrideWindowingMode() != windowingMode) {
+                continue;
+            }
+            // If not already set, pick a launch tile which is not the one we are launching
+            // into.
+            if (mLaunchTile == null) {
+                for (int j = 0, n = getStackCount(); j < n; ++j) {
+                    TaskTile tt = getStackAt(j).asTile();
+                    if (tt != t) {
+                        mLaunchTile = tt;
+                        break;
+                    }
+                }
+            }
+            return t;
+        }
+        return mLaunchTile;
+    }
+
     @VisibleForTesting
     ActivityStack createStackUnchecked(int windowingMode, int activityType,
             int stackId, boolean onTop, ActivityInfo info, Intent intent) {
@@ -5769,13 +5753,20 @@
             info.applicationInfo = new ApplicationInfo();
         }
 
+        TaskTile tile = updateLaunchTile(windowingMode);
+        if (tile != null) {
+            // Since this stack will be put into a tile, its windowingMode will be inherited.
+            windowingMode = WINDOWING_MODE_UNDEFINED;
+        }
         final ActivityStack stack = new ActivityStack(this, stackId,
                 mRootWindowContainer.mStackSupervisor, activityType, info, intent);
         addStack(stack, onTop ? POSITION_TOP : POSITION_BOTTOM);
         stack.setWindowingMode(windowingMode, false /* animate */, false /* showRecents */,
                 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */,
                 true /* creating */);
-
+        if (tile != null) {
+            tile.addChild(stack, 0 /* index */);
+        }
         return stack;
     }
 
@@ -5995,20 +5986,19 @@
     void onSplitScreenModeDismissed() {
         mAtmService.deferWindowLayout();
         try {
-            // Adjust the windowing mode of any stack in secondary split-screen to fullscreen.
+            mLaunchTile = null;
             for (int i = getStackCount() - 1; i >= 0; --i) {
-                final ActivityStack otherStack = getStackAt(i);
-                if (!otherStack.inSplitScreenSecondaryWindowingMode()) {
-                    continue;
+                final TaskTile t = getStackAt(i).asTile();
+                if (t != null) {
+                    t.removeAllChildren();
                 }
-                otherStack.setWindowingMode(WINDOWING_MODE_UNDEFINED, false /* animate */,
-                        false /* showRecents */, false /* enteringSplitScreenMode */,
-                        true /* deferEnsuringVisibility */, false /* creating */);
             }
+            mDividerControllerLocked.setMinimizedDockedStack(false /* minimized */,
+                    false /* animate */);
         } finally {
             final ActivityStack topFullscreenStack =
                     getTopStackInWindowingMode(WINDOWING_MODE_FULLSCREEN);
-            final ActivityStack homeStack = getRootHomeTask();
+            final ActivityStack homeStack = getOrCreateRootHomeTask();
             if (topFullscreenStack != null && homeStack != null && !isTopStack(homeStack)) {
                 // Whenever split-screen is dismissed we want the home stack directly behind the
                 // current top fullscreen stack so it shows up when the top stack is finished.
@@ -6022,27 +6012,6 @@
         }
     }
 
-    void onSplitScreenModeActivated() {
-        mAtmService.deferWindowLayout();
-        try {
-            // Adjust the windowing mode of any affected by split-screen to split-screen secondary.
-            final ActivityStack splitScreenPrimaryStack = getRootSplitScreenPrimaryTask();
-            for (int i = getStackCount() - 1; i >= 0; --i) {
-                final ActivityStack otherStack = getStackAt(i);
-                if (otherStack == splitScreenPrimaryStack
-                        || !otherStack.affectedBySplitScreenResize()) {
-                    continue;
-                }
-                otherStack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY,
-                        false /* animate */, false /* showRecents */,
-                        true /* enteringSplitScreenMode */, true /* deferEnsuringVisibility */,
-                        false /* creating */);
-            }
-        } finally {
-            mAtmService.continueWindowLayout();
-        }
-    }
-
     /**
      * Returns true if the {@param windowingMode} is supported based on other parameters passed in.
      * @param windowingMode The windowing mode we are checking support for.
@@ -6574,7 +6543,7 @@
     }
 
     void moveHomeStackToFront(String reason) {
-        final ActivityStack homeStack = getRootHomeTask();
+        final ActivityStack homeStack = getOrCreateRootHomeTask();
         if (homeStack != null) {
             homeStack.moveToFront(reason);
         }
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 38b0ca8..3302445 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -24,7 +24,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
 import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
-import static android.view.Display.TYPE_BUILT_IN;
+import static android.view.Display.TYPE_INTERNAL;
 import static android.view.InsetsState.ITYPE_BOTTOM_GESTURES;
 import static android.view.InsetsState.ITYPE_BOTTOM_TAPPABLE_ELEMENT;
 import static android.view.InsetsState.ITYPE_LEFT_GESTURES;
@@ -934,17 +934,17 @@
      * @return If ok, WindowManagerImpl.ADD_OKAY.  If too many singletons,
      * WindowManagerImpl.ADD_MULTIPLE_SINGLETON
      */
-    int validateAddingWindowLw(WindowManager.LayoutParams attrs) {
+    int validateAddingWindowLw(WindowManager.LayoutParams attrs, int callingPid, int callingUid) {
         if ((attrs.privateFlags & PRIVATE_FLAG_IS_SCREEN_DECOR) != 0) {
-            mContext.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.STATUS_BAR_SERVICE,
+            mContext.enforcePermission(
+                    android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid,
                     "DisplayPolicy");
         }
 
         switch (attrs.type) {
             case TYPE_STATUS_BAR:
-                mContext.enforceCallingOrSelfPermission(
-                        android.Manifest.permission.STATUS_BAR_SERVICE,
+                mContext.enforcePermission(
+                        android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid,
                         "DisplayPolicy");
                 if (mStatusBar != null) {
                     if (mStatusBar.isAlive()) {
@@ -953,8 +953,8 @@
                 }
                 break;
             case TYPE_NOTIFICATION_SHADE:
-                mContext.enforceCallingOrSelfPermission(
-                        android.Manifest.permission.STATUS_BAR_SERVICE,
+                mContext.enforcePermission(
+                        android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid,
                         "DisplayPolicy");
                 if (mNotificationShade != null) {
                     if (mNotificationShade.isAlive()) {
@@ -963,8 +963,8 @@
                 }
                 break;
             case TYPE_NAVIGATION_BAR:
-                mContext.enforceCallingOrSelfPermission(
-                        android.Manifest.permission.STATUS_BAR_SERVICE,
+                mContext.enforcePermission(
+                        android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid,
                         "DisplayPolicy");
                 if (mNavigationBar != null) {
                     if (mNavigationBar.isAlive()) {
@@ -974,16 +974,17 @@
                 break;
             case TYPE_NAVIGATION_BAR_PANEL:
                 // Check for permission if the caller is not the recents component.
-                if (!mService.mAtmInternal.isCallerRecents(Binder.getCallingUid())) {
-                    mContext.enforceCallingOrSelfPermission(
-                            android.Manifest.permission.STATUS_BAR_SERVICE, "DisplayPolicy");
+                if (!mService.mAtmInternal.isCallerRecents(callingUid)) {
+                    mContext.enforcePermission(
+                            android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid,
+                            "DisplayPolicy");
                 }
                 break;
             case TYPE_STATUS_BAR_PANEL:
             case TYPE_STATUS_BAR_SUB_PANEL:
             case TYPE_VOICE_INTERACTION_STARTING:
-                mContext.enforceCallingOrSelfPermission(
-                        android.Manifest.permission.STATUS_BAR_SERVICE,
+                mContext.enforcePermission(
+                        android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid,
                         "DisplayPolicy");
                 break;
         }
@@ -2983,11 +2984,12 @@
 
     /**
      * Return corner radius in pixels that should be used on windows in order to cover the display.
-     * The radius is only valid for built-in displays since the one who configures window corner
-     * radius cannot know the corner radius of non-built-in display.
+     *
+     * The radius is only valid for internal displays, since the corner radius of external displays
+     * is not known at build time when window corners are configured.
      */
     float getWindowCornerRadius() {
-        return mDisplayContent.getDisplay().getType() == TYPE_BUILT_IN
+        return mDisplayContent.getDisplay().getType() == TYPE_INTERNAL
                 ? ScreenDecorationsUtils.getWindowCornerRadius(mContext.getResources()) : 0f;
     }
 
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index e71371a..539853b 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -525,9 +525,15 @@
             }
             mService.mH.removeCallbacks(mDisplayRotationHandlerTimeout);
             mIsWaitingForRemoteRotation = false;
-            mDisplayContent.sendNewConfiguration();
-            if (t != null) {
-                mService.mAtmService.mTaskOrganizerController.applyContainerTransaction(t, null);
+            mService.mAtmService.deferWindowLayout();
+            try {
+                mDisplayContent.sendNewConfiguration();
+                if (t != null) {
+                    mService.mAtmService.mTaskOrganizerController.applyContainerTransaction(t,
+                            null /* organizer */);
+                }
+            } finally {
+                mService.mAtmService.continueWindowLayout();
             }
         }
     }
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 872379e..6431e11 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -745,7 +745,7 @@
      * @param minimizedDock Whether the docked stack is currently minimized.
      * @param animate Whether to animate the change.
      */
-    private void setMinimizedDockedStack(boolean minimizedDock, boolean animate) {
+    void setMinimizedDockedStack(boolean minimizedDock, boolean animate) {
         final boolean wasMinimized = mMinimizedDock;
         mMinimizedDock = minimizedDock;
         if (minimizedDock == wasMinimized) {
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index 3ff1b95..370d125 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -39,13 +39,6 @@
     }
 
     /**
-     * Called when Insets have been dispatched to client. This gets called just after onPostLayout.
-     */
-    void onPostInsetsDispatched() {
-        checkShowImePostLayout();
-    }
-
-    /**
      * Called from {@link WindowManagerInternal#showImePostLayout} when {@link InputMethodService}
      * requests to show IME on {@param imeTarget}.
      *
@@ -80,7 +73,7 @@
         };
     }
 
-    private void checkShowImePostLayout() {
+    void checkShowImePostLayout() {
         // check if IME is drawn
         if (mIsImeLayoutDrawn
                 || (mImeTargetFromIme != null
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index 51b9916..b663336 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -41,7 +41,7 @@
 import android.view.SurfaceControl;
 import android.view.SyncRtSurfaceTransactionApplier;
 import android.view.ViewRootImpl;
-import android.view.WindowInsetsAnimationCallback;
+import android.view.WindowInsetsAnimation;
 import android.view.WindowInsetsAnimationControlListener;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -403,8 +403,8 @@
             @Override
             public void startAnimation(InsetsAnimationControlImpl controller,
                     WindowInsetsAnimationControlListener listener, int types,
-                    WindowInsetsAnimationCallback.InsetsAnimation animation,
-                    WindowInsetsAnimationCallback.AnimationBounds bounds,
+                    WindowInsetsAnimation animation,
+                    WindowInsetsAnimation.Bounds bounds,
                     int layoutDuringAnimation) {
             }
         }
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index 2d7d3f1..a8fe349 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -168,7 +168,6 @@
             mLastState.set(mState, true /* copySources */);
             notifyInsetsChanged();
         }
-        getImeSourceProvider().onPostInsetsDispatched();
     }
 
     void onInsetsModified(InsetsControlTarget windowState, InsetsState state) {
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index 00947d7..44034ed 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -31,14 +31,14 @@
 import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
 import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
 
+import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.KeyguardControllerProto.AOD_SHOWING;
 import static com.android.server.wm.KeyguardControllerProto.KEYGUARD_OCCLUDED_STATES;
 import static com.android.server.wm.KeyguardControllerProto.KEYGUARD_SHOWING;
 import static com.android.server.wm.KeyguardOccludedProto.DISPLAY_ID;
 import static com.android.server.wm.KeyguardOccludedProto.KEYGUARD_OCCLUDED;
-import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
 
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -411,8 +411,7 @@
             if (stack == null) {
                 return;
             }
-            mStackSupervisor.moveTasksToFullscreenStackLocked(stack,
-                    stack.isFocusedStackOnDisplay());
+            mRootWindowContainer.getDefaultDisplay().onSplitScreenModeDismissed();
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 944e0ae..634d7e9 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -20,7 +20,6 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.view.RemoteAnimationTarget.MODE_CLOSING;
 import static android.view.RemoteAnimationTarget.MODE_OPENING;
-import static android.view.WindowManager.DOCKED_INVALID;
 import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 
@@ -414,12 +413,7 @@
         }
 
         // Save the minimized home height
-        final ActivityStack dockedStack =
-                mDisplayContent.getRootSplitScreenPrimaryTask();
-        mDisplayContent.getDockedDividerController().getHomeStackBoundsInDockedMode(
-                mDisplayContent.getConfiguration(),
-                dockedStack == null ? DOCKED_INVALID : dockedStack.getDockSide(),
-                mMinimizedHomeBounds);
+        mMinimizedHomeBounds = mDisplayContent.getRootHomeTask().getBounds();
 
         mService.mWindowPlacerLocked.performSurfacePlacement();
 
@@ -748,8 +742,10 @@
     }
 
     boolean isWallpaperVisible(WindowState w) {
-        return w != null && w.mAttrs.type == TYPE_BASE_APPLICATION && w.mActivityRecord != null
-                && mTargetActivityRecord == w.mActivityRecord && isTargetOverWallpaper();
+        return w != null && w.mAttrs.type == TYPE_BASE_APPLICATION &&
+                ((w.mActivityRecord != null && mTargetActivityRecord == w.mActivityRecord)
+                        || isAnimatingTask(w.getTask()))
+                && isTargetOverWallpaper();
     }
 
     /**
@@ -842,8 +838,8 @@
             mTask = task;
             mIsRecentTaskInvisible = isRecentTaskInvisible;
             final WindowContainer container = mTask.getParent();
-            container.getRelativeDisplayedPosition(mPosition);
             mBounds.set(container.getDisplayedBounds());
+            mPosition.set(mBounds.left, mBounds.top);
         }
 
         RemoteAnimationTarget createRemoteAnimationTarget() {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index e3d85c8..2596452 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -1998,8 +1998,6 @@
         removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
 
         mUserStackInFront.put(mCurrentUser, focusStackId);
-        final int restoreStackId =
-                mUserStackInFront.get(userId, getDefaultDisplay().getRootHomeTask().getRootTaskId());
         mCurrentUser = userId;
 
         mStackSupervisor.mStartingUsers.add(uss);
@@ -2011,9 +2009,10 @@
             }
         }
 
+        final int restoreStackId = mUserStackInFront.get(userId);
         ActivityStack stack = getStack(restoreStackId);
         if (stack == null) {
-            stack = getDefaultDisplay().getRootHomeTask();
+            stack = getDefaultDisplay().getOrCreateRootHomeTask();
         }
         final boolean homeInFront = stack.isActivityTypeHome();
         if (stack.isOnHomeDisplay()) {
@@ -2035,8 +2034,11 @@
      */
     void updateUserStack(int userId, ActivityStack stack) {
         if (userId != mCurrentUser) {
-            mUserStackInFront.put(userId, stack != null ? stack.getRootTaskId()
-                    : getDefaultDisplay().getRootHomeTask().getRootTaskId());
+            if (stack == null) {
+                stack = getDefaultDisplay().getOrCreateRootHomeTask();
+            }
+
+            mUserStackInFront.put(userId, stack.getRootTaskId());
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 0aed691..c7f2cc7 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -199,6 +199,7 @@
     static final int INVALID_MIN_SIZE = -1;
     private float mShadowRadius = 0;
     private final Rect mLastSurfaceCrop = new Rect();
+    private static final boolean ENABLE_FREEFORM_COMPOSITOR_SHADOWS = false;
 
     /**
      * The modes to control how the stack is moved to the front when calling {@link Task#reparent}.
@@ -2144,12 +2145,6 @@
                     // For floating tasks, calculate the smallest width from the bounds of the task
                     inOutConfig.smallestScreenWidthDp = (int) (
                             Math.min(mTmpFullBounds.width(), mTmpFullBounds.height()) / density);
-                } else if (WindowConfiguration.isSplitScreenWindowingMode(windowingMode)) {
-                    // Iterating across all screen orientations, and return the minimum of the task
-                    // width taking into account that the bounds might change because the snap
-                    // algorithm snaps to a different value
-                    inOutConfig.smallestScreenWidthDp =
-                            getSmallestScreenWidthDpForDockedBounds(mTmpFullBounds);
                 }
                 // otherwise, it will just inherit
             }
@@ -2553,8 +2548,10 @@
     }
 
     private void updateSurfaceCrop() {
+        // TODO(b/149585281) remove when root task has the correct bounds for freeform
         // Only update the crop if we are drawing shadows on the task.
-        if (mSurfaceControl == null || !mWmService.mRenderShadowsInCompositor) {
+        if (mSurfaceControl == null || !mWmService.mRenderShadowsInCompositor
+                || !isRootTask() || !ENABLE_FREEFORM_COMPOSITOR_SHADOWS) {
             return;
         }
 
@@ -2978,8 +2975,14 @@
     }
 
     @Override
+    void onSurfaceShown(SurfaceControl.Transaction t) {
+        super.onSurfaceShown(t);
+        t.unsetColor(mSurfaceControl);
+    }
+
+    @Override
     SurfaceControl.Builder makeSurface() {
-        return super.makeSurface().setMetadata(METADATA_TASK_ID, mTaskId);
+        return super.makeSurface().setColorLayer().setMetadata(METADATA_TASK_ID, mTaskId);
     }
 
     boolean isTaskAnimating() {
@@ -3248,6 +3251,10 @@
         return this;
     }
 
+    TaskTile asTile() {
+        return null;
+    }
+
     // TODO(task-merge): Figure-out how this should work with hierarchy tasks.
     boolean shouldBeVisible(ActivityRecord starting) {
         return true;
@@ -3934,7 +3941,8 @@
             return dipToPixel(PINNED_WINDOWING_MODE_ELEVATION_IN_DIP,
                     mDisplayContent.getDisplayMetrics());
         }
-        if (inFreeformWindowingMode()) {
+        // TODO(b/149585281) remove when root task has the correct bounds for freeform
+        if (ENABLE_FREEFORM_COMPOSITOR_SHADOWS && inFreeformWindowingMode()) {
             final int elevation = taskIsFocused
                     ? DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP : DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP;
             return dipToPixel(elevation, mDisplayContent.getDisplayMetrics());
@@ -3949,7 +3957,7 @@
      */
     private void updateShadowsRadius(boolean taskIsFocused,
             SurfaceControl.Transaction pendingTransaction) {
-        if (!mWmService.mRenderShadowsInCompositor) return;
+        if (!mWmService.mRenderShadowsInCompositor || !isRootTask()) return;
 
         final float newShadowRadius = getShadowRadius(taskIsFocused);
         if (mShadowRadius != newShadowRadius) {
diff --git a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
index 2dde0ba..f715d8f 100644
--- a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
+++ b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
@@ -59,6 +59,7 @@
     private static final int NOTIFY_TASK_LIST_UPDATED_LISTENERS_MSG = 24;
     private static final int NOTIFY_SINGLE_TASK_DISPLAY_EMPTY = 25;
     private static final int NOTIFY_TASK_LIST_FROZEN_UNFROZEN_MSG = 26;
+    private static final int NOTIFY_TASK_FOCUS_CHANGED_MSG = 27;
 
     // Delay in notifying task stack change listeners (in millis)
     private static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
@@ -179,6 +180,10 @@
         l.onRecentTaskListFrozenChanged(m.arg1 != 0);
     };
 
+    private final TaskStackConsumer mNotifyTaskFocusChanged = (l, m) -> {
+        l.onTaskFocusChanged(m.arg1, m.arg2 != 0);
+    };
+
     @FunctionalInterface
     public interface TaskStackConsumer {
         void accept(ITaskStackListener t, Message m) throws RemoteException;
@@ -273,6 +278,9 @@
                 case NOTIFY_TASK_LIST_FROZEN_UNFROZEN_MSG:
                     forAllRemoteListeners(mNotifyTaskListFrozen, msg);
                     break;
+                case NOTIFY_TASK_FOCUS_CHANGED_MSG:
+                    forAllRemoteListeners(mNotifyTaskFocusChanged, msg);
+                    break;
             }
         }
     }
@@ -565,4 +573,12 @@
         forAllLocalListeners(mNotifyTaskListFrozen, msg);
         msg.sendToTarget();
     }
+
+    /** @see ITaskStackListener#onTaskFocusChanged(int, boolean) */
+    void notifyTaskFocusChanged(int taskId, boolean focused) {
+        final Message msg = mHandler.obtainMessage(NOTIFY_TASK_FOCUS_CHANGED_MSG,
+                taskId, focused ? 1 : 0);
+        forAllLocalListeners(mNotifyTaskFocusChanged, msg);
+        msg.sendToTarget();
+    }
 }
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 4b13a0c..4d5621c 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -492,6 +492,10 @@
         if (!(container instanceof Task)) {
             throw new IllegalArgumentException("Invalid container in hierarchy op");
         }
+        if (container.getDisplayContent() == null) {
+            Slog.w(TAG, "Container is no longer attached: " + container);
+            return 0;
+        }
         if (hop.isReparent()) {
             // special case for tiles since they are "virtual" parents
             if (container instanceof ActivityStack && ((ActivityStack) container).isRootTask()) {
diff --git a/services/core/java/com/android/server/wm/TaskTile.java b/services/core/java/com/android/server/wm/TaskTile.java
index 369db05..74d5c33 100644
--- a/services/core/java/com/android/server/wm/TaskTile.java
+++ b/services/core/java/com/android/server/wm/TaskTile.java
@@ -31,7 +31,6 @@
 import android.graphics.Rect;
 import android.os.IBinder;
 import android.util.Slog;
-import android.view.SurfaceControl;
 
 import java.util.ArrayList;
 import java.util.Comparator;
@@ -78,30 +77,9 @@
         // Virtual parent, so don't notify children.
     }
 
-    /**
-     * If there is a disconnection, this will clean up any vestigial surfaces left on the tile
-     * leash by moving known children to a new surfacecontrol and then removing the old one.
-     */
-    void cleanupSurfaces() {
-        if (mSurfaceControl == null) {
-            return;
-        }
-        SurfaceControl oldSurface = mSurfaceControl;
-        WindowContainer parentWin = getParent();
-        if (parentWin == null) {
-            return;
-        }
-        mSurfaceControl = parentWin.makeChildSurface(null).setName("TaskTile " + mTaskId + " - "
-                    + getRequestedOverrideWindowingMode()).setContainerLayer().build();
-        SurfaceControl.Transaction t = parentWin.getPendingTransaction();
-        t.show(mSurfaceControl);
-        for (int i = 0; i < mChildren.size(); ++i) {
-            if (mChildren.get(i).getSurfaceControl() == null) {
-                continue;
-            }
-            mChildren.get(i).reparentSurfaceControl(t, mSurfaceControl);
-        }
-        t.remove(oldSurface);
+    @Override
+    TaskTile asTile() {
+        return this;
     }
 
     @Override
@@ -215,6 +193,12 @@
         super.removeImmediately();
     }
 
+    @Override
+    void taskOrganizerDied() {
+        super.taskOrganizerDied();
+        removeImmediately();
+    }
+
     static TaskTile forToken(IBinder token) {
         try {
             return (TaskTile) ((TaskToken) token).getContainer();
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 0bb4e03..294c36a 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -365,6 +365,7 @@
             // build a surface.
             setSurfaceControl(makeSurface().build());
             getPendingTransaction().show(mSurfaceControl);
+            onSurfaceShown(getPendingTransaction());
             updateSurfacePosition();
         } else {
             // If we have a surface but a new parent, we just need to perform a reparent. Go through
@@ -383,6 +384,13 @@
         scheduleAnimation();
     }
 
+    /**
+     * Called when the surface is shown for the first time.
+     */
+    void onSurfaceShown(Transaction t) {
+        // do nothing
+    }
+
     // Temp. holders for a chain of containers we are currently processing.
     private final LinkedList<WindowContainer> mTmpChain1 = new LinkedList<>();
     private final LinkedList<WindowContainer> mTmpChain2 = new LinkedList<>();
@@ -1908,7 +1916,7 @@
 
     @Override
     public Builder makeAnimationLeash() {
-        return makeSurface();
+        return makeSurface().setContainerLayer();
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 2bb6703..bad24917 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -65,6 +65,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
+import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
 import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
 import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
@@ -1336,14 +1337,18 @@
             DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel,
             InsetsState outInsetsState) {
         int[] appOp = new int[1];
-        int res = mPolicy.checkAddPermission(attrs, appOp);
+        final boolean isRoundedCornerOverlay = (attrs.privateFlags
+                & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0;
+        int res = mPolicy.checkAddPermission(attrs.type, isRoundedCornerOverlay, attrs.packageName,
+                appOp);
         if (res != WindowManagerGlobal.ADD_OKAY) {
             return res;
         }
 
         WindowState parentWindow = null;
-        long origId;
         final int callingUid = Binder.getCallingUid();
+        final int callingPid = Binder.getCallingPid();
+        final long origId = Binder.clearCallingIdentity();
         final int type = attrs.type;
 
         synchronized (mGlobalLock) {
@@ -1392,6 +1397,13 @@
                 return WindowManagerGlobal.ADD_PERMISSION_DENIED;
             }
 
+            if (type == TYPE_PRESENTATION && !displayContent.getDisplay().isPublicPresentation()) {
+                ProtoLog.w(WM_ERROR,
+                        "Attempted to add presentation window to a non-suitable display.  "
+                                + "Aborting.");
+                return WindowManagerGlobal.ADD_INVALID_DISPLAY;
+            }
+
             ActivityRecord activity = null;
             final boolean hasParent = parentWindow != null;
             // Use existing parent window token for child windows since they go in the same token
@@ -1410,8 +1422,6 @@
                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                 }
                 final IBinder binder = attrs.token != null ? attrs.token : client.asBinder();
-                final boolean isRoundedCornerOverlay =
-                        (attrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0;
                 token = new WindowToken(this, binder, type, false, displayContent,
                         session.mCanAddInternalSystemWindow, isRoundedCornerOverlay);
             } else if (rootType >= FIRST_APPLICATION_WINDOW
@@ -1504,10 +1514,9 @@
             }
 
             final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();
-            displayPolicy.adjustWindowParamsLw(win, win.mAttrs, Binder.getCallingPid(),
-                    Binder.getCallingUid());
+            displayPolicy.adjustWindowParamsLw(win, win.mAttrs, callingPid, callingUid);
 
-            res = displayPolicy.validateAddingWindowLw(attrs);
+            res = displayPolicy.validateAddingWindowLw(attrs, callingPid, callingUid);
             if (res != WindowManagerGlobal.ADD_OKAY) {
                 return res;
             }
@@ -1559,8 +1568,6 @@
                 displayContent.mTapExcludedWindows.add(win);
             }
 
-            origId = Binder.clearCallingIdentity();
-
             win.attach();
             mWindowMap.put(client.asBinder(), win);
             win.initAppOpsState();
@@ -2560,43 +2567,48 @@
         final boolean callerCanManageAppTokens =
                 checkCallingPermission(MANAGE_APP_TOKENS, "addWindowToken()");
         if (!callerCanManageAppTokens) {
-            // TODO(window-context): refactor checkAddPermission to not take attrs.
-            LayoutParams attrs = new LayoutParams(type);
-            attrs.packageName = packageName;
-            final int res = mPolicy.checkAddPermission(attrs, new int[1]);
+            final int res = mPolicy.checkAddPermission(type, false /* isRoundedCornerOverlay */,
+                    packageName, new int[1]);
             if (res != ADD_OKAY) {
                 return res;
             }
         }
 
-        synchronized (mGlobalLock) {
-            if (!callerCanManageAppTokens) {
-                if (!unprivilegedAppCanCreateTokenWith(null, Binder.getCallingUid(), type, type,
-                        null, packageName) || packageName == null) {
-                    throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
+        final int callingUid = Binder.getCallingUid();
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                if (!callerCanManageAppTokens) {
+                    if (packageName == null || !unprivilegedAppCanCreateTokenWith(
+                            null /* parentWindow */, callingUid, type, type, null /* tokenForLog */,
+                            packageName)) {
+                        throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
+                    }
+                }
+
+                final DisplayContent dc = getDisplayContentOrCreate(displayId, null /* token */);
+                if (dc == null) {
+                    ProtoLog.w(WM_ERROR, "addWindowToken: Attempted to add token: %s"
+                            + " for non-exiting displayId=%d", binder, displayId);
+                    return WindowManagerGlobal.ADD_INVALID_DISPLAY;
+                }
+
+                WindowToken token = dc.getWindowToken(binder);
+                if (token != null) {
+                    ProtoLog.w(WM_ERROR, "addWindowToken: Attempted to add binder token: %s"
+                            + " for already created window token: %s"
+                            + " displayId=%d", binder, token, displayId);
+                    return WindowManagerGlobal.ADD_DUPLICATE_ADD;
+                }
+                // TODO(window-container): Clean up dead tokens
+                if (type == TYPE_WALLPAPER) {
+                    new WallpaperWindowToken(this, binder, true, dc, callerCanManageAppTokens);
+                } else {
+                    new WindowToken(this, binder, type, true, dc, callerCanManageAppTokens);
                 }
             }
-
-            final DisplayContent dc = getDisplayContentOrCreate(displayId, null /* token */);
-            if (dc == null) {
-                ProtoLog.w(WM_ERROR, "addWindowToken: Attempted to add token: %s"
-                        + " for non-exiting displayId=%d", binder, displayId);
-                return WindowManagerGlobal.ADD_INVALID_DISPLAY;
-            }
-
-            WindowToken token = dc.getWindowToken(binder);
-            if (token != null) {
-                ProtoLog.w(WM_ERROR, "addWindowToken: Attempted to add binder token: %s"
-                        + " for already created window token: %s"
-                        + " displayId=%d", binder, token, displayId);
-                return WindowManagerGlobal.ADD_DUPLICATE_ADD;
-            }
-            // TODO(window-container): Clean up dead tokens
-            if (type == TYPE_WALLPAPER) {
-                new WallpaperWindowToken(this, binder, true, dc, callerCanManageAppTokens);
-            } else {
-                new WindowToken(this, binder, type, true, dc, callerCanManageAppTokens);
-            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
         }
         return WindowManagerGlobal.ADD_OKAY;
     }
@@ -6843,34 +6855,32 @@
             throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
         }
 
-        synchronized (mGlobalLock) {
-            final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
-            if (displayContent == null) {
-                ProtoLog.w(WM_ERROR,
-                        "Attempted to set windowing mode to a display that does not exist: %d",
-                        displayId);
-                return;
-            }
-
-            int lastWindowingMode = displayContent.getWindowingMode();
-            mDisplayWindowSettings.setWindowingModeLocked(displayContent, mode);
-
-            displayContent.reconfigureDisplayLocked();
-
-            if (lastWindowingMode != displayContent.getWindowingMode()) {
-                // reconfigure won't detect this change in isolation because the windowing mode is
-                // already set on the display, so fire off a new config now.
-
-                final long origId = Binder.clearCallingIdentity();
-                try {
-                    // direct call since lock is shared.
-                    displayContent.sendNewConfiguration();
-                } finally {
-                    Binder.restoreCallingIdentity(origId);
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
+                if (displayContent == null) {
+                    ProtoLog.w(WM_ERROR,
+                            "Attempted to set windowing mode to a display that does not exist: %d",
+                            displayId);
+                    return;
                 }
-                // Now that all configurations are updated, execute pending transitions
-                displayContent.executeAppTransition();
+
+                int lastWindowingMode = displayContent.getWindowingMode();
+                mDisplayWindowSettings.setWindowingModeLocked(displayContent, mode);
+
+                displayContent.reconfigureDisplayLocked();
+
+                if (lastWindowingMode != displayContent.getWindowingMode()) {
+                    // reconfigure won't detect this change in isolation because the windowing mode
+                    // is already set on the display, so fire off a new config now.
+                    displayContent.sendNewConfiguration();
+                    // Now that all configurations are updated, execute pending transitions.
+                    displayContent.executeAppTransition();
+                }
             }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
         }
     }
 
@@ -6898,18 +6908,22 @@
             throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
         }
 
-        synchronized (mGlobalLock) {
-            final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
-            if (displayContent == null) {
-                ProtoLog.w(WM_ERROR,
-                        "Attempted to set remove mode to a display that does not exist: %d",
-                        displayId);
-                return;
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
+                if (displayContent == null) {
+                    ProtoLog.w(WM_ERROR,
+                            "Attempted to set remove mode to a display that does not exist: %d",
+                            displayId);
+                    return;
+                }
+
+                mDisplayWindowSettings.setRemoveContentModeLocked(displayContent, mode);
+                displayContent.reconfigureDisplayLocked();
             }
-
-            mDisplayWindowSettings.setRemoveContentModeLocked(displayContent, mode);
-
-            displayContent.reconfigureDisplayLocked();
+        } finally {
+            Binder.restoreCallingIdentity(origId);
         }
     }
 
@@ -7320,7 +7334,9 @@
             synchronized (mGlobalLock) {
                 final WindowState imeTarget = mWindowMap.get(imeTargetWindowToken);
                 if (imeTarget != null) {
-                    imeTarget.getDisplayContent().updateImeControlTarget(imeTarget);
+                    InsetsControlTarget controlTarget =
+                            imeTarget.getDisplayContent().computeImeControlTarget(imeTarget);
+                    imeTarget.getDisplayContent().updateImeControlTarget(controlTarget);
                 }
             }
         }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index b336f8d..ed4e684 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1493,7 +1493,8 @@
         // Some system windows (e.g. "Power off" dialog) don't have a task, but we would still
         // associate them with some stack to enable dimming.
         final DisplayContent dc = getDisplayContent();
-        return mAttrs.type >= FIRST_SYSTEM_WINDOW && dc != null ? dc.getRootHomeTask() : null;
+        return mAttrs.type >= FIRST_SYSTEM_WINDOW && dc != null
+                ? dc.getOrCreateRootHomeTask() : null;
     }
 
     /**
@@ -2661,18 +2662,6 @@
                             mWmService.mTaskSnapshotController.onAppDied(win.mActivityRecord);
                         }
                         win.removeIfPossible(shouldKeepVisibleDeadAppWindow());
-                        if (win.mAttrs.type == TYPE_DOCK_DIVIDER) {
-                            // The owner of the docked divider died :( We reset the docked stack,
-                            // just in case they have the divider at an unstable position. Better
-                            // also reset drag resizing state, because the owner can't do it
-                            // anymore.
-                            final ActivityStack stack =
-                                    dc.getRootSplitScreenPrimaryTask();
-                            if (stack != null) {
-                                stack.resetDockedStackToMiddle();
-                            }
-                            resetSplitScreenResizing = true;
-                        }
                     } else if (mHasSurface) {
                         Slog.e(TAG, "!!! LEAK !!! Window removed but surface still valid.");
                         WindowState.this.removeIfPossible();
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index d0eaa48..e1615af 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -645,10 +645,12 @@
     Return<void> gnssSvStatusCb_2_0(const hidl_vec<IGnssCallback_V2_0::GnssSvInfo>& svInfoList) override {
         return gnssSvStatusCbImpl(svInfoList);
     }
+
+    // New in 2.1
     Return<void> gnssSvStatusCb_2_1(const hidl_vec<IGnssCallback_V2_1::GnssSvInfo>& svInfoList) override {
         return gnssSvStatusCbImpl(svInfoList);
     }
-    Return<void> gnssSetCapabilitesCbImpl(uint32_t capabilities, bool hasSubHalCapabilityFlags);
+    Return<void> gnssSetCapabilitiesCb_2_1(uint32_t capabilities) override;
 
     // TODO: Reconsider allocation cost vs threadsafety on these statics
     static const char* sNmeaString;
@@ -851,6 +853,10 @@
     return GnssCallback::gnssSetCapabilitesCb(capabilities);
 }
 
+Return<void> GnssCallback::gnssSetCapabilitiesCb_2_1(uint32_t capabilities) {
+    return GnssCallback::gnssSetCapabilitesCb(capabilities);
+}
+
 Return<void> GnssCallback::gnssAcquireWakelockCb() {
     acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
     return Void();
diff --git a/services/core/xsd/vts/Android.bp b/services/core/xsd/vts/Android.bp
index 5545656..636d110 100644
--- a/services/core/xsd/vts/Android.bp
+++ b/services/core/xsd/vts/Android.bp
@@ -31,4 +31,12 @@
         "-Wall",
         "-Werror",
     ],
+    data: [
+        ":default-permissions",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts-core"
+    ],
+    test_config: "vts_defaultPermissions_validate_test.xml",
 }
diff --git a/services/core/xsd/vts/vts_defaultPermissions_validate_test.xml b/services/core/xsd/vts/vts_defaultPermissions_validate_test.xml
new file mode 100644
index 0000000..1ccacae
--- /dev/null
+++ b/services/core/xsd/vts/vts_defaultPermissions_validate_test.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs vts_defaultPermissions_validate_test.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="default-permissions.xsd->/data/local/tmp/default-permissions.xsd" />
+        <option name="push" value="vts_defaultPermissions_validate_test->/data/local/tmp/vts_defaultPermissions_validate_test" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="vts_defaultPermissions_validate_test" />
+    </test>
+</configuration>
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 6862766..731cd1e 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -11056,14 +11056,21 @@
 
     @Override
     public void setAccountManagementDisabled(ComponentName who, String accountType,
-            boolean disabled) {
+            boolean disabled, boolean parent) {
         if (!mHasFeature) {
             return;
         }
         Objects.requireNonNull(who, "ComponentName is null");
         synchronized (getLockObject()) {
+            /*
+             * When called on the parent DPM instance (parent == true), affects active admin
+             * selection in two ways:
+             * * The ActiveAdmin must be of an org-owned profile owner.
+             * * The parent ActiveAdmin instance should be used for managing the restriction.
+             */
             ActiveAdmin ap = getActiveAdminForCallerLocked(who,
-                    DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+                    parent ? DeviceAdminInfo.USES_POLICY_ORGANIZATION_OWNED_PROFILE_OWNER
+                            : DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, parent);
             if (disabled) {
                 ap.accountTypesWithManagementDisabled.add(accountType);
             } else {
@@ -11075,22 +11082,34 @@
 
     @Override
     public String[] getAccountTypesWithManagementDisabled() {
-        return getAccountTypesWithManagementDisabledAsUser(UserHandle.getCallingUserId());
+        return getAccountTypesWithManagementDisabledAsUser(UserHandle.getCallingUserId(), false);
     }
 
     @Override
-    public String[] getAccountTypesWithManagementDisabledAsUser(int userId) {
+    public String[] getAccountTypesWithManagementDisabledAsUser(int userId, boolean parent) {
         enforceFullCrossUsersPermission(userId);
         if (!mHasFeature) {
             return null;
         }
         synchronized (getLockObject()) {
-            DevicePolicyData policy = getUserData(userId);
-            final int N = policy.mAdminList.size();
-            ArraySet<String> resultSet = new ArraySet<>();
-            for (int i = 0; i < N; i++) {
-                ActiveAdmin admin = policy.mAdminList.get(i);
-                resultSet.addAll(admin.accountTypesWithManagementDisabled);
+            final ArraySet<String> resultSet = new ArraySet<>();
+
+            if (!parent) {
+                final DevicePolicyData policy = getUserData(userId);
+                for (ActiveAdmin admin : policy.mAdminList) {
+                    resultSet.addAll(admin.accountTypesWithManagementDisabled);
+                }
+            }
+
+            // Check if there's a profile owner of an org-owned device and the method is called for
+            // the parent user of this profile owner.
+            final ActiveAdmin orgOwnedAdmin =
+                    getProfileOwnerOfOrganizationOwnedDeviceLocked(userId);
+            final boolean shouldGetParentAccounts = orgOwnedAdmin != null && (parent
+                    || UserHandle.getUserId(orgOwnedAdmin.getUid()) != userId);
+            if (shouldGetParentAccounts) {
+                resultSet.addAll(
+                        orgOwnedAdmin.getParentActiveAdmin().accountTypesWithManagementDisabled);
             }
             return resultSet.toArray(new String[resultSet.size()]);
         }
@@ -15231,15 +15250,27 @@
             final ActiveAdmin admin =
                     getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
             previousCrossProfilePackages = admin.mCrossProfilePackages;
+            if (packageNames.equals(previousCrossProfilePackages)) {
+                return;
+            }
             admin.mCrossProfilePackages = packageNames;
             saveSettingsLocked(mInjector.userHandleGetCallingUserId());
         }
+        logSetCrossProfilePackages(who, packageNames);
         final CrossProfileApps crossProfileApps = mContext.getSystemService(CrossProfileApps.class);
         mInjector.binderWithCleanCallingIdentity(
                 () -> crossProfileApps.resetInteractAcrossProfilesAppOps(
                         previousCrossProfilePackages, new HashSet<>(packageNames)));
     }
 
+    private void logSetCrossProfilePackages(ComponentName who, List<String> packageNames) {
+        DevicePolicyEventLogger
+                .createEvent(DevicePolicyEnums.SET_CROSS_PROFILE_PACKAGES)
+                .setAdmin(who)
+                .setStrings(packageNames.toArray(new String[packageNames.size()]))
+                .write();
+    }
+
     @Override
     public List<String> getCrossProfilePackages(ComponentName who) {
         if (!mHasFeature) {
diff --git a/services/people/java/com/android/server/people/data/ConversationInfo.java b/services/people/java/com/android/server/people/data/ConversationInfo.java
index ce35366..859cdf2 100644
--- a/services/people/java/com/android/server/people/data/ConversationInfo.java
+++ b/services/people/java/com/android/server/people/data/ConversationInfo.java
@@ -137,6 +137,11 @@
         return hasShortcutFlags(ShortcutInfo.FLAG_LONG_LIVED);
     }
 
+    /** Whether the shortcut for this conversation is cached in Shortcut Service. */
+    public boolean isShortcutCached() {
+        return hasShortcutFlags(ShortcutInfo.FLAG_CACHED);
+    }
+
     /** Whether this conversation is marked as important by the user. */
     public boolean isImportant() {
         return hasConversationFlags(FLAG_IMPORTANT);
@@ -213,6 +218,9 @@
         if (isShortcutLongLived()) {
             sb.append("Liv");
         }
+        if (isShortcutCached()) {
+            sb.append("Cac");
+        }
         sb.append("]");
         sb.append(", conversationFlags=0x").append(Integer.toHexString(mConversationFlags));
         sb.append(" [");
diff --git a/services/people/java/com/android/server/people/data/DataManager.java b/services/people/java/com/android/server/people/data/DataManager.java
index 2edfd74..dd9cbd0 100644
--- a/services/people/java/com/android/server/people/data/DataManager.java
+++ b/services/people/java/com/android/server/people/data/DataManager.java
@@ -101,8 +101,8 @@
     private final SparseArray<NotificationListenerService> mNotificationListeners =
             new SparseArray<>();
     private final SparseArray<PackageMonitor> mPackageMonitors = new SparseArray<>();
-    private final ContentObserver mCallLogContentObserver;
-    private final ContentObserver mMmsSmsContentObserver;
+    private ContentObserver mCallLogContentObserver;
+    private ContentObserver mMmsSmsContentObserver;
 
     private ShortcutServiceInternal mShortcutServiceInternal;
     private PackageManagerInternal mPackageManagerInternal;
@@ -118,10 +118,6 @@
         mContext = context;
         mInjector = injector;
         mUsageStatsQueryExecutor = mInjector.createScheduledExecutor();
-        mCallLogContentObserver = new CallLogContentObserver(
-                BackgroundThread.getHandler());
-        mMmsSmsContentObserver = new MmsSmsContentObserver(
-                BackgroundThread.getHandler());
         mDiskReadWriterExecutor = mInjector.createScheduledExecutor();
     }
 
@@ -189,9 +185,12 @@
             // The call log and MMS/SMS messages are shared across user profiles. So only need to
             // register the content observers once for the primary user.
             // TODO: Register observers after the conversations and events being loaded from disk.
+            mCallLogContentObserver = new CallLogContentObserver(BackgroundThread.getHandler());
             mContext.getContentResolver().registerContentObserver(
                     CallLog.CONTENT_URI, /* notifyForDescendants= */ true,
                     mCallLogContentObserver, UserHandle.USER_SYSTEM);
+
+            mMmsSmsContentObserver = new MmsSmsContentObserver(BackgroundThread.getHandler());
             mContext.getContentResolver().registerContentObserver(
                     MmsSms.CONTENT_URI, /* notifyForDescendants= */ false,
                     mMmsSmsContentObserver, UserHandle.USER_SYSTEM);
@@ -226,8 +225,14 @@
             mPackageMonitors.get(userId).unregister();
         }
         if (userId == UserHandle.USER_SYSTEM) {
-            mContext.getContentResolver().unregisterContentObserver(mCallLogContentObserver);
-            mContext.getContentResolver().unregisterContentObserver(mMmsSmsContentObserver);
+            if (mCallLogContentObserver != null) {
+                mContext.getContentResolver().unregisterContentObserver(mCallLogContentObserver);
+                mCallLogContentObserver = null;
+            }
+            if (mMmsSmsContentObserver != null) {
+                mContext.getContentResolver().unregisterContentObserver(mMmsSmsContentObserver);
+                mCallLogContentObserver = null;
+            }
         }
 
         DataMaintenanceService.cancelJob(mContext, userId);
@@ -635,6 +640,14 @@
     private class NotificationListener extends NotificationListenerService {
 
         @Override
+        public void onNotificationPosted(StatusBarNotification sbn) {
+            EventHistoryImpl eventHistory = getEventHistoryIfEligible(sbn);
+            if (eventHistory != null) {
+                eventHistory.addEvent(new Event(sbn.getPostTime(), Event.TYPE_NOTIFICATION_POSTED));
+            }
+        }
+
+        @Override
         public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap,
                 int reason) {
             if (reason != REASON_CLICK) {
@@ -683,7 +696,15 @@
                     break;
             }
             conversationStore.addOrUpdate(builder.build());
-            // TODO: Cache the shortcut when a conversation's notification setting is changed.
+
+            if (modificationType == NOTIFICATION_CHANNEL_OR_GROUP_UPDATED
+                    && conversationInfo.isShortcutLongLived()
+                    && !conversationInfo.isShortcutCached()) {
+                mShortcutServiceInternal.cacheShortcuts(user.getIdentifier(),
+                        mContext.getPackageName(), pkg,
+                        Collections.singletonList(conversationInfo.getShortcutId()),
+                        user.getIdentifier());
+            }
         }
     }
 
diff --git a/services/people/java/com/android/server/people/data/UsageStatsQueryHelper.java b/services/people/java/com/android/server/people/data/UsageStatsQueryHelper.java
index 6dcfaa0..72f1abb 100644
--- a/services/people/java/com/android/server/people/data/UsageStatsQueryHelper.java
+++ b/services/people/java/com/android/server/people/data/UsageStatsQueryHelper.java
@@ -80,10 +80,6 @@
                     addEventByShortcutId(packageData, e.getShortcutId(),
                             new Event(e.getTimeStamp(), Event.TYPE_SHORTCUT_INVOCATION));
                     break;
-                case UsageEvents.Event.NOTIFICATION_INTERRUPTION:
-                    addEventByNotificationChannelId(packageData, e.getNotificationChannelId(),
-                            new Event(e.getTimeStamp(), Event.TYPE_NOTIFICATION_POSTED));
-                    break;
                 case UsageEvents.Event.LOCUS_ID_SET:
                     onInAppConversationEnded(packageData, e);
                     LocusId locusId = e.getLocusId() != null ? new LocusId(e.getLocusId()) : null;
@@ -142,17 +138,4 @@
                 EventStore.CATEGORY_LOCUS_ID_BASED, locusId.getId());
         eventHistory.addEvent(event);
     }
-
-    private void addEventByNotificationChannelId(PackageData packageData,
-            String notificationChannelId, Event event) {
-        ConversationInfo conversationInfo =
-                packageData.getConversationStore().getConversationByNotificationChannelId(
-                        notificationChannelId);
-        if (conversationInfo == null) {
-            return;
-        }
-        EventHistoryImpl eventHistory = packageData.getEventStore().getOrCreateEventHistory(
-                EventStore.CATEGORY_SHORTCUT_BASED, conversationInfo.getShortcutId());
-        eventHistory.addEvent(event);
-    }
 }
diff --git a/services/tests/servicestests/AndroidTest.xml b/services/tests/servicestests/AndroidTest.xml
index bbc6bdb..d34f783 100644
--- a/services/tests/servicestests/AndroidTest.xml
+++ b/services/tests/servicestests/AndroidTest.xml
@@ -26,11 +26,6 @@
         <option name="test-file-name" value="SimpleServiceTestApp.apk" />
     </target_preparer>
 
-    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
-        <option name="cleanup" value="true" />
-        <option name="push" value="AppIntegrityManagerServiceTestApp.apk->/data/local/tmp/AppIntegrityManagerServiceTestApp.apk" />
-    </target_preparer>
-
     <option name="test-tag" value="FrameworksServicesTests" />
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.frameworks.servicestests" />
diff --git a/services/tests/servicestests/assets/AppIntegrityManagerServiceImplTest/AppIntegrityManagerServiceTestApp.apk b/services/tests/servicestests/assets/AppIntegrityManagerServiceImplTest/AppIntegrityManagerServiceTestApp.apk
new file mode 100644
index 0000000..cc1f68c
--- /dev/null
+++ b/services/tests/servicestests/assets/AppIntegrityManagerServiceImplTest/AppIntegrityManagerServiceTestApp.apk
Binary files differ
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 8f70cca..37ce510 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -96,7 +96,6 @@
 import android.util.ArraySet;
 import android.util.Pair;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.R;
@@ -2087,7 +2086,7 @@
 
         FactoryResetProtectionPolicy policy = new FactoryResetProtectionPolicy.Builder()
                 .setFactoryResetProtectionAccounts(new ArrayList<>())
-                .setFactoryResetProtectionDisabled(true)
+                .setFactoryResetProtectionEnabled(false)
                 .build();
         dpm.setFactoryResetProtectionPolicy(admin1, policy);
 
@@ -2105,7 +2104,7 @@
         setupProfileOwner();
 
         FactoryResetProtectionPolicy policy = new FactoryResetProtectionPolicy.Builder()
-                .setFactoryResetProtectionDisabled(true)
+                .setFactoryResetProtectionEnabled(false)
                 .build();
 
         assertExpectException(SecurityException.class, null,
@@ -2157,7 +2156,7 @@
 
         FactoryResetProtectionPolicy policy = new FactoryResetProtectionPolicy.Builder()
                 .setFactoryResetProtectionAccounts(new ArrayList<>())
-                .setFactoryResetProtectionDisabled(true)
+                .setFactoryResetProtectionEnabled(false)
                 .build();
 
         dpm.setFactoryResetProtectionPolicy(admin1, policy);
@@ -2177,8 +2176,8 @@
 
     private void assertPoliciesAreEqual(FactoryResetProtectionPolicy expectedPolicy,
             FactoryResetProtectionPolicy actualPolicy) {
-        assertThat(actualPolicy.isFactoryResetProtectionDisabled()).isEqualTo(
-                expectedPolicy.isFactoryResetProtectionDisabled());
+        assertThat(actualPolicy.isFactoryResetProtectionEnabled()).isEqualTo(
+                expectedPolicy.isFactoryResetProtectionEnabled());
         assertAccountsAreEqual(expectedPolicy.getFactoryResetProtectionAccounts(),
                 actualPolicy.getFactoryResetProtectionAccounts());
     }
@@ -6058,6 +6057,55 @@
                 .thenReturn(packages);
     }
 
+    public void testSetAccountTypesWithManagementDisabledOnManagedProfile() throws Exception {
+        setupProfileOwner();
+
+        final String accountType = "com.example.account.type";
+        int originalUid = mContext.binder.callingUid;
+        dpm.setAccountManagementDisabled(admin1, accountType, true);
+        assertThat(dpm.getAccountTypesWithManagementDisabled()).asList().containsExactly(
+                accountType);
+        mContext.binder.callingUid = DpmMockContext.ANOTHER_UID;
+        assertThat(dpm.getAccountTypesWithManagementDisabled()).isEmpty();
+        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
+        assertThat(dpm.getAccountTypesWithManagementDisabled()).isEmpty();
+
+        mContext.binder.callingUid = originalUid;
+        dpm.setAccountManagementDisabled(admin1, accountType, false);
+        assertThat(dpm.getAccountTypesWithManagementDisabled()).isEmpty();
+    }
+
+    public void testSetAccountTypesWithManagementDisabledOnOrgOwnedManagedProfile()
+            throws Exception {
+        final int managedProfileUserId = 15;
+        final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
+
+        addManagedProfile(admin1, managedProfileAdminUid, admin1);
+        mContext.binder.callingUid = managedProfileAdminUid;
+
+        configureProfileOwnerOfOrgOwnedDevice(admin1, managedProfileUserId);
+
+        int originalUid = mContext.binder.callingUid;
+        final String accountType = "com.example.account.type";
+        dpm.getParentProfileInstance(admin1).setAccountManagementDisabled(admin1, accountType,
+                true);
+        assertThat(dpm.getAccountTypesWithManagementDisabled()).isEmpty();
+        mContext.binder.callingUid = DpmMockContext.ANOTHER_UID;
+        assertThat(dpm.getAccountTypesWithManagementDisabled()).asList().containsExactly(
+                accountType);
+        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
+        assertThat(dpm.getAccountTypesWithManagementDisabled()).asList().containsExactly(
+                accountType);
+
+        mContext.binder.callingUid = originalUid;
+        dpm.getParentProfileInstance(admin1).setAccountManagementDisabled(admin1, accountType,
+                false);
+        mContext.binder.callingUid = DpmMockContext.ANOTHER_UID;
+        assertThat(dpm.getAccountTypesWithManagementDisabled()).isEmpty();
+        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
+        assertThat(dpm.getAccountTypesWithManagementDisabled()).isEmpty();
+    }
+
     // admin1 is the outgoing DPC, adminAnotherPakcage is the incoming one.
     private void assertDeviceOwnershipRevertedWithFakeTransferMetadata() throws Exception {
         writeFakeTransferMetadataFile(UserHandle.USER_SYSTEM,
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/FactoryResetProtectionPolicyTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/FactoryResetProtectionPolicyTest.java
index bc853c6..e8818a3 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/FactoryResetProtectionPolicyTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/FactoryResetProtectionPolicyTest.java
@@ -62,7 +62,7 @@
 
         FactoryResetProtectionPolicy policy = new FactoryResetProtectionPolicy.Builder()
                 .setFactoryResetProtectionAccounts(accounts)
-                .setFactoryResetProtectionDisabled(true)
+                .setFactoryResetProtectionEnabled(false)
                 .build();
 
         testParcelAndUnparcel(policy);
@@ -77,7 +77,7 @@
 
         FactoryResetProtectionPolicy policy = new FactoryResetProtectionPolicy.Builder()
                 .setFactoryResetProtectionAccounts(accounts)
-                .setFactoryResetProtectionDisabled(true)
+                .setFactoryResetProtectionEnabled(false)
                 .build();
 
         testParcelAndUnparcel(policy);
@@ -133,8 +133,8 @@
 
     private void assertPoliciesAreEqual(FactoryResetProtectionPolicy expectedPolicy,
             FactoryResetProtectionPolicy actualPolicy) {
-        assertEquals(expectedPolicy.isFactoryResetProtectionDisabled(),
-                actualPolicy.isFactoryResetProtectionDisabled());
+        assertEquals(expectedPolicy.isFactoryResetProtectionEnabled(),
+                actualPolicy.isFactoryResetProtectionEnabled());
         assertAccountsAreEqual(expectedPolicy.getFactoryResetProtectionAccounts(),
                 actualPolicy.getFactoryResetProtectionAccounts());
     }
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
index 8d5939a..7027185 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -202,7 +202,7 @@
         assertEquals(1, displayIds.length);
         final int displayId = displayIds[0];
         DisplayInfo info = bs.getDisplayInfo(displayId);
-        assertEquals(info.type, Display.TYPE_BUILT_IN);
+        assertEquals(info.type, Display.TYPE_INTERNAL);
 
         displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
 
diff --git a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
index 0d4c6e8..be873bd 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
@@ -90,7 +90,7 @@
 @RunWith(JUnit4.class)
 public class AppIntegrityManagerServiceImplTest {
     private static final String TEST_APP_PATH =
-            "/data/local/tmp/AppIntegrityManagerServiceTestApp.apk";
+            "AppIntegrityManagerServiceImplTest/AppIntegrityManagerServiceTestApp.apk";
 
     private static final String TEST_APP_TWO_CERT_PATH =
             "AppIntegrityManagerServiceImplTest/DummyAppTwoCerts.apk";
@@ -106,9 +106,7 @@
 
     // These are obtained by running the test and checking logcat.
     private static final String APP_CERT =
-            "301AA3CB081134501C45F1422ABC66C24224FD5DED5FDC8F17E697176FD866AA";
-    private static final String INSTALLER_CERT =
-            "301AA3CB081134501C45F1422ABC66C24224FD5DED5FDC8F17E697176FD866AA";
+            "C8A2E9BCCF597C2FB6DC66BEE293FC13F2FC47EC77BC6B2B0D52C11F51192AB8";
     // We use SHA256 for package names longer than 32 characters.
     private static final String INSTALLER_SHA256 =
             "30F41A7CBF96EE736A54DD6DF759B50ED3CC126ABCEF694E167C324F5976C227";
@@ -149,8 +147,12 @@
 
     @Before
     public void setup() throws Exception {
-        mTestApk = new File(TEST_APP_PATH);
-        mTestApkTwoCerts = File.createTempFile("AppIntegrity", ".apk");
+        mTestApk = File.createTempFile("AppIntegrity", ".apk");
+        try (InputStream inputStream = mRealContext.getAssets().open(TEST_APP_PATH)) {
+            Files.copy(inputStream, mTestApk.toPath(), REPLACE_EXISTING);
+        }
+
+        mTestApkTwoCerts = File.createTempFile("AppIntegrityTwoCerts", ".apk");
         try (InputStream inputStream = mRealContext.getAssets().open(TEST_APP_TWO_CERT_PATH)) {
             Files.copy(inputStream, mTestApkTwoCerts.toPath(), REPLACE_EXISTING);
         }
@@ -174,6 +176,7 @@
 
     @After
     public void tearDown() throws Exception {
+        mTestApk.delete();
         mTestApkTwoCerts.delete();
     }
 
@@ -304,7 +307,7 @@
         assertEquals(PACKAGE_NAME, appInstallMetadata.getPackageName());
         assertThat(appInstallMetadata.getAppCertificates()).containsExactly(APP_CERT);
         assertEquals(INSTALLER_SHA256, appInstallMetadata.getInstallerName());
-        assertThat(appInstallMetadata.getInstallerCertificates()).containsExactly(INSTALLER_CERT);
+        // we cannot check installer cert because it seems to be device specific.
         assertEquals(VERSION_CODE, appInstallMetadata.getVersionCode());
         assertFalse(appInstallMetadata.isPreInstalled());
         // These are hardcoded in the test apk android manifest
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index a1baf0e..7e3cfc8 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -1779,7 +1779,7 @@
         // Get active mobile network in place
         expectMobileDefaults();
         mService.updateNetworks();
-        verify(mStatsService).setStatsProviderLimit(TEST_IFACE, Long.MAX_VALUE);
+        verify(mStatsService).setStatsProviderLimitAsync(TEST_IFACE, Long.MAX_VALUE);
 
         // Set limit to 10KB.
         setNetworkPolicies(new NetworkPolicy(
@@ -1788,7 +1788,7 @@
         postMsgAndWaitForCompletion();
 
         // Verifies that remaining quota is set to providers.
-        verify(mStatsService).setStatsProviderLimit(TEST_IFACE, 10000L - 4999L);
+        verify(mStatsService).setStatsProviderLimitAsync(TEST_IFACE, 10000L - 4999L);
 
         reset(mStatsService);
 
@@ -1810,7 +1810,7 @@
         postMsgAndWaitForCompletion();
         verify(mStatsService).forceUpdate();
         postMsgAndWaitForCompletion();
-        verify(mStatsService).setStatsProviderLimit(TEST_IFACE, 10000L - 4999L - 1999L);
+        verify(mStatsService).setStatsProviderLimitAsync(TEST_IFACE, 10000L - 4999L - 1999L);
     }
 
     /**
diff --git a/services/tests/servicestests/src/com/android/server/people/data/ConversationInfoTest.java b/services/tests/servicestests/src/com/android/server/people/data/ConversationInfoTest.java
index c0e7927..70d6cf8 100644
--- a/services/tests/servicestests/src/com/android/server/people/data/ConversationInfoTest.java
+++ b/services/tests/servicestests/src/com/android/server/people/data/ConversationInfoTest.java
@@ -46,7 +46,7 @@
                 .setContactUri(CONTACT_URI)
                 .setContactPhoneNumber(PHONE_NUMBER)
                 .setNotificationChannelId(NOTIFICATION_CHANNEL_ID)
-                .setShortcutFlags(ShortcutInfo.FLAG_LONG_LIVED)
+                .setShortcutFlags(ShortcutInfo.FLAG_LONG_LIVED | ShortcutInfo.FLAG_CACHED)
                 .setImportant(true)
                 .setNotificationSilenced(true)
                 .setBubbled(true)
@@ -62,6 +62,7 @@
         assertEquals(PHONE_NUMBER, conversationInfo.getContactPhoneNumber());
         assertEquals(NOTIFICATION_CHANNEL_ID, conversationInfo.getNotificationChannelId());
         assertTrue(conversationInfo.isShortcutLongLived());
+        assertTrue(conversationInfo.isShortcutCached());
         assertTrue(conversationInfo.isImportant());
         assertTrue(conversationInfo.isNotificationSilenced());
         assertTrue(conversationInfo.isBubbled());
@@ -83,6 +84,7 @@
         assertNull(conversationInfo.getContactPhoneNumber());
         assertNull(conversationInfo.getNotificationChannelId());
         assertFalse(conversationInfo.isShortcutLongLived());
+        assertFalse(conversationInfo.isShortcutCached());
         assertFalse(conversationInfo.isImportant());
         assertFalse(conversationInfo.isNotificationSilenced());
         assertFalse(conversationInfo.isBubbled());
diff --git a/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java b/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
index 0bb984e..3ecd319 100644
--- a/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
@@ -184,6 +184,7 @@
         when(mStatusBarNotification.getNotification()).thenReturn(mNotification);
         when(mStatusBarNotification.getPackageName()).thenReturn(TEST_PKG_NAME);
         when(mStatusBarNotification.getUser()).thenReturn(UserHandle.of(USER_ID_PRIMARY));
+        when(mStatusBarNotification.getPostTime()).thenReturn(System.currentTimeMillis());
         when(mNotification.getShortcutId()).thenReturn(TEST_SHORTCUT_ID);
 
         mNotificationChannel = new NotificationChannel(
@@ -325,6 +326,28 @@
     }
 
     @Test
+    public void testNotificationPosted() {
+        mDataManager.onUserUnlocked(USER_ID_PRIMARY);
+
+        ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID,
+                buildPerson());
+        mDataManager.onShortcutAddedOrUpdated(shortcut);
+
+        NotificationListenerService listenerService =
+                mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
+
+        listenerService.onNotificationPosted(mStatusBarNotification);
+
+        List<Range<Long>> activeNotificationOpenTimeSlots = new ArrayList<>();
+        mDataManager.forAllPackages(packageData ->
+                activeNotificationOpenTimeSlots.addAll(
+                        packageData.getEventHistory(TEST_SHORTCUT_ID)
+                                .getEventIndex(Event.TYPE_NOTIFICATION_POSTED)
+                                .getActiveTimeSlots()));
+        assertEquals(1, activeNotificationOpenTimeSlots.size());
+    }
+
+    @Test
     public void testNotificationOpened() {
         mDataManager.onUserUnlocked(USER_ID_PRIMARY);
 
@@ -393,6 +416,9 @@
         assertTrue(conversationInfo.isImportant());
         assertFalse(conversationInfo.isNotificationSilenced());
         assertFalse(conversationInfo.isDemoted());
+        verify(mShortcutServiceInternal).cacheShortcuts(
+                anyInt(), any(), eq(TEST_PKG_NAME),
+                eq(Collections.singletonList(TEST_SHORTCUT_ID)), eq(USER_ID_PRIMARY));
     }
 
     @Test
@@ -589,6 +615,7 @@
         when(mockContext.getUser()).thenReturn(UserHandle.of(userId));
         ShortcutInfo.Builder builder = new ShortcutInfo.Builder(mockContext, id)
                 .setShortLabel(id)
+                .setLongLived(true)
                 .setIntent(new Intent("TestIntent"));
         if (person != null) {
             builder.setPersons(new Person[] {person});
diff --git a/services/tests/servicestests/src/com/android/server/people/data/UsageStatsQueryHelperTest.java b/services/tests/servicestests/src/com/android/server/people/data/UsageStatsQueryHelperTest.java
index dc4876b..d444466 100644
--- a/services/tests/servicestests/src/com/android/server/people/data/UsageStatsQueryHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/people/data/UsageStatsQueryHelperTest.java
@@ -59,7 +59,6 @@
     private static final String PKG_NAME = "pkg";
     private static final String ACTIVITY_NAME = "TestActivity";
     private static final String SHORTCUT_ID = "abc";
-    private static final String NOTIFICATION_CHANNEL_ID = "test : abc";
     private static final LocusId LOCUS_ID_1 = new LocusId("locus_1");
     private static final LocusId LOCUS_ID_2 = new LocusId("locus_2");
 
@@ -83,7 +82,6 @@
                 scheduledExecutorService, testDir, helper);
         mPackageData.mConversationStore.mConversationInfo = new ConversationInfo.Builder()
                 .setShortcutId(SHORTCUT_ID)
-                .setNotificationChannelId(NOTIFICATION_CHANNEL_ID)
                 .setLocusId(LOCUS_ID_1)
                 .build();
 
@@ -114,19 +112,6 @@
     }
 
     @Test
-    public void testQueryNotificationInterruptionEvent() {
-        addUsageEvents(createNotificationInterruptionEvent(100L));
-
-        assertTrue(mHelper.querySince(50L));
-        assertEquals(100L, mHelper.getLastEventTimestamp());
-        Event expectedEvent = new Event(100L, Event.TYPE_NOTIFICATION_POSTED);
-        List<Event> events = mPackageData.mEventStore.mShortcutEventHistory.queryEvents(
-                Event.ALL_EVENT_TYPES, 0L, Long.MAX_VALUE);
-        assertEquals(1, events.size());
-        assertEquals(expectedEvent, events.get(0));
-    }
-
-    @Test
     public void testInAppConversationSwitch() {
         addUsageEvents(
                 createLocusIdSetEvent(100_000L, LOCUS_ID_1.getId()),
@@ -203,13 +188,6 @@
         return e;
     }
 
-    private static UsageEvents.Event createNotificationInterruptionEvent(long timestamp) {
-        UsageEvents.Event e = createUsageEvent(UsageEvents.Event.NOTIFICATION_INTERRUPTION,
-                timestamp);
-        e.mNotificationChannelId = NOTIFICATION_CHANNEL_ID;
-        return e;
-    }
-
     private static UsageEvents.Event createLocusIdSetEvent(long timestamp, String locusId) {
         UsageEvents.Event e = createUsageEvent(UsageEvents.Event.LOCUS_ID_SET, timestamp);
         e.mClass = ACTIVITY_NAME;
diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
index e28d13a..9670658 100644
--- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
@@ -37,6 +37,7 @@
 import android.content.pm.parsing.ParsingPackage;
 import android.os.Build;
 import android.os.Process;
+import android.platform.test.annotations.Presubmit;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 
@@ -57,6 +58,7 @@
 import java.util.Map;
 import java.util.Set;
 
+@Presubmit
 @RunWith(JUnit4.class)
 public class AppsFilterTest {
 
@@ -314,7 +316,8 @@
                 b -> b.setSigningDetails(frameworkSigningDetails));
         PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package"),
                 DUMMY_TARGET_UID,
-                b -> b.setSigningDetails(frameworkSigningDetails));
+                b -> b.setSigningDetails(frameworkSigningDetails)
+                        .setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
         PackageSetting calling = simulateAddPackage(appsFilter,
                 pkg("com.some.other.package"), DUMMY_CALLING_UID,
                 b -> b.setSigningDetails(otherSigningDetails));
diff --git a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
index 4d0481be..eef9012 100644
--- a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
@@ -18,6 +18,7 @@
 
 import static org.junit.Assert.assertEquals;
 
+import android.platform.test.annotations.Presubmit;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
@@ -48,8 +49,9 @@
  * Build/Install/Run:
  *  atest FrameworksServicesTests:SystemConfigTest
  */
-@RunWith(AndroidJUnit4.class)
 @SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
 public class SystemConfigTest {
     private static final String LOG_TAG = "SystemConfigTest";
 
diff --git a/services/tests/servicestests/test-apps/AppIntegrityManagerServiceTestApp/Android.bp b/services/tests/servicestests/test-apps/AppIntegrityManagerServiceTestApp/Android.bp
deleted file mode 100644
index 9aaa37d..0000000
--- a/services/tests/servicestests/test-apps/AppIntegrityManagerServiceTestApp/Android.bp
+++ /dev/null
@@ -1,21 +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.
-
-android_test_helper_app {
-    name: "AppIntegrityManagerServiceTestApp",
-
-    test_suites: ["device-tests"],
-
-    certificate: "platform",
-}
diff --git a/services/tests/servicestests/test-apps/AppIntegrityManagerServiceTestApp/AndroidManifest.xml b/services/tests/servicestests/test-apps/AppIntegrityManagerServiceTestApp/AndroidManifest.xml
deleted file mode 100644
index 98572d4..0000000
--- a/services/tests/servicestests/test-apps/AppIntegrityManagerServiceTestApp/AndroidManifest.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2019 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.google.android.appintegritymanager.test.app"
-    android:versionCode="5000">
-
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="28" />
-
-    <application android:hasCode="false">
-        <meta-data android:name="allowed-installers" android:value="com.android.vending|play_store_cert,adb"/>
-    </application>
-</manifest>
-
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryProtoHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryProtoHelperTest.java
index 458117d..6eaf546 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryProtoHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryProtoHelperTest.java
@@ -21,6 +21,7 @@
 import android.app.NotificationHistory.HistoricalNotification;
 import android.graphics.drawable.Icon;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.text.TextUtils;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
@@ -57,6 +58,10 @@
         String expectedText = "text" + index;
         Icon expectedIcon = Icon.createWithResource(InstrumentationRegistry.getContext(),
                 index);
+        String conversationId = null;
+        if (index % 2 == 0) {
+            conversationId = "convo" + index;
+        }
 
         return new HistoricalNotification.Builder()
                 .setPackage(packageName)
@@ -68,6 +73,7 @@
                 .setTitle(expectedTitle)
                 .setText(expectedText)
                 .setIcon(expectedIcon)
+                .setConversationId(conversationId)
                 .build();
     }
 
@@ -139,6 +145,9 @@
                 expectedStrings.add(n.getPackage());
                 expectedStrings.add(n.getChannelName());
                 expectedStrings.add(n.getChannelId());
+                if (!TextUtils.isEmpty(n.getConversationId())) {
+                    expectedStrings.add(n.getConversationId());
+                }
                 expectedEntries.add(n);
             }
             history.addNotificationToWrite(n);
@@ -178,6 +187,9 @@
                 expectedStrings.add(n.getPackage());
                 expectedStrings.add(n.getChannelName());
                 expectedStrings.add(n.getChannelId());
+                if (!TextUtils.isEmpty(n.getConversationId())) {
+                    expectedStrings.add(n.getConversationId());
+                }
                 expectedEntries.add(n);
             }
             history.addNotificationToWrite(n);
@@ -227,6 +239,9 @@
                 expectedStrings.add(n.getPackage());
                 expectedStrings.add(n.getChannelName());
                 expectedStrings.add(n.getChannelId());
+                if (n.getConversationId() != null) {
+                    expectedStrings.add(n.getConversationId());
+                }
                 expectedEntries.add(n);
             }
             history.addNotificationToWrite(n);
@@ -264,6 +279,9 @@
             expectedStrings.add(n.getPackage());
             expectedStrings.add(n.getChannelName());
             expectedStrings.add(n.getChannelId());
+            if (n.getConversationId() != null) {
+                expectedStrings.add(n.getConversationId());
+            }
             history.addNotificationToWrite(n);
         }
         history.poolStringsFromNotifications();
@@ -279,6 +297,9 @@
             expectedStrings.add(n.getPackage());
             expectedStrings.add(n.getChannelName());
             expectedStrings.add(n.getChannelId());
+            if (n.getConversationId() != null) {
+                expectedStrings.add(n.getConversationId());
+            }
             actualHistory.addNotificationToWrite(n);
         }
         actualHistory.poolStringsFromNotifications();
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index bc33f08..e5ffb4d 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -1284,6 +1284,27 @@
     }
 
     @Test
+    public void testPostCancelPostNotifiesListeners() throws Exception {
+        // WHEN a notification is posted
+        final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", sbn.getId(),
+                sbn.getNotification(), sbn.getUserId());
+        // THEN it is canceled
+        mBinderService.cancelNotificationWithTag(PKG, PKG, "tag", sbn.getId(), sbn.getUserId());
+        // THEN it is posted again (before the cancel has a chance to finish)
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", sbn.getId(),
+                sbn.getNotification(), sbn.getUserId());
+        // THEN the later enqueue isn't swallowed by the cancel. I.e., ordering is respected
+        waitForIdle();
+
+        // The final enqueue made it to the listener instead of being canceled
+        StatusBarNotification[] notifs =
+                mBinderService.getActiveNotifications(PKG);
+        assertEquals(1, notifs.length);
+        assertEquals(1, mService.getNotificationRecordCount());
+    }
+
+    @Test
     public void testCancelNotificationWhilePostedAndEnqueued() throws Exception {
         mBinderService.enqueueNotificationWithTag(PKG, PKG,
                 "testCancelNotificationWhilePostedAndEnqueued", 0,
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
index 9647178..e8c0362 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
@@ -144,4 +144,33 @@
                 anyInt() /* reason */, anyString() /* packageName */);
         verify(taskChangeNotifier, never()).notifyActivityDismissingDockedStack();
     }
+
+    /**
+     * Ensures that notify focus task changes.
+     */
+    @Test
+    public void testNotifyTaskFocusChanged() {
+        final ActivityRecord fullScreenActivityA = new ActivityBuilder(mService).setCreateTask(true)
+                .setStack(mFullscreenStack).build();
+        final Task taskA = fullScreenActivityA.getTask();
+
+        final TaskChangeNotificationController taskChangeNotifier =
+                mService.getTaskChangeNotificationController();
+        spyOn(taskChangeNotifier);
+
+        mService.setResumedActivityUncheckLocked(fullScreenActivityA, "resumeA");
+        verify(taskChangeNotifier).notifyTaskFocusChanged(eq(taskA.mTaskId) /* taskId */,
+                eq(true) /* focused */);
+        reset(taskChangeNotifier);
+
+        final ActivityRecord fullScreenActivityB = new ActivityBuilder(mService).setCreateTask(true)
+                .setStack(mFullscreenStack).build();
+        final Task taskB = fullScreenActivityB.getTask();
+
+        mService.setResumedActivityUncheckLocked(fullScreenActivityB, "resumeB");
+        verify(taskChangeNotifier).notifyTaskFocusChanged(eq(taskA.mTaskId) /* taskId */,
+                eq(false) /* focused */);
+        verify(taskChangeNotifier).notifyTaskFocusChanged(eq(taskB.mTaskId) /* taskId */,
+                eq(true) /* focused */);
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index fa182d6..d46975c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -29,6 +29,7 @@
 import static android.app.ActivityManager.START_SWITCHES_CANCELED;
 import static android.app.ActivityManager.START_TASK_TO_FRONT;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
@@ -64,8 +65,10 @@
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 
+import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.app.IApplicationThread;
+import android.app.WindowConfiguration;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
@@ -80,6 +83,9 @@
 import android.platform.test.annotations.Presubmit;
 import android.service.voice.IVoiceInteractionSession;
 import android.view.Gravity;
+import android.view.ITaskOrganizer;
+import android.view.IWindowContainer;
+import android.view.SurfaceControl;
 
 import androidx.test.filters.SmallTest;
 
@@ -999,7 +1005,8 @@
         assertThat(outActivity[0].inSplitScreenWindowingMode()).isFalse();
 
         // Move activity to split-screen-primary stack and make sure it has the focus.
-        top.getRootTask().setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+        TestSplitOrganizer splitOrg = new TestSplitOrganizer(mService, top.getDisplayId());
+        splitOrg.mPrimary.addChild(top.getRootTask(), 0 /* index */);
         top.getRootTask().moveToFront("testWindowingModeOptionsLaunchAdjacent");
 
         // Activity must landed on split-screen-secondary when launch adjacent.
@@ -1022,4 +1029,58 @@
 
         verify(recentTasks, times(1)).add(any());
     }
+
+    static class TestSplitOrganizer extends ITaskOrganizer.Stub {
+        final ActivityTaskManagerService mService;
+        TaskTile mPrimary;
+        TaskTile mSecondary;
+        boolean mInSplit = false;
+        int mDisplayId;
+        TestSplitOrganizer(ActivityTaskManagerService service, int displayId) {
+            mService = service;
+            mDisplayId = displayId;
+            mService.mTaskOrganizerController.registerTaskOrganizer(this,
+                    WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+            mService.mTaskOrganizerController.registerTaskOrganizer(this,
+                    WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
+            IWindowContainer primary = mService.mTaskOrganizerController.createRootTask(
+                    displayId, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY).token;
+            mPrimary = TaskTile.forToken(primary.asBinder());
+            IWindowContainer secondary = mService.mTaskOrganizerController.createRootTask(
+                    displayId, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).token;
+            mSecondary = TaskTile.forToken(secondary.asBinder());
+        }
+        @Override
+        public void taskAppeared(ActivityManager.RunningTaskInfo info) {
+        }
+        @Override
+        public void taskVanished(IWindowContainer wc) {
+        }
+        @Override
+        public void transactionReady(int id, SurfaceControl.Transaction t) {
+        }
+        @Override
+        public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
+            if (mInSplit) {
+                return;
+            }
+            if (info.topActivityType != ACTIVITY_TYPE_UNDEFINED) {
+                if (info.configuration.windowConfiguration.getWindowingMode()
+                        == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
+                    mInSplit = true;
+                    mService.mTaskOrganizerController.setLaunchRoot(mDisplayId,
+                            mSecondary.mRemoteToken);
+                    // move everything to secondary because test expects this but usually sysui
+                    // does it.
+                    DisplayContent dc = mService.mRootWindowContainer.getDisplayContent(mDisplayId);
+                    for (int i = dc.getStackCount() - 1; i >= 0; --i) {
+                        if (!WindowConfiguration.isSplitScreenWindowingMode(
+                                dc.getStackAt(i).getWindowingMode())) {
+                            mSecondary.addChild(dc.getStackAt(i), 0);
+                        }
+                    }
+                }
+            }
+        }
+    };
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 2ea00ce..3b6816a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -1033,6 +1033,54 @@
         assertTrue(continued[0]);
     }
 
+    @Test
+    public void testGetOrCreateRootHomeTask_defaultDisplay() {
+        DisplayContent defaultDisplay = mWm.mRoot.getDisplayContent(DEFAULT_DISPLAY);
+
+        // Remove the current home stack if it exists so a new one can be created below.
+        ActivityStack homeTask = defaultDisplay.getRootHomeTask();
+        if (homeTask != null) {
+            defaultDisplay.removeStack(homeTask);
+        }
+        assertNull(defaultDisplay.getRootHomeTask());
+
+        assertNotNull(defaultDisplay.getOrCreateRootHomeTask());
+    }
+
+    @Test
+    public void testGetOrCreateRootHomeTask_supportedSecondaryDisplay() {
+        DisplayContent display = createNewDisplay();
+        doReturn(true).when(display).supportsSystemDecorations();
+        doReturn(false).when(display).isUntrustedVirtualDisplay();
+
+        // Remove the current home stack if it exists so a new one can be created below.
+        ActivityStack homeTask = display.getRootHomeTask();
+        if (homeTask != null) {
+            display.removeStack(homeTask);
+        }
+        assertNull(display.getRootHomeTask());
+
+        assertNotNull(display.getOrCreateRootHomeTask());
+    }
+
+    @Test
+    public void testGetOrCreateRootHomeTask_unsupportedSystemDecorations() {
+        DisplayContent display = createNewDisplay();
+        doReturn(false).when(display).supportsSystemDecorations();
+
+        assertNull(display.getRootHomeTask());
+        assertNull(display.getOrCreateRootHomeTask());
+    }
+
+    @Test
+    public void testGetOrCreateRootHomeTask_untrustedVirtualDisplay() {
+        DisplayContent display = createNewDisplay();
+        doReturn(true).when(display).isUntrustedVirtualDisplay();
+
+        assertNull(display.getRootHomeTask());
+        assertNull(display.getOrCreateRootHomeTask());
+    }
+
     private boolean isOptionsPanelAtRight(int displayId) {
         return (mWm.getPreferredOptionsPanelGravity(displayId) & Gravity.RIGHT) == Gravity.RIGHT;
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java
index 2a20c2e..7ba3fd8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java
@@ -102,10 +102,11 @@
     }
 
     void addWindow(WindowState win) {
-        mDisplayPolicy.adjustWindowParamsLw(win, win.mAttrs, Binder.getCallingPid(),
-                Binder.getCallingUid());
+        final int callingPid = Binder.getCallingPid();
+        final int callingUid = Binder.getCallingUid();
+        mDisplayPolicy.adjustWindowParamsLw(win, win.mAttrs, callingPid, callingUid);
         assertEquals(WindowManagerGlobal.ADD_OKAY,
-                mDisplayPolicy.validateAddingWindowLw(win.mAttrs));
+                mDisplayPolicy.validateAddingWindowLw(win.mAttrs, callingPid, callingUid));
         mDisplayPolicy.addWindowLw(win, win.mAttrs);
         win.mHasSurface = true;
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index a672a95..4449069 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -1098,7 +1098,6 @@
         assertSecurityException(expectCallable,
                 () -> mService.setTaskWindowingModeSplitScreenPrimary(0,
                         SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, true, true, new Rect(), true));
-        assertSecurityException(expectCallable, () -> mService.dismissSplitScreenMode(true));
         assertSecurityException(expectCallable, () -> mService.dismissPip(true, 0));
         assertSecurityException(expectCallable,
                 () -> mService.moveTopActivityToPinnedStack(INVALID_STACK_ID, new Rect()));
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
index 79db927..dd46673 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
@@ -860,6 +860,26 @@
                 secondaryDisplay.mDisplayId, result.getDisplayId());
     }
 
+    @Test
+    public void testSwitchUser_missingHomeRootTask() {
+        doReturn(mFullscreenStack).when(mRootWindowContainer).getTopDisplayFocusedStack();
+
+        DisplayContent defaultDisplay = mRootWindowContainer.getDefaultDisplay();
+        ActivityStack homeStack = defaultDisplay.getRootHomeTask();
+        if (homeStack != null) {
+            homeStack.removeImmediately();
+        }
+        assertNull(defaultDisplay.getRootHomeTask());
+
+        int currentUser = mRootWindowContainer.mCurrentUser;
+        int otherUser = currentUser + 1;
+
+        mRootWindowContainer.switchUser(otherUser, null);
+
+        assertNotNull(defaultDisplay.getRootHomeTask());
+        assertEquals(defaultDisplay.getTopStack(), defaultDisplay.getRootHomeTask());
+    }
+
     /**
      * Mock {@link RootWindowContainer#resolveHomeActivity} for returning consistent activity
      * info for test cases (the original implementation will resolve from the real package manager).
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java
index 0312df6..cd53ece 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java
@@ -28,19 +28,17 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
 
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
-
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -49,6 +47,7 @@
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.ActivityManager.StackInfo;
 import android.app.PictureInPictureParams;
+import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.Binder;
@@ -56,7 +55,6 @@
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
 import android.util.ArrayMap;
-import android.content.pm.ActivityInfo;
 import android.util.Rational;
 import android.view.Display;
 import android.view.ITaskOrganizer;
@@ -458,9 +456,9 @@
     private List<TaskTile> getTaskTiles(DisplayContent dc) {
         ArrayList<TaskTile> out = new ArrayList<>();
         for (int i = dc.getStackCount() - 1; i >= 0; --i) {
-            final Task t = dc.getStackAt(i);
-            if (t instanceof TaskTile) {
-                out.add((TaskTile) t);
+            final TaskTile t = dc.getStackAt(i).asTile();
+            if (t != null) {
+                out.add(t);
             }
         }
         return out;
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 3a68924..7a075a2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -75,7 +75,8 @@
     }
 
     @Override
-    public int checkAddPermission(WindowManager.LayoutParams attrs, int[] outAppOp) {
+    public int checkAddPermission(int type, boolean isRoundedCornerOverlay, String packageName,
+            int[] outAppOp) {
         return 0;
     }
 
diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java
index 9f2537c..203047f 100644
--- a/telephony/java/android/telephony/CellIdentityGsm.java
+++ b/telephony/java/android/telephony/CellIdentityGsm.java
@@ -22,11 +22,12 @@
 import android.os.Parcel;
 import android.telephony.gsm.GsmCellLocation;
 import android.text.TextUtils;
+import android.util.ArraySet;
 
-import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
-import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 
 /**
  * CellIdentity to represent a unique GSM cell
@@ -50,7 +51,7 @@
     private final int mBsic;
 
     // a list of additional PLMN-IDs reported for this cell
-    private final List<String> mAdditionalPlmns;
+    private final ArraySet<String> mAdditionalPlmns;
 
     /**
      * @hide
@@ -62,7 +63,7 @@
         mCid = CellInfo.UNAVAILABLE;
         mArfcn = CellInfo.UNAVAILABLE;
         mBsic = CellInfo.UNAVAILABLE;
-        mAdditionalPlmns = Collections.emptyList();
+        mAdditionalPlmns = new ArraySet<>();
     }
 
     /**
@@ -81,13 +82,13 @@
      */
     public CellIdentityGsm(int lac, int cid, int arfcn, int bsic, @Nullable String mccStr,
             @Nullable String mncStr, @Nullable String alphal, @Nullable String alphas,
-            @NonNull List<String> additionalPlmns) {
+            @NonNull Collection<String> additionalPlmns) {
         super(TAG, CellInfo.TYPE_GSM, mccStr, mncStr, alphal, alphas);
         mLac = inRangeOrUnavailable(lac, 0, MAX_LAC);
         mCid = inRangeOrUnavailable(cid, 0, MAX_CID);
         mArfcn = inRangeOrUnavailable(arfcn, 0, MAX_ARFCN);
         mBsic = inRangeOrUnavailable(bsic, 0, MAX_BSIC);
-        mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+        mAdditionalPlmns = new ArraySet<>(additionalPlmns.size());
         for (String plmn : additionalPlmns) {
             if (isValidPlmn(plmn)) {
                 mAdditionalPlmns.add(plmn);
@@ -99,7 +100,7 @@
     public CellIdentityGsm(@NonNull android.hardware.radio.V1_0.CellIdentityGsm cid) {
         this(cid.lac, cid.cid, cid.arfcn,
                 cid.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE : cid.bsic,
-                cid.mcc, cid.mnc, "", "", Collections.emptyList());
+                cid.mcc, cid.mnc, "", "", new ArraySet<>());
     }
 
     /** @hide */
@@ -107,7 +108,7 @@
         this(cid.base.lac, cid.base.cid, cid.base.arfcn,
                 cid.base.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE : cid.base.bsic, cid.base.mcc,
                 cid.base.mnc, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort,
-                Collections.emptyList());
+                new ArraySet<>());
     }
 
     /** @hide */
@@ -221,8 +222,8 @@
      * @return a list of additional PLMN IDs supported by this cell.
      */
     @NonNull
-    public List<String> getAdditionalPlmns() {
-        return mAdditionalPlmns;
+    public Set<String> getAdditionalPlmns() {
+        return Collections.unmodifiableSet(mAdditionalPlmns);
     }
 
     /**
@@ -296,7 +297,7 @@
         dest.writeInt(mCid);
         dest.writeInt(mArfcn);
         dest.writeInt(mBsic);
-        dest.writeList(mAdditionalPlmns);
+        dest.writeArraySet(mAdditionalPlmns);
     }
 
     /** Construct from Parcel, type has already been processed */
@@ -306,7 +307,7 @@
         mCid = in.readInt();
         mArfcn = in.readInt();
         mBsic = in.readInt();
-        mAdditionalPlmns = in.readArrayList(null);
+        mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null);
 
         if (DBG) log(toString());
     }
diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java
index a194ae3..e4198d1 100644
--- a/telephony/java/android/telephony/CellIdentityLte.java
+++ b/telephony/java/android/telephony/CellIdentityLte.java
@@ -23,11 +23,13 @@
 import android.os.Parcel;
 import android.telephony.gsm.GsmCellLocation;
 import android.text.TextUtils;
+import android.util.ArraySet;
 
-import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 
 /**
  * CellIdentity is to represent a unique LTE cell
@@ -54,7 +56,7 @@
     private final int mBandwidth;
 
     // a list of additional PLMN-IDs reported for this cell
-    private final List<String> mAdditionalPlmns;
+    private final ArraySet<String> mAdditionalPlmns;
 
     private ClosedSubscriberGroupInfo mCsgInfo;
 
@@ -69,7 +71,7 @@
         mTac = CellInfo.UNAVAILABLE;
         mEarfcn = CellInfo.UNAVAILABLE;
         mBandwidth = CellInfo.UNAVAILABLE;
-        mAdditionalPlmns = Collections.emptyList();
+        mAdditionalPlmns = new ArraySet<>();
         mCsgInfo = null;
     }
 
@@ -86,7 +88,7 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     public CellIdentityLte(int mcc, int mnc, int ci, int pci, int tac) {
         this(ci, pci, tac, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, String.valueOf(mcc),
-                String.valueOf(mnc), null, null, Collections.emptyList(), null);
+                String.valueOf(mnc), null, null, new ArraySet<>(), null);
     }
 
     /**
@@ -107,7 +109,7 @@
      */
     public CellIdentityLte(int ci, int pci, int tac, int earfcn, int bandwidth,
             @Nullable String mccStr, @Nullable String mncStr, @Nullable String alphal,
-            @Nullable String alphas, @NonNull List<String> additionalPlmns,
+            @Nullable String alphas, @NonNull Collection<String> additionalPlmns,
             @Nullable ClosedSubscriberGroupInfo csgInfo) {
         super(TAG, CellInfo.TYPE_LTE, mccStr, mncStr, alphal, alphas);
         mCi = inRangeOrUnavailable(ci, 0, MAX_CI);
@@ -115,7 +117,7 @@
         mTac = inRangeOrUnavailable(tac, 0, MAX_TAC);
         mEarfcn = inRangeOrUnavailable(earfcn, 0, MAX_EARFCN);
         mBandwidth = inRangeOrUnavailable(bandwidth, 0, MAX_BANDWIDTH);
-        mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+        mAdditionalPlmns = new ArraySet<>(additionalPlmns.size());
         for (String plmn : additionalPlmns) {
             if (isValidPlmn(plmn)) {
                 mAdditionalPlmns.add(plmn);
@@ -127,14 +129,14 @@
     /** @hide */
     public CellIdentityLte(@NonNull android.hardware.radio.V1_0.CellIdentityLte cid) {
         this(cid.ci, cid.pci, cid.tac, cid.earfcn,
-                CellInfo.UNAVAILABLE, cid.mcc, cid.mnc, "", "", Collections.emptyList(), null);
+                CellInfo.UNAVAILABLE, cid.mcc, cid.mnc, "", "", new ArraySet<>(), null);
     }
 
     /** @hide */
     public CellIdentityLte(@NonNull android.hardware.radio.V1_2.CellIdentityLte cid) {
         this(cid.base.ci, cid.base.pci, cid.base.tac, cid.base.earfcn, cid.bandwidth,
                 cid.base.mcc, cid.base.mnc, cid.operatorNames.alphaLong,
-                cid.operatorNames.alphaShort, Collections.emptyList(), null);
+                cid.operatorNames.alphaShort, new ArraySet<>(), null);
     }
 
     /** @hide */
@@ -270,8 +272,8 @@
      * @return a list of additional PLMN IDs supported by this cell.
      */
     @NonNull
-    public List<String> getAdditionalPlmns() {
-        return mAdditionalPlmns;
+    public Set<String> getAdditionalPlmns() {
+        return Collections.unmodifiableSet(mAdditionalPlmns);
     }
 
     /**
@@ -361,7 +363,7 @@
         dest.writeInt(mTac);
         dest.writeInt(mEarfcn);
         dest.writeInt(mBandwidth);
-        dest.writeList(mAdditionalPlmns);
+        dest.writeArraySet(mAdditionalPlmns);
         dest.writeParcelable(mCsgInfo, flags);
     }
 
@@ -373,7 +375,7 @@
         mTac = in.readInt();
         mEarfcn = in.readInt();
         mBandwidth = in.readInt();
-        mAdditionalPlmns = in.readArrayList(null);
+        mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null);
         mCsgInfo = in.readParcelable(null);
         if (DBG) log(toString());
     }
diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java
index a0ef5aa..cba500a 100644
--- a/telephony/java/android/telephony/CellIdentityNr.java
+++ b/telephony/java/android/telephony/CellIdentityNr.java
@@ -22,11 +22,14 @@
 import android.os.Parcel;
 import android.telephony.AccessNetworkConstants.NgranBands.NgranBand;
 import android.telephony.gsm.GsmCellLocation;
+import android.util.ArraySet;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 
 /**
  * Information to represent a unique NR(New Radio 5G) cell.
@@ -46,7 +49,7 @@
     private final List<Integer> mBands;
 
     // a list of additional PLMN-IDs reported for this cell
-    private final List<String> mAdditionalPlmns;
+    private final ArraySet<String> mAdditionalPlmns;
 
     /**
      *
@@ -66,14 +69,14 @@
     public CellIdentityNr(int pci, int tac, int nrArfcn, @NgranBand List<Integer> bands,
                           @Nullable String mccStr, @Nullable String mncStr, long nci,
                           @Nullable String alphal, @Nullable String alphas,
-                          @NonNull List<String> additionalPlmns) {
+                          @NonNull Collection<String> additionalPlmns) {
         super(TAG, CellInfo.TYPE_NR, mccStr, mncStr, alphal, alphas);
         mPci = inRangeOrUnavailable(pci, 0, MAX_PCI);
         mTac = inRangeOrUnavailable(tac, 0, MAX_TAC);
         mNrArfcn = inRangeOrUnavailable(nrArfcn, 0, MAX_NRARFCN);
         mBands = new ArrayList<>(bands);
         mNci = inRangeOrUnavailable(nci, 0, MAX_NCI);
-        mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+        mAdditionalPlmns = new ArraySet<>(additionalPlmns.size());
         for (String plmn : additionalPlmns) {
             if (isValidPlmn(plmn)) {
                 mAdditionalPlmns.add(plmn);
@@ -85,7 +88,7 @@
     public CellIdentityNr(@NonNull android.hardware.radio.V1_4.CellIdentityNr cid) {
         this(cid.pci, cid.tac, cid.nrarfcn, Collections.emptyList(), cid.mcc, cid.mnc, cid.nci,
                 cid.operatorNames.alphaLong, cid.operatorNames.alphaShort,
-                Collections.emptyList());
+                new ArraySet<>());
     }
 
     /** @hide */
@@ -212,8 +215,8 @@
      * @return a list of additional PLMN IDs supported by this cell.
      */
     @NonNull
-    public List<String> getAdditionalPlmns() {
-        return Collections.unmodifiableList(mAdditionalPlmns);
+    public Set<String> getAdditionalPlmns() {
+        return Collections.unmodifiableSet(mAdditionalPlmns);
     }
 
     @Override
@@ -241,7 +244,7 @@
         dest.writeInt(mNrArfcn);
         dest.writeList(mBands);
         dest.writeLong(mNci);
-        dest.writeList(mAdditionalPlmns);
+        dest.writeArraySet(mAdditionalPlmns);
     }
 
     /** Construct from Parcel, type has already been processed */
@@ -252,7 +255,7 @@
         mNrArfcn = in.readInt();
         mBands = in.readArrayList(null);
         mNci = in.readLong();
-        mAdditionalPlmns = in.readArrayList(null);
+        mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null);
     }
 
     /** Implement the Parcelable interface */
diff --git a/telephony/java/android/telephony/CellIdentityTdscdma.java b/telephony/java/android/telephony/CellIdentityTdscdma.java
index 531487a..30f98bc 100644
--- a/telephony/java/android/telephony/CellIdentityTdscdma.java
+++ b/telephony/java/android/telephony/CellIdentityTdscdma.java
@@ -20,11 +20,12 @@
 import android.annotation.Nullable;
 import android.os.Parcel;
 import android.telephony.gsm.GsmCellLocation;
+import android.util.ArraySet;
 
-import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
-import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 
 /**
  * CellIdentity is to represent a unique TD-SCDMA cell
@@ -50,7 +51,7 @@
     private final int mUarfcn;
 
     // a list of additional PLMN-IDs reported for this cell
-    private final List<String> mAdditionalPlmns;
+    private final ArraySet<String> mAdditionalPlmns;
 
     private ClosedSubscriberGroupInfo mCsgInfo;
 
@@ -63,7 +64,7 @@
         mCid = CellInfo.UNAVAILABLE;
         mCpid = CellInfo.UNAVAILABLE;
         mUarfcn = CellInfo.UNAVAILABLE;
-        mAdditionalPlmns = Collections.emptyList();
+        mAdditionalPlmns = new ArraySet<>();
         mCsgInfo = null;
     }
 
@@ -85,13 +86,14 @@
      */
     public CellIdentityTdscdma(@Nullable String mcc, @Nullable String mnc, int lac, int cid,
             int cpid, int uarfcn, @Nullable String alphal, @Nullable String alphas,
-            @NonNull List<String> additionalPlmns, @Nullable ClosedSubscriberGroupInfo csgInfo) {
+            @NonNull Collection<String> additionalPlmns,
+            @Nullable ClosedSubscriberGroupInfo csgInfo) {
         super(TAG, CellInfo.TYPE_TDSCDMA, mcc, mnc, alphal, alphas);
         mLac = inRangeOrUnavailable(lac, 0, MAX_LAC);
         mCid = inRangeOrUnavailable(cid, 0, MAX_CID);
         mCpid = inRangeOrUnavailable(cpid, 0, MAX_CPID);
         mUarfcn = inRangeOrUnavailable(uarfcn, 0, MAX_UARFCN);
-        mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+        mAdditionalPlmns = new ArraySet<>(additionalPlmns.size());
         for (String plmn : additionalPlmns) {
             if (isValidPlmn(plmn)) {
                 mAdditionalPlmns.add(plmn);
@@ -208,8 +210,8 @@
      * @return a list of additional PLMN IDs supported by this cell.
      */
     @NonNull
-    public List<String> getAdditionalPlmns() {
-        return mAdditionalPlmns;
+    public Set<String> getAdditionalPlmns() {
+        return Collections.unmodifiableSet(mAdditionalPlmns);
     }
 
     /**
@@ -289,7 +291,7 @@
         dest.writeInt(mCid);
         dest.writeInt(mCpid);
         dest.writeInt(mUarfcn);
-        dest.writeList(mAdditionalPlmns);
+        dest.writeArraySet(mAdditionalPlmns);
         dest.writeParcelable(mCsgInfo, flags);
     }
 
@@ -300,7 +302,7 @@
         mCid = in.readInt();
         mCpid = in.readInt();
         mUarfcn = in.readInt();
-        mAdditionalPlmns = in.readArrayList(null);
+        mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null);
         mCsgInfo = in.readParcelable(null);
         if (DBG) log(toString());
     }
diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java
index 15e491b..9d2cb74 100644
--- a/telephony/java/android/telephony/CellIdentityWcdma.java
+++ b/telephony/java/android/telephony/CellIdentityWcdma.java
@@ -22,11 +22,12 @@
 import android.os.Parcel;
 import android.telephony.gsm.GsmCellLocation;
 import android.text.TextUtils;
+import android.util.ArraySet;
 
-import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
-import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 
 /**
  * CellIdentity to represent a unique UMTS cell
@@ -51,7 +52,7 @@
     private final int mUarfcn;
 
     // a list of additional PLMN-IDs reported for this cell
-    private final List<String> mAdditionalPlmns;
+    private final ArraySet<String> mAdditionalPlmns;
 
     @Nullable
     private final ClosedSubscriberGroupInfo mCsgInfo;
@@ -65,7 +66,7 @@
         mCid = CellInfo.UNAVAILABLE;
         mPsc = CellInfo.UNAVAILABLE;
         mUarfcn = CellInfo.UNAVAILABLE;
-        mAdditionalPlmns = Collections.emptyList();
+        mAdditionalPlmns = new ArraySet<>();
         mCsgInfo = null;
     }
 
@@ -86,13 +87,14 @@
      */
     public CellIdentityWcdma(int lac, int cid, int psc, int uarfcn, @Nullable String mccStr,
             @Nullable String mncStr, @Nullable String alphal, @Nullable String alphas,
-            @NonNull List<String> additionalPlmns, @Nullable ClosedSubscriberGroupInfo csgInfo) {
+            @NonNull Collection<String> additionalPlmns,
+            @Nullable ClosedSubscriberGroupInfo csgInfo) {
         super(TAG, CellInfo.TYPE_WCDMA, mccStr, mncStr, alphal, alphas);
         mLac = inRangeOrUnavailable(lac, 0, MAX_LAC);
         mCid = inRangeOrUnavailable(cid, 0, MAX_CID);
         mPsc = inRangeOrUnavailable(psc, 0, MAX_PSC);
         mUarfcn = inRangeOrUnavailable(uarfcn, 0, MAX_UARFCN);
-        mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+        mAdditionalPlmns = new ArraySet<>(additionalPlmns.size());
         for (String plmn : additionalPlmns) {
             if (isValidPlmn(plmn)) {
                 mAdditionalPlmns.add(plmn);
@@ -104,14 +106,14 @@
     /** @hide */
     public CellIdentityWcdma(@NonNull android.hardware.radio.V1_0.CellIdentityWcdma cid) {
         this(cid.lac, cid.cid, cid.psc, cid.uarfcn, cid.mcc, cid.mnc, "", "",
-                Collections.emptyList(), null);
+                new ArraySet<>(), null);
     }
 
     /** @hide */
     public CellIdentityWcdma(@NonNull android.hardware.radio.V1_2.CellIdentityWcdma cid) {
         this(cid.base.lac, cid.base.cid, cid.base.psc, cid.base.uarfcn,
                 cid.base.mcc, cid.base.mnc, cid.operatorNames.alphaLong,
-                cid.operatorNames.alphaShort, Collections.emptyList(), null);
+                cid.operatorNames.alphaShort, new ArraySet<>(), null);
     }
 
     /** @hide */
@@ -232,8 +234,8 @@
      * @return a list of additional PLMN IDs supported by this cell.
      */
     @NonNull
-    public List<String> getAdditionalPlmns() {
-        return mAdditionalPlmns;
+    public Set<String> getAdditionalPlmns() {
+        return Collections.unmodifiableSet(mAdditionalPlmns);
     }
 
     /**
@@ -305,7 +307,7 @@
         dest.writeInt(mCid);
         dest.writeInt(mPsc);
         dest.writeInt(mUarfcn);
-        dest.writeList(mAdditionalPlmns);
+        dest.writeArraySet(mAdditionalPlmns);
         dest.writeParcelable(mCsgInfo, flags);
     }
 
@@ -316,7 +318,7 @@
         mCid = in.readInt();
         mPsc = in.readInt();
         mUarfcn = in.readInt();
-        mAdditionalPlmns = in.readArrayList(null);
+        mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null);
         mCsgInfo = in.readParcelable(null);
         if (DBG) log(toString());
     }
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index f9de47d..c74e17f 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -258,7 +258,7 @@
         mCellIdentity = cellIdentity;
         mEmergencyOnly = emergencyOnly;
         mNrState = NR_STATE_NONE;
-        mRplmn = (rplmn == null) ? "" : rplmn;
+        mRplmn = rplmn;
     }
 
     /**
@@ -408,13 +408,13 @@
      * <p>If the device is registered, this will return the registered PLMN-ID. If registration
      * has failed, then this will return the PLMN ID of the last attempted registration. If the
      * device is not registered, or if is registered to a non-3GPP radio technology, then this
-     * will return an empty string.
+     * will return null.
      *
      * <p>See 3GPP TS 23.122 for further information about the Registered PLMN.
      *
-     * @return the registered PLMN-ID or an empty string.
+     * @return the registered PLMN-ID or null.
      */
-    @NonNull public String getRegisteredPlmn() {
+    @Nullable public String getRegisteredPlmn() {
         return mRplmn;
     }
 
@@ -892,7 +892,7 @@
          * @return The same instance of the builder.
          */
         public @NonNull Builder setRegisteredPlmn(@Nullable String rplmn) {
-            mRplmn = (rplmn == null) ? "" : rplmn;
+            mRplmn = rplmn;
             return this;
         }
 
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 15103bf..68b6683 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -13135,7 +13135,7 @@
     */
     static IPhoneSubInfo getSubscriberInfoService() {
         // Keeps cache disabled until test fixes are checked into AOSP.
-        if (true) {
+        if (!sServiceHandleCacheEnabled) {
             return IPhoneSubInfo.Stub.asInterface(
                 TelephonyFrameworkInitializer
                         .getTelephonyServiceManager()
@@ -13169,7 +13169,7 @@
     */
     static ISub getSubscriptionService() {
         // Keeps cache disabled until test fixes are checked into AOSP.
-        if (true) {
+        if (!sServiceHandleCacheEnabled) {
             return ISub.Stub.asInterface(
                     TelephonyFrameworkInitializer
                             .getTelephonyServiceManager()
@@ -13203,7 +13203,7 @@
     */
     static ISms getSmsService() {
         // Keeps cache disabled until test fixes are checked into AOSP.
-        if (true) {
+        if (!sServiceHandleCacheEnabled) {
             return ISms.Stub.asInterface(
                     TelephonyFrameworkInitializer
                             .getTelephonyServiceManager()
diff --git a/tests/RollbackTest/RollbackTest/AndroidManifest.xml b/tests/RollbackTest/RollbackTest/AndroidManifest.xml
index 2b8c964..9274da2 100644
--- a/tests/RollbackTest/RollbackTest/AndroidManifest.xml
+++ b/tests/RollbackTest/RollbackTest/AndroidManifest.xml
@@ -17,6 +17,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.tests.rollback" >
 
+    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
     <application>
         <receiver android:name="com.android.cts.install.lib.LocalIntentSender"
                   android:exported="true" />
diff --git a/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/WindowInsetsActivity.java b/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/WindowInsetsActivity.java
index 01e212d..b9f5ac0 100644
--- a/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/WindowInsetsActivity.java
+++ b/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/WindowInsetsActivity.java
@@ -16,24 +16,26 @@
 
 package com.google.android.test.windowinsetstests;
 
+import static android.view.WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP;
+
 import android.animation.ObjectAnimator;
 import android.animation.TypeEvaluator;
 import android.animation.ValueAnimator;
 import android.app.Activity;
 import android.graphics.Insets;
 import android.os.Bundle;
-import android.util.Log;
 import android.util.Property;
 import android.view.View;
 import android.view.WindowInsets;
 import android.view.WindowInsets.Type;
-import android.view.WindowInsetsAnimationCallback;
-import android.view.WindowInsetsAnimationCallback.InsetsAnimation;
+import android.view.WindowInsetsAnimation;
 import android.view.WindowInsetsAnimationControlListener;
 import android.view.WindowInsetsAnimationController;
 
 import com.google.android.test.windowinsetstests.R;
 
+import java.util.List;
+
 public class WindowInsetsActivity extends Activity {
 
     private View mRoot;
@@ -70,7 +72,7 @@
 
     float startY;
     float endY;
-    InsetsAnimation imeAnim;
+    WindowInsetsAnimation imeAnim;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -85,15 +87,11 @@
                 v.getWindowInsetsController().hide(Type.ime());
             }
         });
-        mRoot.setWindowInsetsAnimationCallback(new WindowInsetsAnimationCallback() {
+        mRoot.setWindowInsetsAnimationCallback(new WindowInsetsAnimation.Callback(
+                DISPATCH_MODE_STOP) {
 
             @Override
-            public int getDispatchMode() {
-                return DISPATCH_MODE_STOP;
-            }
-
-            @Override
-            public void onPrepare(InsetsAnimation animation) {
+            public void onPrepare(WindowInsetsAnimation animation) {
                 if ((animation.getTypeMask() & Type.ime()) != 0) {
                     imeAnim = animation;
                 }
@@ -101,20 +99,21 @@
             }
 
             @Override
-            public WindowInsets onProgress(WindowInsets insets) {
+            public WindowInsets onProgress(WindowInsets insets,
+                    List<WindowInsetsAnimation> runningAnimations) {
                 mButton.setY(startY + (endY - startY) * imeAnim.getInterpolatedFraction());
                 return insets;
             }
 
             @Override
-            public AnimationBounds onStart(InsetsAnimation animation,
-                    AnimationBounds bounds) {
+            public WindowInsetsAnimation.Bounds onStart(WindowInsetsAnimation animation,
+                    WindowInsetsAnimation.Bounds bounds) {
                 endY = mButton.getTop();
                 return bounds;
             }
 
             @Override
-            public void onFinish(InsetsAnimation animation) {
+            public void onEnd(WindowInsetsAnimation animation) {
                 imeAnim = null;
             }
         });
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 968f552..2e59966 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -799,6 +799,14 @@
             mProbesSucceeded = probesSucceeded;
         }
 
+        void notifyCaptivePortalDataChanged(CaptivePortalData data) {
+            try {
+                mNmCallbacks.notifyCaptivePortalDataChanged(data);
+            } catch (RemoteException e) {
+                throw new AssertionError("This cannot happen", e);
+            }
+        }
+
         public String waitForRedirectUrl() {
             assertTrue(mNetworkStatusReceived.block(TIMEOUT_MS));
             return mRedirectUrl;
@@ -1845,18 +1853,21 @@
         final Uri capportUrl = Uri.parse("https://capport.example.com/api");
         final CaptivePortalData capportData = new CaptivePortalData.Builder()
                 .setCaptive(true).build();
-        newLp.setCaptivePortalApiUrl(capportUrl);
-        newLp.setCaptivePortalData(capportData);
-        mWiFiNetworkAgent.sendLinkProperties(newLp);
 
         final Uri expectedCapportUrl = sanitized ? null : capportUrl;
-        final CaptivePortalData expectedCapportData = sanitized ? null : capportData;
+        newLp.setCaptivePortalApiUrl(capportUrl);
+        mWiFiNetworkAgent.sendLinkProperties(newLp);
         callback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp ->
-                Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl())
-                && Objects.equals(expectedCapportData, lp.getCaptivePortalData()));
+                Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl()));
         defaultCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp ->
-                Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl())
-                && Objects.equals(expectedCapportData, lp.getCaptivePortalData()));
+                Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl()));
+
+        final CaptivePortalData expectedCapportData = sanitized ? null : capportData;
+        mWiFiNetworkAgent.notifyCaptivePortalDataChanged(capportData);
+        callback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp ->
+                Objects.equals(expectedCapportData, lp.getCaptivePortalData()));
+        defaultCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp ->
+                Objects.equals(expectedCapportData, lp.getCaptivePortalData()));
 
         final LinkProperties lp = mCm.getLinkProperties(mWiFiNetworkAgent.getNetwork());
         assertEquals(expectedCapportUrl, lp.getCaptivePortalApiUrl());
@@ -2810,6 +2821,40 @@
         assertNoCallbacks(captivePortalCallback, validatedCallback);
     }
 
+    @Test
+    public void testCaptivePortalApi() throws Exception {
+        mServiceContext.setPermission(
+                android.Manifest.permission.NETWORK_SETTINGS, PERMISSION_GRANTED);
+
+        final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
+        final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
+                .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
+        mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback);
+
+        mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
+        final String redirectUrl = "http://example.com/firstPath";
+
+        mWiFiNetworkAgent.connectWithCaptivePortal(redirectUrl, false /* isStrictMode */);
+        captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+
+        final CaptivePortalData testData = new CaptivePortalData.Builder()
+                .setUserPortalUrl(Uri.parse(redirectUrl))
+                .setBytesRemaining(12345L)
+                .build();
+
+        mWiFiNetworkAgent.notifyCaptivePortalDataChanged(testData);
+
+        captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent,
+                lp -> testData.equals(lp.getCaptivePortalData()));
+
+        final LinkProperties newLps = new LinkProperties();
+        newLps.setMtu(1234);
+        mWiFiNetworkAgent.sendLinkProperties(newLps);
+        // CaptivePortalData is not lost and unchanged when LPs are received from the NetworkAgent
+        captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent,
+                lp -> testData.equals(lp.getCaptivePortalData()) && lp.getMtu() == 1234);
+    }
+
     private NetworkRequest.Builder newWifiRequestBuilder() {
         return new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI);
     }
@@ -3154,6 +3199,7 @@
                 mCellNetworkAgent);
         cellNetworkCallback.expectCallback(CallbackEntry.SUSPENDED, mCellNetworkAgent);
         cellNetworkCallback.assertNoCallback();
+        assertEquals(NetworkInfo.State.SUSPENDED, mCm.getActiveNetworkInfo().getState());
 
         // Register a garden variety default network request.
         TestNetworkCallback dfltNetworkCallback = new TestNetworkCallback();
@@ -3169,6 +3215,7 @@
                 mCellNetworkAgent);
         cellNetworkCallback.expectCallback(CallbackEntry.RESUMED, mCellNetworkAgent);
         cellNetworkCallback.assertNoCallback();
+        assertEquals(NetworkInfo.State.CONNECTED, mCm.getActiveNetworkInfo().getState());
 
         dfltNetworkCallback = new TestNetworkCallback();
         mCm.registerDefaultNetworkCallback(dfltNetworkCallback);
diff --git a/tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java b/tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java
index 37842de..957216e 100644
--- a/tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java
+++ b/tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java
@@ -45,7 +45,6 @@
             "android.view.InsetsSourceTest",
             "android.view.InsetsSourceConsumerTest",
             "android.view.InsetsStateTest",
-            "android.view.WindowMetricsTest"
     };
 
     public FrameworksTestsFilter(Bundle testArgs) {
diff --git a/wifi/Android.bp b/wifi/Android.bp
index 1763975..7669983 100644
--- a/wifi/Android.bp
+++ b/wifi/Android.bp
@@ -86,6 +86,7 @@
         // TODO(b/146757305): should be unnecessary once
         // sdk_version="module_lib_current"
         "android_system_stubs_current",
+        "framework_mediaprovider_annotation", // for android.annotation.CurrentTimeMillisLong
     ],
     srcs: [
         ":framework-wifi-updatable-sources",
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index dc5ac1e..e1450cb 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -486,7 +486,7 @@
                 allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SAE);
                 allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
                 allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
-                requirePMF = true;
+                requirePmf = true;
                 break;
             case SECURITY_TYPE_EAP_SUITE_B:
                 allowedProtocols.set(WifiConfiguration.Protocol.RSN);
@@ -496,14 +496,14 @@
                 allowedGroupManagementCiphers.set(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256);
                 // Note: allowedSuiteBCiphers bitset will be set by the service once the
                 // certificates are attached to this profile
-                requirePMF = true;
+                requirePmf = true;
                 break;
             case SECURITY_TYPE_OWE:
                 allowedProtocols.set(WifiConfiguration.Protocol.RSN);
                 allowedKeyManagement.set(WifiConfiguration.KeyMgmt.OWE);
                 allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
                 allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
-                requirePMF = true;
+                requirePmf = true;
                 break;
             case SECURITY_TYPE_WAPI_PSK:
                 allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WAPI_PSK);
@@ -662,7 +662,7 @@
      * @hide
      */
     @SystemApi
-    public boolean requirePMF;
+    public boolean requirePmf;
 
     /**
      * Update identifier, for Passpoint network.
@@ -2169,7 +2169,7 @@
                 append(" BSSID: ").append(this.BSSID).append(" FQDN: ").append(this.FQDN)
                 .append(" PRIO: ").append(this.priority)
                 .append(" HIDDEN: ").append(this.hiddenSSID)
-                .append(" PMF: ").append(this.requirePMF)
+                .append(" PMF: ").append(this.requirePmf)
                 .append("CarrierId: ").append(this.carrierId)
                 .append('\n');
 
@@ -2761,7 +2761,7 @@
             mRandomizedMacAddress = source.mRandomizedMacAddress;
             macRandomizationSetting = source.macRandomizationSetting;
             randomizedMacExpirationTimeMs = source.randomizedMacExpirationTimeMs;
-            requirePMF = source.requirePMF;
+            requirePmf = source.requirePmf;
             updateIdentifier = source.updateIdentifier;
             carrierId = source.carrierId;
             mPasspointUniqueId = source.mPasspointUniqueId;
@@ -2793,7 +2793,7 @@
         dest.writeInt(wepTxKeyIndex);
         dest.writeInt(priority);
         dest.writeInt(hiddenSSID ? 1 : 0);
-        dest.writeInt(requirePMF ? 1 : 0);
+        dest.writeInt(requirePmf ? 1 : 0);
         dest.writeString(updateIdentifier);
 
         writeBitSet(dest, allowedKeyManagement);
@@ -2869,7 +2869,7 @@
                 config.wepTxKeyIndex = in.readInt();
                 config.priority = in.readInt();
                 config.hiddenSSID = in.readInt() != 0;
-                config.requirePMF = in.readInt() != 0;
+                config.requirePmf = in.readInt() != 0;
                 config.updateIdentifier = in.readString();
 
                 config.allowedKeyManagement   = readBitSet(in);
diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
index 7d56585..7d9bdba 100644
--- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
+++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
@@ -19,6 +19,7 @@
 import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NONE;
 import static android.net.wifi.WifiConfiguration.MeteredOverride;
 
+import android.annotation.CurrentTimeMillisLong;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
@@ -247,12 +248,12 @@
      *
      * Use Long.MIN_VALUE to indicate unset value.
      */
-    private long mSubscriptionExpirationTimeInMillis = Long.MIN_VALUE;
+    private long mSubscriptionExpirationTimeMillis = Long.MIN_VALUE;
     /**
      * @hide
      */
     public void setSubscriptionExpirationTimeInMillis(long subscriptionExpirationTimeInMillis) {
-        mSubscriptionExpirationTimeInMillis = subscriptionExpirationTimeInMillis;
+        mSubscriptionExpirationTimeMillis = subscriptionExpirationTimeInMillis;
     }
     /**
      *  Utility method to get the time this subscription will expire. It is in the format of number
@@ -260,8 +261,9 @@
      *
      *  @return The time this subscription will expire, or Long.MIN_VALUE to indicate unset value
      */
-    public long getSubscriptionExpirationTimeInMillis() {
-        return mSubscriptionExpirationTimeInMillis;
+    @CurrentTimeMillisLong
+    public long getSubscriptionExpirationTimeMillis() {
+        return mSubscriptionExpirationTimeMillis;
     }
 
     /**
@@ -561,7 +563,7 @@
         mUpdateIdentifier = source.mUpdateIdentifier;
         mCredentialPriority = source.mCredentialPriority;
         mSubscriptionCreationTimeInMillis = source.mSubscriptionCreationTimeInMillis;
-        mSubscriptionExpirationTimeInMillis = source.mSubscriptionExpirationTimeInMillis;
+        mSubscriptionExpirationTimeMillis = source.mSubscriptionExpirationTimeMillis;
         mSubscriptionType = source.mSubscriptionType;
         mUsageLimitDataLimit = source.mUsageLimitDataLimit;
         mUsageLimitStartTimeInMillis = source.mUsageLimitStartTimeInMillis;
@@ -590,7 +592,7 @@
         dest.writeInt(mUpdateIdentifier);
         dest.writeInt(mCredentialPriority);
         dest.writeLong(mSubscriptionCreationTimeInMillis);
-        dest.writeLong(mSubscriptionExpirationTimeInMillis);
+        dest.writeLong(mSubscriptionExpirationTimeMillis);
         dest.writeString(mSubscriptionType);
         dest.writeLong(mUsageLimitUsageTimePeriodInMinutes);
         dest.writeLong(mUsageLimitStartTimeInMillis);
@@ -628,7 +630,7 @@
                 && mUpdateIdentifier == that.mUpdateIdentifier
                 && mCredentialPriority == that.mCredentialPriority
                 && mSubscriptionCreationTimeInMillis == that.mSubscriptionCreationTimeInMillis
-                && mSubscriptionExpirationTimeInMillis == that.mSubscriptionExpirationTimeInMillis
+                && mSubscriptionExpirationTimeMillis == that.mSubscriptionExpirationTimeMillis
                 && TextUtils.equals(mSubscriptionType, that.mSubscriptionType)
                 && mUsageLimitUsageTimePeriodInMinutes == that.mUsageLimitUsageTimePeriodInMinutes
                 && mUsageLimitStartTimeInMillis == that.mUsageLimitStartTimeInMillis
@@ -646,7 +648,7 @@
     public int hashCode() {
         return Objects.hash(mHomeSp, mCredential, mPolicy, mSubscriptionUpdate, mTrustRootCertList,
                 mUpdateIdentifier, mCredentialPriority, mSubscriptionCreationTimeInMillis,
-                mSubscriptionExpirationTimeInMillis, mUsageLimitUsageTimePeriodInMinutes,
+                mSubscriptionExpirationTimeMillis, mUsageLimitUsageTimePeriodInMinutes,
                 mUsageLimitStartTimeInMillis, mUsageLimitDataLimit, mUsageLimitTimeLimitInMinutes,
                 mServiceFriendlyNames, mCarrierId, mIsAutojoinEnabled, mIsMacRandomizationEnabled,
                 mMeteredOverride);
@@ -661,8 +663,8 @@
                 mSubscriptionCreationTimeInMillis != Long.MIN_VALUE
                 ? new Date(mSubscriptionCreationTimeInMillis) : "Not specified").append("\n");
         builder.append("SubscriptionExpirationTime: ").append(
-                mSubscriptionExpirationTimeInMillis != Long.MIN_VALUE
-                ? new Date(mSubscriptionExpirationTimeInMillis) : "Not specified").append("\n");
+                mSubscriptionExpirationTimeMillis != Long.MIN_VALUE
+                ? new Date(mSubscriptionExpirationTimeMillis) : "Not specified").append("\n");
         builder.append("UsageLimitStartTime: ").append(mUsageLimitStartTimeInMillis != Long.MIN_VALUE
                 ? new Date(mUsageLimitStartTimeInMillis) : "Not specified").append("\n");
         builder.append("UsageTimePeriod: ").append(mUsageLimitUsageTimePeriodInMinutes)
diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
index 05a3dce..00790d5 100644
--- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
@@ -363,7 +363,7 @@
         assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE));
         assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.CCMP));
         assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.CCMP));
-        assertTrue(config.requirePMF);
+        assertTrue(config.requirePmf);
     }
 
     /**
@@ -380,7 +380,7 @@
         assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.OWE));
         assertTrue(config.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.CCMP));
         assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.CCMP));
-        assertTrue(config.requirePMF);
+        assertTrue(config.requirePmf);
     }
 
     /**
@@ -399,7 +399,7 @@
         assertTrue(config.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.GCMP_256));
         assertTrue(config.allowedGroupManagementCiphers
                 .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256));
-        assertTrue(config.requirePMF);
+        assertTrue(config.requirePmf);
     }
 
     /**
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
index af6fb5c..51bf738 100644
--- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
@@ -140,7 +140,7 @@
         assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
                 .get(WifiConfiguration.KeyMgmt.OWE));
         assertNull(suggestion.wifiConfiguration.preSharedKey);
-        assertTrue(suggestion.wifiConfiguration.requirePMF);
+        assertTrue(suggestion.wifiConfiguration.requirePmf);
         assertFalse(suggestion.isUserAllowedToManuallyConnect);
         assertTrue(suggestion.isInitialAutoJoinEnabled);
     }
@@ -163,7 +163,7 @@
                 .get(WifiConfiguration.KeyMgmt.SAE));
         assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
                 suggestion.wifiConfiguration.preSharedKey);
-        assertTrue(suggestion.wifiConfiguration.requirePMF);
+        assertTrue(suggestion.wifiConfiguration.requirePmf);
         assertTrue(suggestion.isUserAllowedToManuallyConnect);
         assertFalse(suggestion.isInitialAutoJoinEnabled);
     }
@@ -191,7 +191,7 @@
                 .get(WifiConfiguration.GroupCipher.GCMP_256));
         assertTrue(suggestion.wifiConfiguration.allowedGroupManagementCiphers
                 .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256));
-        assertTrue(suggestion.wifiConfiguration.requirePMF);
+        assertTrue(suggestion.wifiConfiguration.requirePmf);
         assertNull(suggestion.wifiConfiguration.preSharedKey);
         // allowedSuiteBCiphers are set according to the loaded certificate and cannot be tested
         // here.